8.9 KiB
Toon — Known Issues
For planned/actionable work see TOON_TODO.md.
ACCORE-TOON-I-B7L4: Compact preset XML doc contradicts code behaviour
Severity: Trivial (doc-only, no runtime effect) · Status: Open (direction not decided) · Area: Serializers/Toons/AcToonSerializerOptions.cs
Description
The XML doc on AcToonSerializerOptions.Compact claims "Minimal output, no meta, no indentation", but the property initializer sets UseIndentation = true. Real output is DataOnly + no type names + no reference handling with indentation whitespace. Consumers reading IntelliSense expect a tighter output than they receive.
/// <summary>
/// Compact mode: Minimal output, no meta, no indentation. ← doc says no indent
/// ...
/// </summary>
public static AcToonSerializerOptions Compact => new()
{
Mode = ToonSerializationMode.DataOnly,
UseMeta = false,
UseIndentation = true, ← code sets true
...
};
Root cause
Likely the XML comment predates a later preset revision that flipped UseIndentation to true. The comment was not updated to match.
Fix options (undecided)
- (a) Fix the doc — update the XML comment to match current behaviour. "Compact" then means "DataOnly, no type names, no refs" — not literal whitespace-free.
- (b) Fix the code — flip
UseIndentationtofalsein the preset to honour original intent. Output-breaking change for anyone relying on currentCompactformatting.
Known workaround
Build a custom options instance when truly token-minimal output is needed:
var trulyCompact = new AcToonSerializerOptions {
Mode = ToonSerializationMode.DataOnly,
UseMeta = false,
UseIndentation = false,
OmitDefaultValues = true,
WriteTypeNames = false,
ReferenceHandling = ReferenceHandlingMode.None
};
TOON_OPTIONS.md already notes this divergence next to the Compact preset; decision here governs whether it persists or gets resolved.
Related TODO
None yet — fix direction not decided.
ACCORE-TOON-I-X3H2: Age inference substring false positive
Severity: Minor (constraint-only, no runtime effect) · Status: Open · Area: Serializers/Toons/AcToonSerializer.Descriptions.cs → GetPropertyConstraints / GetInferredConstraints
Description
Integer properties whose name contains the substring age (case-insensitive, not word-bounded) erroneously receive the range: 0-150 constraint from the Age inference rule. False positives observed: LanguageId, and by pattern Package*, Image*, Page*, Message*, Storage*, Stage*.
Observed in a 2026-04-24 Toon dump:
LanguageId: int?
constraints: "range: 0-150"
Root cause
if (propertyName.Contains("Age", StringComparison.OrdinalIgnoreCase))
constraints.Add("range: 0-150");
"LanguageId".Contains("Age", OrdinalIgnoreCase) returns true — the substring age sits at position 5-7 inside Language. The rule's intent was to match an Age-named property, but Contains has no word-boundary awareness.
Fix options
- (a) Exact match:
propertyName.Equals("Age", OrdinalIgnoreCase)— loses legitimate matches likeCustomerAge,MinAge. - (b) Suffix:
propertyName.EndsWith("Age", OrdinalIgnoreCase)— still matchesLanguage(ends inage). - (c) Word-boundary regex — accurate but adds a regex pass per property.
- (d)
EndsWith("Age")+ preceded-by-uppercase guard —CustomerAgeok (r→Acapital transition),Languagerejected (u→alowercase transition).
Similar risk applies to other substring-based rules in Descriptions.cs (Email, Phone, Address, Url, Date, Version, CreatedAt, UpdatedAt, DeletedAt) — audit them under the same word-boundary lens.
Known workaround
Explicit [ToonDescription(Constraints = "...")] on the affected property (replace mode — no placeholder).
Related TODO
None yet.
ACCORE-TOON-I-P6V5: Property override duplicated on inheritance in @types
Severity: Minor (schema correctness; LLM may misinterpret) · Status: Open · Area: Property enumeration — likely AcToonSerializer.ToonSerializeTypeMetadata.cs or the shared base in Serializers/ root.
Description
When a derived class uses override on a property inherited from its base, both the derived and the base version appear in the @types schema — two entries for the same logical member, each with its own business-logic string.
Observed in a 2026-04-24 Toon dump on OrderItemPallet:
OrderItemPallet:
...
MeasuringStatus: MeasuringStatus
business-logic: "get => IsAudited ? MeasuringStatus.Audited : base.MeasuringStatus"
constraints: "readonly, not-mapped"
...
MeasuringStatus: MeasuringStatus
business-logic: "get => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? ..."
constraints: "readonly, not-mapped"
Only affected when a class uses override on a property. Sibling non-overriding classes (ShippingItemPallet, StockTakingItemPallet) emit the property once as expected.
Root cause (likely)
Type.GetProperties(BindingFlags.Public | BindingFlags.Instance) returns overridden properties twice — once per declaring type in the inheritance chain. The Toon property enumeration does not dedupe on Name, so both versions reach the writer.
Fix options
- (a) Filter in the metadata build step: group by
Name, keep the most-derived override (lowest inheritance distance from the target type). - (b) Walk the inheritance chain with
BindingFlags.DeclaredOnlyper level, collecting names into a set; skip if already seen.
Known workaround
None — the schema is wrong as-is. Downstream consumers must tolerate the duplicate entry.
Related TODO
None yet.
ACCORE-TOON-I-K4Z9: Property order in @types is not pure alphabetical
Severity: Minor (readability / predictability) · Status: Open · Area: Property ordering — likely AcToonSerializer.ToonSerializeTypeMetadata.cs, inherited from the shared base in Serializers/ root.
Description
Per-class property emission in @types is hierarchy-aware derived→base, with alphabetical order within each inheritance level. The inherited Id property therefore appears at the very end of every class definition, instead of its alphabetical slot between H… and J….
Observed in a 2026-04-24 Toon dump on Customer (simplified):
Customer:
Active, AdminComment, ..., ZipPostalCode, ← own properties, alphabetical
Id ← inherited, placed LAST
And on OrderItemPallet (which has multi-level inheritance):
OrderItemPallet:
AverageWeight, IsAudited, MeasuringStatus, ..., TrayQuantity, ← derived-class props
Created, CreatorId, ForeignKey, ..., TrayQuantity, ← base class props
Id ← base-base entity
Expected behavior
Pure alphabetical order across all properties of the type, regardless of inheritance level. For Toon's LLM-readability goal, a predictable flat order matters more than hierarchy preservation.
Docs inconsistency
Serializers/README.md "Property ordering" section states: "Hierarchy-aware (base→derived) then alphabetical. Ensures stable property indices across type versions." Two mismatches with actual behavior:
- Direction reversed — real output is
derived→base, notbase→derivedas the doc claims. - Rationale irrelevant to Toon — "stable property indices across type versions" is a wire-format concern for AcBinary. Toon is a descriptive schema format where property order is cosmetic, not semantic.
Fix options
- (a) Override the property ordering specifically in
ToonSerializeTypeMetadatato plainOrderBy(p => p.Name)— Toon diverges from the Binary/JSON shared ordering. Recommended: AcBinary needs the hierarchy-aware order for wire stability; Toon does not, and can opt out. - (b) Fix the direction in the shared base (
base→derivedas the docs claim) — partial fix, still not pure alphabetical. - (c) Accept current behavior and update
Serializers/README.mdto match observed reality — reject the issue. Not recommended: the user expectation is pure alphabetical, and the docs-vs-code gap is real either way.
Known workaround
None — consumers must tolerate the current order.
Related TODO
None yet. Fix also requires reconciling Serializers/README.md with the chosen direction.
Issue entry template
## ISSUE-NN: Short title
**Severity:** Trivial / Low / Minor / Major · **Status:** Open / Documented / Mitigated · **Area:** <subsystem>
### Description
What breaks, and under what conditions.
### Root cause
Why it happens (code location + design mismatch).
### Known workaround
Steps a consumer can take until fixed.
### Related TODO
`TOON_TODO.md#todo-NN` (if applicable).