# OpenMetrics 1.0 compatibility

This document makes the version 0.1.x boundary explicit. “Supported” means the
behavior has a public API and automated tests. “Validated” means semantic
checks run after syntactic parsing.

## Text grammar

| Feature | Status | Notes |
|---|---|---|
| HELP | Supported | Backslash, quote, and newline escapes; leading/trailing spaces retained; empty values treated as absent |
| TYPE | Supported | unknown, counter, gauge, histogram, gaugehistogram, summary, info, stateset |
| UNIT | Supported | OpenMetrics identifier and family-suffix checks; empty values treated as absent |
| Sample labels | Supported | Quoted Unicode values; `\\`, `\"`, `\n` |
| Decimal/scientific values | Supported | Includes signed values |
| NaN and infinities | Supported | Case-insensitive `NaN`, `Inf`, and `Infinity` spellings on input; canonical output |
| Unix-second timestamps | Supported | Finite `Double`, including fractional seconds |
| Exemplars | Supported | Empty or populated labels, value, optional timestamp |
| EOF marker | Supported | Missing EOF parses leniently and validates as an error |
| Family/metric/point ordering | Validated | Interleaved families are rejected while parsing; interleaved metrics and points are diagnosed |
| Unknown comments | Accepted | Ignored rather than retained |
| CRLF and LF | Supported | Canonical output uses LF |
| Quoted UTF-8 identifiers | Not yet | ASCII interoperable identifier subset is used |
| Undefined backslash escapes | Strict subset | Rejected even though the ABNF can ingest them; producers should avoid them |
| Protobuf format | Out of scope | This module implements text exposition |

## Metric-family validation

| Family | Checks |
|---|---|
| Counter | Per-point `_total` presence, non-negative/monotonic total, reset/created consistency |
| Gauge | Exact family sample name |
| Histogram | Required `_bucket`/`+Inf`; numeric bucket order; non-negative integer and monotonic counts; optional `_sum`/`_count` coupling |
| Gauge histogram | Required `_bucket`/`+Inf`; numeric bucket order; non-negative integer counts; optional `_gsum`/`_gcount` coupling |
| Summary | Optional quantiles, `_sum`, and `_count`; quantile range/value, empty-point, and count checks |
| Info | `_info` suffix and value 1 |
| State set | family-named state label and 0/1 value |

All families also receive identifier, duplicate label, duplicate series,
metadata, unit, family wire-name collision, exemplar-placement/size, and EOF
checks. Created values for counter, histogram, and summary families must be
finite Unix-second timestamps. Histogram and summary grouping is evaluated
independently for each combination of ordinary labels and explicit
metric-point timestamp. A family may contain no metrics. Repeated points require
monotonically increasing explicit timestamps and may not be interleaved.

## Canonicalization

Encoding preserves:

- family order;
- sample order;
- label order;
- numeric meaning;
- timestamps and exemplars.

It canonicalizes metadata to TYPE, UNIT, HELP, samples and emits exactly one EOF
marker. Positive infinity in histogram `le` and summary `quantile` labels is
emitted as `+Inf`; equally named opaque labels on other family types are left
unchanged. It does not preserve ignored comments, blank lines, whitespace
choices, or the original numeric spelling.

## Registry contract

The registry is intentionally explicit and deterministic. It has no singleton,
clock, mutex, HTTP endpoint, or background task. It:

- rejects duplicate family registration;
- rejects updates through an incompatible metric type;
- replaces gauge values;
- accumulates non-negative counter deltas;
- accumulates non-negative histogram observations into a fixed, non-negative
  bucket schema for each label set, plus sum and count;
- replaces gauge-histogram, summary, info, and state-set snapshots;
- preserves timestamps and exemplars when replacing an arbitrary sample;
- produces an owned document snapshot suitable for validation and encoding.

Separate snapshots can be merged with reject, keep-first, or keep-last duplicate
series policies. Conflicting concrete TYPE, HELP, or UNIT metadata is always an
error.

Applications that mutate one registry from multiple threads must provide their
own synchronization.
