Files
astro-han__karpathy-llm-wiki/tests/test_check_evidence.py
T
2026-07-24 00:57:31 +08:00

766 lines
27 KiB
Python

import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
SCRIPT = Path(__file__).resolve().parent.parent / "scripts" / "check_evidence.py"
RAW_CONTENT = """# Ghostty Update
> Source: https://example.com/ghostty
> Collected: 2026-04-17
> Published: 2026-04-16
Ghostty reached 42K stars on GitHub in April 2026.
The maintainer said "the terminal should feel invisible to users" in the interview.
Daily active users reached 10,000 by March.
"""
ARTICLE_CONTENT = """# Ghostty
> Sources: Example, 2026-04-16
> Raw: [ghostty](../../raw/ai-research/2026-04-17-ghostty.md)
## Overview
Ghostty has 42K stars and reached 10,000 daily active users.
The maintainer said "the terminal should feel invisible to users".
## Growth
Forks grew to 3,020 last week.
Install with `--limit 9000` after downloading.
```
example 78K and 9,999
```
> **Status: Outdated** (2026-07-23)
> The forks situation changed after this was written.
"""
SENTENCE_FINAL_RAW = """# Numbers
> Source: https://example.com/numbers
> Collected: 2026-06-01
> Published: Unknown
Revenue hit 42K. Uptime was 99.9%. The round closed on 2026-06-15.
"""
SENTENCE_FINAL_ARTICLE = """# Sentence final
> Sources: Example, 2026-06-01
> Raw: [numbers](../../raw/t/numbers.md)
Revenue hit 42K and uptime was 99.9%. The round closed on 2026-06-15.
"""
STATUS_EXPLANATION_ARTICLE = """# Status article
> Sources: Example, 2026-04-16
> Raw: [ghostty](../../raw/ai-research/2026-04-17-ghostty.md)
Ghostty has 42K stars.
> **Status: Outdated** (2026-07-23)
> Superseded by the 2026-07-18 report, which restated the count as 55K.
"""
FENCE_VARIANTS_ARTICLE = """# Fences
> Sources: Example, 2026-04-16
> Raw: [ghostty](../../raw/ai-research/2026-04-17-ghostty.md)
~~~text
not a factual claim: 777K
~~~
````text
also not a claim: 888K
````
"""
BODY_ARCHIVED_ARTICLE = """# Ordinary article
> Sources: Example, 2026-01-01
Some paragraph first.
> Archived: 2025-01-01
The release reached 321K users.
"""
RAW_WITH_BODY_METADATA_LINE = """# Source
> Source: https://example.com/x
> Collected: 2026-06-01
> Published: Unknown
First paragraph.
> Updated: The release reached 999K users.
"""
BODY_METADATA_ARTICLE = """# Body metadata
> Sources: Example, 2026-06-01
> Raw: [src](../../raw/t/src.md)
The release reached 999K users.
"""
ESCAPE_ARTICLE = """# Escape
> Sources: Example, 2026-01-01
> Raw: [support](../../notes/support.md)
The release reached 654K users.
"""
DEDUP_ARTICLE = """# Dedup
> Sources: Example, 2026-04-16
> Raw: [ghostty](../../raw/ai-research/2026-04-17-ghostty.md)
Missing value 88,123 appears here and again as 88,123 elsewhere.
"""
BOUNDARY_RAW = """# Numbers
> Source: https://example.com/numbers
> Collected: 2026-06-01
> Published: Unknown
Ghostty reached 142K stars. Uptime was 95.5%. Forks: 13,020.
"""
BOUNDARY_ARTICLE = """# Boundary
> Sources: Example, 2026-06-01
> Raw: [numbers](../../raw/t/numbers.md)
Ghostty has 42K stars and uptime of 5.5%. Forks grew to 3,020.
"""
PLAIN_RAW = """# Plain
> Source: https://example.com/plain
> Collected: 2026-06-01
> Published: Unknown
No numeric facts here at all.
"""
PLAIN_ARTICLE = """# Plain numbers
> Sources: Example, 2026-06-01
> Raw: [plain](../../raw/t/plain.md)
There were 42 users; the ratio was 3.14; founded in 2026.
"""
ARCHIVE_ARTICLE = """# Old answer
> Sources: [Ghostty](ghostty.md)
> Archived: 2026-07-01
At the time, Ghostty had 999K stars and the maintainer said "totally made up quote here".
"""
NO_RAW_ARTICLE = """# No raw
> Sources: Example, 2026-06-01
This ordinary article forgot its Raw field and claims 999K users.
"""
BROKEN_RAW_ARTICLE = """# Broken
> Sources: Example, 2026-06-01
> Raw: [gone](../../raw/t/nonexistent.md)
Claims 999K users with no evidence anywhere.
"""
def make_wiki(root: Path, log: str = ""):
(root / "raw" / "ai-research").mkdir(parents=True)
(root / "raw" / "ai-research" / "2026-04-17-ghostty.md").write_text(RAW_CONTENT)
(root / "raw" / "misc").mkdir(parents=True)
(root / "raw" / "misc" / "notes.md").write_text(SECOND_RAW)
(root / "wiki" / "ai-research").mkdir(parents=True)
(root / "wiki" / "ai-research" / "ghostty.md").write_text(ARTICLE_CONTENT)
(root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(root / "wiki" / "log.md").write_text(log or "# Wiki Log\n")
def run_checker(root: Path, *args: str, cwd: str | None = None) -> subprocess.CompletedProcess:
return subprocess.run(
[sys.executable, str(SCRIPT), str(root), *args],
capture_output=True,
text=True,
cwd=cwd,
)
class WikiTestCase(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.root = Path(self.tmp.name)
def tearDown(self):
self.tmp.cleanup()
class FidelityCheckTest(WikiTestCase):
def setUp(self):
super().setUp()
make_wiki(self.root)
def test_flags_value_absent_from_raw(self):
result = run_checker(self.root)
self.assertIn("3,020", result.stdout)
def test_passes_values_and_quotes_present_in_raw(self):
result = run_checker(self.root)
self.assertNotIn("42K", result.stdout.replace("3,020", ""))
self.assertNotIn("10,000", result.stdout)
self.assertNotIn("invisible to users", result.stdout)
def test_ignores_numbers_in_code(self):
result = run_checker(self.root)
self.assertNotIn("9000", result.stdout)
self.assertNotIn("78K", result.stdout)
self.assertNotIn("9,999", result.stdout)
def test_ignores_status_block_marker_date(self):
result = run_checker(self.root)
self.assertNotIn("2026-07-23", result.stdout)
class BoundaryMatchingTest(WikiTestCase):
def setUp(self):
super().setUp()
(self.root / "raw" / "t").mkdir(parents=True)
(self.root / "raw" / "t" / "numbers.md").write_text(BOUNDARY_RAW)
(self.root / "wiki" / "t").mkdir(parents=True)
(self.root / "wiki" / "t" / "a.md").write_text(BOUNDARY_ARTICLE)
(self.root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(self.root / "wiki" / "log.md").write_text("# Wiki Log\n")
def test_substring_of_larger_number_does_not_pass(self):
result = run_checker(self.root)
self.assertIn("42K", result.stdout)
self.assertIn("5.5%", result.stdout)
self.assertIn("3,020", result.stdout)
class DateBoundaryTest(WikiTestCase):
def test_missing_date_does_not_also_report_its_year(self):
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"Released on 2031-09-12.",
)
plain_wiki(self.root, "a.md", article, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("- 2031-09-12", result.stdout)
self.assertNotIn("- 2031\n", result.stdout)
def test_month_does_not_match_prefix_of_full_date(self):
raw = PLAIN_RAW.replace(
"No numeric facts here at all.",
"Released on 2026-03-19.",
)
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"Released in 2026-03.",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("- 2026-03", result.stdout)
class NumberCoverageTest(WikiTestCase):
def setUp(self):
super().setUp()
(self.root / "raw" / "t").mkdir(parents=True)
(self.root / "raw" / "t" / "plain.md").write_text(PLAIN_RAW)
(self.root / "wiki" / "t").mkdir(parents=True)
(self.root / "wiki" / "t" / "a.md").write_text(PLAIN_ARTICLE)
(self.root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(self.root / "wiki" / "log.md").write_text("# Wiki Log\n")
def test_flags_decimals_and_long_numbers(self):
result = run_checker(self.root)
self.assertIn("3.14", result.stdout)
self.assertIn("2026", result.stdout)
def test_small_plain_integers_are_out_of_scope(self):
result = run_checker(self.root)
self.assertNotIn("42 users", result.stdout)
for line in result.stdout.splitlines():
self.assertFalse(line.strip() == "- 42", f"small int flagged: {line}")
class EvidenceErrorTest(WikiTestCase):
def setUp(self):
super().setUp()
make_wiki(self.root)
def test_archive_page_without_raw_is_legitimate(self):
(self.root / "wiki" / "ai-research" / "old-answer.md").write_text(ARCHIVE_ARTICLE)
result = run_checker(self.root)
self.assertNotIn("999K", result.stdout)
self.assertNotIn("old-answer", result.stdout)
def test_ordinary_article_without_raw_is_an_evidence_error(self):
(self.root / "wiki" / "ai-research" / "no-raw.md").write_text(NO_RAW_ARTICLE)
result = run_checker(self.root)
self.assertIn("no-raw", result.stdout)
self.assertIn("no Raw field", result.stdout)
def test_broken_raw_link_is_an_evidence_error(self):
(self.root / "wiki" / "ai-research" / "broken.md").write_text(BROKEN_RAW_ARTICLE)
result = run_checker(self.root)
self.assertIn("broken", result.stdout)
self.assertIn("unresolvable Raw link", result.stdout)
class CliTest(WikiTestCase):
def setUp(self):
super().setUp()
make_wiki(self.root)
def test_article_args_resolve_against_root_not_cwd(self):
result = run_checker(self.root, "wiki/ai-research/ghostty.md", cwd="/")
self.assertEqual(result.returncode, 0)
self.assertIn("3,020", result.stdout)
def test_missing_article_is_a_warning_not_a_traceback(self):
result = run_checker(self.root, "wiki/nope.md")
self.assertEqual(result.returncode, 0)
self.assertIn("wiki/nope.md", result.stderr)
self.assertNotIn("Traceback", result.stderr)
SECOND_RAW = """# Unrelated Notes
> Source: https://example.com/notes
> Collected: 2026-05-01
> Published: Unknown
Nothing here is compiled anywhere.
"""
def plain_wiki(root: Path, article_name: str, article: str, raw: str = PLAIN_RAW, raw_name: str = "src.md"):
(root / "raw" / "t").mkdir(parents=True)
(root / "raw" / "t" / raw_name).write_text(raw)
(root / "wiki" / "t").mkdir(parents=True)
(root / "wiki" / "t" / article_name).write_text(article)
(root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(root / "wiki" / "log.md").write_text("# Wiki Log\n")
class SentenceFinalTest(WikiTestCase):
def test_sentence_final_values_pass(self):
plain_wiki(self.root, "a.md", SENTENCE_FINAL_ARTICLE, raw=SENTENCE_FINAL_RAW)
(self.root / "raw" / "t" / "src.md").unlink()
(self.root / "raw" / "t" / "numbers.md").write_text(SENTENCE_FINAL_RAW)
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
class StatusBlockTest(WikiTestCase):
def test_status_block_explanation_is_not_checked(self):
make_wiki(self.root)
(self.root / "wiki" / "ai-research" / "statused.md").write_text(STATUS_EXPLANATION_ARTICLE)
result = run_checker(self.root)
self.assertNotIn("2026-07-18", result.stdout)
self.assertNotIn("55K", result.stdout)
class FenceVariantsTest(WikiTestCase):
def test_tilde_and_long_backtick_fences_are_stripped(self):
make_wiki(self.root)
(self.root / "wiki" / "ai-research" / "fences.md").write_text(FENCE_VARIANTS_ARTICLE)
result = run_checker(self.root)
self.assertNotIn("777K", result.stdout)
self.assertNotIn("888K", result.stdout)
class HeaderScopeTest(WikiTestCase):
def test_archived_marker_in_body_does_not_exempt(self):
plain_wiki(self.root, "a.md", BODY_ARCHIVED_ARTICLE)
result = run_checker(self.root)
self.assertIn("no Raw field", result.stdout)
def test_raw_body_metadata_line_remains_evidence(self):
plain_wiki(self.root, "a.md", BODY_METADATA_ARTICLE, raw=RAW_WITH_BODY_METADATA_LINE)
result = run_checker(self.root)
self.assertNotIn("999K", result.stdout)
class RawEscapeTest(WikiTestCase):
def test_raw_link_outside_raw_dir_is_an_evidence_error(self):
(self.root / "raw").mkdir()
(self.root / "notes").mkdir()
(self.root / "notes" / "support.md").write_text("The release reached 654K users.\n")
(self.root / "wiki" / "t").mkdir(parents=True)
(self.root / "wiki" / "t" / "a.md").write_text(ESCAPE_ARTICLE)
(self.root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(self.root / "wiki" / "log.md").write_text("# Wiki Log\n")
result = run_checker(self.root)
self.assertIn("escapes raw/", result.stdout)
class NoMaterialParsingTest(WikiTestCase):
def test_heading_inside_fence_does_not_suppress(self):
(self.root / "raw" / "t").mkdir(parents=True)
(self.root / "raw" / "t" / "orphan.md").write_text("# Orphan\n")
(self.root / "wiki").mkdir()
(self.root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(self.root / "wiki" / "log.md").write_text(
"# Wiki Log\n\n```markdown\n"
"## [2026-01-01] ingest | no material: raw/t/orphan.md\n"
"- Disposition: No material\n```\n"
)
result = run_checker(self.root)
self.assertIn("raw/t/orphan.md", result.stdout)
def test_prose_mention_in_lint_entry_does_not_suppress(self):
(self.root / "raw" / "t").mkdir(parents=True)
(self.root / "raw" / "t" / "orphan.md").write_text("# Orphan\n")
(self.root / "wiki").mkdir()
(self.root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(self.root / "wiki" / "log.md").write_text(
"# Wiki Log\n\n"
"## [2026-01-01] lint | 1 issues found, 0 auto-fixed\n"
"- Note: investigate no material: raw/t/orphan.md\n"
)
result = run_checker(self.root)
self.assertIn("raw/t/orphan.md", result.stdout)
class DedupTest(WikiTestCase):
def test_candidate_reported_once_without_trailing_space(self):
make_wiki(self.root)
(self.root / "wiki" / "ai-research" / "dedup.md").write_text(DEDUP_ARTICLE)
result = run_checker(self.root)
self.assertEqual(result.stdout.count("- 88,123"), 1)
class ExplicitArgsTest(WikiTestCase):
def test_index_and_log_are_skipped_even_when_passed_explicitly(self):
make_wiki(self.root)
result = run_checker(self.root, "wiki/log.md")
self.assertNotIn("no Raw field", result.stdout)
class TokenizerClosedFormTest(WikiTestCase):
def test_version_numbers_match_as_whole(self):
raw = PLAIN_RAW.replace("No numeric facts here at all.", "After v2.1.80, everything changed.")
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"After v2.1.80, everything changed.",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
def test_version_number_absent_flagged_as_whole(self):
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"After v2.1.80, everything changed.",
)
plain_wiki(self.root, "a.md", article, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("- 2.1.80", result.stdout)
self.assertNotIn("- 2.1\n", result.stdout)
def test_prose_commas_do_not_create_candidates(self):
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"There were 42, then 17, and finally 9 items.",
)
plain_wiki(self.root, "a.md", article, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
class RawLinksHeaderScopeTest(WikiTestCase):
def test_fence_template_raw_line_is_ignored(self):
article = (
"# A\n\n> Sources: Example, 2026-01-01\n> Raw: [src](../../raw/t/src.md)\n\n"
"Value 42K.\n\n```markdown\n> Raw: [template](../../raw/topic/filename.md)\n```\n"
)
raw = PLAIN_RAW.replace("No numeric facts here at all.", "Value 42K confirmed.")
plain_wiki(self.root, "a.md", article, raw=raw)
result = run_checker(self.root)
self.assertNotIn("unresolvable Raw link", result.stdout)
def test_body_raw_line_does_not_count(self):
article = (
"# A\n\n> Sources: Example, 2026-01-01\n\n"
"Claims 42% growth.\n\n> Raw: [src](../../raw/t/src.md)\n"
)
raw = PLAIN_RAW.replace("No numeric facts here at all.", "42% growth confirmed.")
plain_wiki(self.root, "a.md", article, raw=raw)
result = run_checker(self.root)
self.assertIn("no Raw field", result.stdout)
class DocumentStructureTest(WikiTestCase):
def test_fence_between_h1_and_body_raw_does_not_create_header(self):
article = (
"# A\n\n```text\nthis is body content\n```\n\n"
"> Raw: [src](../../raw/t/src.md)\n\nValue 42K.\n"
)
raw = PLAIN_RAW.replace("No numeric facts here at all.", "Value 42K.")
plain_wiki(self.root, "a.md", article, raw=raw)
result = run_checker(self.root)
self.assertIn("article has no Raw field", result.stdout)
def test_archived_marker_in_fence_before_real_h1_does_not_exempt(self):
article = (
"```markdown\n# Fake\n> Archived: 2026-01-01\n```\n\n"
"# Real article\n\n> Sources: Example, 2026-01-01\n\nValue 777K.\n"
)
plain_wiki(self.root, "a.md", article)
result = run_checker(self.root)
self.assertIn("article has no Raw field", result.stdout)
def test_title_candidates_are_checked(self):
article = (
"# GPT 9.7 Migration Notes\n\n"
"> Sources: Example, 2026-01-01\n"
"> Raw: [src](../../raw/t/src.md)\n\nNo other claim.\n"
)
plain_wiki(self.root, "a.md", article)
result = run_checker(self.root)
self.assertIn("- 9.7", result.stdout)
def test_fence_closer_with_trailing_text_does_not_close(self):
article = (
"# A\n\n> Sources: Example, 2026-01-01\n"
"> Raw: [src](../../raw/t/src.md)\n\n"
"```text\ninside 777K\n``` trailing text\nstill inside 888K\n```\n"
)
plain_wiki(self.root, "a.md", article)
result = run_checker(self.root)
self.assertNotIn("777K", result.stdout)
self.assertNotIn("888K", result.stdout)
def test_backtick_in_info_string_does_not_open_fence(self):
article = (
"# A\n\n> Sources: Example, 2026-01-01\n"
"> Raw: [src](../../raw/t/src.md)\n\n"
"```lang`bad\nUnsupported 666K claim.\n```\n"
)
plain_wiki(self.root, "a.md", article)
result = run_checker(self.root)
self.assertIn("- 666K", result.stdout)
class QuotePairingTest(WikiTestCase):
def test_multiline_quote_is_checked_within_paragraph(self):
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
'The maintainer said "the terminal should\nfeel invisible to users".\n',
)
plain_wiki(self.root, "a.md", article, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("the terminal should feel invisible to users", result.stdout)
def test_short_quote_pairs_do_not_create_phantom_quote(self):
raw = PLAIN_RAW.replace(
"No numeric facts here at all.",
"Accuracy is high on paper but reliability is low in practice.",
)
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
'Accuracy is "high" but reliability is "low".',
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertNotIn("but reliability is", result.stdout)
class NestedIndexLogTest(WikiTestCase):
def test_article_named_index_in_topic_dir_is_checked(self):
article = BODY_METADATA_ARTICLE.replace("999K users", "888K users")
plain_wiki(self.root, "index.md", article)
result = run_checker(self.root)
self.assertIn("888K", result.stdout)
def test_article_named_log_in_topic_dir_is_checked(self):
article = BODY_METADATA_ARTICLE.replace("999K users", "888K users")
plain_wiki(self.root, "log.md", article)
result = run_checker(self.root)
self.assertIn("888K", result.stdout)
class BlockquoteQuoteTest(WikiTestCase):
def test_short_blockquote_number_is_checked(self):
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"> 999K users\n",
)
plain_wiki(self.root, "a.md", article, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("- 999K", result.stdout)
def test_blockquote_link_target_is_not_part_of_quote(self):
raw = PLAIN_RAW.replace(
"No numeric facts here at all.",
"The terminal should feel invisible to users.",
)
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"> The [terminal](https://example.com) should feel invisible to users.\n",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
def test_fabricated_blockquote_quote_is_flagged(self):
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"As the review put it:\n\n> This fabricated quotation is definitely absent.\n",
)
plain_wiki(self.root, "a.md", article, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("fabricated quotation", result.stdout)
def test_verbatim_blockquote_quote_passes(self):
article = ARTICLE_CONTENT.replace(
"Forks grew to 3,020 last week.",
"> the terminal should feel invisible to users\n",
)
make_wiki(self.root)
(self.root / "wiki" / "ai-research" / "ghostty.md").write_text(article)
result = run_checker(self.root)
self.assertNotIn("invisible to users", result.stdout)
class FenceIndentTest(WikiTestCase):
def test_four_space_indented_backticks_are_not_a_fence(self):
article = (
"# A\n\n> Sources: Example, 2026-01-01\n> Raw: [src](../../raw/t/src.md)\n\n"
" ```\n some indented text\n\nUnsupported claim 777K here.\n"
)
plain_wiki(self.root, "a.md", article)
result = run_checker(self.root)
self.assertIn("777K", result.stdout)
class BacktickNoMaterialTest(WikiTestCase):
def test_backticked_path_still_suppresses(self):
log = (
"# Wiki Log\n\n"
"## [2026-05-01] ingest | no material: `raw/misc/notes.md`\n"
"- Disposition: No material\n"
)
make_wiki(self.root, log=log)
result = run_checker(self.root)
self.assertNotIn("notes.md", result.stdout)
class SpacedSuffixTest(WikiTestCase):
def test_word_after_number_is_not_a_suffix(self):
raw = PLAIN_RAW.replace(
"No numeric facts here at all.",
"The product reached 10 Million users and used 42 Kilobytes.",
)
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"The product reached 10 Million users and used 42 Kilobytes.",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
def test_same_spaced_suffix_in_article_and_raw_passes(self):
raw = PLAIN_RAW.replace("No numeric facts here at all.", "Uptime hit 99.9 % last week.")
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"Uptime hit 99.9 % last week.",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
def test_suffix_does_not_match_prefix_of_word(self):
raw = PLAIN_RAW.replace("No numeric facts here at all.", "The package weighs 42Kg.")
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"The package weighs 42K.",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("- 42K", result.stdout)
def test_spaced_suffix_does_not_match_different_raw_spelling(self):
raw = PLAIN_RAW.replace("No numeric facts here at all.", "Uptime hit 99.9% last week.")
article = PLAIN_ARTICLE.replace(
"There were 42 users; the ratio was 3.14; founded in 2026.",
"Uptime hit 99.9 % last week.",
)
plain_wiki(self.root, "a.md", article, raw=raw, raw_name="plain.md")
result = run_checker(self.root)
self.assertIn("- 99.9 %", result.stdout)
EXAMPLES_DIR = Path(__file__).resolve().parent.parent / "examples"
class ExamplesSmokeTest(WikiTestCase):
def test_examples_have_zero_suspects(self):
raw_src = EXAMPLES_DIR / "2026-03-19-claude-code-statusline-landscape.md"
article_src = EXAMPLES_DIR / "claude-code-statusline-landscape.md"
(self.root / "raw" / "ai-coding-tools").mkdir(parents=True)
(self.root / "raw" / "ai-coding-tools" / raw_src.name).write_text(raw_src.read_text())
(self.root / "wiki" / "ai-coding-tools").mkdir(parents=True)
(self.root / "wiki" / "ai-coding-tools" / article_src.name).write_text(article_src.read_text())
(self.root / "wiki" / "index.md").write_text("# Knowledge Base Index\n")
(self.root / "wiki" / "log.md").write_text("# Wiki Log\n")
result = run_checker(self.root)
self.assertIn("0 fidelity suspect(s)", result.stdout)
self.assertIn("0 evidence error(s)", result.stdout)
class RawInventoryTest(WikiTestCase):
def test_reports_raw_file_never_compiled(self):
make_wiki(self.root)
result = run_checker(self.root)
self.assertIn("raw/misc/notes.md", result.stdout)
def test_no_material_disposition_suppresses_report(self):
log = (
"# Wiki Log\n\n"
"## [2026-05-01] ingest | no material: raw/misc/notes.md\n"
"- Disposition: No material\n"
)
make_wiki(self.root, log=log)
result = run_checker(self.root)
self.assertNotIn("notes.md", result.stdout)
def test_no_material_does_not_suppress_same_name_elsewhere(self):
(self.root / "raw" / "other").mkdir(parents=True)
(self.root / "raw" / "other" / "notes.md").write_text(SECOND_RAW)
log = (
"# Wiki Log\n\n"
"## [2026-05-01] ingest | no material: raw/misc/notes.md\n"
"- Disposition: No material\n"
)
make_wiki(self.root, log=log)
result = run_checker(self.root)
self.assertNotIn("raw/misc/notes.md", result.stdout)
self.assertIn("raw/other/notes.md", result.stdout)
if __name__ == "__main__":
unittest.main()