diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42eeb76..066bdd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.11", "3.13"] + python-version: ["3.11", "3.12", "3.13", "3.14"] env: PYTHONIOENCODING: utf-8 diff --git a/check_commands.py b/check_commands.py index 624a3c7..83f3ecd 100644 --- a/check_commands.py +++ b/check_commands.py @@ -94,6 +94,13 @@ EXTERNAL_SCRIPTS = { "blutter's own environment script, run from inside the blutter checkout -- the " "record's preceding line is `git clone --depth 1 worawit/blutter` " "(docs/tool-verification/TOOL-VERDICTS.md)", + 'dcc.py': + "the dcc tool's own entry point, run from inside its checkout -- the record's " + "preceding line is `cd tools/_work/bench/repos/dcc`, and this repository ships " + "no dcc.py (docs/tool-verification/EXTENSION-java2c.md). Declared rather than " + "inferred because the `cd`-then-bare-name form only skips as workbench-after-cd " + "while the gitignored tools/ tree happens to exist locally; a clean checkout has " + "no such file to recognise, and without this entry the gate reported drift there.", } # Commands an evidence record *quotes* rather than offers. The key is (document, diff --git a/tests/integration/test_check_commands_gate.py b/tests/integration/test_check_commands_gate.py index ef13c77..36fe321 100644 --- a/tests/integration/test_check_commands_gate.py +++ b/tests/integration/test_check_commands_gate.py @@ -83,6 +83,30 @@ def test_a_bare_name_after_a_cd_in_the_same_block_is_not_drift(gate): assert "workbench-after-cd" in kinds, findings +def test_the_external_dcc_entry_point_is_never_drift(gate): + """`python dcc.py` after `cd tools/_work/bench/repos/dcc` runs inside the external dcc + checkout, so it is a skip on every machine -- including one without the workbench. + + The name is declared in EXTERNAL_SCRIPTS because the workbench-name recognition that + used to cover it needs tools/ to exist: on a clean checkout `dcc.py` degraded from + workbench-after-cd to missing-script drift, and the gate failed away from the machine + that wrote the record. + """ + doc = str(REPO_ROOT / "docs" / "tool-verification" / "EXTENSION-java2c.md") + _path, why = gate.resolve_script("dcc.py", doc, include_workbench=False, chdir=True) + if gate._workbench_names(): + assert why == "workbench-after-cd", why + else: + assert why == "external", why + + text = "```\n$ cd tools/_work/bench/repos/dcc\n$ python dcc.py --no-build\n```\n" + findings = gate.command_findings(doc, text, {}, False) + kinds = [f["kind"] for f in findings] + assert "missing-script" not in kinds, findings + assert "unqualified-workbench" not in kinds, findings + assert any(k in ("workbench-after-cd", "external") for k in kinds), findings + + def test_a_shipped_script_resolves_from_the_repository_root(gate): """The order that matters: root, then the skill's scripts, then the document's own directory.""" doc = str(REPO_ROOT / "docs" / "tool-verification" / "README.md")