Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ on `MetaLogDiff`, a rewritten §13.2 clause, a `diff_version` rule (§13.1.1) th
a producer stamping an older value now violates, and a definition of `window.start`
and `window.end` (§2.2) that a producer writing its own bounds there now violates,
a definition of `behavior.top_ngrams[].probability` (§4) that a producer writing a
joint probability at `ngram_size` above 2 now violates, and a rule on which templates get a
joint probability at `ngram_size` above 2 now violates, a rule on which templates get a
`branching_delta` row (§13.1) that a producer emitting one for a template branching on one
side only now violates.
side only now violates, and a binding of each param to a whole-token wildcard (§3.5) that a
producer emitting a param for a wildcard inside a token, or none for a whole-token wildcard,
now violates.
It also adds one optional member
(`withheld_signals`, §13.2.2), which is additive on its own. MINOR bump: MAJOR stays `0`, so
§6's *"the MAJOR field of `metalog_version` must equal the MAJOR of the spec"* is
Expand Down Expand Up @@ -154,6 +156,23 @@ proposed; any of them that is taken lands as an editor change recorded here.
adopts it in the same release; on its determinism corpus the rule removes 45 of 48 rows,
every one comparing a template the other window never held in `branching`.

- **§3.5 — `param_index` is the ordinal among the template's whole-token wildcards, and a
producer MUST bind one param to each.** The comment called `param_index` a "0-based wildcard
position", which a template whose normalization writes a wildcard INSIDE a token (a path
segment, a bracketed index) makes ambiguous: counting every wildcard puts a param on a slot
that carries no value. A new paragraph after the §3.5 example requires a producer to emit
exactly one param for every template token that is the wildcard, in token order, and none
for a wildcard inside a token, so `param_index` *i* names the value under the (*i* + 1)-th
whole-token wildcard and a consumer can put each value back into its slot from the template
alone. The reference producer emitted no param for a whole token its normalization reduced to
the wildcard (a dashed UUID standing alone), so the indices after it pointed one slot early.
**Breaking** — a producer that emits a param for a wildcard inside a token, or none for a
whole-token wildcard, becomes non-conformant — and editor-merged under
[`GOVERNANCE.md`](GOVERNANCE.md) §2's 0.x rule. No schema changed: the rule relates a
template's text to its params, which no keyword can see. The reference implementation
adopts it in the same release; template text and ids do not move, and only templates
carrying such a whole-token wildcard gain a param.

### Added

- **§13.2.1 — `x-metalog-vacuous`, a per-property vacuity declaration.** The witness
Expand Down
10 changes: 9 additions & 1 deletion SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ paths, status codes) rather than only at the template level.
"frequency": 0.0676,
"param_histograms": [ // array, optional; one entry per tracked wildcard slot
{
"param_index": 0, // integer, required, 0-based wildcard position
"param_index": 0, // integer, required, 0-based ordinal among the template's
// tokens that are exactly the wildcard
"value_counts": { // object, required, top-N observed values → count
"/api/users": 800,
"/health": 200
Expand All @@ -467,6 +468,13 @@ paths, status codes) rather than only at the template level.
}
```

A producer **MUST** emit exactly one param for every template token that is the wildcard,
in token order, and none for a wildcard inside a token, which is a normalization. So
`param_index` *i* is the value under the (*i* + 1)-th whole-token wildcard: in
`"GET <*> -> <*>"` it is 0 for the path and 1 for the status, and in
`"fetch cache/<*> took <*> ms"` the only param, index 0, is the duration, because
`cache/<*>` is one token that merely contains the wildcard.

- A producer **MUST NOT** emit `param_histograms` for entries not in `top_k`.
- The `value_counts` map **MUST** be bounded (producers **SHOULD** cap at a
configurable limit, default 256, and count overflows in `total`).
Expand Down
Loading