Fix the budget gate and add CI, lint and coverage guards

- check_budget.py escalated a hard index-row violation to 'warn' on both
  branches, so INDEX_ROW_HARD could never fail anything. It fails now, and
  tests/unit/test_budget_measurement.py pins both thresholds.
- The corpus note counted scripts/__pycache__/*.pyc, so the same commit
  reported 27 scripts after the suite had run and 16 on a clean checkout.
- TOKENS_PER_CHAR is re-derived from a measurement (26,795 chars -> 6,065
  tokens = 4.418); the comment's old figure and its arithmetic were both
  wrong for this file.
- check_repo.py's yaml sentinel carries the type ignore, so mypy is clean
  with PyYAML installed as well as without it.
- The CPUID test now skips with the probe's own note on a host without
  CPUID instead of failing, and pytest.ini points at tests/README.md, which
  exists, instead of an EXTENSION file that never did.

Tooling: .flake8 (a measured 120-column limit), .gitattributes, .gitignore
and .github/workflows/ci.yml (the five gates, the suite on 3.11-3.14 and a
lint job), which is what CONTRIBUTING.md already claimed CI runs. The
pull-request template it refers to now exists.

Content: pitfalls P26-P34 -- the analysis-level failures the catalogue was
missing (sampling read as observation, a self-built parser trusted, a
verification that could not have failed, a shell-mangled command line) --
registered in the symptom index and its routing mirror. FINDINGS F11-F15
record the defects above.

Tests: the coverage guard derives its subject from scripts/ rather than a
hand-written list, pe_triage.py and pe_diff.py gain their first tests, and
plan.py / preflight.py are declared uncovered with reasons.
This commit is contained in:
root
2026-10-24 14:55:02 +08:00
parent 25f2286cb6
commit 63b2aca8d8
19 changed files with 812 additions and 14 deletions
+41 -1
View File
@@ -390,8 +390,48 @@ def test_prober_rows_carry_a_measurement_and_a_note(hwprobe_report):
assert row["state"] in ROUTE_STATES or row["state"].startswith("needs-"), row
def test_prober_can_dump_raw_cpuid_registers(run_script):
def test_prober_can_dump_raw_cpuid_registers(run_script, hwprobe_report):
"""A requested CPUID dump must be non-empty -- where CPUID is reachable at all.
The probe's own report says which of those two situations this host is in, so the test reads it
instead of assuming x64 Windows: on a non-x64 or non-Windows host the stub cannot run, and
"nothing was reported" is the correct answer rather than a defect. A missing capability is a
skip with the probe's own note, never a red test (tests/README.md, conftest.py).
"""
cpu = hwprobe_report["cpu"][0]
if cpu["state"] != "available":
pytest.skip("CPUID is not reachable on this host, so there is no register dump to check: %s"
% cpu["note"])
result = run_script("hwprobe.py", "--raw", "--json", timeout=120)
assert result.returncode == 0, result.stderr
payload = json.loads(result.stdout)
assert payload["raw_cpuid"], "a raw dump was requested but nothing was reported"
# --- pe_triage ---------------------------------------------------------------
def test_triage_reports_identity_and_leaves_the_sample_untouched(fixtures, run_script):
"""The first script a task should run: it parses, classifies, and must not write."""
sample = fixtures.pe64
before = sample.data
result = run_script("pe_triage.py", sample.path, "--json")
assert result.returncode == 0, result.stderr
payload = json.loads(result.stdout)
assert payload["sha256"] == sample.sha256
assert payload["identity"]["arch"] == "amd64"
assert payload["identity"]["bitness"] == 64
assert payload["identity"]["kind"] == "exe"
assert sample.data == before, "triage modified the image it was reading"
# --- pe_diff -----------------------------------------------------------------
def test_diff_of_the_same_build_reports_no_material_change(fixtures, run_script):
"""Self-comparison is the control for every other diff: it must find nothing."""
sample = fixtures.pe64
result = run_script("pe_diff.py", sample.path, sample.path, "--json")
assert result.returncode == 0, result.stderr
payload = json.loads(result.stdout)
assert payload["verdict"] == "identical-modulo-normalised-fields"
assert payload["material_change"] is False
assert payload["byte_diff"]["differ_bytes"] == 0