Orchestrata Ultimate › Tests › Reference › gates
Tests reference — tests/gates
tests/gates — 8 test modules, 203 test functions. Source tree: tests/gates at commit 8a2cb42ad. Generated from the tests AST snapshot by scripts/gen-data-pages.py.
Prose pending.
Modules
| Module | Tests | Covers |
|---|---|---|
test_commit_review.py |
34 | 2 |
test_differential_coverage.py |
10 | 1 |
test_differential_vs_legacy.py |
18 | 3 |
test_fact_extractor.py |
44 | 3 |
test_freshness_inference.py |
16 | 1 |
test_gate_explain.py |
18 | 1 |
test_gate_rules.py |
63 | 3 |
Module details
tests/gates/test_commit_review.py
source · 34 tests · 512 lines
Tests for the pre-commit review verdict derived in Prolog.
Covers: gates.commit_review, gates.engine
| Kind | Name | Line | Description |
|---|---|---|---|
| function | test_review_required_mirrors_each_reviewers_own_scope |
171 | |
| function | test_a_name_matching_both_test_patterns_requires_one_review |
177 | |
| function | test_nothing_to_review_is_a_pass_that_says_so |
182 | |
| function | test_clean_reports_pass |
192 | |
| function | test_a_code_review_error_fails_and_names_the_finding |
202 | |
| function | test_code_review_below_error_does_not_block |
213 | |
| function | test_test_review_blocks_at_warning |
218 | |
| function | test_test_review_info_does_not_block |
225 | |
| function | test_a_repo_wide_finding_naming_another_file_still_blocks |
230 | code-review.py's banned-dependency and Prolog-boundary gates scan the |
| function | test_a_required_review_that_never_ran_is_invalid |
242 | |
| function | test_a_reviewer_exit_that_is_not_a_verdict_is_invalid |
250 | 2 is argparse rejecting a flag — the dead --format, exactly. |
| function | test_a_verdict_exit_without_a_report_is_invalid |
258 | The json.load failure: the reviewer finished, but nothing parsed. |
| function | test_a_report_over_zero_files_is_invalid |
265 | |
| function | test_a_stated_total_the_parsed_findings_do_not_match_is_invalid |
272 | The parser drifted from the report: it says 3, we read 1. |
| function | test_an_unclassifiable_severity_is_invalid_once_per_severity |
279 | |
| function | test_an_exit_that_contradicts_the_report_is_invalid |
295 | |
| function | test_a_defective_review_has_no_pass_or_fail_answer |
305 | A count from a report that is not sound means nothing. |
| function | test_a_review_the_rules_did_not_ask_for_is_invalid |
312 | |
| function | test_invalid_dominates_fail |
319 | |
| function | test_an_invalid_review_shows_the_reviewers_own_output |
327 | |
| function | test_a_fact_file_without_its_staged_count_is_invalid |
348 | |
| function | test_a_fact_file_missing_staged_paths_is_invalid |
355 | The driver stated 3 staged paths; only 1 reached the fact file. |
| function | test_commit_status_has_exactly_one_answer |
371 | |
| function | test_runs_do_not_contaminate_each_other |
379 | janus keeps ONE SWI database per process. Run 1 asserts an ERROR; run 2, |
| function | test_scope_does_not_leak_between_runs |
388 | |
| function | test_real_code_review_report_parses_and_adds_up |
397 | |
| function | test_real_test_review_report_parses_and_adds_up |
409 | |
| function | test_real_test_review_declines_a_conftest_with_no_report |
422 | Post-D10: handed a conftest EXPLICITLY, test-review.py analyzes it via T21 |
| function | test_staged_scripts_source_file_with_fabricated_env_key_routes_to_t21 |
435 | W3 founding regression (ADR-0116): a staged scripts/*.py carrying a |
| function | test_parsers_return_none_for_text_that_is_not_a_report |
467 | |
| function | test_end_to_end_bad_files_fail_with_every_finding |
475 | |
| function | test_end_to_end_clean_files_pass |
485 | |
| function | test_end_to_end_a_missing_reviewer_is_invalid |
497 | The checkout has no test reviewer: python exits 2 ("can't open file"). |
| function | test_end_to_end_a_reviewer_past_its_limit_is_invalid |
507 |
tests/gates/test_differential_coverage.py
source · 10 tests · 247 lines
Coverage-completion tests for the pure comparator paths of the differential.
Covers: gates.differential
| Kind | Name | Line | Description |
|---|---|---|---|
| function | test_finding_str_is_file_line_rule |
38 | The comparator's one-line identity: file:line [rule], never the message. |
| function | test_difference_str_appends_detail_when_present |
44 | |
| function | test_difference_str_omits_suffix_without_detail |
57 | |
| function | test_render_reports_counts_then_differences_sorted |
66 | render() leads with the four counters, then one indented line per |
| function | test_render_on_empty_report_has_no_detail_lines |
115 | |
| function | test_prolog_only_import_banned_in_registry_but_not_legacy_set |
122 | A registry entry the legacy hardcoded set lacks is a named GAIN: |
| function | test_prolog_only_import_in_both_sets_is_unexplained |
152 | If the legacy rule ALSO bans the module, the registry-overlap mechanism |
| function | test_prolog_only_known_key_in_legacy_list_is_unexplained |
180 | A key the legacy list already covers cannot explain the difference via |
| function | test_prolog_only_no_module_no_key_no_keys_list_is_unexplained |
204 | Rule present, file inspected, but nothing at that line for either |
| function | test_known_loss_causes_do_not_fail_equivalence |
229 | An OUT_OF_PROJECT_SCOPE legacy-only finding is one this layer is RIGHT |
tests/gates/test_differential_vs_legacy.py
source · 18 tests · 494 lines
The Prolog gate against the checkers it replaces (P5).
Covers: gates.differential, gates.engine, gates.fact_extractor
| Kind | Name | Line | Description |
|---|---|---|---|
| function | test_side_decides_direction_not_cause |
489 | is_loss asks which side found it, not why. A cause classifies the |
| class | TestTheFourDefectsItFound |
148 | One test per defect the differential surfaced, so none can return. |
| method | TestTheFourDefectsItFound.test_pyswip_is_banned_by_the_registry_not_by_a_literal |
151 | standards held _FORBIDDEN_IMPORTS = {"pyswip"} in code. The |
| method | TestTheFourDefectsItFound.test_a_dotted_registry_entry_bans_the_submodule_only |
165 | unittest.mock is banned, unittest is not. A top-level-only |
| method | TestTheFourDefectsItFound.test_a_project_root_of_dot_does_not_silence_every_rule |
180 | project(_, '.') made in_project/1 fail for every file, and |
| method | TestTheFourDefectsItFound.test_the_module_lookup_is_asked_only_about_import_rules |
196 | A relative-import finding at a line importing .relative was |
| class | TestLosses |
219 | |
| method | TestLosses.test_a_package_only_the_legacy_checker_bans_is_a_loss |
220 | |
| method | TestLosses.test_a_classified_loss_still_fails |
240 | Knowing WHY a hole exists does not fill it. A cause is an |
| method | TestLosses.test_a_substring_only_match_is_not_a_loss |
261 | _check_no_mocks flags any module whose name CONTAINS "mock", so |
| class | TestGains |
285 | |
| method | TestGains.test_a_rule_no_legacy_checker_has_is_a_named_gain |
286 | |
| method | TestGains.test_a_file_the_legacy_rule_never_inspected_is_a_named_gain |
300 | _check_no_mocks only reads pytest files; banned_import reads |
| method | TestGains.test_an_infra_key_the_legacy_list_omits_is_a_named_gain |
321 | ENV_VAR_KEYS covers 6 of the 10 required infra keys. |
| method | TestGains.test_a_gain_never_fails_the_differential |
342 | Equality of the two sets is the WRONG acceptance test: it would |
| class | TestScope |
359 | |
| method | TestScope.test_a_legacy_finding_outside_the_project_is_not_a_loss |
360 | |
| class | TestBanTargets |
377 | |
| method | TestBanTargets.test_both_granularities_are_offered |
386 | Mirrors ban_target/3: the comparison does not know whether the |
| class | TestMessages |
395 | |
| method | TestMessages.test_a_relative_import_with_no_module_names_its_dots |
396 | from . import sibling has no module, and interpolating the empty |
| class | TestRegistryAgreement |
413 | |
| method | TestRegistryAgreement.test_the_prolog_rule_flags_every_package_in_the_registry |
414 | The registry is read in Python (banned_registry) and matched in |
| class | TestCLIRefusal |
440 | The ledger is empty. Both refusals below are the LIVE behaviour. |
| method | TestCLIRefusal.test_the_cli_refuses_when_no_legacy_checker_is_left |
443 | Every row is deleted, so a comparison would report zero differences |
| method | TestCLIRefusal.test_a_refilled_map_with_no_collector_fails_loudly |
462 | P7 refills the map for the next slice. If it refills the map and |
tests/gates/test_fact_extractor.py
source · 44 tests · 989 lines
Tests for the Prolog gate fact extractor (P1).
Covers: core.infra_env_rule, core.janus_bootstrap, gates.fact_extractor
| Kind | Name | Line | Description |
|---|---|---|---|
| class | TestFactsComeFromTheSnapshot |
108 | REQ-GATE-001 — the extractor must not open a source file. |
| method | TestFactsComeFromTheSnapshot.test_structural_facts_ignore_the_on_disk_bytes |
111 | The snapshot says the module imports json; disk says otherwise. |
| method | TestFactsComeFromTheSnapshot.test_a_file_absent_from_disk_still_yields_its_structural_facts |
152 | Nothing is read, so nothing needs to be there. |
| method | TestFactsComeFromTheSnapshot.test_a_missing_snapshot_raises_instead_of_yielding_zero_facts |
168 | Zero facts means zero violations means a green gate (REQ-GATE-003). |
| method | TestFactsComeFromTheSnapshot.test_a_snapshot_that_is_not_an_object_raises |
181 | |
| class | TestFreshnessIsTheOnlyDiskAccess |
189 | REQ-GATE-002 — staleness needs both sides, so it may touch disk. |
| method | TestFreshnessIsTheOnlyDiskAccess.test_both_hashes_are_emitted_when_the_file_exists |
192 | |
| method | TestFreshnessIsTheOnlyDiskAccess.test_a_snapshot_file_gone_from_disk_emits_no_disk_side |
221 | The MISSING disk fact is what freshness.pl reads as staleness. |
| method | TestFreshnessIsTheOnlyDiskAccess.test_snapshot_built_at_is_the_snapshots_own_mtime |
250 | |
| class | TestEnvAccessFacts |
259 | The two slice-1 env rules read this predicate and disagree about it. |
| method | TestEnvAccessFacts.test_form_folds_the_default_in |
276 | |
| method | TestEnvAccessFacts.test_env_access_reaches_the_fact_base_with_its_line_and_key |
281 | |
| class | TestArgvLiteralFacts |
309 | ADR-0089 (Q2b): the spawn-site program token reaches the fact base. |
| method | TestArgvLiteralFacts.test_argv_literal_is_emitted_with_its_exact_arguments |
318 | |
| method | TestArgvLiteralFacts.test_the_program_token_is_emitted_verbatim |
348 | An absolute system path is a record like any other — WHICH tokens |
| method | TestArgvLiteralFacts.test_an_unrenderable_callee_keeps_its_question_mark |
376 | The analyzer records '?' when the callee chain is not |
| class | TestSnapshotCaptureFacts |
405 | Provenance: which per-module captures the snapshot attests it performed. |
| method | TestSnapshotCaptureFacts.test_one_fact_per_capture_entry |
415 | |
| method | TestSnapshotCaptureFacts.test_no_captures_key_emits_no_capture_facts |
431 | The pre-Q2a snapshot shape. Emitting a fact for a capture nobody |
| class | TestPolicyData |
444 | |
| method | TestPolicyData.test_infra_keys_are_emitted_from_the_injected_set |
445 | |
| method | TestPolicyData.test_the_live_infra_key_set_is_the_default |
459 | The gate must not carry its own copy of the infra-key list. |
| method | TestPolicyData.test_banned_imports_carry_their_rationale |
474 | |
| method | TestPolicyData.test_a_version_pin_is_stripped_to_the_module_name |
496 | |
| class | TestDifferentialLookups |
510 | The two lookups the P5 differential asks the extractor for. |
| method | TestDifferentialLookups.test_the_import_index_keeps_the_full_dotted_path |
518 | Not folded to the top-level package. |
| method | TestDifferentialLookups.test_the_env_index_carries_the_key_read_at_each_line |
538 | The legacy ENV_VAR_KEYS list covers 6 of the 10 required infra |
| method | TestDifferentialLookups.test_the_import_index_excludes_files_outside_the_project |
561 | A legacy-only finding in an out-of-scope file is a scope difference, |
| method | TestDifferentialLookups.test_the_registry_is_normalised_for_comparison |
581 | PyPI treats - and _ as the same character, and so does |
| method | TestDifferentialLookups.test_file_class |
612 | |
| class | TestPrologSyntax |
616 | |
| method | TestPrologSyntax.test_atoms_are_escaped |
629 | One unescaped newline in one default expression would fail the |
| method | TestPrologSyntax.test_empty_list_renders_as_prolog_nil |
634 | |
| method | TestPrologSyntax.test_list_elements_are_atoms |
637 | |
| method | TestPrologSyntax.test_a_default_expression_with_a_newline_survives |
640 | |
| class | TestFactBaseLayout |
661 | |
| method | TestFactBaseLayout.test_facts_are_grouped_by_predicate |
662 | Interleaved clauses make SWI warn once per run boundary — measured |
| method | TestFactBaseLayout.test_every_emitted_predicate_is_declared_in_sections |
696 | A predicate the layout does not know about lands under an explicit |
| method | TestFactBaseLayout.test_write_persists_the_fact_base |
708 | |
| class | TestToolingLayer |
718 | REQ-GATE-010/011 — the linter as a fact source, not a thing to reimplement. |
| method | TestToolingLayer.test_the_live_catalogue_and_its_configured_status_are_facts |
727 | |
| method | TestToolingLayer.test_e501_is_recorded_as_ignored_which_is_what_makes_it_derivable |
743 | The single fact pair P3's uncovered/1 turns into a conclusion. |
| method | TestToolingLayer.test_a_catalogue_that_cannot_be_obtained_is_NAMED |
773 | Zero catalogue facts must never be silent. |
| method | TestToolingLayer.test_a_catalogue_that_hangs_is_reported_as_timeout |
795 | |
| method | TestToolingLayer.test_rule_status_keeps_ignored_and_unknown_apart |
820 | A deliberate exemption and an oversight must not look the same — |
| method | TestToolingLayer.test_fixability_survives_either_ruff_field |
837 | |
| method | TestToolingLayer.test_a_legacy_top_level_ruff_config_is_still_read |
842 | A config that moved must not silently report every rule unknown — |
| method | TestToolingLayer.test_a_missing_pyproject_yields_no_selectors |
857 | |
| class | TestConsultsIntoARealEngine |
869 | The emitted text must be valid Prolog, and nothing else proves it. |
| method | TestConsultsIntoARealEngine.test_adversarial_atoms_consult_without_error |
879 | |
| method | TestConsultsIntoARealEngine.test_the_live_fact_base_consults_and_answers |
905 | 88k facts through the real engine, then a slice-1-shaped query. |
| class | TestLiveTreeAcceptance |
937 | P1's acceptance lines, asserted rather than eyeballed. |
| method | TestLiveTreeAcceptance.test_the_ontology_declares_no_rule_shaped_predicate |
940 | REQ-GATE-004. A clause with a body in code_facts.pl means policy |
| method | TestLiveTreeAcceptance.test_distinct_fact_predicates_stay_within_the_ceiling |
954 | |
| method | TestLiveTreeAcceptance.test_no_per_line_fact_layer_exists |
961 | REQ-GATE-010. A per-line layer was measured at 845,547 facts for the |
| method | TestLiveTreeAcceptance.test_the_live_tree_yields_facts_for_every_module |
983 |
tests/gates/test_freshness_inference.py
source · 16 tests · 423 lines
Tests for freshness-as-inference and the three-valued verdict (P2).
Covers: gates.engine
| Kind | Name | Line | Description |
|---|---|---|---|
| class | TestAStaleFactBaseIsInvalidNotPass |
189 | REQ-GATE-003, the acceptance line: touching a file must not exit 0. |
| method | TestAStaleFactBaseIsInvalidNotPass.test_a_touch_that_changes_no_bytes_is_NOT_stale |
192 | Mohamed, 2026-08-08: "compare the file hash not the time." |
| method | TestAStaleFactBaseIsInvalidNotPass.test_a_content_change_with_an_UNCHANGED_mtime_is_still_caught |
209 | The case an mtime-only check misses entirely. |
| method | TestAStaleFactBaseIsInvalidNotPass.test_a_file_the_snapshot_describes_but_disk_lost_is_caught |
231 | |
| method | TestAStaleFactBaseIsInvalidNotPass.test_a_file_on_disk_the_snapshot_never_saw_is_caught |
242 | The worst blind spot of the four. |
| method | TestAStaleFactBaseIsInvalidNotPass.test_staleness_is_reported_before_any_rule_runs |
263 | A stale base yields NO violations, even under an always-firing rule. |
| class | TestNoRulesIsAlsoInvalid |
279 | |
| method | TestNoRulesIsAlsoInvalid.test_zero_rules_does_not_report_a_pass |
280 | Zero violations found by zero rules is not a pass. |
| method | TestNoRulesIsAlsoInvalid.test_the_live_tree_with_no_rulebase_is_invalid |
290 | The state of this repo at P2, asserted rather than assumed. |
| class | TestAFreshBaseWithRulesReachesAVerdict |
306 | |
| method | TestAFreshBaseWithRulesReachesAVerdict.test_rules_that_find_nothing_produce_pass |
307 | |
| method | TestAFreshBaseWithRulesReachesAVerdict.test_rules_that_find_something_produce_fail |
317 | |
| method | TestAFreshBaseWithRulesReachesAVerdict.test_the_three_exit_codes_are_distinct |
330 | A caller that only checks rc == 0 must still be stopped by |
| class | TestRunsDoNotContaminateEachOther |
337 | janus shares ONE process-global SWI database. |
| method | TestRunsDoNotContaminateEachOther.test_a_second_run_does_not_inherit_the_first_runs_facts |
340 | The exact leak measured while building P2. |
| method | TestRunsDoNotContaminateEachOther.test_a_run_that_raises_still_unloads |
369 | A syntactically broken rulebase must not strand 90k facts. |
| class | TestVerdictReporting |
394 | |
| method | TestVerdictReporting.test_truncation_is_announced |
395 | A list silently cut at N reads as 'there were N' — which is how a |
| method | TestVerdictReporting.test_a_short_list_is_not_annotated |
408 | |
| method | TestVerdictReporting.test_a_violation_renders_as_a_clickable_location |
413 | |
| method | TestVerdictReporting.test_exit_code_follows_status |
422 |
tests/gates/test_gate_explain.py
source · 18 tests · 319 lines
Proof trees and why-not, over the real meta-interpreter (P4).
Covers: gates.engine
| Kind | Name | Line | Description |
|---|---|---|---|
| class | TestExplain |
118 | |
| method | TestExplain.test_a_violation_yields_a_proof_naming_the_facts_it_consumed |
119 | The point of a proof: every step is inspectable, so a wrong finding |
| method | TestExplain.test_the_proof_distinguishes_facts_from_inference |
134 | A uniform tree hides the only question a reader has: which steps |
| method | TestExplain.test_the_rendered_tree_marks_each_kind |
144 | |
| method | TestExplain.test_the_project_scope_check_appears_in_the_proof |
155 | in_project/1 is not decoration — a proof that omitted it would |
| method | TestExplain.test_the_bare_toolchain_proof_names_the_fact_and_the_enumeration |
170 | ADR-0089 (Q2b): the proof of a bare_toolchain finding must show |
| method | TestExplain.test_a_location_that_does_not_violate_yields_no_proof |
188 | None, not an empty tree. An empty proof renders as 'explained'. |
| method | TestExplain.test_an_unknown_rule_id_yields_no_proof |
198 | |
| class | TestWhyNot |
206 | REQ-GATE-008 — the question the tree-sitter checker died for want of. |
| method | TestWhyNot.test_an_absolute_import_names_the_level_comparison_WITH_ITS_VALUE |
209 | 0>0, not _G>0. |
| method | TestWhyNot.test_a_correct_infra_read_names_the_form_that_saved_it |
226 | REDIS_HOST read WITHOUT a default is the required form, and the |
| method | TestWhyNot.test_an_ordinary_key_with_a_default_names_the_infra_key_check |
239 | |
| method | TestWhyNot.test_a_non_banned_import_names_the_banned_lookup |
249 | |
| method | TestWhyNot.test_a_line_with_no_import_at_all_names_the_missing_fact |
257 | Different cause, different answer: there is no import HERE, as |
| method | TestWhyNot.test_an_unknown_rule_has_no_candidate_clause |
269 | Empty, and the CLI turns that into a message rather than silence — |
| method | TestWhyNot.test_every_rule_can_be_asked_why_not |
288 | A rule that cannot answer why-not is a rule that can die silently. |
| class | TestRenderers |
300 | |
| method | TestRenderers.test_a_leaf_renders_without_children |
301 | |
| method | TestRenderers.test_nesting_is_indented |
304 | |
| method | TestRenderers.test_an_unknown_kind_renders_a_question_mark |
311 | A node kind explain.pl gains later must be VISIBLE, not silently |
| method | TestRenderers.test_a_why_not_names_both_the_clause_and_the_blocker |
316 |
tests/gates/test_gate_rules.py
source · 63 tests · 1379 lines
Slice-1 rules, with a negative corpus at least as large as the positive (P3).
Covers: core.janus_bootstrap, gates.engine, gates.fact_extractor
| Kind | Name | Line | Description |
|---|---|---|---|
| class | TestNoRelativeImport |
305 | |
| method | TestNoRelativeImport.test_positive |
309 | |
| method | TestNoRelativeImport.test_negative |
318 | |
| method | TestNoRelativeImport.test_the_detail_names_the_depth_and_the_module |
323 | A finding that does not say WHAT is wrong makes the reader re-derive |
| class | TestBannedImport |
335 | |
| method | TestBannedImport.test_positive |
339 | |
| method | TestBannedImport.test_negative |
347 | |
| method | TestBannedImport.test_the_detail_carries_the_ban_reason |
352 | "xdist is banned" is a wall. The registry records WHY, and carrying |
| class | TestEnvMutation |
363 | The write, split from the read on 2026-08-08. |
| method | TestEnvMutation.test_positive |
375 | |
| method | TestEnvMutation.test_negative |
383 | |
| method | TestEnvMutation.test_a_write_does_not_also_fire_the_read_rule |
388 | The defect itself: one access, one rule. Two findings on one line |
| method | TestEnvMutation.test_a_read_does_not_fire_the_mutation_rule |
395 | |
| method | TestEnvMutation.test_an_infra_key_read_bare_fires_nothing |
400 | The two env rules must not contradict each other on one line. |
| class | TestBareOsEnviron |
413 | |
| method | TestBareOsEnviron.test_positive |
417 | |
| method | TestBareOsEnviron.test_negative |
425 | |
| class | TestWaivers |
431 | The repo's # gate-ok: <reason> convention, honoured by the rules. |
| method | TestWaivers.test_a_reasoned_waiver_clears_a_mutation |
442 | |
| method | TestWaivers.test_the_same_mutation_fires_without_one |
449 | The control. Without it the test above would pass on a rule that |
| method | TestWaivers.test_a_reasoned_waiver_clears_a_bare_read |
456 | |
| method | TestWaivers.test_a_bare_marker_with_no_reason_waives_nothing |
461 | An unexplained waiver is a mute button. Every checker that honours |
| method | TestWaivers.test_a_marker_on_the_line_above_reaches_the_finding |
473 | The form the repo uses when the statement cannot carry a trailing |
| method | TestWaivers.test_a_marker_two_lines_above_does_not_reach |
484 | Bounded on purpose — a waiver that drifted down a file would cover |
| method | TestWaivers.test_a_waiver_does_not_reach_banned_import |
493 | gate_severity.pl says banned_import has NO exception in any context. |
| class | TestInfraKeyWithDefault |
526 | |
| method | TestInfraKeyWithDefault.test_positive |
530 | |
| method | TestInfraKeyWithDefault.test_negative |
538 | |
| method | TestInfraKeyWithDefault.test_it_is_the_exact_inverse_of_bare_os_environ |
543 | The two rules over env_access/4 disagree on purpose, and the pair is |
| class | TestBareToolchain |
558 | ADR-0089 (Q2b): a literal toolchain program token at a spawn site. |
| method | TestBareToolchain.test_positive |
579 | Exactly ONE violation per record, with the enumerated Kind in the |
| method | TestBareToolchain.test_negative |
595 | |
| method | TestBareToolchain.test_the_detail_carries_the_remedy |
600 | "bare toolchain name python" is a wall. The remedy is DATA |
| method | TestBareToolchain.test_a_python_tool_remedy_names_the_module_form |
612 | |
| method | TestBareToolchain.test_a_waived_line_does_not_fire |
620 | The 4 test-data records in this tree (a program name passed to a |
| method | TestBareToolchain.test_the_same_record_fires_without_the_waiver |
628 | The control. Without it the test above would pass on a rule that |
| method | TestBareToolchain.test_a_record_outside_the_project_scope_does_not_fire |
635 | in_project/1 is defence in depth behind the extractor's scope |
| class | TestRequiredCaptures |
665 | A rule whose input was never captured matches nothing and reports PASS. |
| method | TestRequiredCaptures.test_a_snapshot_without_argv_literals_is_invalid |
676 | |
| method | TestRequiredCaptures.test_a_snapshot_without_env_accesses_is_invalid |
685 | |
| method | TestRequiredCaptures.test_a_snapshot_with_no_capture_list_at_all_is_invalid |
694 | The pre-Q2a snapshot shape: no captures key means NO capture is |
| method | TestRequiredCaptures.test_both_captures_present_with_zero_records_passes |
708 | Captured and found nothing IS clean — the distinction the capture |
| class | TestSeverityIsSeparateData |
718 | REQ-GATE-006 — enforcement policy lives outside the rule clauses. |
| method | TestSeverityIsSeparateData.test_no_rule_clause_mentions_a_severity |
721 | The check that keeps the two files honest. |
| method | TestSeverityIsSeparateData.test_no_severity_clause_mentions_a_fact_predicate |
735 | |
| method | TestSeverityIsSeparateData.test_a_src_violation_blocks |
745 | |
| method | TestSeverityIsSeparateData.test_an_infra_key_default_blocks_even_in_generated_code |
754 | gate_severity.pl grants NO exception for this rule, anywhere. |
| class | TestProjectScope |
772 | Mohamed, 2026-08-08: "make sure to scope facts by project". |
| method | TestProjectScope.test_a_rule_does_not_fire_outside_the_declared_project |
775 | in_project/1 is defence in depth behind the extractor's scope |
| method | TestProjectScope.test_a_fact_base_with_no_declared_scope_is_invalid_not_clean |
808 | The false-PASS this whole layer exists to refuse. |
| method | TestProjectScope.test_the_project_fact_names_the_snapshot |
848 | |
| class | TestCorpusDiscipline |
854 | The property all four 2026-08-06 hooks were missing. |
| method | TestCorpusDiscipline.test_negative_corpus_is_at_least_as_large_as_positive |
884 | |
| method | TestCorpusDiscipline.test_every_declared_rule_has_a_corpus |
893 | A rule in gate_rules.pl with no test here would be the tree-sitter |
| class | TestPolicyMechanismFacts |
914 | REQ-GATE-011: policy_mechanism/3, emitted from what is ACTUALLY in the |
| method | TestPolicyMechanismFacts.test_every_native_rule_gets_its_own_mechanism_fact |
922 | One policy_mechanism(RuleId, native, RuleId) per rule |
| method | TestPolicyMechanismFacts.test_a_missing_gate_rules_file_emits_no_native_mechanisms |
950 | The injection seam works, and fails OPEN toward "nothing claimed" |
| method | TestPolicyMechanismFacts.test_ruff_mechanisms_mirror_the_catalogue_exactly |
969 | Every ruff-side policy_mechanism fact has a matching tool_rule/4 |
| class | TestFormatterMechanism |
1010 | Coordinator finding, 2026-08-19: covered/1 must not be blind to a |
| method | TestFormatterMechanism.test_black_configured_emits_a_formatter_mechanism_for_trailing_whitespace |
1023 | |
| method | TestFormatterMechanism.test_black_configured_emits_a_formatter_mechanism_for_all_four_codes |
1035 | W191/W291/W292/W293 — every code |
| method | TestFormatterMechanism.test_e501_never_gets_a_formatter_mechanism |
1060 | The regression pin for the false positive the coordinator found: |
| method | TestFormatterMechanism.test_no_black_section_emits_no_formatter_mechanisms |
1081 | The condition IS the fact: no [tool.black], no formatter claim. |
| class | TestPolicyCoverage |
1099 | REQ-GATE-011: covered/1, uncovered/1, policy_requirement/1 — RUL-014 |
| method | TestPolicyCoverage.test_a_native_policy_with_a_live_rule_is_covered_not_uncovered |
1127 | gate_rules.pl's OWN violation/4 clause backs this policy — it must |
| method | TestPolicyCoverage.test_an_ignored_ruff_policy_is_uncovered |
1143 | A policy whose ONLY mechanism is a ruff rule this project's config |
| method | TestPolicyCoverage.test_an_enabled_ruff_policy_is_covered_not_uncovered |
1158 | This is the "IS covered" half again, over the TOOL mechanism this |
| method | TestPolicyCoverage.test_a_stale_native_mechanism_is_uncovered_not_covered |
1175 | native_rule_live/1 re-checks at QUERY time: a policy_mechanism |
| method | TestPolicyCoverage.test_unknown_ruff_status_is_not_a_policy_requirement |
1190 | A ruff rule this project has never selected is not one of ITS |
| method | TestPolicyCoverage.test_a_formatter_mechanism_is_covered_not_uncovered |
1213 | The THIRD mechanism kind (coordinator finding, 2026-08-19): |
| method | TestPolicyCoverage.test_a_formatter_mechanism_is_also_a_policy_requirement |
1229 | A formatter-only-mechanised policy must be able to be ASKED |
| class | TestClauseCountInvariant |
1247 | REQ-114-FR2-004 clause (a) (SPEC-114 FR-002): the violation/4 clause-count |
| method | TestClauseCountInvariant.test_the_real_gate_rules_pl_loads_every_declared_clause_and_passes |
1265 | The clean-tree control: no clobbering, 6 declared, 6 loaded, |
| method | TestClauseCountInvariant.test_a_second_moduleless_rulebase_defining_violation4_is_invalid |
1276 | THE NEGATIVE CORPUS. A quarantine-shaped pending.pl — no |
| method | TestClauseCountInvariant.test_the_clobber_reason_names_the_survivor_and_the_wiped_file |
1308 | The verdict must say WHICH file clobbered it, not just that the |
| method | TestClauseCountInvariant.test_consult_order_decides_who_survives_and_the_message_tracks_it |
1332 | Consulting pending.pl FIRST reverses which file wins — SWI |
| method | TestClauseCountInvariant.test_no_rulebases_still_falls_through_to_the_zero_rules_reason |
1354 | 0 declared == 0 loaded satisfies the invariant trivially, so the |
| method | TestClauseCountInvariant.test_declared_rule_count_of_a_missing_file_is_zero |
1372 | A rulebases entry that does not exist on disk counts as zero |
Support files
Fixtures, package markers and helpers without test functions.