Skip to content

test(ci): probe an unmapped Python file through the fallback - #6116

Closed
kyle-sexton wants to merge 5 commits into
mainfrom
probe/unmapped-python-ci
Closed

kyle-sexton wants to merge 5 commits into
mainfrom
probe/unmapped-python-ci

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

No related issue: CI probe for #6115, closed unmerged once its test-bash run is read.

Summary

One commit on top of #6115 that adds a comment to plugins/harness-ops/lib/plugin_cache_versions.py, a file the selector reports UNMAPPED, so the test-bash fallback branch of #6115 runs on a pull request.

Fix

None: a probe. check-plugins is expected to fail (no version bump); only test-bash is read.

Verification

test-bash should run the full shell corpus plus its leg's slice of the Python corpus, one pytest process per suite.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 2 commits October 3, 2026 13:36
An unmapped changed file sent test-bash to the full shell corpus and ran no
Python suite, so every test_*.py the selector picked in that pull request went
unrun, and the whole-tree runs (schedule, dispatch, a push with no base) never
ran pytest at all. #6059 widened the unmapped set by dropping the Python import
rule, so this now hits more pull requests than before.

- The UNMAPPED branch keeps the full shell corpus and also runs this leg's
  slice of the selector's --unmapped-corpus listing that is not a shell suite:
  the selection's Python and Node suites, plus every Python suite when the
  unmapped file is a .py and every Node suite when it is Node.
- The whole tree runs every Python suite, each leg every legs-th one.
- Python suites run one pytest process each: suites in different directories
  import same-named helpers (from conftest import ...), so one process broke
  collection once suites from two such directories ran together.
- Eval fixtures (*/evals/fixtures/*) are data the skill evals read and are not
  run; two of them error under pytest by design.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Never merged: this commit only makes the selector report an unmapped .py so
the test-bash fallback branch runs on a pull request.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@kyle-sexton kyle-sexton added the do-not-merge Hard merge gate: do not merge while applied. label Oct 3, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 3, 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-03T18:26:05.825497Z 1beb9ab PR opened
ℹ️ 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.

@claude

claude Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 28s —— View job


Security review complete

  • Gather context (PR body, diff, changed files)
  • Review .github/workflows/ci.yml diff for security surface
  • Review plugins/harness-ops/lib/plugin_cache_versions.py diff
  • Post findings

No security issues found.

This PR is a stated probe (labeled do-not-merge, intended to be closed unmerged once its test-bash run is read — see PR body and #6115). The diff is two files:

  • plugins/harness-ops/lib/plugin_cache_versions.py: adds a single trailing comment after the orphan_marker function body. No functional change, no security surface.
  • .github/workflows/ci.yml: expands the "Run plugin contract tests" step's UNMAPPED fallback to also run the leg's slice of the Python (and outside-Node) corpus via a new run_delegated/pytest_each pair, and rewords several comments. I checked specifically for:
    • Command/argument injection from PR-controlled filenames. File paths collected from git ls-files, the selector's NOT RUN: list, and the new --unmapped-corpus listing are all passed to python -m pytest via xargs -0 -n1 ... --, with -- already present before the path argument in both the pre-existing and new call sites. That blocks both shell-metacharacter injection (xargs/exec, not sh -c) and flag-injection (a filename like --exitfirst can't be read as an option). Same pattern for run-outside-node-suites.sh --paths <file>.
    • New --base "$DIFF_BASE" use. The second affected-tests.sh --unmapped-corpus call reuses the same DIFF_BASE env var the existing --run call already used earlier in the same step — no new trust boundary.
    • ::warning::$summary workflow-command echo. Pre-existing (only the trailing wording changed, "full contract corpus" → "full shell corpus"); out of scope as a pre-existing pattern, and not altered in a way that changes its risk here.
    • Actions hardening (permissions, triggers, pinning): untouched by this diff; deferred to zizmor per this lane's scope.
    • Instruction-surface deletions: none — no rules/CLAUDE.md/AGENTS.md/hook files touched.

No ## Summary/## Fix/## Verification/## Related body-contract note needed here since that's reported by ci-status, not this lane.

@claude

claude Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 6m 38s —— View job


CI code review

  • Gather context (PR body, diff, CLAUDE.md/AGENTS.md)
  • Apply skip-gate check — doesn't apply: this probe PR carries a real, substantive change in .github/workflows/ci.yml (the fix(ci) commit it's probing), so the fallback logic gets a full review
  • Review .github/workflows/ci.yml diff
  • Review plugins/harness-ops/lib/plugin_cache_versions.py diff
  • Post findings

Summary

Reviewed the two changed files against origin/main...HEAD.

plugins/harness-ops/lib/plugin_cache_versions.py: trailing comment only, no behavior change. Nothing to flag.

.github/workflows/ci.yml: the new UNMAPPED-fallback and NOT RUN:-delegation logic (the pytest_each/run_delegated helpers, one-pytest-process-per-suite, and the --unmapped-corpus listing consumption) is internally consistent with the pre-existing scripts/affected-tests.sh and scripts/run-outside-node-suites.sh contracts I cross-checked (shard indexing, exit codes 0/1/3/4, .Tests.ps1 classification, etc.) — no issues there.

One finding posted inline at ci.yml#L2327-L2329:

  • In the UNMAPPED fallback branch, the unconditional "fixed pair" scripts/run-outside-node-suites.sh call (leg 3 % LEGS) and the later run_delegated call's scripts/run-outside-node-suites.sh --paths ... (ci.yml#L2288) can both select the same package when the UNMAPPED file's language family is node. I confirmed the fixed pair's own suites (plugins/knowledge/vendor/repo-analysis/repo-analysis.test.js, and 6 files under video-digestion) match the --unmapped-corpus widening pattern, so npm test for those packages would run twice in one step on that leg — contradicting the "runs once on leg 3 (ci: no runner for the Node suites outside the four sub-projects, or for Pester, on either the PR or push path #3703)" comment immediately above it. Details and a fix direction are in the inline comment.

This PR is labeled do-not-merge and its own description says it will be closed unmerged once its CI run is read, so no action is expected here beyond the fallback's correctness for the underlying #6115 fix.
· branch

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review has reviewed this pull request through 0f244c3; a later push is reviewed from there.

Comment thread .github/workflows/ci.yml
Comment on lines 2327 to +2329
# Same fixed pair the whole-tree path runs once on leg 3 (#3703).
if [ "$LEG" = $((3 % LEGS)) ]; then
scripts/run-outside-node-suites.sh
scripts/run-outside-node-suites.sh || status=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This "fixed pair" run-outside-node-suites.sh call and the run_delegated call a few lines below it (line 2340, which internally runs scripts/run-outside-node-suites.sh --paths ... at line 2288) can both select the same package on this leg.

When the UNMAPPED file's lang_family is node, affected-tests.sh --unmapped-corpus widens the listing to "every Node suite" (any *.test.js/*.test.mjs), which includes the fixed pair's own suites — confirmed, both contain matching files:

  • plugins/knowledge/vendor/repo-analysis/repo-analysis.test.js
  • plugins/knowledge/vendor/video-digestion/**/*.test.js (6 files)

So on the leg where LEG = 3 % LEGS, an UNMAPPED Node-family file causes npm test for plugins/knowledge/vendor/repo-analysis and video-digestion to run twice in the same step: once unconditionally here, and again via run_delegated's --paths call once package_of matches the widened listing's entries back to the same packages. That directly contradicts the comment on line 2327 ("runs once on leg 3") for this fallback path, and wastes a full npm test pass (and risks a flaky second run if either suite isn't safely re-runnable back-to-back in one job).

Repro: a PR whose only changed file is an unmapped .js/.mjs file outside the suite-mapped set, on the leg where LEG = 3 % LEGS.

Fix direction: skip the unconditional call here when the widened listing will already cover the fixed pair (e.g. only run the "same fixed pair" call when corpus_used's language isn't node, or dedupe the fixed-pair packages out of outside-node-paths.txt before calling run_delegated).

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-review has reviewed this pull request through 0f244c3; a later push is reviewed from there.

kyle-sexton and others added 3 commits October 3, 2026 13:49
A whole-tree dispatch run (37141114979) ran the Python corpus on every leg
for the first time: legs 0-2 passed in 7 to 7.5 minutes, and leg 3, which
also runs the outside-Node packages and the Node sub-projects, was cancelled
at the 11-minute limit in its Node steps after its Python share (the
planning surface server suite alone took 202 s) had passed. 16 minutes is
the ceiling for a job here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
xargs -t prints every pytest command before it runs, so a leg's log names
each Python suite it ran, not only pytest's count line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 1s —— View job


Reviewing incremental changes to .github/workflows/ci.yml

  • Gather context (PR body, prior review comments, .claude-lane/incremental.diff)
  • Invoke /review:code-review for this PR
  • Review the incremental diff since 1beb9ab
  • Post findings as inline comments
  • Final summary

Summary

Incremental review scope: only the diff in .claude-lane/incremental.diff since 1beb9ab was in scope — two changes to .github/workflows/ci.yml. Every other file (including plugins/harness-ops/lib/plugin_cache_versions.py) is unchanged since the commit this lane already reviewed.

Change 1 — ci.yml#L2032-L2035: test-bash's timeout-minutes goes from 11 to 16, with a comment explaining the Python planning-surface suite (~200s) pushed the Node-sub-projects leg past the old budget. Consistent with the fallback widening landed in the prior commits on this branch; no issue.

Change 2 — ci.yml#L2280: pytest_each()'s xargs call gains -t, tracing each constructed python -m pytest ... invocation to stderr before it runs. I checked that this stderr is the step's own log stream, not the "$err" file captured at line 2310 (scripts/affected-tests.sh ... 2>"$err") that the NOT RUN:/UNMAPPED: parsing at lines 2320/2324 depends on — the two are unrelated streams, so the added trace can't corrupt that parsing. No functional or correctness issue.

No new findings from this incremental diff — both changes are small, well-scoped, and consistent with the comments describing them. The duplicate-npm test-on-one-leg finding from the prior review round (inline comment on ci.yml:2332, about the fixed-pair run-outside-node-suites.sh call overlapping run_delegated's widened listing on a Node-family UNMAPPED file) is untouched by this diff and remains open from that round; not re-reported here since neither of those lines changed.

This PR is labeled do-not-merge and is a stated probe per its own description (closed unmerged once its test-bash run is read), so no action is expected beyond this correctness check.
· branch

@claude

claude Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 52s —— View job


Security review complete

  • Gather context (PR body, incremental diff, custom instructions)
  • Read .claude-lane/incremental.diff (changes to .github/workflows/ci.yml since 1beb9ab)
  • Review the incremental diff for security-relevant issues
  • Post findings

No security issues found.

This is an incremental review: only the diff in .github/workflows/ci.yml since the last-reviewed commit (1beb9ab) was in scope, up to head 0f244c3. That diff (ci.yml#L2032-L2034 and ci.yml#L2279-L2280) contains two changes, both purely operational:

  • timeout-minutes: 11 → 16 on the test-bash job, with a comment explaining the Python-corpus leg now runs longer. No security surface.
  • pytest_each()'s xargs -0 -r -n1 python -m pytest ... gains a -t flag (xargs -0 -r -t -n1 ...), which only makes xargs echo each constructed command line to stderr before running it, for the "log each Python suite test-bash starts" commit. I checked whether this trace echo could leak anything sensitive: the echoed line is just python -m pytest -q -o tmp_path_retention_policy=none -- <path> for a repo-tracked file path — no secrets, tokens, or env values pass through it, and the -- separator and argument handling are unchanged from the already-reviewed call, so there's no new injection surface. DIFF_BASE and the other step env vars aren't part of the argv xargs prints.

No new trust boundary, no widened permissions, no instruction-surface changes in this increment (no rules/CLAUDE.md/AGENTS.md/hook files are touched here). The rest of this PR's files (plugins/harness-ops/lib/plugin_cache_versions.py and the broader ci.yml fallback logic) are unchanged since 1beb9ab and were already covered by that review.

This PR is labeled do-not-merge and is a stated probe per its description, so no action is expected beyond this read.
· branch

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Probe done: runs 37141180493 and 37141969828 show test-bash's UNMAPPED fallback running the full shell corpus plus every Python corpus suite once across the four legs (139), all green. Closing unmerged.

@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: 1beb9ab249

ℹ️ 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 .github/workflows/ci.yml
Comment on lines +2300 to +2302
git ls-files | awk -v leg="$LEG" -v legs="$LEGS" '{ b = $0; sub(/.*\//, "", b) }
b ~ /^test_.*\.py$/ && n++ % legs == leg' >"$RUNNER_TEMP/python-suites.txt"
pytest_each "$RUNNER_TEMP/python-suites.txt" || status=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.

P1 Badge Keep the full Python corpus within the job timeout

On schedule/dispatch runs and pushes without a usable base, this adds roughly 34 sequential pytest processes to every matrix leg after the full shell corpus. In the exact four-way partition used here, leg 3's Python slice alone took about 540 seconds locally, while test-bash still has an 11-minute timeout and the workflow documents the pre-change job maximum as 593 seconds; checkout/toolchain setup, shell tests, and the later Node steps therefore leave no viable timeout margin. Split or parallelize this workload (or recompute the timeout) so whole-tree runs do not terminate before completing.

Useful? React with 👍 / 👎.

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

Labels

do-not-merge Hard merge gate: do not merge while applied.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant