You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
From the second verified review of PR #26 (finding R2-7, CONFIRMED; the argument-guard half landed on the PR — carriers now refuse an unparsed default(JsonElement) payload). This issue owns the remaining design half.
Finding. The eight Unknown* carriers' public [JsonConstructor] accepts any (tag, payload) pair, while the converters' Write emits payload-only (ADR-0009 raw replay). A hand-built carrier therefore drops its stored marker on serialization: new UnknownSessionForkBoundary("custom", JsonDocument.Parse("{}").RootElement) serializes as {}, which the same converter's Read then rejects; a payload whose discriminator differs from the constructor tag round-trips into a carrier with a silently different Type.
Design question: what is the hand-construction contract? Options: refuse construction when the payload's discriminator disagrees with (or lacks) the tag; inject the stored marker on Write; or document carriers as wire-read-only artifacts whose construction surface exists solely for the serializer. The wire-replay path (carrier read from the wire, replayed verbatim) must stay byte-identical either way — that tolerance is ADR-0009's contract.
Trigger: the M3 union single-pass redesign (#23) rewrites these same converters; decide the contract there so the converters are touched once.
Sealed as constructor refusal (research log Session 24): a carrier's payload must carry the union's marker property agreeing with the tag — never fires on the wire read path, refuses the silent marker-drop on hand-construction; Write stays payload-only verbatim replay (ADR-0009 intact). Executes inside #23's converter rewrite (M3 plan Arc 6).
Completed in fa6124d and passed hosted CI run 32374393085 on Linux, Windows, and macOS. Every generated Unknown carrier constructor now refuses whitespace markers, non-object/unparsed payloads, missing or disagreeing discriminators, and disagreeing fixed outer markers. Wire-read carriers derive the same marker from the payload, so unknown-union tolerance remains intact; Write still performs payload-only replay through both interface and concrete metadata. Tests cover missing/different/non-object hand construction, valid hand-constructed replay, nested fixed-marker refusal, and duplicate-discriminator last-value behavior. No public signature or generated-manifest membership changed.
Activity
docs: seal Q92 (ADR-0010) and open M3 — simplicity-first construction…
Blind-Striker commentedon Aug 15, 2026
Sealed as constructor refusal (research log Session 24): a carrier's payload must carry the union's marker property agreeing with the tag — never fires on the wire read path, refuses the silent marker-drop on hand-construction; Write stays payload-only verbatim replay (ADR-0009 intact). Executes inside #23's converter rewrite (M3 plan Arc 6).
Blind-Striker commentedon Aug 20, 2026
Completed in fa6124d and passed hosted CI run 32374393085 on Linux, Windows, and macOS. Every generated Unknown carrier constructor now refuses whitespace markers, non-object/unparsed payloads, missing or disagreeing discriminators, and disagreeing fixed outer markers. Wire-read carriers derive the same marker from the payload, so unknown-union tolerance remains intact; Write still performs payload-only replay through both interface and concrete metadata. Tests cover missing/different/non-object hand construction, valid hand-constructed replay, nested fixed-marker refusal, and duplicate-discriminator last-value behavior. No public signature or generated-manifest membership changed.