Skip to content

Make Whitaker fallback tests hermetic (#53) - #54

Merged
leynos merged 11 commits into
mainfrom
issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout
Aug 3, 2026
Merged

Make Whitaker fallback tests hermetic (#53)#54
leynos merged 11 commits into
mainfrom
issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout

Conversation

@lodyai

@lodyai lodyai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

This branch makes the generated-project Whitaker fallback tests hermetic by stripping inherited WHITAKER, MAKEFLAGS, MFLAGS, and MAKELEVEL values before invoking make lint. It preserves the template Makefile behaviour and keeps the fallback cases focused on the intended PATH, $HOME/.local/bin, and missing-tool branches.

Closes #53.

Review walkthrough

Validation

  • WHITAKER=true uvx --with pytest-copier --with pyyaml --with syrupy --with make-parser --with hypothesis pytest -vv tests/test_template/test_lint_targets.py::test_makefile_resolves_whitaker_fallback: 3 passed.
  • uvx --with pytest-copier --with pyyaml --with syrupy --with make-parser --with hypothesis pytest tests/: 50 passed, 1 skipped.
  • coderabbit review --agent: first pass reported one docstring concern, which was fixed.
  • coderabbit review --agent: second pass completed with 0 findings.

Notes

No template or snapshot changes were needed because the failure was caused by inherited environment state in the test subprocess, not by the generated Makefile fallback chain.

References

@sourcery-ai sourcery-ai 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.

Sorry @LodyAI[bot], you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97300d20-0a99-41ab-92b5-bd349126c921

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Summary

  • Make generated-project Whitaker fallback tests hermetic.
  • Remove inherited WHITAKER, GNUMAKEFLAGS, MAKEFLAGS, MFLAGS, and MAKELEVEL values.
  • Isolate test PATH values while retaining access to bash and make.
  • Assert the selected Whitaker binary.
  • Add and document generated_project_env.
  • Test environment filtering, overrides, copy isolation, and parent-environment preservation.
  • Link the changes to issue #53.

Validation

  • Pass 3 targeted tests.
  • Pass 50 tests with 1 skipped.
  • Pass act-validation, build-test, and CodeRabbit checks.

Walkthrough

Add a shared helper for hermetic subprocess environments. Verify filtering, overrides, copying, and mutation isolation. Update Whitaker fallback tests to isolate tool resolution and report captured output. Document the helper.

Changes

Subprocess environment isolation

Layer / File(s) Summary
Build hermetic project environments
tests/helpers/subprocess_env.py, tests/test_helpers.py, docs/developers-guide.md
Define Make and Whitaker resolution variables. Construct copied subprocess environments from controlled overrides. Test filtering, preservation, precedence, and independence. Document the helper.
Apply the helper to fallback testing
tests/test_template/test_lint_targets.py
Use isolated tool paths and the shared environment helper. Create the Whitaker marker through quoted shell redirection. Include captured output in assertion diagnostics.

Suggested labels: Issue

Suggested reviewers: leynos

Poem

Clear inherited controls.
Isolate each tool path.
Let Whitaker write its mark.
Show captured output on failure.
Run the fallback checks.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Tests derive the expected controls from MAKE_RESOLUTION_VARIABLES, so omitting GNUMAKEFLAGS or defining the set incorrectly would still pass; no test independently asserts the required five names. Assert MAKE_RESOLUTION_VARIABLES equals the literal five required names, and use an independent literal control set to test stripping and override precedence for every control.
✅ Passed checks (19 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #53 by isolating PATH and HOME, removing resolution controls, and verifying the intended Whitaker fallback branches.
Out of Scope Changes check ✅ Passed The helper, test updates, documentation, and diagnostics directly support the linked issue objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
User-Facing Documentation ✅ Passed Pass this check: the PR changes only test infrastructure and developer documentation; it adds no user-facing template or generated-project behaviour requiring docs/users-guide.md.
Developer Documentation ✅ Passed Accept this check: docs/developers-guide.md documents tests/helpers/subprocess_env.py, its hermetic clearing behaviour, controlled overrides, and the direct helper tests; no locale or roadmap c...
Module-Level Documentation ✅ Passed Accept the module documentation: every Python module has a module docstring, and tests/helpers/subprocess_env.py clearly defines its purpose, use, and subprocess relationship.
Testing (Unit And Behavioural) ✅ Passed Direct tests cover control filtering, overrides, preservation, parent immutability, and copy isolation; a real rendered make lint test covers PATH, HOME, and missing Whitaker branches.
Testing (Property / Proof) ✅ Passed The helper introduces environment invariants, and the PR adds Hypothesis property tests covering arbitrary overrides, control filtering, preservation, copy isolation, and parent immutability.
Testing (Compile-Time / Ui) ✅ Passed Pass this check: the PR changes only Python helpers/tests/docs, adds no Rust or TypeScript compile-time behaviour, and uses focused marker/path/output assertions; existing Makefile snapshots remain...
Unit Architecture ✅ Passed Accept this change: keep environment access isolated in generated_project_env; it returns a copied, filtered mapping, while tests invoke subprocesses explicitly and verify no parent mutation.
Domain Architecture ✅ Passed The PR changes only documentation and test infrastructure. generated_project_env isolates os.environ inside tests/helpers, and no template or domain source imports it.
Observability ✅ Passed The changes are limited to test helpers, test subprocess setup, and developer documentation; they do not alter production operational behaviour, so logging, metrics, tracing, and alerts are not app...
Security And Privacy ✅ Passed Approve this check: the PR adds no credentials or sensitive data; it copies and filters test environments, uses fixed test values, and safely quotes the marker path with shlex.quote.
Performance And Resource Use ✅ Passed The helper performs one bounded environment copy, removes five fixed variables, and applies one mapping update; new tests use bounded Hypothesis inputs and no hot-path or unbounded I/O is added.
Concurrency And State ✅ Passed Keep the helper state-free: it copies os.environ into a local dict, uses an immutable frozenset, and tests parent immutability and copy isolation; no async or parallel path is introduced.
Architectural Complexity And Maintainability ✅ Passed Keep the change: the 47-line stdlib-only helper isolates a real environment invariant, has two consumers, direct property tests, documented scope, and no new dependency or import cycle.
Rust Compiler Lint Integrity ✅ Passed The PR changes only Python tests/helpers and documentation; the repository has no Rust or Cargo files, and the diff adds no Rust lint suppressions or clone calls.
Title check ✅ Passed Accept the title because it identifies the hermetic Whitaker fallback test change and links issue #53.
Description check ✅ Passed Accept the description because it clearly explains the changes, objectives, issue link, and validation results.
📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #53

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout

Comment @coderabbitai help to get the list of available commands.

@leynos
leynos force-pushed the issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout branch from 7584444 to b062f30 Compare July 17, 2026 18:01
@leynos
leynos marked this pull request as ready for review July 17, 2026 18:01

@sourcery-ai sourcery-ai 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.

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@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: b062f30234

ℹ️ 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 tests/helpers/subprocess_env.py Outdated
@coderabbitai coderabbitai Bot added the Issue label Jul 17, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_template/test_lint_targets.py`:
- Around line 96-103: Update the test assertions around the generated lint
target execution to verify that result.stdout contains “Whitaker binary:
{expected_whitaker}” for cases where WHITAKER is present, using the resolved
expected path or home-directory value. Keep the existing return-code and marker
assertions, but ensure the test distinguishes the intended WHITAKER resolution
from the bare whitaker fallback.
- Around line 71-75: Update the PATH setup in the test targeting logic to use an
isolated temporary tool directory for the home and missing cases instead of
/usr/bin:/bin, while retaining path_bin for the path case. Ensure any required
test utilities are available in that sandbox or rely on shell built-ins so
host-installed whitaker cannot affect the intended branch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 18c89b8e-1163-42a7-862e-ee029f3b1fe8

📥 Commits

Reviewing files that changed from the base of the PR and between c35f20a and b062f30.

📒 Files selected for processing (2)
  • tests/helpers/subprocess_env.py
  • tests/test_template/test_lint_targets.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

Comment thread tests/test_template/test_lint_targets.py Outdated
Comment thread tests/test_template/test_lint_targets.py
@leynos

leynos commented Jul 21, 2026

Copy link
Copy Markdown
Owner

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@lodyai
lodyai Bot force-pushed the issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout branch 2 times, most recently from 5e6d7c1 to a78fc9f Compare July 24, 2026 02:15
@leynos

leynos commented Jul 24, 2026

Copy link
Copy Markdown
Owner

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error The fallback test can pass for the wrong Whitaker binary because it does not assert the resolved path and still exposes /usr/bin:/bin. Assert stdout contains the expected Whitaker binary: ... line and use an isolated PATH for the home/missing cases so a host Whitaker cannot satisfy them.
Developer Documentation ⚠️ Warning No docs changed: the PR only touches tests, and searches found no developer-guide/design/ADR entry for the new subprocess_env helper or env-sanitising policy. Update docs/developers-guide.md (and any relevant design/ADR/execplan entry) to describe the new test helper and the hermetic subprocess environment contract.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== PR 54 changed files and diff summary ==='
git diff --stat origin/main...HEAD
git diff --name-status origin/main...HEAD

echo '=== Relevant source outlines ==='
ast-grep outline tests/test_template/test_lint_targets.py --items all || true
ast-grep outline tests/helpers/subprocess_env.py --items all || true

echo '=== Fallback test and environment helper ==='
sed -n '/def test_makefile_resolves_whitaker_fallback/,/^def /p' tests/test_template/test_lint_targets.py
printf '\n--- tests/helpers/subprocess_env.py ---\n'
cat -n tests/helpers/subprocess_env.py

echo '=== Candidate documentation and references ==='
fd -t f -i 'developer*guide*|adr|execplan|design|readme' . \
  -E .git -E target -E node_modules | sort
rg -n -i -C2 'generated_project_env|subprocess[_ -]?env|hermetic|WHITAKER|MAKEFLAGS|MFLAGS|MAKELEVEL' \
  -g '!target/**' -g '!node_modules/**' .

echo '=== PR metadata, checks, and issue `#53` ==='
gh pr view 54 --repo leynos/agent-template-rust --json url,headRefName,baseRefName,statusCheckRollup,body
gh issue view 53 --repo leynos/agent-template-rust --json url,title,body,state

Length of output: 1574


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Local repository state ==='
git status --short --branch
git branch -a
printf '\n=== Available relevant files ===\n'
fd -t f . tests docs | sort | grep -E '(^tests/(test_template/test_lint_targets\.py|helpers/subprocess_env\.py)$|(^docs/)|README)' || true

echo '=== Test module structure ==='
ast-grep outline tests/test_template/test_lint_targets.py --items all || true
printf '\n=== Fallback test implementation ===\n'
sed -n '/^def test_makefile_resolves_whitaker_fallback/,/^def /p' tests/test_template/test_lint_targets.py || true
printf '\n=== Environment helper ===\n'
cat -n tests/helpers/subprocess_env.py || true

echo '=== Documentation files and relevant terminology ==='
fd -t f . docs -E .git 2>/dev/null | sort || true
rg -n -i -C3 'generated_project_env|subprocess[_ -]?env|hermetic|WHITAKER|MAKEFLAGS|MFLAGS|MAKELEVEL' \
  README.md docs tests -g '!target/**' 2>/dev/null || true

echo '=== GitHub PR 54 files, checks, and issue 53 ==='
gh api 'repos/leynos/agent-template-rust/pulls/54/files?per_page=100' \
  --jq '.[] | [.filename, .status, (.patch // "")] | `@tsv`'
gh pr view 54 --repo leynos/agent-template-rust \
  --json url,headRefName,baseRefName,statusCheckRollup,body
gh issue view 53 --repo leynos/agent-template-rust --json url,title,body,state

Length of output: 42423


@leynos Treat both reported checks as resolved.

Check Status Verification
Testing (Overall) ✅ Resolved tests/test_template/test_lint_targets.py now asserts stdout contains the exact Whitaker binary: {expected_whitaker} line for the path and home success cases. It isolates PATH to path-bin or tool-bin; neither includes /usr/bin or /bin. The helper also strips inherited WHITAKER, GNUMAKEFLAGS, MAKEFLAGS, MFLAGS, and MAKELEVEL, preventing parent-process resolution overrides.
Developer Documentation ✅ Resolved docs/developers-guide.md now documents tests/helpers/subprocess_env.py and its contract: clear inherited Whitaker/Make resolution variables, then apply controlled overrides for generated-project subprocess tests.

GitHub currently reports act-validation, build-test, and CodeRabbit as successful for PR #54. No further work, AI-agent prompt, or follow-up GitHub issue is required for these findings.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/helpers/subprocess_env.py`:
- Line 1: Expand the module docstring in subprocess_env.py to document
generated_project_env: state that it copies the parent environment, removes
Make/Whitaker control variables, applies explicit overrides, and is passed to
subprocess calls. Include a brief usage example in the docstring.

In `@tests/test_template/test_lint_targets.py`:
- Line 64: Update the generated shell script in the test fixture to quote the
marker path using shlex.quote(str(marker)) while preserving the shell built-in
redirection and existing script behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0c1eb493-2c1e-41b3-a8fc-72059d57c913

📥 Commits

Reviewing files that changed from the base of the PR and between a48b07a and a78fc9f.

📒 Files selected for processing (3)
  • docs/developers-guide.md
  • tests/helpers/subprocess_env.py
  • tests/test_template/test_lint_targets.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

Comment thread tests/helpers/subprocess_env.py Outdated
Comment thread tests/test_template/test_lint_targets.py Outdated
@lodyai
lodyai Bot force-pushed the issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout branch 2 times, most recently from b12f321 to c2b76ac Compare August 2, 2026 13:54
@leynos

leynos commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos

leynos commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

❌ Failed checks (1 error, 1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error The new helper has no direct test, and the fallback test does not inject inherited controls; it can pass with a no-op helper in a normal environment. Add deterministic unit tests that seed all listed controls, verify removal, preserve unrelated variables, apply overrides, and leave os.environ unchanged.
Testing (Unit And Behavioural) ⚠️ Warning The rendered Makefile test covers path, home, and missing Whitaker branches, but no unit test verifies generated_project_env removes all five controls, preserves the parent environment, or applies... Add focused tests in tests/test_helpers.py that monkeypatch each control variable and verify removal, copy isolation, override precedence, and ordinary-variable preservation.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Changed files ==='
git diff --name-status origin/main...HEAD

echo '=== Relevant outlines ==='
ast-grep outline tests/helpers/subprocess_env.py --items all || true
fd -t f 'test*helper*' tests -x sh -c 'echo "--- $1"; ast-grep outline "$1" --items all || true' sh {} \;

echo '=== Environment helper ==='
cat -n tests/helpers/subprocess_env.py

echo '=== Helper tests and references ==='
rg -n -C4 '\bgenerated_project_env\b|MAKE_RESOLUTION_VARIABLES|subprocess_env' tests \
  -g '*.py' || true

echo '=== Relevant PR diff ==='
git diff --find-renames origin/main...HEAD -- tests/helpers/subprocess_env.py tests/test_helpers.py tests

echo '=== GitHub PR checks ==='
gh pr view 54 --repo leynos/agent-template-rust \
  --json url,headRefName,statusCheckRollup \
  --jq '{url, headRefName, checks: [.statusCheckRollup[] | {name, status: .status, conclusion: .conclusion}]}'

Length of output: 1325


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Candidate test files ==='
fd -t f -e py . tests | sort

echo '=== Environment helper ==='
if [ -f tests/helpers/subprocess_env.py ]; then
  cat -n tests/helpers/subprocess_env.py
else
  echo 'tests/helpers/subprocess_env.py is absent'
fi

echo '=== Helper implementation references ==='
rg -n -C4 '\bgenerated_project_env\b|MAKE_RESOLUTION_VARIABLES|subprocess_env' \
  tests -g '*.py' || true

echo '=== Test function declarations ==='
ast-grep outline tests --items all --type function --match 'test|generated_project_env|subprocess' || true

echo '=== PR changed files ==='
gh api 'repos/leynos/agent-template-rust/pulls/54/files?per_page=100' \
  --jq '.[] | [.filename, .status, .additions, .deletions] | `@tsv`'

echo '=== PR checks ==='
gh pr view 54 --repo leynos/agent-template-rust \
  --json url,headRefName,statusCheckRollup \
  --jq '{url, headRefName, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'

Length of output: 15625


@leynos: Treat both reported testing checks as resolved.

Check Status Verification
Testing (Overall) ✅ Resolved tests/test_helpers.py now directly tests generated_project_env. test_generated_project_env_strips_resolution_controls seeds every variable in MAKE_RESOLUTION_VARIABLES, verifies removal, preserves ORDINARY_VARIABLE, verifies PATH and CARGO overrides, and verifies that os.environ remains unchanged.
Testing (Unit And Behavioural) ✅ Resolved test_generated_project_env_returns_independent_copy verifies copy isolation from later parent-environment changes. The direct tests, together with the rendered Makefile fallback tests, cover the helper contract and its integration use.

GitHub reports successful act-validation and build-test checks for PR #54. No further work or follow-up GitHub issue is required.

You are interacting with an AI system.

@leynos

leynos commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

❌ Failed checks (1 error, 1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error The new helper has no direct test, and the fallback test does not inject inherited controls; it can pass with a no-op helper in a normal environment. Add deterministic unit tests that seed all listed controls, verify removal, preserve unrelated variables, apply overrides, and leave os.environ unchanged.
Testing (Unit And Behavioural) ⚠️ Warning The rendered Makefile test covers path, home, and missing Whitaker branches, but no unit test verifies generated_project_env removes all five controls, preserves the parent environment, or applies... Add focused tests in tests/test_helpers.py that monkeypatch each control variable and verify removal, copy isolation, override precedence, and ordinary-variable preservation.

@leynos

leynos commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== PR changed files ==='
git diff --name-status origin/main...HEAD

echo '=== Helper outline and implementation ==='
ast-grep outline tests/helpers/subprocess_env.py --items all
cat -n tests/helpers/subprocess_env.py

echo '=== Direct helper-test declarations and implementations ==='
ast-grep outline tests/test_helpers.py --items all
rg -n -C 12 '\btest_generated_project_env_(strips_resolution_controls|returns_independent_copy)\b|\bgenerated_project_env\b|\bMAKE_RESOLUTION_VARIABLES\b' \
  tests/test_helpers.py

echo '=== GitHub PR checks ==='
gh pr view 54 --repo leynos/agent-template-rust \
  --json url,headRefName,statusCheckRollup \
  --jq '{url, headRefName, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'

Length of output: 1186


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='leynos/agent-template-rust'
pr='54'

echo '=== PR head and current checks ==='
head_sha=$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq .headRefOid)
printf 'head_sha=%s\n' "$head_sha"
gh pr view "$pr" --repo "$repo" --json url,statusCheckRollup \
  --jq '{url, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'

echo '=== Changed files ==='
gh api "repos/$repo/pulls/$pr/files?per_page=100" \
  --jq '.[] | [.filename, .status, .additions, .deletions] | `@tsv`'

echo '=== Helper and helper-test patches ==='
gh api "repos/$repo/pulls/$pr/files?per_page=100" \
  --jq '.[] | select(.filename == "tests/helpers/subprocess_env.py" or .filename == "tests/test_helpers.py") | "----- \(.filename) -----\n\(.patch // "(No patch returned)")"'

echo '=== Current helper source ==='
gh api "repos/$repo/contents/tests/helpers/subprocess_env.py?ref=$head_sha" --jq .content \
  | base64 --decode | nl -ba

echo '=== Current helper-test source: relevant sections ==='
gh api "repos/$repo/contents/tests/test_helpers.py?ref=$head_sha" --jq .content \
  | base64 --decode \
  | rg -n -C 14 '\btest_generated_project_env_(strips_resolution_controls|returns_independent_copy)\b|\bgenerated_project_env\b|\bMAKE_RESOLUTION_VARIABLES\b'

Length of output: 6142


@leynos Treat both testing findings as resolved.

Check Status Verification
Testing (Overall) ✅ Resolved tests/test_helpers.py adds test_generated_project_env_strips_resolution_controls. It seeds all five MAKE_RESOLUTION_VARIABLES values, verifies that generated_project_env removes them, preserves ORDINARY_VARIABLE, applies PATH and CARGO overrides, and does not modify os.environ.
Testing (Unit And Behavioural) ✅ Resolved test_generated_project_env_returns_independent_copy verifies that the returned environment is independent from subsequent parent-environment changes. The first direct test also verifies override precedence and ordinary-variable preservation.

GitHub reports successful act-validation and build-test checks for PR #54. No further work, AI agent prompt, or GitHub issue is required.

You are interacting with an AI system.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/helpers/subprocess_env.py`:
- Around line 15-23: Annotate MAKE_RESOLUTION_VARIABLES explicitly as
frozenset[str] while preserving its existing values and frozenset
initialization.

In `@tests/test_helpers.py`:
- Around line 76-85: Add an explicit override for one MAKE_RESOLUTION_VARIABLES
member, such as WHITAKER, when calling generated_project_env. Assert the
returned env preserves that override while the other inherited resolution
controls remain absent, and retain the existing PATH, CARGO, and
process-environment assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 103b5d6a-c4da-4f9e-b6db-5295742f4179

📥 Commits

Reviewing files that changed from the base of the PR and between a78fc9f and 9fac30b.

📒 Files selected for processing (4)
  • docs/developers-guide.md
  • tests/helpers/subprocess_env.py
  • tests/test_helpers.py
  • tests/test_template/test_lint_targets.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

Comment thread tests/helpers/subprocess_env.py Outdated
Comment thread tests/test_helpers.py Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_helpers.py`:
- Around line 97-108: Update every assertion in the shown test and the
referenced lines 139–156 to include a diagnostic message instead of using bare
asserts. In the assertions around MAKE_RESOLUTION_VARIABLES, env,
inherited_controls, PATH, CARGO, and WHITAKER, make messages identify the
relevant variable, expected value, and applicable override mapping so
generated-example failures are actionable.
- Around line 62-72: Add type annotations to the environment_value and
generated_project_overrides Hypothesis strategy declarations, using
st.SearchStrategy[str] and st.SearchStrategy[dict[str, str]] respectively while
preserving their existing strategy definitions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d49b9e41-f976-4ead-8d60-ee479ee321b8

📥 Commits

Reviewing files that changed from the base of the PR and between 9fac30b and 9bb2c57.

📒 Files selected for processing (1)
  • tests/test_helpers.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

Comment thread tests/test_helpers.py Outdated
Comment thread tests/test_helpers.py Outdated
@leynos

leynos commented Aug 2, 2026

Copy link
Copy Markdown
Owner

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_helpers.py`:
- Around line 152-179: Extend the assertions around generated_project_env to
verify inherited CARGO preservation: when overrides does not contain "CARGO",
assert env["CARGO"] equals the parent-cargo value established by
monkeypatch.setenv. Keep the existing override behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 09004b8e-018c-46ad-bd7d-4787f2e4704d

📥 Commits

Reviewing files that changed from the base of the PR and between 9fac30b and b5f0f99.

📒 Files selected for processing (1)
  • tests/test_helpers.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

Comment thread tests/test_helpers.py
@lodyai
lodyai Bot force-pushed the issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout branch from b5f0f99 to 23811ee Compare August 2, 2026 22:53

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_helpers.py`:
- Around line 220-221: Add diagnostic messages to both assertions in the
relevant test, clearly identifying the expected child value ("changed") and
parent value ("after") when copy isolation fails; retain the existing assertion
conditions and use the repository’s required assert-with-message style.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 51718bf2-75b1-47ac-9d75-fc56ff15b5e4

📥 Commits

Reviewing files that changed from the base of the PR and between b5f0f99 and 23811ee.

📒 Files selected for processing (4)
  • docs/developers-guide.md
  • tests/helpers/subprocess_env.py
  • tests/test_helpers.py
  • tests/test_template/test_lint_targets.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

Comment thread tests/test_helpers.py Outdated
leynos and others added 11 commits August 3, 2026 11:58
Strip inherited make and Whitaker resolution variables from generated-project
lint subprocesses so the fallback cases exercise the intended PATH, HOME, and
missing-tool branches regardless of the parent test environment.

Include captured stdout and stderr in fallback assertions so future resolution
failures report the selected Whitaker command directly.
Strip `GNUMAKEFLAGS`, isolate the test PATH while supplying only `bash`, and
assert the resolved Whitaker binary in successful fallback cases. Document
the hermetic generated-project subprocess environment helper.
Describe the hermetic subprocess environment helper's public contract and
quote the marker filename written by the generated Whitaker fixture.
Apply the repository formatter after rebasing onto the current parent tooling.
Cover inherited Make and Whitaker control sanitisation, override precedence,
and parent-environment isolation in the shared subprocess helper.
Exercise arbitrary generated-project overrides, resolution-control stripping,
and copy isolation alongside the focused Whitaker override case.
Type Hypothesis strategies and include expected values, actual values, and
override mappings in environment helper assertion failures.
Assert that generated subprocess environments retain the inherited `CARGO`
value whenever callers do not provide a CARGO override.
Include expected child and parent values in copy-isolation assertions to make
future generated environment failures actionable.
Declare the Whitaker and Make resolution-control collection as
`frozenset[str]`.
Report only unexpected resolution-control names when the test fails.
@lodyai
lodyai Bot force-pushed the issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout branch from 640246e to ef1487a Compare August 3, 2026 10:00
@leynos

leynos commented Aug 3, 2026

Copy link
Copy Markdown
Owner

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_template/test_lint_targets.py (1)

124-133: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Resolve executable paths before changing directories or creating symlinks.

When PATH contains a relative directory, shutil.which() returns a relative path. Resolve make and bash with Path(...).resolve() immediately after each lookup at all four listed sites. Otherwise, the make calls can fail after cwd=project.path, and the bash symlinks can be broken.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_template/test_lint_targets.py` around lines 124 - 133, Resolve
executable paths immediately after each shutil.which lookup by converting the
returned make and bash paths through Path(...).resolve(). Apply this at
tests/test_template/test_lint_targets.py lines 124-133, 204-213, 244-247, and
262-278; preserve the existing assertions, subprocess calls, and symlink
behavior while ensuring all paths remain valid after directory changes.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tests/test_template/test_lint_targets.py`:
- Around line 124-133: Resolve executable paths immediately after each
shutil.which lookup by converting the returned make and bash paths through
Path(...).resolve(). Apply this at tests/test_template/test_lint_targets.py
lines 124-133, 204-213, 244-247, and 262-278; preserve the existing assertions,
subprocess calls, and symlink behavior while ensuring all paths remain valid
after directory changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97f17430-2230-4061-b6c3-199fdf052d29

📥 Commits

Reviewing files that changed from the base of the PR and between b5f0f99 and ef1487a.

📒 Files selected for processing (4)
  • docs/developers-guide.md
  • tests/helpers/subprocess_env.py
  • tests/test_helpers.py
  • tests/test_template/test_lint_targets.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos

leynos commented Aug 3, 2026

Copy link
Copy Markdown
Owner

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

Check name Status Explanation Resolution Security And Privacy ❌ Error New test failure text formats the entire os.environ-derived env at tests/test_helpers.py:99; this can expose CI tokens and other secrets in pytest errors. Replace env={env} with allow-listed, redacted diagnostics. Do not log inherited environment values; retain assertions on individual variables.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='leynos/agent-template-rust'
pr='54'

echo '=== PR head and checks ==='
head_sha="$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq .headRefOid)"
printf 'head_sha=%s\n' "$head_sha"
gh pr view "$pr" --repo "$repo" --json url,statusCheckRollup \
  --jq '{url, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'

echo '=== Relevant test source ==='
ast-grep outline tests/test_helpers.py --items all --type function --match 'generated_project_env|test_generated_project_env' || true
rg -n -C 12 'env=\{env\}|generated_project_env|MAKE_RESOLUTION_VARIABLES|assert ' \
  tests/test_helpers.py

echo '=== Relevant PR patch ==='
gh api "repos/$repo/pulls/$pr/files?per_page=100" \
  --jq '.[] | select(.filename == "tests/test_helpers.py") | .patch'

echo '=== Search for full-environment diagnostic patterns in changed Python tests ==='
git diff --unified=20 origin/main...HEAD -- tests \
  | rg -n -C 3 '(env=\{|environment=\{|os\.environ|repr\(env\)|\{env\})' || true

Length of output: 33732


@leynos Treat the Security And Privacy finding as resolved.

tests/test_helpers.py no longer formats the full env mapping in assertion output.

The assertion at Lines 97-103 now reports only:

  • the expected control-variable names,
  • the unexpected control-variable names, and
  • the test-controlled overrides mapping.

The remaining related assertions report values for explicitly named, test-controlled variables. They do not serialize inherited os.environ values.

act-validation and build-test are successful for PR #54. No further work, AI agent prompt, or follow-up GitHub issue is required.


✏️ Learnings added
Learnt from: leynos
URL: https://github.com/leynos/agent-template-rust/pull/54

Timestamp: 2026-08-03T18:44:35.771Z
Learning: In `tests/test_helpers.py`, assertion diagnostics for subprocess environment helpers must not serialize an environment mapping derived from `os.environ`. Report only allow-listed variable names and test-controlled values so pytest failures cannot expose CI credentials or other inherited secrets.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@leynos
leynos merged commit 54d25e7 into main Aug 3, 2026
6 checks passed
@leynos
leynos deleted the issue-53-test-lint-targets-whitaker-fallback-cases-fail-on-a-clean-main-checkout branch August 3, 2026 19:09
@leynos

leynos commented Aug 3, 2026

Copy link
Copy Markdown
Owner

@coderabbitai Have the following now been resolved?

tests/test_template/test_lint_targets.py (1)

124-133: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Resolve executable paths before changing directories or creating symlinks.
When PATH contains a relative directory, shutil.which() returns a relative path. Resolve make and bash with Path(...).resolve() immediately after each lookup at all four listed sites. Otherwise, the make calls can fail after cwd=project.path, and the bash symlinks can be broken.

🤖 Detailed instructions

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @tests/test_template/test_lint_targets.py around lines 124 - 133, Resolve
executable paths immediately after each shutil.which lookup by converting the
returned make and bash paths through Path(...).resolve(). Apply this at
tests/test_template/test_lint_targets.py lines 124-133, 204-213, 244-247, and
262-278; preserve the existing assertions, subprocess calls, and symlink
behavior while ensuring all paths remain valid after directory changes.

Source: Path instructions

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Relevant test structure ==='
ast-grep outline tests/test_template/test_lint_targets.py --items all --type function || true

echo '=== All shutil.which call sites with context ==='
rg -n -C 8 'shutil\.which\s*\(' tests/test_template/test_lint_targets.py

echo '=== Requested source ranges ==='
nl -ba tests/test_template/test_lint_targets.py | sed -n '118,138p;198,218p;238,252p;256,284p'

echo '=== PR patch for the affected test file ==='
git diff --unified=12 origin/main...HEAD -- tests/test_template/test_lint_targets.py

echo '=== PR `#54` status checks ==='
gh pr view 54 --repo leynos/agent-template-rust \
  --json url,headRefOid,statusCheckRollup \
  --jq '{url, headRefOid, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'

Length of output: 4233


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Requested source ranges with line numbers ==='
awk 'NR >= 118 && NR <= 138 || NR >= 198 && NR <= 218 || NR >= 238 && NR <= 252 || NR >= 256 && NR <= 284 { printf "%5d  %s\n", NR, $0 }' \
  tests/test_template/test_lint_targets.py

echo '=== All make/bash lookup assignments and resolve calls ==='
rg -n -C 3 '(shutil\.which\("(make|bash)"\)|Path\(.*\)\.resolve\(\))' \
  tests/test_template/test_lint_targets.py || true

echo '=== PR patch for affected test file ==='
git diff --unified=12 origin/main...HEAD -- tests/test_template/test_lint_targets.py || true

echo '=== PR `#54` status checks ==='
gh pr view 54 --repo leynos/agent-template-rust \
  --json url,headRefOid,statusCheckRollup \
  --jq '{url, headRefOid, checks: [.statusCheckRollup[] | {name, status, conclusion}]}' || true

Length of output: 6389


@leynos The finding is not resolved.

tests/test_template/test_lint_targets.py still uses raw shutil.which() results at Lines 124, 204, 244, and 262. The file has no Path(...).resolve() calls.

This remains a valid defect:

  • Lines 128 and 208 use make after cwd=project.path.
  • Line 247 creates bash symlinks from the raw lookup result.
  • Line 266 uses make after cwd=project.path.

PR #54 has successful act-validation and build-test checks. Those checks do not test a relative PATH directory. Do not treat them as validation of this case.

  • Resolve each shutil.which("make") and shutil.which("bash") result immediately after the existing non-None assertion.
  • Preserve the existing subprocess calls, assertions, and symlink logic.
  • Add or run focused validation that uses a relative PATH directory.

  • 📌 Create a pull request with these changes

You are interacting with an AI system.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test_lint_targets whitaker-fallback cases fail on a clean main checkout

2 participants