Squashed 'scanners/commons/' changes from 532d70d..4641a7b
4641a7b release(0.3.0): a detection pattern changed value — that is new here 1482c0b feat(schema,spec): give the §1.1 MUST a shape, since v0.2.0 shipped it without one 25a2cf9 feat(conformance): the witness case, and the derivation rule that had no room for it c1b2385 fix(lexicon): converge script-tag on its source — re-extraction, not revision 6f79a6e fix(lexicon,docs): the script-tag row reversed — commons is now the sole diverger git-subtree-dir: scanners/commons git-subtree-split: 4641a7b5184047460e3f10038b615a61e7a4ac21
This commit is contained in:
parent
9b95fc607e
commit
bbd03f9b52
9 changed files with 585 additions and 25 deletions
130
CHANGELOG.md
130
CHANGELOG.md
|
|
@ -11,6 +11,136 @@ case ids, disposition semantics). Each JSON file additionally carries its own
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
Nothing yet.
|
||||
|
||||
## [0.3.0] — 2026-08-11
|
||||
|
||||
**A detection pattern changed value. That has not happened in this repository before, and it
|
||||
is the reason this is a release.** `v0.2.0` changed what a runtime must *declare*; this one
|
||||
changes what a conforming runtime *finds*. A consumer that vendors `0.3.0` and re-runs its
|
||||
suite will see a finding on inputs that produced none under `0.2.0`. In 0.x that is a minor
|
||||
bump by the rules; read the first entry below before upgrading, not the version number.
|
||||
|
||||
The lexicon `0.6.0` entry previously sitting under *Unreleased* is folded in here — it was
|
||||
committed but never tagged, and `0.7.0` supersedes its central claim.
|
||||
|
||||
### Changed
|
||||
|
||||
- **`lexicon/injection-lexicon.json` (`0.5.1` → `0.7.0`) — `hybrid-xss:script-tag` converged
|
||||
on `llm-security`'s current form.**
|
||||
|
||||
```
|
||||
0.6.0 and earlier <script\b[^>]*>[\s\S]*?<\/script> closing tag REQUIRED
|
||||
0.7.0 <script\b[^>]*> opening tag only
|
||||
```
|
||||
|
||||
Byte-identical to `llm-security`'s `RegExp.prototype.source` at `b1ba1fb`
|
||||
(`scanners/lib/injection-patterns.mjs:170`), verified by compiling both. They dropped the
|
||||
closing-tag requirement in `90f576f` (2026-08-10) because it was a recall hole:
|
||||
`<script>alert(1)` and `<script src=x.js>` both returned no finding.
|
||||
|
||||
**This is re-extraction, not revision, and the distinction is the whole justification.**
|
||||
This repository's behaviour-preservation invariant forbids commons from *correcting* seed
|
||||
data it believes is wrong — that rule stands and was not weakened. It does not forbid
|
||||
re-reading the source after the source itself moved and its owner asked. The lexicon's
|
||||
declared provenance is `llm-security`'s injection table, and being loadable verbatim by
|
||||
that table's owner is the one thing it exists to do; the standing alternative was a
|
||||
per-pattern override in `llm-security`'s own loader, i.e. a published core its source
|
||||
repository could not load as published.
|
||||
|
||||
**Direction matters for what it cannot break:** the new form matches a strict superset of
|
||||
the old one, so relative to `0.6.0` it can add matches and cannot introduce a false
|
||||
negative. The reverse change would not have been adoptable on the same reasoning.
|
||||
|
||||
Operator decision, 2026-08-11, on `llm-security`'s blocking request. Explicitly **not**
|
||||
decided by the 2-of-3 majority across the three ports: a count of implementations is not a
|
||||
mandate over detection data, and the provenance argument would hold with the guard on
|
||||
either side.
|
||||
|
||||
Measured collateral: **none.** The full corpus was run under both patterns — 84/84
|
||||
lexicon-scoped cases pass under `0.7.0`, and exactly one case's finding set differs between
|
||||
the two forms (the new one below). The widening added no finding to any other case's input.
|
||||
|
||||
`source_fidelity` restructured to keep its numbers coordinate-bearing:
|
||||
`patterns_byte_identical_to_source` keeps its key and its value (83) and gains the field it
|
||||
was missing, `byte_identical_against_commit: b1ba1fb`. Against the original extraction
|
||||
commit `b0de0ca` this file is now 82/83, recorded as `count_against_extraction_commit`.
|
||||
`post_extraction_drift` — added in the folded-in `0.6.0` to record the then-open divergence
|
||||
— is now marked `status: resolved in 0.7.0 by re-extraction` and carries the before/after
|
||||
pattern text, so a consumer diffing against either commit has a coordinate for what it
|
||||
finds.
|
||||
|
||||
- **`conformance/manifest.json` (`0.2.0` → `0.3.0`) — `case_id_derivation` extended with an
|
||||
optional variant suffix.**
|
||||
|
||||
```
|
||||
before case_id = <pattern_id, ':' → '__'>
|
||||
after case_id = <pattern_id, ':' → '__'> [ '--' <variant-slug> ]
|
||||
reverse truncate at first '--', then '__' → ':'
|
||||
```
|
||||
|
||||
No existing case id moved, so this is additive. `--` was measured absent from all 83
|
||||
ratified pattern ids and all 89 pre-existing case ids, which keeps the reverse transform
|
||||
purely lexical — no lookup against the id list — the property the original one-to-one rule
|
||||
was protecting.
|
||||
|
||||
The `one_case_per_pattern_id` key is **removed**, superseded by
|
||||
`case_id_derivation.variant_suffix.supersedes`, which quotes its text. It was documentation
|
||||
of the constraint, not data a consumer matches on, but it is called out here because a
|
||||
removed key is normally a breaking change in this repository.
|
||||
|
||||
`omitted_payloads` gains `derivation_ground_withdrawn_in_0_3_0`: the guard's seventh
|
||||
active-content payload was omitted on two grounds, and this change retires one of them. The
|
||||
other stands, so the payload stays omitted — on one ground instead of two. **It was not
|
||||
added back**; that is a separate decision, not a consequence of this one.
|
||||
|
||||
### Added
|
||||
|
||||
- **`conformance/hybrid-xss__script-tag--src-no-close/` (89 → 90 cases)** — input
|
||||
`<script src=x.js>`, 17 bytes, expecting `hybrid-xss:script-tag`. The regression gate for
|
||||
the change above, and the reason the corpus could not previously see it: the existing
|
||||
`hybrid-xss__script-tag` input `<script>steal()</script>` matches the pattern under *both*
|
||||
forms, so it passes either way. Reverting the pattern to its `0.6.0` form fails this case
|
||||
and only this case — mutation-verified in both directions across all 90.
|
||||
|
||||
**The first case input authored in this repository** rather than reproduced verbatim from a
|
||||
runtime's payload set, recorded in the new `authored_payloads` block rather than folded into
|
||||
`payload_provenance`, whose value is precisely the claim that its inputs are verbatim
|
||||
upstream. That claim stays exactly as strong as it was: 83 of 83. Both witnesses for this
|
||||
axis were named by `llm-security` on 2026-08-10; this is the first of the two. Findings
|
||||
measured through the guard's public API at `0dce50f` / `0.5.0`, with the existing case's
|
||||
committed bytes and digest reproduced by the same harness in the same run as a control.
|
||||
|
||||
- **`schema/conformance-declaration.schema.json` (`0.1.0`)** — the shape a runtime publishes
|
||||
alongside a conformance result, satisfying the §1.1 MUST that `v0.2.0` created and left
|
||||
without a form. Requested by `llm-security` in those terms (runtime, commit measured,
|
||||
implemented file paths) with the stated reason that two runtimes publishing free-form
|
||||
declarations makes `83/83 + 6 not-applicable` unparseable by anyone but its author.
|
||||
|
||||
Carries the two arithmetic invariants §1.1 implies but cannot state unambiguously in prose:
|
||||
the four verdict counts MUST sum to the total, and the total MUST equal the corpus case
|
||||
count at the commit measured. Requires the enumeration arrays whenever their counts are
|
||||
non-zero, which turns §1.1's "MUST still be enumerated" from prose into a schema failure.
|
||||
Keeps `error` and `not_applicable` structurally distinct, per §1.1. Records
|
||||
`declaration_source` — whether the declared set is derived from the runner's own constant or
|
||||
hand-maintained beside it — because only the derived form makes the anti-narrowing fence
|
||||
structural. **Deliberately not a gate:** nothing in this repository runs, and no validation
|
||||
was asked for. Mutation-tested: the example validates, and five distinct defect classes are
|
||||
rejected.
|
||||
|
||||
- **`spec/conformance-corpus.md` §1.1** — normative pointer to that schema, plus a SHOULD that
|
||||
a runtime derive its declared set from the constant its runner uses to accept or reject a
|
||||
`scope`, and record which it did.
|
||||
|
||||
### Fixed
|
||||
|
||||
- `docs/lexicon-port-divergence.md` — the `hybrid-xss:script-tag` row is closed on the
|
||||
closing-tag axis, having reversed twice in three days (guard-diverges → commons-diverges →
|
||||
converged). What remains open is the one-byte span difference: the guard excludes `<` from
|
||||
its negated class and the other two do not, so `<script <x>` matches commons and
|
||||
`llm-security` and not the guard. Measured by compiling all three forms, not reasoned from
|
||||
the character classes; neither side has claimed it.
|
||||
|
||||
## [0.2.0] — 2026-08-11
|
||||
|
||||
The contract gained a normative MUST, which is why this is a release rather than a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue