Adopt read-side coercion for schema-owned fields

Design-review resolutions: schema-owned display fields coerce where a
sensible reading exists (wrong-type scalars read as source text, width
accepts exact-integer strings/doubles) and default where none does;
null reads as missing; duplicate keys last-one-wins and inline-comment
re-splicing recorded in the design (engine change follows). Strict
schema/order fail-fast unchanged. 85 tests green.

Claude-Session: https://claude.ai/code/session_018BjQRYBR6jQja3jCRi5S3A
This commit is contained in:
2026-07-26 15:47:33 -04:00
parent a6f4960492
commit 8e7c565e07
4 changed files with 107 additions and 22 deletions
+21
View File
@@ -100,6 +100,27 @@ struct BoardLoaderWellFormedTests {
#expect(result.warnings.isEmpty)
}
/// Tombstone semantics key on the `deleted` key's *presence*, not its validity
/// (01-storage-format.md § Frontmatter, § Deletion): a `deleted` value with no sensible
/// date reading still tombstones the user's intent to delete outranks the broken date.
@Test func malformedDeletedValueStillTombstonesLaneAndCard() throws {
let fixture = try BoardFixture()
defer { fixture.tearDown() }
try fixture.index("", "schema: 1\n")
try fixture.index("lane-1", "schema: 1\norder: 1024\ndeleted: yesterday\n")
try fixture.index("lane-1/card-1", "schema: 1\norder: 1024\ndeleted: yesterday\n")
let result = try BoardLoader.load(boardRoot: fixture.root)
let lane = try #require(result.model.lanes.first { $0.id.rawValue == "lane-1" })
#expect(lane.deleted == .malformed(raw: "yesterday"))
#expect(lane.isDeleted)
let card = try #require(lane.cards.first { $0.id.rawValue == "card-1" })
#expect(card.deleted == .malformed(raw: "yesterday"))
#expect(card.isDeleted)
}
@Test func tiesAreBrokenByFolderNameNotTitle() throws {
let fixture = try BoardFixture()
defer { fixture.tearDown() }