"""A document the gate refuses WHOLE is named in the run's own summary. Measured on 2026-09-20 against a real documentation corpus (594 source files, 197 official documentation pages) built with the shipped default gate: 17 sources -- 16 of the 197 pages -- were refused outright, `fail_secure` 3 and `quarantine_review` 14, and the pages lost were hooks, skills, permissions, errors, env-vars and authentication. The build exited 0 and said so like this: - `fail_secure`: 3/594 - `quarantine_review`: 14/594 Three of the four facts a reader needs were absent. The code was there (c); the COUNT of documents the gate refused whole was not (the `rejected (coded)` line sums gate refusals and extraction failures into one number), the NAMES were not (b), and the way out -- `--gate none` for a source you vouch for yourself -- was not (d). So a bundle could lose the pages it exists for while its summary read like a clean run. The exit code deliberately does NOT move. The build is valid: every refusal is coded, the conservation identity holds, and the bundle is a true record of what the gate allowed. What was wrong was the silence, not the status. The fixture is a two-document inbox, never the real corpus: `CARRIER` carries a zero-width space inside a word and is measured `fail_secure` under BOTH guard presets, and `BENIGN` clears both, so the run has a refusal AND a survivor and cannot pass by refusing everything. """ from __future__ import annotations from pathlib import Path import pytest from llm_ingestion_okf import cli, corpus BUNDLE_ID = "gate-loud-fixture" OKF_VERSION = "0.2" CARRIER = "# Kostnader\n\nEn merknad med et nullbredde​tegn i seg.\n" BENIGN = "# Kostnader\n\nKvartalstall for plattformgruppen, uten funn.\n" def _inbox(root: Path, documents: dict[str, str]) -> Path: inbox = root / "inbox" inbox.mkdir(parents=True, exist_ok=True) for name, body in documents.items(): (inbox / name).write_text(body, encoding="utf-8", newline="") return inbox def _build(inbox: Path, bundle: Path, *extra: str) -> int: return cli.main( [ "build", str(inbox), "--bundle", str(bundle), "--bundle-id", BUNDLE_ID, "--okf-version", OKF_VERSION, *extra, ] ) def _section(out: str) -> str: """Exactly the refusal section, bounded at the next heading. Taken to the end of the report, the slice would also hold `## Rejection codes`, and an assertion about how many names the section lists would count that section's totals too. """ after = out.split(corpus.REFUSED_HEADING, 1)[1] end = after.find("\n## ") return after if end < 0 else after[:end] def _run( tmp_path: Path, documents: dict[str, str], capsys: pytest.CaptureFixture[str] ) -> tuple[int, str, str]: pytest.importorskip("llm_ingestion_guard") inbox = _inbox(tmp_path, documents) code = _build(inbox, tmp_path / "bundle") captured = capsys.readouterr() return code, captured.out, captured.err def test_the_refused_documents_are_counted_with_their_denominator( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """(a) how many documents the gate refused whole -- its own number. `rejected (coded): 1/2` already existed and is not this number: it also counts a file the extractor could not read, which is a different fact about a different failure and points at a different remedy. """ code, out, _ = _run(tmp_path, {"carrier.md": CARRIER, "benign.md": BENIGN}, capsys) assert code == 0, "a build whose gate refused one of two documents is still a valid build" assert corpus.REFUSED_HEADING in out assert "1 of 2" in out def test_the_refused_documents_are_named( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """(b) the file names, and (c) the code beside each one.""" _, out, _ = _run(tmp_path, {"carrier.md": CARRIER, "benign.md": BENIGN}, capsys) section = _section(out) assert "carrier.md" in section assert "fail_secure" in section assert "benign.md" not in section, "a document that reached the bundle is not a refusal" def test_the_way_out_is_stated_in_the_summary( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """(d) the exact command, not a hint that one exists.""" _, out, _ = _run(tmp_path, {"carrier.md": CARRIER, "benign.md": BENIGN}, capsys) section = _section(out) assert "--gate none" in section assert "trust" in section.lower() def test_a_run_the_gate_refused_nothing_from_says_nothing( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """The known-positive: the section must be earned, not unconditional. Without this, every assertion above is satisfied by a constant string and the test says nothing about whether a refusal was observed. """ code, out, err = _run(tmp_path, {"benign.md": BENIGN}, capsys) assert code == 0 assert corpus.REFUSED_HEADING not in out assert "--gate none" not in err def test_the_refusal_also_reaches_stderr( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """Loud where a redirected stdout cannot hide it. `okf build > report.txt` is an ordinary thing to do, and it puts the whole summary in a file the reader opens later, if at all. """ _, _, err = _run(tmp_path, {"carrier.md": CARRIER, "benign.md": BENIGN}, capsys) banner = [line for line in err.splitlines() if "refused" in line] assert banner, "stderr must carry the refusal" assert "carrier.md" in banner[0] assert "--gate none" in banner[0] def test_a_long_list_is_capped_and_points_at_the_whole_one( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """A capped list is only honest if the rest is somewhere a reader can go. The bundle's own `log.md` is that somewhere: SPEC section 9 already holds this run's denominator and gate name, and a document the gate dropped is the same class of fact -- the one thing about the run the bundle cannot otherwise recover. """ # Distinct titles, not thirteen copies: two documents reducing to one # concept name hit the section 3 collision refusal BEFORE the gate, which # would make this row green over a set the gate never saw. documents = { f"carrier-{index:02d}.md": CARRIER.replace("Kostnader", f"Kostnader {index:02d}") for index in range(corpus.REFUSED_NAME_CAP + 3) } documents["benign.md"] = BENIGN _, out, _ = _run(tmp_path, documents, capsys) section = _section(out) assert section.count("`fail_secure`") == corpus.REFUSED_NAME_CAP + 1, ( "the per-name list is capped; the count line carries the code totals" ) assert "3 more" in section assert corpus.LOG_NAME in section log = (tmp_path / "bundle" / corpus.LOG_NAME).read_text(encoding="utf-8") for name in sorted(documents): if name != "benign.md": assert name in log, "log.md names every refused document, uncapped" def test_the_log_is_unchanged_when_the_gate_refused_nothing( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: """Exposure, measured rather than argued: a clean run's bytes do not move. Every bundle this repository ships was built without a gate refusal, so a bullet written only when there is one cannot have moved a byte of them. """ _run(tmp_path, {"benign.md": BENIGN}, capsys) log = (tmp_path / "bundle" / corpus.LOG_NAME).read_text(encoding="utf-8") assert "refused" not in log.lower()