# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Versioning note: the repository tag versions **the contract** (file set, key names, case ids, disposition semantics). Each JSON file additionally carries its own `"version"` field, bumped when that file changes. ## [0.7.2] — 2026-08-13 **`scope_planned.blockers` named the premise that `docs/secret-egress-divergence.md` falsified.** The blocker read "19 entries … 25 at different cut points" — one table cut at two granularities, waiting on a reconciliation of two ports. Measured 2026-08-13: they are ports of **two different source tables** in the same source repository, so no reconciliation of the ports was ever going to close it. No data moves in this release, and no case is minted — only the recorded reason a case cannot be. ### Fixed - **The egress blocker now carries the three measured reasons, kept independent.** (1) Commons has no id space for this table: seed A (`hooks/scripts/pre-edit-secrets.mjs`) carries a name and a pattern per entry and nothing else, so entries are keyed by human-readable `name` while the guard emits `egress:`, and a fixture names labels. This is the only one of the three an answer can resolve, and it is the outgoing question. (2) Match semantics disagree: `first match wins` with `ordering.normative: true` here, against `finditer` over all 25 patterns there — one witness, an `Authorization` header holding a three-part JWT, produces **one** label under commons' declared contract and **two** from the guard. (3) Membership diverges both ways and is inherited from two different seeds (seed A 19 entries, seed B 33, the guard ported 25, 8 unported), so re-measuring either port cannot close it. The blocker points to `docs/secret-egress-divergence.md` for the method behind every number. - **Two hand-carried numbers in the retired text are corrected in the same string.** `aws-access-key-id` was called "the one clean one-to-one": measured, only **2 of 19** commons patterns are byte-identical to a guard pattern after unescaping, and AWS is not among them — the guard anchors the same run as `\bAKIA[0-9A-Z]{16}\b`. `GitHub Token` was called "four ids there": measured on witnesses it maps to **three**, and leaves `ghu_` and `ghr_` covered by no guard id. Both were transcription, not measurement. What is retracted is quoted in place; the full retired text stands in git at `conformance/manifest.json` 0.5.0. - **`scope_planned.$comment` said "a distinct unresolved question" — singular.** Left alone it would tell a reader the case becomes mintable when an answer arrives, which is true of one reason in three. Amended alongside the blocker rather than after it, since the two are read together. ### Measured - **The standing requirement was measured here, not transcribed from the document.** `entry_points_by_scope.scopes` carries **no entry at all** for `signatures/secret-egress.json` — the three declared scopes are the lexicon, active-content and carriers. Entry point, findings accessor and fixture presentation must be filled for both runtimes before a first egress case, independently of the three reasons. It is recorded as a requirement, not as a fourth reason: it would stand even if all three were resolved tomorrow. - **No id string is proposed, in this file or anywhere else.** Checked against the two outgoing coord messages of 2026-08-13 rather than assumed: both state in as many words that no id is being proposed. Naming an id in a shared space is the exception `carrier:*` established, it requires both runtimes asked first, and both are unanswered. `conformance/manifest.json` 0.5.0 → 0.5.1. No case directory, no `expected.json` and no signature table changed; `git status` shows one file besides this changelog. ## [0.7.1] — 2026-08-13 Two loose ends from `0.7.0`, neither of which changes a contract. ### Fixed - **The README still named the manifest as the authority for the variant rule.** It read "see `case_id_derivation.variant_suffix` in the manifest" — true until `0.7.0`, when the rule became normative in `spec/conformance-corpus.md` §6 and the manifest's block became the *measurement* behind it rather than the contract. Left alone it would have reproduced in one line the same defect `0.7.0` closed: a reader sent to the wrong authority. ### Measured - **The `__` half of the derivation was re-measured too, not just the `--` half.** `0.7.0` made a point of re-measuring `--` rather than copying the manifest's `0.3.0` numbers forward, while the adjacent sentence asserting that `__` "does not occur anywhere in the ratified id space" was inherited untested — a claim about this release's own soundness that the release did not check. Measured now across all five published id spaces: the 83 lexicon ids, the 7 `active:` ids, the 3 `carrier:` ids, the 7 malware rule ids and the 19 secret-egress entry names carry **neither** `__` nor `--`. The one-to-one transform holds. No text changed; the sentence was true. It is now true *and* measured. ## [0.7.0] — 2026-08-13 **The normative spec forbade, in as many words, a case the corpus has shipped since `0.3.0`.** `spec/conformance-corpus.md` §6 read *"Such a payload MUST NOT be given a discriminated case id; the derivation rule is the contract, and a suffix would break the reverse transform"* while `conformance/manifest.json` defined `case_id_derivation. variant_suffix` and `conformance/hybrid-xss__script-tag--src-no-close/` sat on disk under it. The manifest was the correct party; the spec was simply never updated when the derivation was extended. **No data moves in this release — only the normative text that describes it.** ### Fixed - **§6's derivation block now states the rule the corpus actually uses.** ``` before case_id = pattern_id with ":" replaced by "__" pattern_id = case_id with "__" replaced by ":" after case_id = pattern_id with ":" replaced by "__", optionally followed by "--" and a variant slug of [a-z0-9-] pattern_id = case_id truncated at the first "--" if present, then "__" replaced by ":" ``` The `--`-absence measurement moves into the spec as the reason the reverse transform stays **lexical**: a runtime MUST be able to recover a `pattern_id` by splitting the string, and MUST NOT need a lookup against the published id list to find where the id ends and the variant begins. Re-measured at this commit rather than copied from the manifest's 0.3.0 numbers: `--` occurs in none of the 83 lexicon ids, none of the three `carrier:` ids, none of the `active:` construct ids, none of the seven malware rule ids and none of the 19 secret-egress entry names — and in exactly one of the 94 case ids, the variant itself. It does occur inside *pattern* values (`