diff --git a/product/skills/show-me-your-work/SKILL.md b/product/skills/show-me-your-work/SKILL.md index f855dc7d..ffbb3323 100644 --- a/product/skills/show-me-your-work/SKILL.md +++ b/product/skills/show-me-your-work/SKILL.md @@ -128,7 +128,7 @@ the audit trail and the run's transcript, then flags what the user should pay attention to. Not a redo of the work — a scan for what's risky. If the harness cannot spawn a different-family model, still list flags and -mark the Attention line `UNVERIFIED: same-model self-review`. +mark the Attention line `{{CAT-UNVERIFIED: the review -- cannot verify: same-model self-review}}`. - Decisions logged with weak or absent evidence. - Verification steps skipped or claimed without proof in the transcript. diff --git a/tests/test_escape_hatch_vocabulary.py b/tests/test_escape_hatch_vocabulary.py new file mode 100644 index 00000000..d43050a6 --- /dev/null +++ b/tests/test_escape_hatch_vocabulary.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +"""No rule or skill tells an author to write the retired bare `UNVERIFIED:`. + +Every evidence hook clears on the `{{CAT-UNVERIFIED}}` tag and nothing else, +so prose that still says "write `UNVERIFIED:`" sends an agent into a block. + +Run: python3 -m unittest discover -s tests -v +""" +import os +import sys +import unittest + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +import escape_hatch_vocab as vocab # noqa: E402 + + +class InstructionalProseUsesTheTag(unittest.TestCase): + def test_no_instructional_file_names_the_retired_marker(self): + offenders = [] + for path in vocab.instructional_files(): + with open(path, encoding="utf-8") as handle: + for line in vocab.instructs_retired_marker(handle.read()): + offenders.append(f"{os.path.relpath(path, vocab.REPO_ROOT)}: {line[:100]}") + self.assertEqual(offenders, []) + + def test_scan_covers_the_always_loaded_rules(self): + scanned = {os.path.relpath(p, vocab.REPO_ROOT) for p in vocab.instructional_files()} + for rel in ("engine/CLAUDE.core.md", "corpus/CLAUDE.learned.md", "always-on/evidence-check.md"): + self.assertIn(rel, scanned) + + +class DetectorShape(unittest.TestCase): + def test_bare_marker_instruction_is_flagged(self): + self.assertEqual(len(vocab.instructs_retired_marker("- Prefix `UNVERIFIED:` until then.")), 1) + + def test_tag_is_not_flagged(self): + text = "Tag it `{{CAT-UNVERIFIED: -- cannot verify: }}`." + self.assertEqual(vocab.instructs_retired_marker(text), []) + + def test_line_calling_the_marker_retired_is_not_flagged(self): + self.assertEqual(vocab.instructs_retired_marker("Bare `UNVERIFIED:` is retired."), []) + + def test_other_uses_of_the_word_are_not_flagged(self): + text = "| Codex | UNVERIFIED schema | UNVERIFIED end-to-end |" + self.assertEqual(vocab.instructs_retired_marker(text), []) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_show_me_your_work.py b/tests/test_show_me_your_work.py index 06d651e3..95af7223 100644 --- a/tests/test_show_me_your_work.py +++ b/tests/test_show_me_your_work.py @@ -129,5 +129,15 @@ def test_strips_tabs_and_newlines_from_cells(self): self.assertNotIn("\n", cells[3]) +class TestEscapeHatchVocabulary(unittest.TestCase): + def test_attention_line_uses_the_tag_not_the_retired_marker(self): + import sys + sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + import escape_hatch_vocab as vocab + text = read_skill() + self.assertEqual(vocab.instructs_retired_marker(text), []) + self.assertIn("{{CAT-UNVERIFIED: the review -- cannot verify: same-model self-review}}", text) + + if __name__ == "__main__": unittest.main()