From 5cb4970e2410a43e528b4b3e44dda15fac0a219a Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Sun, 20 Sep 2026 20:58:23 +0800 Subject: feat(m6a): add file save acceptance smoke [Change Nature] This commit adds the bounded M6a file-save acceptance path. [New Capability] - Add file-level round-trip and deterministic continuation coverage. - Add Headless --m6a-smoke with digest checks and explicit PASS/FAIL output. [Implementation] - Reject non-finite numeric values and negative inventory quantities. - Exercise dialogue, chat/rumor, trade, events, annals, time, and RNG state. [Impact] - Affects Kernel save parsing, Kernel tests, and Headless smoke tooling. - Preserves the existing save format and M5 smoke behavior. --- src/LivingVillage.Kernel/WorldSave.fs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/LivingVillage.Kernel') diff --git a/src/LivingVillage.Kernel/WorldSave.fs b/src/LivingVillage.Kernel/WorldSave.fs index 726170b..8a47c7d 100644 --- a/src/LivingVillage.Kernel/WorldSave.fs +++ b/src/LivingVillage.Kernel/WorldSave.fs @@ -72,13 +72,13 @@ module WorldSave = let private readFloat (reader: TokenReader) label = let token = reader.Take(label) match Double.TryParse(token, NumberStyles.Float, invariant) with - | true, value -> value + | true, value when not (Double.IsNaN(value) || Double.IsInfinity(value)) -> value | _ -> invalid (sprintf "invalid %s" label) let private readFloat32 (reader: TokenReader) label = let token = reader.Take(label) match Single.TryParse(token, NumberStyles.Float, invariant) with - | true, value -> value + | true, value when not (Single.IsNaN(value) || Single.IsInfinity(value)) -> value | _ -> invalid (sprintf "invalid %s" label) let private readBool (reader: TokenReader) label = @@ -450,6 +450,8 @@ module WorldSave = [ for index in 0 .. count - 1 do let item = readItemKind reader (sprintf "%s[%d].item" label index) let quantity = readInt reader (sprintf "%s[%d].quantity" label index) + if quantity < 0 then + invalid (sprintf "invalid %s[%d].quantity" label index) yield item, quantity ] |> Map.ofList -- cgit v1.2.3