test(okf): pin the two boundary classes the new carriers introduced
Probed after 1.3.0 landed, on advisor challenge. Both came back clean -- these pin them so they cannot regress silently. 1. A `- ` item whose text begins with a YAML indicator AND carries a `": "` could in principle route into the block-mapping path with a half-validated key instead of into `_reject_dangerous_value`. It does not: `&anchor id` fails `_KEY_RE` on the key side, so the item falls through intact and raises on the indicator. One row each for & * ! % backtick, plus the merge key inside an entry. 2. `_consume_block_mapping` ends at a blank line and at column zero, and hands an index back to `_consume_block_list`, which hands one back to `_parse_flat`. A line orphaned by that boundary -- a `resource:` left over from a mapping that closed early -- must RAISE, not be dropped. A pointer that vanishes rather than failing is this repo's failure class, so it gets a test rather than a probe. Plus the return-index contract: a top-level key after a multi-entry list is neither swallowed nor re-read as an item. 868 green (was 859), 130/130 classes. Test-only; no source change.
This commit is contained in:
parent
a965e8ac5b
commit
44e2b31afd
3 changed files with 42 additions and 2 deletions
|
|
@ -53,7 +53,7 @@ scope descriptor a consumer cannot follow at all. A consumer that dereferences
|
||||||
it must call `okf.validate_resource_url` itself.
|
it must call `okf.validate_resource_url` itself.
|
||||||
|
|
||||||
No exported surface changed and no detector behaviour or calibration changed.
|
No exported surface changed and no detector behaviour or calibration changed.
|
||||||
Suite 834 → 859 (25 new rows, plus four pre-existing rows updated where this
|
Suite 834 → 868 (34 new rows, plus four pre-existing rows updated where this
|
||||||
release changed the behaviour they pinned); 130/130 classes, 6/6 documented
|
release changed the behaviour they pinned); 130/130 classes, 6/6 documented
|
||||||
gaps hold, 45 limitations, ReDoS sweep 0/152 candidates flagged.
|
gaps hold, 45 limitations, ReDoS sweep 0/152 candidates flagged.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ python -m llm_ingestion_guard.coverage # exit 0 = all as documented
|
||||||
|
|
||||||
As of `v1.3.0`: **130 / 130 defended classes demonstrated (recall 100%)** and **6 /
|
As of `v1.3.0`: **130 / 130 defended classes demonstrated (recall 100%)** and **6 /
|
||||||
6 documented gaps still hold** (a *closed* gap fails the test, forcing a doc
|
6 documented gaps still hold** (a *closed* gap fails the test, forcing a doc
|
||||||
update). The matrix is the single source of truth for the test suite (**859
|
update). The matrix is the single source of truth for the test suite (**868
|
||||||
passing**), which also asserts total recall, that every lexicon pattern has a
|
passing**), which also asserts total recall, that every lexicon pattern has a
|
||||||
case (so the matrix cannot fall behind the lexicon), the full LLM02 secret-egress
|
case (so the matrix cannot fall behind the lexicon), the full LLM02 secret-egress
|
||||||
set, and the container-layer front-end (CSV formula-injection, zip-slip/bomb,
|
set, and the container-layer front-end (CSV formula-injection, zip-slip/bomb,
|
||||||
|
|
|
||||||
|
|
@ -1092,3 +1092,43 @@ def test_the_producer_golden_now_passes_the_gate():
|
||||||
result = import_bundle({"datasets/sales.md": doc})
|
result = import_bundle({"datasets/sales.md": doc})
|
||||||
assert result.disposition is Disposition.WARN
|
assert result.disposition is Disposition.WARN
|
||||||
assert result.concepts[0].error is None
|
assert result.concepts[0].error is None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("cid,fm", [
|
||||||
|
# A `- ` item whose text begins with a YAML indicator AND carries a `": "`
|
||||||
|
# must fall through to the scalar predicates, not into the block-mapping
|
||||||
|
# route with a half-validated key. Each of these fails `_KEY_RE` on the key
|
||||||
|
# side, so `_reject_dangerous_value` gets the item intact.
|
||||||
|
("anchor", "sources:\n - &anchor id: a\n"),
|
||||||
|
("alias", "sources:\n - *anchor id: a\n"),
|
||||||
|
("tag", "sources:\n - !!str id: a\n"),
|
||||||
|
("directive", "sources:\n - %YAML id: a\n"),
|
||||||
|
("reserved", "sources:\n - `x id: a\n"),
|
||||||
|
("merge key", "sources:\n - id: a\n <<: *base\n"),
|
||||||
|
])
|
||||||
|
def test_an_indicator_in_a_block_item_is_refused_before_the_mapping_route(cid, fm):
|
||||||
|
with pytest.raises(OKFFrontmatterError):
|
||||||
|
parse_frontmatter(f"---\ntype: t\n{fm}---\n\nbody\n")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("cid,fm", [
|
||||||
|
# The block mapping ends at a blank line and at a line in column zero. Both
|
||||||
|
# hand control back with an index that must not skip or re-read a line: a
|
||||||
|
# dangling `resource:` line left over from a mapping that closed early must
|
||||||
|
# RAISE, never be silently dropped -- a pointer that vanishes rather than
|
||||||
|
# failing is exactly this repo's failure class.
|
||||||
|
("blank line inside the mapping", "sources:\n - id: a\n\n resource: b\n"),
|
||||||
|
("top-level key interleaved", "sources:\n - id: a\ntags: x\n resource: b\n"),
|
||||||
|
])
|
||||||
|
def test_a_line_orphaned_by_the_mapping_boundary_raises_rather_than_vanishing(cid, fm):
|
||||||
|
with pytest.raises(OKFFrontmatterError):
|
||||||
|
parse_frontmatter(f"---\ntype: t\n{fm}---\n\nbody\n")
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_block_list_hands_back_an_index_that_resumes_at_the_next_key():
|
||||||
|
# The return-index contract: a top-level key following a multi-entry block
|
||||||
|
# list is neither swallowed by the list nor re-read as a list item.
|
||||||
|
fm, _ = parse_frontmatter(
|
||||||
|
"---\ntype: t\nsources:\n - id: a\n resource: b\n - id: c\ntitle: T\n---\n\nbody\n")
|
||||||
|
assert fm == {"type": "t", "sources": [{"id": "a", "resource": "b"}, {"id": "c"}],
|
||||||
|
"title": "T"}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue