docs(url-shape): make the rule reconstructable, and record what three corpora measured
Three consumers reconstructed is_ordinary_url from prose we sent in coordination messages and each produced a different wrong number on a real corpus: one omitted the base64 20-char floor and fired on path words like /blog/; one omitted the opaque-token condition entirely and undercounted; one computed Shannon entropy over whole filenames instead of tokens and concluded the 4.4 floor over-blocks ordinary documents. Same cause each time -- our prose described the rules without their tokenizer. docs/URL-SHAPE.md states the algorithm in order, spells out the separator class and all three length floors, and lists the three reconstruction errors as worked counter-examples. Its example table is parsed and asserted against the real predicate by tests/test_url_shape_doc.py, so the reference cannot drift from the code -- all 18 rows verified load-bearing. LIMITATIONS.md brought current with the field measurements: - Percent-escape is no longer zero. Two English corpora measured 0; a 389-file Norwegian/Microsoft corpus found 10, all Norwegian (%C3%B8, %C3%A5 are just o-slash and a-ring). It is a non-ASCII-language tax, and both zero-measuring corpora being English was a sampling bias invisible from inside. - The query over-block now has THREE disjoint benign populations: utm_* tracking, content identity (?v=, ?channel_id=), and Microsoft Learn's ?view= version selector. No parameter-level remedy covers any two, which moves this from a conclusion to a settled constraint on 0.4.0. - Legitimate CDN asset ids trip the hex branch permanently; the branch is otherwise precise (no other FP in 2401 distinct URLs) and stays. - Raw HTML with a relative URL attribute is HIGH though it reaches no external host, and end tags are counted. - OKF frontmatter: a one-key block-sequence item is silently misparsed to a string where two keys hard-reject, so a pointer can ride past the resource allowlist. Consequence: a conformant OKF v0.2 concept cannot traverse door C at all, since both backward-breaking migration targets are nested. Fail-secure, but a compatibility wall that needs a deliberate parse-safety decision. - A persist gate cannot cover execution risk, and that boundary is unowned. New behaviour claims are pinned by tests so a closed concession fails and forces this doc to be updated. 593 -> 631 passed.
This commit is contained in:
parent
956c835d38
commit
684ce3a45f
6 changed files with 383 additions and 18 deletions
|
|
@ -516,3 +516,69 @@ def test_okf_adapter_is_exposed_from_package():
|
|||
|
||||
assert "okf" in guard.__all__
|
||||
assert guard.okf.import_bundle is import_bundle
|
||||
|
||||
|
||||
# --- v0.2 frontmatter reach: what the restricted grammar admits (2026-07-26) ---
|
||||
# Measured for a consumer planning an additive OKF v0.2 profile. Documented in
|
||||
# docs/LIMITATIONS.md; pinned here so the compatibility wall cannot move silently.
|
||||
|
||||
_V02_REJECTED = [
|
||||
("generated (nested)", "generated:\n at: 2026-07-26T10:00:00Z\n"),
|
||||
("executor (nested)", "executor:\n resource: skills/run-on-bq.md\n"),
|
||||
("attester (nested)", "attester:\n resource: attesters/sql_equality.py\n"),
|
||||
("sources (block list of mappings)",
|
||||
"sources:\n - uri: https://e.com/a\n kind: doc\n"),
|
||||
("flow sequence", "tags: [a, b, c]\n"),
|
||||
("flow mapping", "executor: {resource: skills/run.md}\n"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("cid,fm", _V02_REJECTED, ids=[c[0] for c in _V02_REJECTED])
|
||||
def test_v02_nested_and_flow_frontmatter_hard_rejects(cid, fm):
|
||||
# Both of v0.2's backward-breaking migration targets (`generated.at`, `sources`)
|
||||
# are on this list, so a conformant v0.2 concept cannot pass the gate at all.
|
||||
with pytest.raises(OKFFrontmatterError):
|
||||
parse_frontmatter(f"---\nid: x\n{fm}---\n\nbody\n")
|
||||
|
||||
|
||||
_V02_ADMITTED = [
|
||||
("runtime", "runtime: bigquery\n"),
|
||||
("computation path", "computation: computations/gm.sql\n"),
|
||||
("status/stale_after", "status: active\nstale_after: 2026-12-01\n"),
|
||||
("verified bool", "verified: true\n"),
|
||||
("block sequence of scalars", "tags:\n - alpha\n - beta\n"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("cid,fm", _V02_ADMITTED, ids=[c[0] for c in _V02_ADMITTED])
|
||||
def test_v02_flat_frontmatter_still_parses(cid, fm):
|
||||
assert parse_frontmatter(f"---\nid: x\n{fm}---\n\nbody\n")[0]["id"] == "x"
|
||||
|
||||
|
||||
def test_one_key_block_sequence_item_is_misparsed_as_a_string():
|
||||
# The documented defect: two keys per item hard-reject (loud, safe), but ONE key
|
||||
# parses "successfully" into the wrong type. A consumer reading
|
||||
# frontmatter["sources"][0].get("uri") gets a string, not a mapping.
|
||||
fm, _ = parse_frontmatter(
|
||||
"---\nid: x\nsources:\n - uri: https://e.com/a\n---\n\nbody\n"
|
||||
)
|
||||
assert fm["sources"] == ["uri: https://e.com/a"], "shape changed — update LIMITATIONS.md"
|
||||
assert not isinstance(fm["sources"][0], dict)
|
||||
|
||||
|
||||
def test_relative_resource_pointer_fails_the_allowlist():
|
||||
# A top-level `resource` naming executable code is caught by the https allowlist.
|
||||
for pointer in ("attesters/sql_equality.py", "skills/run-on-bq.md"):
|
||||
with pytest.raises(OKFResourceError):
|
||||
validate_resource_url(pointer)
|
||||
|
||||
|
||||
def test_pointer_in_one_key_sequence_reaches_the_consumer_tree():
|
||||
# The security-relevant consequence of the misparse above: the pointer never
|
||||
# touches the top-level `resource` key, so the https allowlist never inspects it
|
||||
# and door C admits the concept. Not conformant OKF — a well-formed bundle will
|
||||
# not produce this shape — but mode-b writes the merged concept verbatim.
|
||||
doc = ("---\nid: x\ntype: Attested Computation\n"
|
||||
"attester:\n - resource: attesters/sql_equality.py\n---\n\nbody\n")
|
||||
result = import_bundle({"computations/x.md": doc})
|
||||
assert result.disposition is Disposition.WARN, "hole closed — update LIMITATIONS.md"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue