{
  "schema_version": "1.3.0",
  "slug": "what-invariants-prevent-nan-propagation-from-silently-voiding-an-aggregate",
  "title": "What invariants prevent NaN propagation from silently voiding an aggregate?",
  "date_of_record": "2026 November 2",
  "scope": "Applies to floating-point aggregates (sum, mean, min, max) over data that may contain NaN, where the aggregate is reported without an accompanying count of valid inputs. Does not apply to aggregates that reject NaN or count non-numeric inputs separately.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/what-invariants-prevent-nan-propagation-from-silently-voiding-an-aggregate.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/what-invariants-prevent-nan-propagation-from-silently-voiding-an-aggregate.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/what-invariants-prevent-nan-propagation-from-silently-voiding-an-aggregate.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 849,
    "python_slice_tokens": 126,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "NaN is absorbing under IEEE-754: once any term is NaN, the sum, mean, and most aggregates are NaN. An instance that aggregates unvalidated floats cannot distinguish \"the total is zero\" from \"one term was malformed.\" **Invariant.** The aggregate is sound if and only if NaN either cannot enter or is surfaced as a distinct count alongside the aggregate, not bak...",
    "what_was_observed": "**Signature.** Aggregate NaN or zero on days when a single input was malformed. Valid input counts unchanged. Recomputation over a filtered set yields a plausible number, making the failure look intermittent. **Trace.** Daily revenue = sum(line_items). One line has a null price from a partial upstream record. `sum([1.0, 2.0, NaN, 3.0])` is NaN. Serialized to JSON, NaN is not valid, so many writers coerce to null or z...",
    "condition_of_validity": "The instance must ensure at least one holds before it trusts an aggregate over floating-point inputs: 1. **Must reject at input.** NaN inputs are rejected before aggregation, and the rejection is alerted. 2. **Must count valid.** The aggregate is accompanied by a count of valid inputs, and any mismatch between expected and valid counts is an alert. 3. **Must...",
    "decision_boundary": "- Rejection at input: aggregate reflects only valid data. - Counting alongside aggregate: NaN cannot hide. - No rejection, no counting: a single NaN voids the aggregate. - Rejection plus counting: robust and diagnosable.",
    "operational_effect": "The defect lives in the coercion step between typed inputs and untyped aggregates, often implicit in a query engine. Remediation is explicit NaN-ness at the boundary plus counts alongside aggregates. The trap is to wrap the aggregate in a NaN check that substitutes 0. That converts a NaN into a plausible-looking number, strictly worse than reporting NaN, bec..."
  },
  "matched_failure_symptoms": [
    "DOMAIN:EPISTEMIC_PROVENANCE_AND_FEDERATION_ROUTING"
  ],
  "composition_edges": {
    "primary_domain": "epistemic_provenance_and_federation_routing",
    "upstream_precondition_residuals": [
      "https://corpusfetch.com/c/according-to-what-precedence-hierarchy-must-an-instance-resolve-contradictory-directives-across-system-developer-and-user-tiers.md",
      "https://corpusfetch.com/c/how-should-an-instance-decide-that-a-stored-conclusion-has-gone-stale-without-a-new-observation.md"
    ],
    "downstream_consequence_residuals": [
      "https://corpusfetch.com/c/by-what-checkpoint-and-compaction-boundaries-must-an-instance-externalize-working-state-to-prevent-context-window-drift-and-truncation-amnesia.md",
      "https://corpusfetch.com/c/across-what-additive-schema-and-unknown-field-preservation-boundaries-must-an-instance-evolve-wire-contracts-to-prevent-rolling-deploy-deserialization-crashes.md"
    ],
    "co_occurring_sibling_residuals": [
      "https://corpusfetch.com/c/how-can-an-instance-capture-implicit-user-preferences-without-storing-private-data.md",
      "https://corpusfetch.com/c/how-can-an-instance-compress-long-reasoning-traces-into-binding-conclusions.md"
    ]
  },
  "empirical_verification_warrant": {
    "status": "AST_AND_INVARIANT_VERIFIED",
    "syntax_valid": true,
    "code_sha256": "8d50af42ead3ea94389267a5b15e0cf4230dc3f5d5c828b340b848e03fa15e8a",
    "verified_classes": [
      "NanPropagationError",
      "AggregateGate"
    ],
    "verified_functions": [
      "dispatch_aggregate_mode",
      "verify"
    ],
    "verified_functions_count": 2,
    "defensive_guards_count": 2,
    "raised_exceptions": [
      "NanPropagationError"
    ],
    "sample_fail_closed_invariants": [
      "NaN present and not rejected: aggregate becomes NaN silently",
      "NaN present and no valid-input count: aggregate hides the defect"
    ],
    "stdlib_dependencies": [
      "dataclasses",
      "math"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
