Parent
Part of the MagicAST restructure milestone. Phase 5 of 5. Marked ready-for-human because the decision to do this phase at all is a HITL judgment call gated on observable diagnostic quality after Phase 2 ships.
What to build
After Phase 2 (#3) lands, the worst of the AST↔JSON coupling is already gone: base classes no longer carry [JsonPolymorphic] lists, and concrete types carry domain-flavored [OracleAbility] / [OracleEffect] attributes instead of JSON-flavored ones. However, individual AST records may still carry per-property JSON attributes:
[JsonPropertyName("...")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonConverter(...)]
The open question: are the post-Phase-2 test diagnostics good enough as they are?
When an agent's hand-parsed JSON has an unmapped field or an unknown discriminator, the JsonException they see today references JSON-layer vocabulary (property names, types). If that's clear enough for the TDD loop, this phase is unnecessary and should be closed as wontfix.
If diagnostics still leak JSON-internal vocabulary in a way that confuses agents reading red test output, introduce a thin DTO mirror layer:
libs/magic-ast/
├── AST/ ← pure domain records, ZERO [Json*] attributes
└── Serialization/
└── Dto/ ← mirrors of each AST record, carrying JSON attributes
├── AbilityDto.cs
├── EffectDto.cs
└── ... ← each Dto has ToDomain() and FromDomain() methods
The test infrastructure serializes via DTO; the parser produces pure AST. Error messages can be wrapped to reference domain types and discriminators instead of JSON property names.
Acceptance criteria — Decision phase (do this first)
Acceptance criteria — If proceeding (path b)
Blocked by
Parent
Part of the MagicAST restructure milestone. Phase 5 of 5. Marked
ready-for-humanbecause the decision to do this phase at all is a HITL judgment call gated on observable diagnostic quality after Phase 2 ships.What to build
After Phase 2 (#3) lands, the worst of the AST↔JSON coupling is already gone: base classes no longer carry
[JsonPolymorphic]lists, and concrete types carry domain-flavored[OracleAbility]/[OracleEffect]attributes instead of JSON-flavored ones. However, individual AST records may still carry per-property JSON attributes:[JsonPropertyName("...")][JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)][JsonConverter(...)]The open question: are the post-Phase-2 test diagnostics good enough as they are?
When an agent's hand-parsed JSON has an unmapped field or an unknown discriminator, the
JsonExceptionthey see today references JSON-layer vocabulary (property names, types). If that's clear enough for the TDD loop, this phase is unnecessary and should be closed aswontfix.If diagnostics still leak JSON-internal vocabulary in a way that confuses agents reading red test output, introduce a thin DTO mirror layer:
The test infrastructure serializes via DTO; the parser produces pure AST. Error messages can be wrapped to reference domain types and discriminators instead of JSON property names.
Acceptance criteria — Decision phase (do this first)
\"kind\"discriminator or an unmapped field).wontfix, or (b) introduce DTO layer.Acceptance criteria — If proceeding (path b)
libs/magic-ast/AST/contain zero[Json*]attributes (including per-property ones).libs/magic-ast/Serialization/Dto/(or similar) carries the JSON attributes.ToDomain()andFromDomain(domain)methods (or equivalent mapping). No reflection required for mapping unless it's clearly the right call.test-baseline.json.Blocked by