Realign read-side rules — width range coercion, finite order, symlink pins

The design corpus ratified that ranges are part of a sensible reading:
an exact-integer width below 1 now coerces to 1 read-side (bytes
untouched) instead of reading as malformed — the width division must
never see a zero or negative unit — while a non-finite order (.nan,
.inf) is now the same loud malformed-order rejection as a non-numeric
one, guarded at the single point where the double arrives so loader
and Writer inherit it together. The symlink-never-traversed rule
turned out to be already enforced (the loader has filtered symlinks
ahead of the directory check since the first commit); it and the
copy-preserves-the-link-verbatim behavior are now pinned by tests,
alongside the two hostile shapes the corpus names (width: 0,
order: .nan). Five new tests.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-27 14:21:03 -04:00
parent b4c90838b4
commit bea6d02d1d
6 changed files with 155 additions and 27 deletions
+12 -3
View File
@@ -139,13 +139,22 @@ struct LaneDisplayUnitsTests {
#expect(missing.width.isMissing)
#expect(LaneLayoutMath.displayUnits(of: missing) == 1)
// Each of these stays `.malformed` on the model the bytes are preserved, not corrected
// and renders as 1 (01-storage-format.md § Frontmatter's lenient-field rule).
for raw in ["wide", "0", "-3", "1.5"] {
// A fraction or non-numeric text has no integer reading at all stays `.malformed` on
// the model (bytes preserved, not corrected) and renders as 1.
for raw in ["wide", "1.5"] {
let lane = try lane(width: raw)
#expect(lane.width.isMalformed, "width: \(raw) should stay malformed rather than coerce")
#expect(LaneLayoutMath.displayUnits(of: lane) == 1, "width: \(raw) should render as one unit")
}
// An exact integer below 1 is a **different** case (01-storage-format.md § Frontmatter,
// "ranges are part of the sensible reading", settled): it coerces to `.valid(1)`, not
// malformed same on-screen result, different model reading.
for raw in ["0", "-3"] {
let lane = try lane(width: raw)
#expect(lane.width == .valid(1), "width: \(raw) should coerce to 1, not stay malformed")
#expect(LaneLayoutMath.displayUnits(of: lane) == 1, "width: \(raw) should render as one unit")
}
}
@Test("The strip's unit total is the sum over the lanes it is given")