Repository navigation
Enforced practices: real tests only, live outside world, CI gate rules, upstream currency - #10
RandyNorthrup wants to merge 27 commits into
Conversation
Add a standard-library command that refuses what lint and type gates cannot see: test doubles, fake servers and timers, in-memory stand-ins, presence-only and one-off tests, re-runs and fixed delays, merge-gate workflow defects, stale pins in upstreams.json, and pitfalls-register entries that no code enforces. Ship the CI merge-gate and upstream-watch templates, the process-rules template with its register, and the pin template. This repository now passes the checker in pre-commit and CI: its tests use real OS failures instead of mocks, the gate runs on merge_group, gitleaks is current, and CONTRIBUTING.md carries an enforced register. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the two-case delivery drill file with one table of 27 drills across the validator, the practices checker, and the behavioral oracle. Each drill requires the named test to fail with an assertion, restores the source byte-exact by SHA-256, and requires green again. Remove smoke-suite assertions that only checked that skill wording or package files exist; they passed regardless of behavior. The scanner, root, pinning, and release-gate checks and their six drills remain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
project_setup scaffolds the merge gate, upstream watch, pin file, and process-rules file from the first commit and sets up a test suite with no doubles. quality_retrofit baselines practice findings, makes CI a merge gate, and adds a phase for real tests. feature_delivery requires real tests, drills for every new test and gate, local checks before pushing, first-run green CI, and claims only after real use. RED-DRILLS proves gate scripts as commands and compares restoration by hash. DELIVERY, CODE-QUALITY, PHILOSOPHY, the brief, and the plan template keep process rules apart from product rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Record the checker's first findings on this repository and their fixes, the executed drills, results on Windows and Linux, the live upstream watch, and the open gates: hosted CI and macOS have not run yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (5)
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d69b3f8855
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Each practice is enforced where a file pattern can detect it and documented, with its blind spot, where it cannot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
error-cause refuses a catch-all handler in product code that never uses the caught error and raises a new one or emits a fixed message. hand-written-double refuses classes, functions, lambdas, and namespaces named as doubles in test code, and fake-server now covers a createServer call with an inline handler. Each has refused cases, negative controls, and drills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
git-shared-state refuses git stash and base-branch worktree checkouts in scripts, hooks, workflows, task runners, and started commands. local-full-suite refuses a local hook that runs the whole test suite; hosted CI stays the full gate. PRACTICES.md gains a parallel-work section. Each check has refused cases, negative controls, and drills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PRACTICES.md adds checking dead code against unmerged branches and open plans. The three workflows, DELIVERY.md, and the rules template carry all seven practices; CONTRIBUTING.md runs the touched suites locally and leaves every suite to hosted CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Where each practice landed, enforced or documented, the 16 new drills, gate exit codes on the final tree, real use of the command, and the two places review found the practices apply to this repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each unresolved thread from the 21:09Z review still reproduces at 58e6cdd; the plan names the fix at its cause, plus the scanner's dropped failure cause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ci-secret finds a secret read anywhere in an expression, by property, by index, or through toJSON(secrets), keeping the GITHUB_TOKEN exception. ci-merge-group covers pull_request_target. ci-continue-on- error accepts only a literal false. Review threads on workflows.py lines 23, 30, and 118. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
upstream-pin-drift accepted any substring, so an old version kept in a comment, a file name, or a longer version hid a changed pin. The pin now counts only as a whole version token in the file's code. Review thread on upstreams.py line 232. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mocker check reads keyword-only and positional-only parameters; requirements files in a requirements/ folder are manifests; pytest's reruns key counts as a configured re-run; a module named inside a JavaScript string literal is not an import. Review threads on python_rules.py 307, script_rules.py 201, manifests.py 182, and cli.py 60. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A gate script named only in a workflow or runner comment satisfied the register's enforcement requirement. Comments are removed before the search. Review thread on register.py line 138. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--watch ignored --format json and always printed the line report, so tooling that asked for JSON failed to parse a successful watch. Review thread on cli.py line 279. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A shell-only project scanned zero code files and failed with nothing-scanned. Shell files now count as code and run the shell checks: shared Git state everywhere and fixed sleeps in tests. Review thread on source.py line 105. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
detect-stack.ps1 answered every failure with "scan failed" or "unreadable path" and dropped the cause. Both scanners now add detail: the shell's reason for an unreadable root and, in PowerShell, the caught error and line for a failed scan. error stays the stable code, so AGENTS.md and CONTRIBUTING.md callers keep matching it. The smoke suite asserts the cause with a new drill; CI checks the Bash contract. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A root `ruff check .` treated templates/python/ruff.toml as a nested project and wrote a .ruff_cache there, which test_templates.py then rejected as an unclassified template. Reproduced twice in local full-suite runs; excluding templates/python stops it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each of the 11 review threads with its cause and fix commit, the scanner's error detail, the template-cache defect found while running the gates, the new drills, and gate exit codes at 787d06b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 193f09e85a
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 193f09e85a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Each of the 12 new threads reproduces at 193f09e; the plan names the fix at its cause for each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Expressions are matched across lines, so a folded secret is found. On pull_request_target the automatic token is refused unless top-level permissions are read-only. Path filters count only under merge-gate triggers. --reruns 0 passes. A '#' inside a quoted value is data, for allowances and code alike. Input errors honor --format json. Review threads on workflows.py 144, 146, 166; cli.py 61, 316; source.py 170. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A data file in a test directory no longer enforces a pitfall; exc_info=False no longer keeps an error's cause; NuGet references are read in any attribute order and quote style; a Rust cfg(test) module is test code; a Python git command bound to a name is resolved. Review threads on register.py 134, error_rules.py 103, manifests.py 69, family_rules.py 117, and parallel_rules.py 233. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A commit SHA in pinned never equals a release tag, so the practices checker pinned by commit in the CI templates read as behind forever, and recording the tag instead failed pin drift. Each upstream entry now records version, the release a SHA or digest identifies, or null; upstream-behind compares latest_seen with it. Review thread on upstreams.py line 226 (P1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each of the 12 new threads with its cause and fix commit, the new and re-anchored drills, the drill that first survived, and gate exit codes at ee76585. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a1e7348c0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if inline: | ||
| names = frozenset(re.findall(r"[A-Za-z_]+", inline)) | ||
| return Workflow(relative, lines, names, (index, index + 1)) |
There was a problem hiding this comment.
Inspect path filters in inline trigger mappings
When a workflow uses a valid flow-style trigger mapping such as "on": {pull_request: {paths: ["src/**"]}, merge_group: {}}, this branch extracts only a bag of words and records an empty trigger block range, so filtered_gate_triggers() never sees the paths key. The checker consequently accepts a required merge gate that can be skipped and remain pending for out-of-scope changes; parse inline mappings and associate their filters with the owning trigger.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| earlier = [words for bound, words in bindings.get(argument.id, []) if bound <= line] | ||
| if earlier: | ||
| return earlier[-1] |
There was a problem hiding this comment.
Choose the latest binding by source position
When a command variable is assigned more than once before subprocess.run(command), scope_nodes() visits sibling statements in reverse order and literal_bindings() preserves that order, so earlier[-1] selects the oldest assignment rather than the latest one. A safe assignment followed by command = ["git", "stash", "push"] is therefore accepted, while the reverse order produces a false finding; select the eligible binding with the greatest source position.
Useful? React with 👍 / 👎.
| r"|\bgithub\s*\.\s*(?P<context>token)\b", | ||
| re.IGNORECASE, | ||
| ) | ||
| INHERITED_SECRETS = re.compile(r"\bsecrets:\s*inherit\b") |
There was a problem hiding this comment.
Recognize whitespace before inherited-secret colons
When a reusable-workflow job uses the valid YAML spelling secrets : inherit, this exact secrets: pattern does not match, and there is no expression for the other secret scanner to detect. The merge gate is therefore accepted even though it receives every caller secret; allow YAML whitespace before the colon or parse the mapping key structurally.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| start = next(index for index, line in enumerate(lines) if line.rstrip() == "jobs:") | ||
| except StopIteration: | ||
| return [] |
There was a problem hiding this comment.
Locate jobs keys that have trailing comments
When a workflow writes the valid YAML form jobs: # required checks, this exact-line comparison returns no jobs, so every job bypasses the timeout-minutes validation without producing an unparsed finding. Strip the comment or parse the top-level key before locating the jobs block.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| for element in NUGET_ELEMENT.finditer(text): | ||
| include = NUGET_INCLUDE.search(element["attributes"]) |
There was a problem hiding this comment.
Exclude XML comments from NuGet dependency matches
When a project file retains a commented reference such as <!-- <PackageReference Include="Moq" /> -->, these regexes scan the raw XML and report a strict mock finding even though NuGet does not install that package. Because strict findings cannot be allowed, an ordinary commented example or retired dependency blocks the gate; parse XML elements or remove XML comments before matching references.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| if not workflow.triggers: | ||
| message = "no trigger block was found, so this workflow was not checked" | ||
| return [Finding(relative, 1, "unparsed", message)] | ||
| findings = gate_findings(workflow) if workflow.triggers & GATE_TRIGGERS else [] |
There was a problem hiding this comment.
Apply gate checks to called reusable workflows
When a pull-request gate delegates to a local workflow through jobs.<id>.uses, the callee has only the workflow_call trigger, so this condition skips gate_findings() for it. A continue-on-error: true inside the reusable workflow is consequently accepted and can turn its failing gate job green; trace local reusable-workflow calls from merge-triggered workflows and apply the gate-only checks to their callees.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| ENTRY = re.compile(r"^(?P<lead>\s*(?:-\s+)?)entry\s*:\s*(?P<value>.*)$") | ||
| YAML_KEY = re.compile(r"^\s*(?:-\s+)?[\w-]+\s*:") | ||
| # A hook that runs without the changed file names, or even when none changed. | ||
| IGNORES_CHANGES = re.compile(r"^\s*(?:-\s+)?(?:pass_filenames\s*:\s*false|always_run\s*:\s*true)\b") |
There was a problem hiding this comment.
Parse YAML booleans for local-hook selection
When a pre-commit hook writes a valid YAML boolean such as pass_filenames: False or always_run: True, this case-sensitive regex does not classify the hook as ignoring changed files. A whole-suite entry such as pytest -q then passes the local-hook gate even though pre-commit interprets the setting exactly like lowercase false or true; parse the boolean value or match all YAML boolean spellings.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 1a1e7348c0
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
| SECRET_REFERENCE = re.compile( | ||
| r"\btoJSON\s*\(\s*secrets\s*\)" | ||
| r"|\bsecrets\s*(?:\.\s*(?P<dotted>[\w-]+)|\[\s*(?P<indexed>[^\]]*)\])" | ||
| r"|\bgithub\s*\.\s*(?P<context>token)\b", |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Security: Detect alternate GITHUB_TOKEN expressions
When an adopter has a pull_request_target gate with write permissions that runs PR-head code, reject alternate token expressions too. This pattern only matches dotted github.token; a gate assigning ${{ github['token'] }} or ${{ toJSON(github) }} to that code's environment returns passed: true, exposing the base-repository token to a fork author. Fresh evidence beyond the prior direct-reference fix is that the new regex adds only dotted GitHub access while supporting indexed secret access. Parse indexed properties and whole-context serialization before applying the permissions check.
Useful? React with 👍 / 👎.
Each of the 8 new threads reproduces at 1a1e734; the plan names the fix at its cause for each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Flow-style triggers are parsed, so their path filters count; secrets : inherit, github['token'], and toJSON(github) are found; a commented jobs: key no longer hides every job; a repository workflow that a gate calls gets the gate checks; YAML booleans in any spelling count for pre-commit hooks; a commented NuGet reference is ignored; the latest binding of a Python command name wins. Review threads on workflows.py 33, 36, 80, 109, 246; parallel_rules.py 109, 277; and manifests.py 166. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each of the 8 new threads with its cause and fix, the new drills and controls, and gate exit codes at de5cb26. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 8c9e411e81
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
| SECRET_REFERENCE = re.compile( | ||
| r"\btoJSON\s*\(\s*(?:(?P<all_secrets>secrets)|(?P<all_github>github))\s*\)" | ||
| r"|\bsecrets\s*(?:\.\s*(?P<dotted>[\w-]+)|\[\s*(?P<indexed>[^\]]*)\])" | ||
| r"|\bgithub\s*(?:\.\s*(?P<context>token)\b|\[\s*(?P<github_index>[^\]]*)\])", | ||
| re.IGNORECASE, |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Security: Reject wildcard secret-context projections
On a pull_request_target gate that executes PR-head code, ${{ toJSON(secrets.*) }} passes this check. Fresh evidence beyond the fixed indexed and whole-context cases is that GitHub object filters select every value of an object and toJSON serializes the result (expression docs). SECRET_REFERENCE only accepts exact toJSON(secrets) or named/indexed properties; the saved reproduction returns no ci-secret, letting fork code receive repository secrets. Parse the expression or reject wildcard projections and add a regression test.
Useful? React with 👍 / 👎.
| # pull_request_target it carries the base repository's permissions. | ||
| FORK_SAFE_NAME = "GITHUB_TOKEN" | ||
| TARGET_TRIGGER = "pull_request_target" | ||
| PERMISSIONS = re.compile(r"^(?P<indent>\s*)permissions\s*:\s*(?P<inline>.*)$") |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Security: Parse quoted permission keys before exempting tokens
On a pull_request_target gate that executes PR-head code, a job can spell "permissions": and override top-level contents: read with contents: write. Fresh evidence beyond the direct-write fix is that PERMISSIONS accepts only an unquoted key; the saved valid-YAML reproduction returns no ci-secret. GitHub applies permissions again at job level (workflow syntax), so fork code receives the base repository's write-capable token. Normalize YAML keys before applying the GITHUB_TOKEN exemption and add this case.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c9e411e81
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| is_gate = bool(workflow.triggers & GATE_TRIGGERS) or called_by_gate | ||
| findings = gate_findings(workflow) if is_gate else [] |
There was a problem hiding this comment.
Preserve target-trigger context through reusable calls
When a pull_request_target gate with undeclared or write permissions calls a local reusable workflow that reads ${{ github.token }}, called_by_gate records only a boolean and the callee's own trigger set contains only workflow_call. Consequently secret_findings() considers the token safe and emits no ci-secret finding, even though the callee receives the caller's privileged token; propagate the caller's target-trigger safety state through direct and transitive calls.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| inline = strip_hash_comment(match["inline"]).strip() | ||
| if inline: | ||
| children = flow_triggers(inline) |
There was a problem hiding this comment.
Parse continuation lines in flow-style trigger maps
When a valid flow mapping spans lines—for example, the first line declares merge_group and pull_request while a continuation adds paths under pull_request—only the text on the on: line is passed to flow_triggers(). The workflow is therefore accepted without ci-path-filter; accumulate the complete flow collection before extracting triggers and their settings.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| earlier = sorted( | ||
| (bound, words) for bound, words in bindings.get(argument.id, []) if bound <= line | ||
| ) |
There was a problem hiding this comment.
Order same-line command bindings by column
When multiple assignments and the process call share one physical line, sorting only (lineno, words) cannot identify the latest binding and instead breaks ties lexicographically. Fresh evidence is command=["git","status"]; command=["git","stash"]; subprocess.run(command), which still resolves to git status and misses the prohibited stash; retain col_offset and compare the complete source position against the call.
Useful? React with 👍 / 👎.
| setting = RETRY_SETTING.search(line) | ||
| if RETRY_FLAG.search(line) or (setting and re.search(r"[1-9]", setting["value"])): |
There was a problem hiding this comment.
Ignore retry text that is not active configuration
When a runner file contains a commented setting such as # reruns = 3, or package.json contains documentation like "description": "use --reruns 3", scanning each raw line emits the strict rerun finding even though no runner enables retries. Because that finding cannot be allowed, ordinary comments or metadata can block the gate; parse the applicable configuration fields or at least exclude comments and non-command JSON values before matching.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| elif name == "go.mod": | ||
| for module in go_names(text): | ||
| check = next( | ||
| (value for key, value in GO_MODULES.items() if module.startswith(key)), None |
There was a problem hiding this comment.
Match prohibited Go modules at path boundaries
When go.mod requires a different module whose path merely begins with a prohibited name, such as github.com/jarcoal/httpmockx, this prefix test reports the strict fake-server finding. Match only the exact registered module or a subpackage beginning with key + "/" so unrelated modules with a shared textual prefix do not make the project permanently fail the gate.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| version = entry["version"] | ||
| if version is not None and not (isinstance(version, str) and version.strip()): | ||
| fail(location, "version must be the release a SHA or digest pin identifies, or null") |
There was a problem hiding this comment.
Reject version overrides on release pins
When an entry pins a release version directly but also supplies a different non-null version, validation accepts it and released_version() trusts the override. For example, pinned: "1.2.3", version: "1.3.0", and latest_seen: "1.3.0" passes both currency and pin-drift checks while the referenced file still uses 1.2.3; require version to be null unless pinned is an immutable SHA or digest.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| if handler.name and isinstance(node, ast.Name) and node.id == handler.name: | ||
| return True | ||
| if isinstance(node, ast.Call) and ( | ||
| type_name(node.func) in CAUSE_RECORDERS |
There was a problem hiding this comment.
Require formatted traces to be consumed
When a broad handler calls traceback.format_exc() as a standalone expression and then raises a fixed replacement error, this condition treats the formatting call as preserving the cause even though its returned traceback is discarded. Count format_exc and format_exception only when their result is actually returned, logged, stored for later use, or included in the emitted diagnostic.
Useful? React with 👍 / 👎.
| observed, arguments = observe_calls(quantity.quantity.__code__, lambda: orders.create_order(12)) | ||
| if observed != {"quantity": quantity.quantity(12)} or 12 not in arguments: |
There was a problem hiding this comment.
Verify delegation for every behavioral input
The oracle observes calls only while evaluating create_order(12), so an implementation can make a dummy quantity(12) call and independently reimplement validation for the actual argument; all later positive and rejected cases then pass without ever invoking the canonical helper for their inputs. This makes check_product() accept the parallel implementation that the reuse trial is intended to reject, so observe canonical calls across the behavior table and associate each call with that case's actual input.
AGENTS.md reference: AGENTS.md:L79-L86
Useful? React with 👍 / 👎.
| dependencies = table.get(section, {}) if isinstance(table, dict) else {} | ||
| if isinstance(dependencies, dict): | ||
| yield from dependencies |
There was a problem hiding this comment.
Resolve renamed Cargo dependencies before checking
When Cargo renames a prohibited crate, for example test-support = { package = "mockall", version = "0.13" }, iterating only the dependency-table keys yields test-support and the strict mock check emits nothing. Inspect each dependency value's package field when present, falling back to the table key, so Cargo aliases cannot install a mocking or fake-server crate unnoticed.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
| if owner == "monkeypatch" and name in REPLACING_MONKEYPATCH: | ||
| self.add(node, "mock", f"monkeypatch.{name} {DOUBLE_MESSAGES['mock']}") |
There was a problem hiding this comment.
Track manually constructed MonkeyPatch instances
When a test uses the common explicit form patcher = pytest.MonkeyPatch() followed by patcher.setattr(...), the owner is patcher rather than the literal name monkeypatch, so the strict mock gate accepts behavior replacement. Track names bound to pytest.MonkeyPatch() and their aliases, or refuse construction of that patching object in test code, in addition to recognizing the built-in fixture name.
AGENTS.md reference: AGENTS.md:L102-L105
Useful? React with 👍 / 👎.
Summary
scripts/verify-practices.py(packagescripts/practices/), a checker that enforces the practices in code: tests run real code only (no mocks, fake servers, fake CLIs, stand-ins or fake timers, in code or dependency manifests); the outside world is tested live or not at all; no presence-only, copy-paste or ticket-named tests; hosted CI as the merge gate (no secrets in gate workflows, no configured retries or fixed sleeps,merge_grouprequired, job timeouts); upstream currency through oneupstreams.jsonpin file with a staleness gate and a weekly watch template.project_setup,quality_retrofitandfeature_deliveryto the enforced practices; keeps process rules apart from product rules; requires superseded decisions to be rewritten everywhere; adds a pitfalls register the checker validates.unittest.mockuses with real OS failures; consolidates drills intotests/test_red_drills.py(27 drills, keeping both original validator drills); removes tests that only checked that text or files exist.Removed
tests/cross-platform-smoke.ps1(88 lines); the scanner, root, SHA-pin, release-gate, template and manifest checks and all six drills remain.tests/test_delivery_red_drills.py, superseded bytests/test_red_drills.py.Test plan
ruff format --check,ruff check, mypy (scripts and tests),verify-practiceson this repo: exit 0pre-commit run --all-files: exit 0cross-platform-smoke.ps1 -RedDrillsandrelease-package-smoke.ps1, PowerShell 7 and 5.1: exit 0🤖 Generated with Claude Code