4.3 KiB
Session handoff — 2026-06-02 (56)
Fifty-sixth handover, same day as #54/#55. Clears the pre-existing
YAML security debt flagged in handoff-55 §3: migrated off the
unsound + unmaintained serde_yml / libyml to the maintained
serde_norway. Clean dependency swap — no API friction, no
behaviour change, full suite unchanged.
§1. State at handoff
Branch: main. Builds on handoff-55's two commits (d0c8f9d #11,
c9a92c9 handoff-55). This session adds the migration commit + this
handoff on top. Tests: 2151 passing / 0 failing / 1 ignored
(identical to post-#11 — the migration changed no behaviour). Clippy
clean (nursery, all targets, -D warnings). Push is the user's step.
GitHub #11 is closed (done this session, after the #55 work). Per the user: this repo's GitHub issues are dev-phase bug tracking only (the repo will move elsewhere), so follow-on tasks like this migration are tracked in handoffs, not issues.
§2. The migration — serde_yml → serde_norway
Why. Handoff-55 §3 flagged two RustSec advisories, both dated
2025-09-11, both informational = "unsound" (not exploitable-CVE
class — hence cargo audit's exit-0 "allowed warnings"):
- RUSTSEC-2025-0068 —
serde_yml0.0.12:Serializer.emittercan segfault; project archived; no patched version. - RUSTSEC-2025-0067 — its
libyml0.0.5 backend:yaml_string_extendhas UB; project archived; no patched version.
serde_yml was a fork of the deprecated serde_yaml that then got
flagged + archived itself. The only remedy RustSec offers is switching
crates. serde_norway (0.9.42, MIT OR Apache-2.0, MSRV 1.71.1) is the
maintained serde_yaml fork (repo cafkafk/serde-yaml), backed by the
maintained unsafe-libyaml-norway.
Threat that motivated it. Input is normally the project's own
project.yaml / undo index / embedded catalog, but import <zip>
and shared/exported projects carry externally-authored YAML — a
crafted project.yaml could trigger the segfault (crash/DoS) or UB.
What changed (mechanical — serde_norway is API-compatible with
serde_yaml/serde_yml for everything we use):
Cargo.toml—serde_yml = "0.0.12"→serde_norway = "0.9.42"(with a comment recording the two RUSTSEC IDs).src/persistence/yaml.rs—from_str(project + raw-project read); doc comments updated to name the new crate.src/persistence/migrations.rs—from_str(version probe).src/undo.rs—from_str/to_string(snapshot index round-trip).src/friendly/format.rs—Value/Value::{Mapping,String,Null}(embeddeden-US.yamlcatalog parse).
No function signatures, call shapes, or Value pattern matches needed
adjustment — a straight identifier swap (serde_yml:: →
serde_norway::).
Verification:
cargo build --all-targets— clean (drop-in confirmed).- Full
cargo test— 2151 / 0 / 1, unchanged from post-#11; the existingproject.yamlround-trip + persistence + undo-index + catalog-format suites are the safety net and all stayed green. clippynursery-D warnings— clean.- Advisories cleared, three scanners agree:
cargo audit(294 crates) → no advisories;osv-scanner→ No issues found;grype→ no findings.cargo tree -i serde_yml/-i libyml→ both gone from the tree;serde_norwaypresent.serde_norwayintroduces no advisory of its own.
§3. What's open
- The two arboard decisions from handoff-55 §3 remain open-for-correction (no-Wayland-feature; verbatim-copy-with-tags).
- Other tracks unchanged from handoff-55 §5 (Track 2 Iter 6 leftovers; C3a/C4; H1 friendly errors; tutorial system; V4 session-log/Markdown export; I1/I1b/I3/I4 input UX). The serde_yml security debt is now resolved — strike it from the list.
§4. How to take over
- Read handoff-55 first (the #11 / clipboard / ADR-0041 work), then
this note, then
CLAUDE.md/requirements.md/docs/adr/README.md. - The codebase is on
main; this migration commit + handoff sit on top of the handoff-55 commits, all unpushed (the user's step). - No ADR was written for the migration — it's a like-for-like dependency swap with no design decision, tracked here per the handoff-not-issue convention. If the project later wants a written record of the dependency rationale, this handoff §2 is it.