Skip to content

ci: wire conda_avail gate to 27 conda-full self-tests + loud tripwire - #397

Merged
mixmansoundude merged 2 commits into
mainfrom
claude/pipreqs-fallback-maintenance-49jhr9
Jul 28, 2026
Merged

ci: wire conda_avail gate to 27 conda-full self-tests + loud tripwire#397
mixmansoundude merged 2 commits into
mainfrom
claude/pipreqs-fallback-maintenance-49jhr9

Conversation

@mixmansoundude

Copy link
Copy Markdown
Owner

Summary

The final residual of CLAUDE.md's Active Backlog item 7: wires the already-relocated, already-verified conda_avail diagnostic (PR #394, confirmed positive across two real conda-full runs in PR #395/#396) to the 27 real/conda-full/conda-full-only self-test steps it was staged for. Owner-directed after a full risk/benefit assessment discussed in chat, with an explicit instruction: default to a loud CI failure on any problem, even when it isn't necessarily our own fault.

Ships as two pieces, deliberately never one without the other:

  • The gate: 22 shared real/conda-full steps and 5 conda-full-only steps now require steps.conda_avail.outputs.available == 'true' for their conda-full half -- skip fast instead of each independently retrying a doomed sub-bootstrap.
  • The tripwire (new step, "Enforce Miniconda availability"): unconditionally FAILS the job (no continue-on-error) whenever that reads anything but 'true' in the conda-full lane -- deliberately without trying to distinguish a genuine Miniconda install failure from a bug in the gate mechanism itself, per the owner's explicit direction. Shipping the gate alone would reintroduce exactly the PR ci: lane-aware if:always() rollout for remaining 36 gating-lane steps (item 7) #390 failure class (a wrong condition silently skips real tests while the job stays green); the tripwire is what makes the gate safe to ship.

A key fact found by re-reading tests/selfapps_envsmoke.ps1 before implementing: a genuine Miniconda install failure already independently fails that step's own self.env.smoke.conda NDJSON row today (its $bootstrapPass requires a clean interpreter, successful entry-run, and the absence of any [ERROR] line -- not just a zero exit code). So the tripwire's real new protection is narrower and more precise than "catch Miniconda failing" -- it specifically catches a bug in the gate/tripwire mechanism itself (wrong lane, wrong step id, wrong output name, a GH Actions expression typo). The genuine-failure case still gets caught too, via an independent signal (Test-Path on disk vs. log-text parsing), matching "default to fail CI if any problem."

Recovery-mechanism exploration (per the owner's own ask): traced what already exists inside run_setup.bat's own single invocation -- AllUsers→JustMe fallback, REQ-022's transient-retry, REQ-013's connectivity-aware retry, a secondary download URL, and a bounded installer timeout. Decided not to add a CI-level auto-retry wrapper on top: no genuine Miniconda install failure has ever been observed in this repo's real CI history, and a silent auto-retry would reduce signal quality by smoothing over a real transient issue rather than surfacing it -- directly against the stated preference for loud, attributable failure. Shipped the lower-risk, genuinely additive piece instead: on tripwire failure, the step also prints the tail of tests\~envsmoke\~envsmoke_bootstrap.log inline for immediate root-cause visibility, at zero new control-flow risk.

No genuinely blocking open question was found while implementing this -- nothing added to docs/open-questions.md.

Test plan

  • python -m compileall -q .
  • python -m pyflakes .
  • python tools/check_delimiters.py run_setup.bat
  • markdownlint-cli2 CLAUDE.md (clean, only the expected permanent baseline finding)
  • python -m yamllint .github/workflows/
  • actionlint -oneline .github/workflows/*.yml
  • Repo-wide ASCII sweep -- clean
  • PowerShell AST parse sweep (tests/.ps1, tools/.ps1)
  • python -m pytest tests/test_*.py -q (437 passed, 2 skipped)
  • Scripted diff-scope check: exactly 27 if: lines changed, one-for-one against the enumerated step names, no stray edits
  • Full tools/run_sanity_sweep.sh run, all checks OK

This cannot be verified end-to-end locally (real GitHub Actions step-output/expression semantics across a job). The real confirmation is the conda-full lane of this PR's own CI run: available should read true and all 27 gated steps should run normally (not skip), and the new tripwire step should pass cleanly.

Claude-Session: https://claude.ai/code/session_015xbWLPbiaKVsobB9FZy8kS


Generated by Claude Code

Gates the conda-full half of 22 real/conda-full self-test steps plus 5
conda-full-only steps on steps.conda_avail.outputs.available == 'true'
(skip fast instead of each independently retrying a doomed sub-bootstrap).
Ships paired with a new "Enforce Miniconda availability" tripwire step
that unconditionally fails the job when that reads anything but 'true'
in the conda-full lane -- deliberately without distinguishing a genuine
Miniconda install failure from a bug in the gate mechanism itself, per
explicit owner direction to default to a loud failure either way. This
is what makes the gate safe to ship: shipping it alone would reintroduce
the exact PR #390 failure class (a wrong condition silently skips real
tests while the job stays green).

Owner-directed after a full risk/benefit assessment discussed in chat,
including exploring (and declining, with documented reasoning) an
additional CI-level retry mechanism on top of run_setup.bat's own
already-comprehensive Miniconda recovery (AllUsers->JustMe, REQ-022
retry, REQ-013 connectivity retry, download-URL fallback, bounded
installer timeout).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xbWLPbiaKVsobB9FZy8kS
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@mixmansoundude
mixmansoundude enabled auto-merge (squash) July 27, 2026 23:32
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • CI Improvements

    • Added a Miniconda availability diagnostic used to determine whether conda-full self-tests should proceed.
    • Enforced the diagnostic via a new availability gate: conda-full now hard-fails when Miniconda is not available, while other lanes skip cleanly.
    • Expanded NDJSON logging and failure output with more actionable environment bootstrap log context.
    • Updated multiple self-test groups to require Miniconda availability before running in conda-full.
  • Documentation

    • Updated the NDJSON reference and debugging guidance to include the new availability gate row (diag.conda.available.gate).

Walkthrough

The workflow records Miniconda availability, enforces it for conda-full, and gates downstream self-tests on confirmed availability. Project and NDJSON documentation describe the enforcement row and failure behavior.

Changes

Miniconda availability gating

Layer / File(s) Summary
Availability diagnostic and enforcement
.github/workflows/batch-check.yml
The workflow emits diagnostic and gate NDJSON rows, exposes availability to later steps, skips enforcement outside conda-full, and fails conda-full when availability is not true.
Self-test lane conditions
.github/workflows/batch-check.yml
Dependency, warning, collection, hidden-import, EXE-smokerun, runtime, pyvisa, and pyproject self-tests now require confirmed Miniconda availability in conda-full.
Gate behavior documentation
CLAUDE.md, docs/agent-ndjson.md
Documentation describes the enforcement step, failure diagnostics, availability semantics, and the registered gate row.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant conda_avail
  participant conda_avail_gate
  participant conda_full_selftests
  conda_avail->>conda_avail_gate: provide available output
  conda_avail_gate->>conda_full_selftests: allow when available is true
  conda_avail_gate->>conda_full_selftests: fail and block when unavailable
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main CI change: wiring the conda_avail gate to conda-full self-tests with a fail-fast tripwire.
Description check ✅ Passed The description is directly related to the PR and accurately describes the gating and tripwire changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/pipreqs-fallback-maintenance-49jhr9

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

@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 @.github/workflows/batch-check.yml:
- Around line 392-395: Correct the availability-row documentation to state that
both availability steps run and emit rows in every non-cache-corrupted lane, not
every lane. Update the comment at .github/workflows/batch-check.yml lines
392-395 and the corresponding “in EVERY lane” wording at CLAUDE.md lines
857-860; make no workflow logic changes.
🪄 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: 730d47b3-71cb-460f-bd8f-9d4dc6321c13

📥 Commits

Reviewing files that changed from the base of the PR and between e20a973 and 7e8a65a.

📒 Files selected for processing (3)
  • .github/workflows/batch-check.yml
  • CLAUDE.md
  • docs/agent-ndjson.md
📜 Review details
⏰ Context from checks skipped due to timeout. (9)
  • GitHub Check: auto_merge
  • GitHub Check: Batch syntax/run check (real)
  • GitHub Check: Batch syntax/run check (contract-uv)
  • GitHub Check: Batch syntax/run check (justme-test)
  • GitHub Check: Batch syntax/run check (contract-uv-fail)
  • GitHub Check: Batch syntax/run check (cache)
  • GitHub Check: Batch syntax/run check (uv)
  • GitHub Check: Batch syntax/run check (uv-dl-fallback)
  • GitHub Check: Batch syntax/run check (conda-full)
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

Treat GitHub Actions results, especially Windows runner results, as authoritative; local or sandbox runs are advisory.

**/*: Keep knowledge documentation current in the same commit as changes that teach or invalidate a lesson: update docs/agent-interconnect.md, docs/agent-lessons-learned.md, or docs/agent-ndjson.md as applicable.
Follow the iteration contract: freeze scope for the current loop, fix CI/configuration before tests and product code, implement one feature slice and one missing test per loop, then verify no false positives.

Files:

  • docs/agent-ndjson.md
  • CLAUDE.md
**/*.{md,bat,cmd}

📄 CodeRabbit inference engine (AGENTS.md)

Document run_setup.bat locations using stable label or subroutine names rather than exact line numbers.

Files:

  • docs/agent-ndjson.md
  • CLAUDE.md
**/*.{bat,cmd,ps1,py,yml,yaml,json,md,sh}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ASCII-only text; do not add emojis, curly quotes, em-dashes, or other non-ASCII characters.

Files:

  • docs/agent-ndjson.md
  • CLAUDE.md
CLAUDE.md

📄 CodeRabbit inference engine (AGENTS.md)

Run the narrowly scoped advisory Markdown lint for CLAUDE.md; new Active Backlog entries must be bullets with the identifier in prose, reserving literal ordered-list syntax for grandfathered item 7.

Files:

  • CLAUDE.md
.github/workflows/*.yml

📄 CodeRabbit inference engine (CLAUDE.md)

.github/workflows/*.yml: Keep real and conda-full lanes gating; do not add continue-on-error: true to steps or jobs that determine merge status.
Use !cancelled() rather than bare always() when a workflow step must run after prior failures but should still respect workflow cancellation.
Do not use merge-multiple: true with identically named files from multiple artifacts unless collisions are impossible; otherwise ensure artifact contents are uniquely named or aggregated safely.

Files:

  • .github/workflows/batch-check.yml
🪛 LanguageTool
docs/agent-ndjson.md

[uncategorized] ~540-~540: The official name of this software platform is spelled with a capital “H”.
Context: .... - diag.conda.available.gate (inline .github/workflows/batch-check.yml, the "Enforc...

(GITHUB)

🪛 zizmor (1.26.1)
.github/workflows/batch-check.yml

[info] 400-400: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🔇 Additional comments (3)
.github/workflows/batch-check.yml (1)

325-391: LGTM!

Also applies to: 396-440, 470-508, 643-658, 769-859, 993-1005

CLAUDE.md (1)

848-856: LGTM!

Also applies to: 861-908

docs/agent-ndjson.md (1)

210-210: LGTM!

Also applies to: 532-551

Comment thread .github/workflows/batch-check.yml Outdated
…injection hardening)

- The conda_avail/conda_avail_gate steps' own if: already excludes the
  HP_CACHE_CORRUPTED=1 path, so "runs in every lane" was inaccurate --
  corrected to "every non-cache-corrupted lane" in both the workflow
  comment and CLAUDE.md's mirrored description.
- Route conda_avail's output through an env: mapping instead of
  interpolating it directly into the PowerShell script body, per a
  zizmor template-injection info-level finding. The value was never
  attacker-controlled (an enum string from our own prior Test-Path
  check), but the env: form is the established safe idiom and costs
  nothing to use for newly-authored code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xbWLPbiaKVsobB9FZy8kS

@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)
.github/workflows/batch-check.yml (1)

372-379: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve the lane field on every new NDJSON row.

HP_CI_LANE is documented to tag every NDJSON row, and the existing writer adds a top-level lane field. These manually written diagnostic and gate rows omit it; the skip row stores the lane only under details, while pass/fail rows omit it entirely. Multi-lane diagnostics therefore cannot reliably attribute these judgments. Add lane = $env:HP_CI_LANE to all four row shapes or route them through the shared writer.

Proposed fix
$row = [ordered]@{
  id      = 'diag.conda.available'
+ lane    = $env:HP_CI_LANE
  pass    = $true
  desc    = '...'
  details = [ordered]@{ available = $avail }
}

Apply the same top-level field to each diag.conda.available.gate row.

Also applies to: 407-435

🤖 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 @.github/workflows/batch-check.yml around lines 372 - 379, Add the top-level
lane field to every manually constructed NDJSON row for the conda availability
diagnostics, including the rows in the diag.conda.available block and each
diag.conda.available.gate shape around the related writer logic. Set lane from
$env:HP_CI_LANE consistently, including skip and pass/fail rows, while
preserving the existing details fields and shared output destinations.
🤖 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 @.github/workflows/batch-check.yml:
- Around line 372-379: Add the top-level lane field to every manually
constructed NDJSON row for the conda availability diagnostics, including the
rows in the diag.conda.available block and each diag.conda.available.gate shape
around the related writer logic. Set lane from $env:HP_CI_LANE consistently,
including skip and pass/fail rows, while preserving the existing details fields
and shared output destinations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f6a32919-36db-4515-873f-31c826c98e36

📥 Commits

Reviewing files that changed from the base of the PR and between 7e8a65a and f7c55f7.

📒 Files selected for processing (2)
  • .github/workflows/batch-check.yml
  • CLAUDE.md
📜 Review details
⏰ Context from checks skipped due to timeout. (8)
  • GitHub Check: Batch syntax/run check (uv-dl-fallback)
  • GitHub Check: Batch syntax/run check (justme-test)
  • GitHub Check: Batch syntax/run check (real)
  • GitHub Check: Batch syntax/run check (contract-uv-fail)
  • GitHub Check: Batch syntax/run check (uv)
  • GitHub Check: Batch syntax/run check (conda-full)
  • GitHub Check: Batch syntax/run check (cache)
  • GitHub Check: Batch syntax/run check (contract-uv)
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

Treat GitHub Actions results, especially Windows runner results, as authoritative; local or sandbox runs are advisory.

**/*: Run the full mandatory sanity sweep before every commit, including compilation, linting, delimiter checks, workflow validation, PowerShell parsing, and pytest.
Update the relevant knowledge document in the same commit when a change teaches or invalidates a lesson; edit existing entries rather than only appending.
Implement exactly one missing feature slice and add exactly one missing test per iteration loop; freeze scope and defer new requirements to the backlog.

Files:

  • CLAUDE.md
CLAUDE.md

📄 CodeRabbit inference engine (AGENTS.md)

Run the narrowly scoped advisory Markdown lint for CLAUDE.md; new Active Backlog entries must be bullets with the identifier in prose, reserving literal ordered-list syntax for grandfathered item 7.

Files:

  • CLAUDE.md
**/*.{md,bat,cmd}

📄 CodeRabbit inference engine (AGENTS.md)

Document run_setup.bat locations using stable label or subroutine names rather than exact line numbers.

Files:

  • CLAUDE.md
**/*.{bat,cmd,ps1,py,yml,yaml,json,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Keep repository source and documentation ASCII-only; avoid emojis, curly quotes, em-dashes, and other non-ASCII characters.

Files:

  • CLAUDE.md
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (CLAUDE.md)

Validate modified GitHub Actions workflows with both yamllint and actionlint.

Files:

  • .github/workflows/batch-check.yml
🔇 Additional comments (4)
.github/workflows/batch-check.yml (3)

325-325: LGTM!


348-358: LGTM!


475-513: LGTM!

Also applies to: 647-654, 663-663, 774-864, 998-1010

CLAUDE.md (1)

858-860: LGTM!

@mixmansoundude
mixmansoundude merged commit 807bdbd into main Jul 28, 2026
16 checks passed
@mixmansoundude
mixmansoundude deleted the claude/pipreqs-fallback-maintenance-49jhr9 branch July 28, 2026 02:44
mixmansoundude added a commit that referenced this pull request Jul 28, 2026
…ows (#398)

CodeRabbit finding on PR #397 (f7c55f7 re-review): HP_CI_LANE is
documented to tag every NDJSON row via a top-level lane field (already
true of every other row emitted in this job -- confirmed directly
against the real conda-full artifact from this same PR), but the two
new manually-constructed conda_avail/conda_avail_gate row shapes
omitted it. Multi-lane diagnostics couldn't reliably attribute these
rows without it. Added lane = $env:HP_CI_LANE to all four row shapes
(the diag.conda.available row, and the skip/pass/fail shapes of
diag.conda.available.gate), removing the now-redundant lane key that
had been nested under details in the skip shape.


Claude-Session: https://claude.ai/code/session_015xbWLPbiaKVsobB9FZy8kS

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants