Skip to content

ci: add advisory ImpactGate reports - #1138

Open
tobyhede wants to merge 5 commits into
mainfrom
ci/impact-gate-1137
Open

tobyhede wants to merge 5 commits into
mainfrom
ci/impact-gate-1137

Conversation

@tobyhede

@tobyhede tobyhede commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR: Adds advisory ImpactGate reports to PRs, scoring change impact with and without test files against Stack’s history.

Stack currently has no repository-calibrated change-impact report. This adds a read-only, advisory ImpactGate workflow with two job-summary reports: eligible source including test files, and eligible source excluding test files. Existing FTA/CRAP checks remain unchanged; impact scores do not gate merges or post PR comments.

The workflow pins ImpactGate and Lizard, builds matching baselines from 200 recent mainline entries, and caches them by measurement policy and target branch. The driver validates cached pairs, rebuilds corrupt or incompatible data, explicitly discloses seed-only grading, and preserves operational failures. Scope rules account for generated output and current/historical test layouts; reports disclose unsupported SQL/module extensions and remaining TypeScript parser defects.

Validation

  • Nine real-tool tests passed, covering reporting, filtering, cache reuse/repair, empty histories, advisory scores, and failure propagation.
  • Repository script suite: 1,269 passed, 28 skipped; subsequent focused workflow suite passed all four tests, including the review-added exclusion guard.
  • All 16 repository typecheck tasks passed; direct check-JS and Python mypy checks passed.
  • All 28 supply-chain tests, actionlint, and repository Biome checks passed (existing warnings remain).
  • Full package suite attempted: 12/19 tasks passed. Seven tasks encountered missing native bindings; auth packing tests also failed on npm JSON-output assumptions after sandbox restrictions were removed. The full suite is not claimed green.
  • Local final-policy calibration: 279.55 seconds to build both baselines; 1.63 seconds to score both reports using them. Large real changes exceeded p98 and still exited successfully under advisory enforcement.
  • Separate standards/spec reviews found no implementation-correctness violations; the shared-exclusion consistency concern is covered by a guard.

Rollout

The first PR run can verify cold generation and rendered summaries. A main run saving the baseline pair and a subsequent PR restoring it remain to be verified after merge. Local timing does not establish hosted cache behavior. Evidence and reproduction details are recorded in docs/plans/2026-10-08-impact-gate-rollout.md.

Implements #1137; leave the issue open until hosted rollout verification is recorded.

Summary by CodeRabbit

  • Developer Experience
    • Pull requests now include advisory impact summaries for repository-wide changes and eligible source code.
    • Reports compare changes with recent project history and exclude generated, dependency, and test files from analysis.
    • Analysis and reporting failures are surfaced instead of being hidden; impact results remain advisory and do not block changes.

@tobyhede
tobyhede requested a review from a team as a code owner October 8, 2026 00:07
@changeset-bot

changeset-bot Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 587d06e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
stash Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-prisma Patch
@cipherstash/stack-supabase Patch
@cipherstash/stack Patch
@cipherstash/wizard Patch
@cipherstash/bench Patch
@cipherstash/prisma-example Patch
@cipherstash/test-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 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-08T00:12:29.524780Z 0a84761 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.

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 57c4883a-aabf-4923-85b5-2241d5b3ebd4
📥 Commits

Reviewing files that changed from the base of the PR and between 0a84761 and 587d06e.

📒 Files selected for processing (10)
  • .changeset/impact-gate-pip-supply-chain.md
  • .github/dependabot.yml
  • .github/impact-gate/requirements.txt
  • .github/workflows/impact.yml
  • docs/plans/2026-10-08-impact-gate-rollout.md
  • e2e/tests/supply-chain.e2e.test.ts
  • scripts/__tests__/impact-workflow.test.mjs
  • scripts/impact-gate.py
  • scripts/tests/test_impact_gate.py
  • skills/stash-supply-chain-security/SKILL.md

Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.


📝 Walkthrough

Walkthrough

This change adds ImpactGate policies, a CLI that prepares baselines and reports impact scores, and a GitHub Actions workflow that runs analysis on pull requests and pushes to main. It also adds pip dependency pinning, monitoring, and related tests and documentation.

Changes

ImpactGate analysis

Layer / File(s) Summary
Analysis policies and rollout record
.github/impact-gate/*, .gitignore, docs/plans/2026-10-08-impact-gate-rollout.md
Policy files define analysis exclusions and scoring settings. The requirements file pins the analysis tools and dependencies with hashes. The rollout record documents calibration results, coverage limits, reproduction commands, and workflow settings.
Baseline preparation and impact reporting
scripts/impact-gate.py, scripts/tests/test_impact_gate.py
The CLI validates, reuses, or rebuilds baseline pairs, then reports advisory scores for the all and source scopes. Integration tests cover cache behavior, history cases, file classification, and report output.
GitHub Actions integration
.github/workflows/impact.yml, scripts/__tests__/impact-workflow.test.mjs
The workflow prepares baselines for the event’s target commit, saves rebuilt baselines, and reports impact on pull requests. Tests check workflow triggers, permissions, cache conditions, and commands.
Pip dependency monitoring and supply-chain checks
.github/dependabot.yml, .changeset/impact-gate-pip-supply-chain.md, e2e/tests/supply-chain.e2e.test.ts, skills/stash-supply-chain-security/SKILL.md
Dependabot monitors the pip requirements. The ecosystem manifest test maps pip to requirements.txt, and the supply-chain guidance describes hash-pinned installation requirements.

Priority: ⬇️ Low

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

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant ImpactGateScript as impact-gate.py
  participant ImpactGateCLI as ImpactGate CLI
  participant StepSummary as GitHub step summary
  GitHubActions->>ImpactGateScript: Run prepare for the pinned base commit
  ImpactGateScript->>ImpactGateCLI: Build or validate baseline data
  GitHubActions->>ImpactGateScript: Run report for pull requests
  ImpactGateScript->>ImpactGateCLI: Score both analysis scopes
  ImpactGateScript->>StepSummary: Append the report
Loading

Suggested reviewers: coderdan

Merge Risk: ⚪ Minimal · up to 587d0

This change adds advisory impact reports that do not gate merges. No merge-blocking issue was found. Check cache behavior in hosted runs after merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 3.45% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 29 functions across 4 files. (6 skipped: 6… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding advisory ImpactGate reports to CI.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 3.45% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 29 functions across 4 files. (6 skipped: 6 unsupported.)

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@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: 0a84761464

ℹ️ 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/impact-gate/requirements.txt Outdated
Comment on lines +1 to +2
impact-gate==0.4.1
lizard==1.23.0

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 Pin transitive analyzers before caching baselines

When PyYAML, Pygments, or pathspec publishes a new compatible release, this requirements file allows pip install to select it while the cache identity remains unchanged because identity() records only ImpactGate and Lizard versions. ImpactGate and Lizard declare those dependencies with open-ended constraints (ImpactGate metadata, Lizard metadata), so a PR can restore a baseline produced with different configuration or file-filtering code than the current scoring process, making the percentile report non-reproducible. Pin the complete resolved dependency set or include every measurement-affecting installed version in the cache identity.

Useful? React with 👍 / 👎.

@tobyhede tobyhede left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review attestation (code-review, medium effort)

  • Files reviewed: .github/workflows/impact.yml, scripts/impact-gate.py, scripts/tests/test_impact_gate.py, scripts/__tests__/impact-workflow.test.mjs, .github/impact-gate/* (policies, requirements), .gitignore, docs/plans/2026-10-08-impact-gate-rollout.md
  • Models: Sonnet 5.5

Generated by Claude Code

Comment thread scripts/impact-gate.py Outdated
prepare(args, policy, head)
else:
report(args, policy)
except (subprocess.CalledProcessError, OSError, ValueError, KeyError, TypeError,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This except tuple is narrower than what the impact_gate library can raise. build_baseline and MeasureConfig.load can fail with a YAML parse error, a RuntimeError from the history walk, or a lizard failure. None of those are caught here. The job then dies with a bare traceback and no **ImpactGate analysis failed:** entry in the step summary, which is the visibility the test test_analysis_failure_is_not_hidden_by_summary is meant to guarantee. Consider catching Exception here, since main re-reports the error and returns non-zero anyway.


Generated by Claude Code

Comment thread scripts/impact-gate.py


def cli(*args: str) -> str:
return run(sys.executable, '-m', 'impact_gate', *args)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

check_output doesn't capture stderr, so if impact_gate score exits non-zero the published message is only "returned non-zero exit status N". The tool's own error text goes to the job log and not to the step summary. Capturing stderr (for example stderr=subprocess.STDOUT, or subprocess.run with capture_output) and including it in the failure summary would make the report debuggable.


Generated by Claude Code


concurrency:
group: impact-${{ github.ref }}
cancel-in-progress: true

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

cancel-in-progress: true applies to main pushes too. If two merges land close together, the first run is cancelled before "Save main baselines" and no cache is written for that SHA. PRs based on it then fall back to an older ancestor cache through restore-keys, because valid_pair accepts any ancestor, and they are scored against a stale baseline. Consider cancel-in-progress: ${{ github.event_name == 'pull_request' }}.


Generated by Claude Code

uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ${{ env.BASELINE_DIR }}
key: ${{ steps.restore.outputs.cache-primary-key }}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This save can fail permanently for a given SHA. If an exact-key cache exists but fails validation (policy or hash mismatch, corrupt files), REFRESH is false because cache-hit is true. prepare still rebuilds, and rebuilt=true triggers this save. GitHub refuses to overwrite the existing immutable key ("Unable to reserve cache"). The bad cache stays in place and every later run for that SHA rebuilds again. The key already hashes the policy files, so this is rare, but a corrupt entry never self-heals. Options are to delete the bad key first, or to add a run-attempt or ID suffix to the save key and match it through restore-keys.


Generated by Claude Code

Comment thread .github/workflows/impact.yml Outdated
python scripts/impact-gate.py prepare --base "$BASE_REF" --cache-dir "$BASELINE_DIR" "${args[@]}"

- name: Save main baselines
if: github.event_name == 'push' && steps.prepare.outputs.rebuilt == 'true'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pull-request runs never save a baseline. If no cache exists for the base (evicted after 7 days idle, or the main-push run was cancelled), each PR run rebuilds both scopes from scratch. The docs measure about 280 s locally for the pair, so a slow runner could use a large share of the 20-minute budget on every synchronize, and the result is discarded each time. A fallback that fails fast with a clear "no baseline yet" message, or a saved PR-side cache keyed on the base SHA, would avoid repeating this work.


Generated by Claude Code

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