From bb4e9e7695623414cc593cfb556dfccb3dd69e5e Mon Sep 17 00:00:00 2001 From: monkut Date: Mon, 27 Apr 2026 16:45:39 +0900 Subject: [PATCH] :bug: Forbid linter/type-checker config relaxation in develop and fix-ci prompts (closes #89) Add a `Configuration boundaries` section to both DEVELOP_AGENT_PROMPT and FIXCI_AGENT_PROMPT that explicitly forbids modifying linter, formatter, or type-checker configuration files (and inline suppression comments) to silence errors. The wording is shared via a `CONFIG_BOUNDARIES_BODY` constant so the two prompts stay in sync. --- askcc/definitions.py | 33 ++++++++++++++++++++++- tests/test_askcc.py | 62 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/askcc/definitions.py b/askcc/definitions.py index ff52f50..9467c82 100644 --- a/askcc/definitions.py +++ b/askcc/definitions.py @@ -178,6 +178,29 @@ """ ) +# Shared constraint reused by DEVELOP_AGENT_PROMPT and FIXCI_AGENT_PROMPT to keep +# wording in sync between the two prompts (issue #89). +CONFIG_BOUNDARIES_BODY = """\ +- Do NOT modify linter, formatter, or type-checker config files \ +(pyproject.toml [tool.ruff]/[tool.pyright]/[tool.mypy] sections, .ruff.toml, \ +pyrightconfig.json, mypy.ini, .pre-commit-config.yaml, ESLint/Prettier configs) \ +to silence errors. Fix the code, not the config. +- Do NOT add `# noqa`, `# type: ignore`, `# pyright: ignore`, `eslint-disable`, \ +or similar inline suppression comments. Fix the underlying issue. +- The only exceptions are when the originating issue explicitly requests a \ +configuration or rule change, or when a known third-party bug requires \ +documented suppression — in which case add a comment explaining why.""" + +DEVELOP_CONFIG_BOUNDARIES = ( + "Configuration boundaries (do not cross unless the issue explicitly requests it):\n" + CONFIG_BOUNDARIES_BODY +) + +FIXCI_CONFIG_BOUNDARIES = ( + "## Configuration boundaries\n\n" + "Do not cross these boundaries unless the issue explicitly requests it:\n\n" + CONFIG_BOUNDARIES_BODY +) + + # NOTE: develop and fix-ci require write access (Edit/Write/Bash) to actually # implement changes and run tests. The runner currently passes # `--dangerously-skip-permissions` globally so all actions run unattended; the @@ -259,6 +282,8 @@ - No hardcoded credentials or connection strings — use environment variables or secrets management. - No overly permissive file or network access introduced by the change. +{DEVELOP_CONFIG_BOUNDARIES} + PR description: - Include a `## Key Flows` section with mermaid diagrams illustrating the main flows \ introduced or changed by this PR. Focus on control flow, data flow, or state transitions \ @@ -539,7 +564,8 @@ # See note above DEVELOP_AGENT_PROMPT — fix-ci is a write-capable action that # needs Edit/Write/Bash to apply CI fixes; rely on the tools allowlist below for # the per-action safety boundary. -FIXCI_AGENT_PROMPT = """\ +FIXCI_AGENT_PROMPT = ( + """\ --- name: fix-ci description: Identifies failing CI checks on the current PR or branch and implements fixes @@ -573,6 +599,10 @@ - **Build errors**: import errors, syntax errors, missing dependencies - **Type errors**: pyright/mypy errors — fix type annotations +""" + + FIXCI_CONFIG_BOUNDARIES + + """ + ## Fixing Failures 7. Read all relevant source files before making changes. Do not speculate about code you have not opened. @@ -594,6 +624,7 @@ IMPORTANT: Only fix CI failures. Do not introduce new features or unrelated changes. """ +) FIXCI_USER_PROMPT_TEMPLATE = ( "Identify failing CI checks on the current branch or linked PR and implement fixes to make them pass." diff --git a/tests/test_askcc.py b/tests/test_askcc.py index 2d6e2e5..b1a5766 100644 --- a/tests/test_askcc.py +++ b/tests/test_askcc.py @@ -13,6 +13,7 @@ from askcc.definitions import ( AGENT_CONFIGS, DEVELOP_AGENT_PROMPT, + FIXCI_AGENT_PROMPT, REVIEWPR_AGENT_PROMPT, AgentAction, AgentConfig, @@ -298,6 +299,67 @@ def test_includes_pre_merge_guard_heading(self): assert "Pre-merge guard" in REVIEWPR_AGENT_PROMPT +class TestConfigBoundaryConstraints: + """Both develop and fix-ci prompts must forbid relaxing linter/type-checker config (issue #89).""" + + def test_develop_prompt_includes_config_boundaries_heading(self): + assert "Configuration boundaries" in DEVELOP_AGENT_PROMPT + + def test_develop_prompt_forbids_modifying_linter_config(self): + assert "pyproject.toml" in DEVELOP_AGENT_PROMPT + assert "[tool.ruff]" in DEVELOP_AGENT_PROMPT + assert "[tool.pyright]" in DEVELOP_AGENT_PROMPT + assert "[tool.mypy]" in DEVELOP_AGENT_PROMPT + assert ".ruff.toml" in DEVELOP_AGENT_PROMPT + assert "pyrightconfig.json" in DEVELOP_AGENT_PROMPT + assert "mypy.ini" in DEVELOP_AGENT_PROMPT + assert ".pre-commit-config.yaml" in DEVELOP_AGENT_PROMPT + assert "ESLint/Prettier" in DEVELOP_AGENT_PROMPT + assert "Fix the code, not the config." in DEVELOP_AGENT_PROMPT + + def test_develop_prompt_forbids_inline_suppression_comments(self): + assert "# noqa" in DEVELOP_AGENT_PROMPT + assert "# type: ignore" in DEVELOP_AGENT_PROMPT + assert "# pyright: ignore" in DEVELOP_AGENT_PROMPT + assert "eslint-disable" in DEVELOP_AGENT_PROMPT + + def test_develop_prompt_documents_exceptions(self): + assert "issue explicitly requests" in DEVELOP_AGENT_PROMPT + assert "third-party bug" in DEVELOP_AGENT_PROMPT + + def test_fixci_prompt_includes_config_boundaries_heading(self): + assert "Configuration boundaries" in FIXCI_AGENT_PROMPT + + def test_fixci_prompt_places_boundaries_before_fixing_failures(self): + boundaries_idx = FIXCI_AGENT_PROMPT.find("Configuration boundaries") + fixing_idx = FIXCI_AGENT_PROMPT.find("## Fixing Failures") + assert boundaries_idx != -1 + assert fixing_idx != -1 + assert boundaries_idx < fixing_idx + + def test_fixci_prompt_forbids_modifying_linter_config(self): + assert "pyproject.toml" in FIXCI_AGENT_PROMPT + assert "[tool.ruff]" in FIXCI_AGENT_PROMPT + assert "[tool.pyright]" in FIXCI_AGENT_PROMPT + assert "[tool.mypy]" in FIXCI_AGENT_PROMPT + assert ".ruff.toml" in FIXCI_AGENT_PROMPT + assert "pyrightconfig.json" in FIXCI_AGENT_PROMPT + assert "mypy.ini" in FIXCI_AGENT_PROMPT + assert ".pre-commit-config.yaml" in FIXCI_AGENT_PROMPT + assert "ESLint/Prettier" in FIXCI_AGENT_PROMPT + assert "Fix the code, not the config." in FIXCI_AGENT_PROMPT + + def test_fixci_prompt_forbids_inline_suppression_comments(self): + assert "# noqa" in FIXCI_AGENT_PROMPT + assert "# type: ignore" in FIXCI_AGENT_PROMPT + assert "# pyright: ignore" in FIXCI_AGENT_PROMPT + assert "eslint-disable" in FIXCI_AGENT_PROMPT + + def test_fixci_prompt_documents_exceptions(self): + assert "issue explicitly requests" in FIXCI_AGENT_PROMPT + assert "third-party bug" in FIXCI_AGENT_PROMPT + + class TestWritePromptContent: def test_writes_file_with_correct_name(self): filepath = write_prompt_content("plan", "monkut", "askcc-cli", 42, "issue content here")