Skip to content

Enforced practices: real tests only, live outside world, CI gate rules, upstream currency - #10

Open
RandyNorthrup wants to merge 27 commits into
mainfrom
lessons/2026-10-17
Open

RandyNorthrup wants to merge 27 commits into
mainfrom
lessons/2026-10-17

Conversation

@RandyNorthrup

Copy link
Copy Markdown
Owner

Summary

  • Adds scripts/verify-practices.py (package scripts/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_group required, job timeouts); upstream currency through one upstreams.json pin file with a staleness gate and a weekly watch template.
  • Routes project_setup, quality_retrofit and feature_delivery to the enforced practices; keeps process rules apart from product rules; requires superseded decisions to be rewritten everywhere; adds a pitfalls register the checker validates.
  • Strengthens RED-DRILLS (hash-compared restoration, a drill for every new test, gate scripts proven as commands) and CODE-QUALITY.
  • Replaces this repo's own unittest.mock uses with real OS failures; consolidates drills into tests/test_red_drills.py (27 drills, keeping both original validator drills); removes tests that only checked that text or files exist.

Removed

  • Text-existence checks in 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 by tests/test_red_drills.py.

Test plan

  • ruff format --check, ruff check, mypy (scripts and tests), verify-practices on this repo: exit 0
  • Full suite on Windows (69 tests, 4 POSIX-only skips) and Linux (69 tests): pass; coverage 85.1% (floor 82%)
  • pre-commit run --all-files: exit 0
  • cross-platform-smoke.ps1 -RedDrills and release-package-smoke.ps1, PowerShell 7 and 5.1: exit 0
  • actionlint and zizmor on both CI templates: exit 0
  • Hosted CI on macOS and the CI symlink case (first run on this PR)

🤖 Generated with Claude Code

drill and others added 4 commits October 17, 2026 13:53
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>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-18T04:17:15.035341Z 8c9e411 Manual request
🔒 Security Review ✅ Completed 2026-10-18T04:14:28.080013Z 8c9e411 Manual request

Security findings

Advisory findings (5)

ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread scripts/practices/workflows.py Resolved
Comment thread scripts/practices/upstreams.py Resolved
Comment thread scripts/practices/python_rules.py Resolved
Comment thread scripts/practices/script_rules.py Resolved
Comment thread scripts/practices/register.py Resolved
Comment thread scripts/practices/manifests.py Resolved
Comment thread scripts/practices/cli.py Resolved
Comment thread scripts/practices/cli.py Resolved
Comment thread scripts/practices/workflows.py Resolved
Comment thread scripts/practices/source.py Resolved
drill and others added 15 commits October 17, 2026 16:19
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>
@RandyNorthrup

Copy link
Copy Markdown
Owner Author

@codex review — the eleven earlier threads are addressed in f27731d, f93d2fa, 0bf88db, 89417f5, 09866ad and cfada06 (one line per thread in the PR's record, 193f09e). Please check each fix and anything new.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ 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.

Comment thread scripts/practices/workflows.py Resolved
Comment thread scripts/practices/workflows.py Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread scripts/practices/cli.py Resolved
Comment thread scripts/practices/cli.py Resolved
Comment thread scripts/practices/source.py Resolved
Comment thread scripts/practices/register.py Resolved
Comment thread scripts/practices/error_rules.py Resolved
Comment thread scripts/practices/workflows.py Resolved
Comment thread scripts/practices/manifests.py Resolved
Comment thread scripts/practices/family_rules.py Resolved
Comment thread scripts/practices/upstreams.py Resolved
Comment thread scripts/practices/parallel_rules.py Resolved
drill and others added 5 commits October 17, 2026 20:04
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>
@RandyNorthrup

Copy link
Copy Markdown
Owner Author

@codex review — the twelve threads from your second review are addressed in 1b0a3da, 3c8c7fa and ee76585 (one line per thread in 1a1e734's record). Please check each fix and anything new.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread scripts/practices/workflows.py Outdated
Comment on lines +78 to +80
if inline:
names = frozenset(re.findall(r"[A-Za-z_]+", inline))
return Workflow(relative, lines, names, (index, index + 1))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread scripts/practices/parallel_rules.py Outdated
Comment on lines +275 to +277
earlier = [words for bound, words in bindings.get(argument.id, []) if bound <= line]
if earlier:
return earlier[-1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread scripts/practices/workflows.py Outdated
r"|\bgithub\s*\.\s*(?P<context>token)\b",
re.IGNORECASE,
)
INHERITED_SECRETS = re.compile(r"\bsecrets:\s*inherit\b")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment thread scripts/practices/workflows.py Outdated
Comment on lines +107 to +109
start = next(index for index, line in enumerate(lines) if line.rstrip() == "jobs:")
except StopIteration:
return []

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +165 to +166
for element in NUGET_ELEMENT.finditer(text):
include = NUGET_INCLUDE.search(element["attributes"])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread scripts/practices/workflows.py Outdated
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 []

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment thread scripts/practices/parallel_rules.py Outdated
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")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ 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.

Comment thread scripts/practices/workflows.py Outdated
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",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

P2 Badge 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 👍 / 👎.

drill and others added 3 commits October 17, 2026 20:53
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>
@RandyNorthrup

Copy link
Copy Markdown
Owner Author

@codex review — the eight third-round threads are addressed in 1874841 de5cb26 8c9e411 (one line per thread in docs/QUALITY-REVIEW.md). Please check each fix and anything new.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ 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.

Comment on lines +31 to +35
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,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

P2 Badge 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>.*)$")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

P2 Badge 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 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +343 to +344
is_gate = bool(workflow.triggers & GATE_TRIGGERS) or called_by_gate
findings = gate_findings(workflow) if is_gate else []

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +86 to +88
inline = strip_hash_comment(match["inline"]).strip()
if inline:
children = flow_triggers(inline)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +281 to +283
earlier = sorted(
(bound, words) for bound, words in bindings.get(argument.id, []) if bound <= line
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread scripts/practices/cli.py
Comment on lines +145 to +146
setting = RETRY_SETTING.search(line)
if RETRY_FLAG.search(line) or (setting and re.search(r"[1-9]", setting["value"])):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +174 to +176
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")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread tests/behavioral/probe.py
Comment on lines +42 to +43
observed, arguments = observe_calls(quantity.quantity.__code__, lambda: orders.create_order(12))
if observed != {"quantity": quantity.quantity(12)} or 12 not in arguments:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +137 to +139
dependencies = table.get(section, {}) if isinstance(table, dict) else {}
if isinstance(dependencies, dict):
yield from dependencies

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +287 to +288
if owner == "monkeypatch" and name in REPLACING_MONKEYPATCH:
self.add(node, "mock", f"monkeypatch.{name} {DOUBLE_MESSAGES['mock']}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant