[LOADED_DOCS: 2 files, no new loads]
Add issue/TODO for AcBinary default-value omission risk Documented ACCORE-BIN-I-D9Y2 in BINARY_ISSUES.md, detailing the risk of silent data corruption when omitting default-valued properties if type defaults diverge between writer and reader. Added ACCORE-BIN-T-W7N5 in BINARY_TODO.md to track mitigation options, including a possible opt-out flag and required documentation/tests. Both entries are cross-referenced; decision on mitigation is deferred.
This commit is contained in:
parent
ed59a0c031
commit
265b89da0a
|
|
@ -219,6 +219,27 @@ With `ThrowOnCircularReference=false` + reference handling enabled, **only `IId`
|
||||||
- **Universal cycle detection** — track all reference types for cycle detection regardless of `IId`-ness when `ThrowOnCircularReference=false` (deduplication remains `IId`-only — cycle detection becomes universal).
|
- **Universal cycle detection** — track all reference types for cycle detection regardless of `IId`-ness when `ThrowOnCircularReference=false` (deduplication remains `IId`-only — cycle detection becomes universal).
|
||||||
- **Diagnostic event** — surface "non-`IId` cycle dropped at depth N" as an `Action<CycleDroppedDiagnostic>?` on options, opt-in.
|
- **Diagnostic event** — surface "non-`IId` cycle dropped at depth N" as an `Action<CycleDroppedDiagnostic>?` on options, opt-in.
|
||||||
|
|
||||||
|
### ACCORE-BIN-I-D9Y2: Default-value omission relies on type-level default consistency across writer/reader
|
||||||
|
|
||||||
|
**Status:** Open
|
||||||
|
**Affects:** All property writes — `BinaryTypeCode.PropertySkip` (102) marker
|
||||||
|
|
||||||
|
The serializer writes a 1-byte `PropertySkip` marker for any property whose value equals `default(T)` instead of the full encoded value. The deserializer interprets this marker as "leave the target property at its CLR default" — which assumes the consumer-side type definition has the **same default value** as the producer-side.
|
||||||
|
|
||||||
|
**Impact:** Latent silent corruption across version-mismatched readers/writers. Three concrete failure modes:
|
||||||
|
|
||||||
|
1. **Default-value change in type definition**: `bool IsActive = true` refactored to `bool IsActive = false` → wire produced with the old default decodes to wrong value on the new reader.
|
||||||
|
2. **Property added with non-zero default in v2**: e.g., v2 adds `int RetryCount = 3`. Deserializing a v1 wire on the v2 reader → `RetryCount = 0` (CLR default) instead of the expected v2 default 3.
|
||||||
|
3. **Cross-language consumers**: a non-.NET reader following the wire spec must implement the same default-resolution rules per type — not portable, not self-describing on the wire.
|
||||||
|
|
||||||
|
**Wire-size impact (production-realistic):** Significant for DTOs with many optional/default-valued fields (status flags, nullable refs, default ints/decimals/Guids/DateTimes). Benchmark contribution: estimated **~3-8% of AcBinary wire-size advantage** vs MemoryPack on the current test data; real-world DTOs may see 10-30% depending on the default-value share.
|
||||||
|
|
||||||
|
**Possible fix directions** (decision deferred — see `BINARY_TODO.md#accore-bin-t-w7n5`):
|
||||||
|
|
||||||
|
- **Doc-only**: position as a deliberate protobuf-style feature, consumer responsibility to keep type definitions stable across versions.
|
||||||
|
- **Option flag**: `AcBinarySerializerOptions.OmitDefaults` (default `true` for back-compat); `false` writes every property's full value regardless. Lets consumers opt out for fragile-class-evolution scenarios.
|
||||||
|
- **Hybrid**: ship doc + flag, default `true`.
|
||||||
|
|
||||||
## Cross-cutting (canonical home: `../XCUT/`)
|
## Cross-cutting (canonical home: `../XCUT/`)
|
||||||
|
|
||||||
### ACCORE-XCUT-I-X8Q1: JSON-in-Binary request parameters — cross-ref
|
### ACCORE-XCUT-I-X8Q1: JSON-in-Binary request parameters — cross-ref
|
||||||
|
|
|
||||||
|
|
@ -797,3 +797,20 @@ Replace `Encoding.UTF8.GetBytes` calls in `WriteStringUtf8` / `WriteStringUtf8In
|
||||||
- Wire format unchanged (custom encoder produces same bytes as `Encoding.UTF8`)
|
- Wire format unchanged (custom encoder produces same bytes as `Encoding.UTF8`)
|
||||||
- Round-trip tests pass
|
- Round-trip tests pass
|
||||||
|
|
||||||
|
## ACCORE-BIN-T-W7N5: Default-value omission policy — doc + optional opt-out
|
||||||
|
**Priority:** P2 · **Type:** Refactor + Documentation · **Related:** `BINARY_ISSUES.md#accore-bin-i-d9y2` (canonical issue)
|
||||||
|
|
||||||
|
The serializer's `PropertySkip` (102) optimization saves 1 byte per default-valued property by omitting the full value from the wire — relying on the consumer-side type definition to have the same `default(T)`. This is a **latent correctness risk** documented in `ACCORE-BIN-I-D9Y2`. This entry tracks the mitigation plan; full failure-mode analysis lives in the issue.
|
||||||
|
|
||||||
|
### Decision tree (TBD when implementing)
|
||||||
|
|
||||||
|
1. **Doc-only**: position as a deliberate protobuf-style feature; consumer keeps type defaults stable across versions. Lowest cost, maximum benchmark wire-size advantage retained.
|
||||||
|
2. **Option flag**: `AcBinarySerializerOptions.OmitDefaults` boolean. Default `true` (preserves current behavior + benchmark numbers). `false` writes every property in full — opt-out for fragile-class-evolution scenarios.
|
||||||
|
3. **Both**: ship doc + flag. Default behavior unchanged; consumers who hit silent-corruption have an explicit opt-out.
|
||||||
|
|
||||||
|
### Acceptance (when implementing)
|
||||||
|
|
||||||
|
- `BINARY_FEATURES.md` adds a "Default-Value Omission" section documenting the semantic and the tradeoff (with cross-ref to `ACCORE-BIN-I-D9Y2`)
|
||||||
|
- If flag added: round-trip tests covering both `true` and `false`; benchmark comparison table showing wire-size delta on ASCII / Hungarian / DTO-heavy workloads
|
||||||
|
- Decision rationale recorded in `LLM_PROTOCOL_DECISIONS.md` (or a `### Resolution` block on the issue) once implemented
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue