Skip to content

Add advisory review and risk checks for the shadow week - #58

Merged
gabe4coding merged 5 commits into
mainfrom
bots/validation-shadow-week
Oct 19, 2026
Merged

gabe4coding merged 5 commits into
mainfrom
bots/validation-shadow-week

Conversation

@gabe-bots

@gabe-bots gabe-bots Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Intent

Start the shadow week of the validation loop on this repo, the same setup as gabe4coding/puredori#10 and #58. Two new checks run on every PR. Both are advisory: they are not required, they never fail a PR, and nothing here merges, approves or changes repo settings.

  • review (.github/workflows/review.yml): two passes in one job.
    1. shall: the diff against the engineering standards, adapted from shall's ci/github/shall-review.yml.
    2. General pass (.github/scripts/general_review.py): one tool-less, isolated claude -p call that checks for bugs, missing or weaker tests, silent behavior changes, PR body vs diff drift and irreversible changes. The PR text is passed as untrusted data. It also records the risk-judgment JSON from the design, which does not change the tier yet.
    • Findings go in PR comments and the job summary. This week the job always ends green.
    • If secrets are missing, each pass skips with a neutral ::notice that names the secret.
  • risk (.github/workflows/risk.yml, .github/scripts/risk_tier.py, .github/risk.yml): the deterministic tiers HOLD / T2-hard / T2-soft / T1 / T0.
    • The rules and the script are read from the base branch, so a PR cannot loosen its own tier. This PR is the bootstrap and uses its own copy.
    • The tier is posted as a risk tier check run (success for T0/T1, neutral for T2/HOLD, never failure) and as a risk:* label.
    • Kill switch: if the repo variable AUTOMERGE is off, every PR becomes T2-hard. It is read only.
    • There is no LLM layer yet. The vendor names that HOLD a PR are stored as sha256 hashes, so this public repo never spells them out.
  • Sensitive files (T2-soft): bin/kb-guard, src/kb/redact.py, gitleaks_fetch.py, install.sh and templates/data/.github/. tests/conftest.py and tests/fixtures.py count as code, not tests.
  • No plugin files change, so no version bump.
  • Tests: .github/scripts/test_risk_tier.py and test_general_review.py, run by the risk (classifier tests) job.

Secrets to add (Settings > Secrets and variables > Actions):

  • TYPESAFE_API_KEY: needed for shall's Jev rule selection.
  • ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN: needed for claude -p in both passes.
  • Data note: diffs and PR text go to TypeSafe (shall) and Anthropic (both passes).

This PR is T2-hard by its own rules, because it adds .github/risk.yml and the review and risk workflows. Gabe reviews and merges it.

Evidence

PR Title Size Tier Why
#57 Report a stale Codex plugin cache like a stale Claude Code one +202/-69, 11 files T1 source-change: 4 code files, 114 changed lines
#56 Require the plugin version to be above the tip of origin/main too +34/-8, 2 files T1 source-change: 1 code files, 8 changed lines
#55 Report a plugin cache copy that differs from the code clone at the sam +87/-11, 6 files T1 source-change: 4 code files, 54 changed lines
#54 Hand the cached kb-guard over to the code clone +74/-11, 8 files T2-soft sensitive-path: touches bin/kb-guard
#53 Raise the plugin version so the guard fix of #49 reaches the cache +37/-8, 6 files T2-soft workflow-additive: .github/workflows/test.yml: additive edit or pinned version bump
#52 docs(readme): add a banner +47/-3, 2 files T0 docs-only: 2 files
#51 Add the verification loop and a /verify recipe +413/-2, 8 files T1 source-change: 7 code files, 402 changed lines
#49 fix(kb-guard): block option/quote/sh -c bypasses of kb decide +278/-20, 2 files T2-soft sensitive-path: touches bin/kb-guard
#50 fix(install): find a Python >=3.9 with FTS5, uv fallback +188/-15, 6 files T2-soft sensitive-path: touches install.sh
#48 fix(decide): refresh the band after /clear without classic.SessionStar +47/-13, 4 files T1 source-change: 4 code files, 60 changed lines
#47 test: remove duplicate sync, read-only and enable tests +19/-156, 3 files T1 assertions-removed: removes 21 assertion lines, adds 4
#46 refactor: remove dead code, unused params and the cloud import cache +44/-110, 16 files T1 source-change: 11 code files, 123 changed lines
#45 refactor(harness): drop the decide mod's kb fallback and the skill fol +15/-28, 9 files T1 source-change: 7 code files, 28 changed lines
#44 refactor(hint, decide): drop PostToolUse parsing, the hint tail regexe +65/-103, 11 files T1 source-change: 6 code files, 118 changed lines
#43 refactor(routine): remove the one-time review of open threads +9/-57, 4 files T1 source-change: 2 code files, 43 changed lines
#42 refactor(lock): drop stale_seconds, the no-op touch() and the lock par +12/-27, 4 files T1 source-change: 2 code files, 23 changed lines
#41 fix(setup): refresh the Claude Code plugin cache on each update +200/-24, 13 files T2-soft sensitive-path: touches install.sh
#40 feat(decide): memory fixes, an agent guard, and a Claude Code mod for +1191/-75, 25 files T2-soft sensitive-path: touches bin/kb-guard
#39 feat(decide): let the owner accept or reject retro suggestions with kb +464/-27, 13 files T1 source-change: 8 code files, 272 changed lines
#38 feat(setup): make the setup plug and play +606/-101, 27 files T2-soft sensitive-path: touches install.sh; sensitive-path: touches src/kb/gitleaks_fetch.py

Totals: T0 1, T1 12, T2-soft 7.

Things to compare by hand this week: whether each T2-soft really needed you, and whether any T1 should have been T2.

Harness and others added 2 commits October 19, 2026 11:04
The review job ran on pull_request, so the PR's own workflow ran with
the ANTHROPIC, OAuth and TypeSafe secrets. Nothing in that file is left
without those secrets, so the workflow is gone. general_review.py stays
on disk; no job runs it.

Closes gabe4coding/puredori#12

Co-authored-by: Gabe <gpavanello@thefork.com>
Port the risk-gate hardening. The tier job runs on pull_request_target
with the workflow, rules and classifier from the base branch. The PR head
is fetched as data and never executed. Python runs with -I and uv with
--no-config. The classifier tests job has contents: read only and no
stored git credentials.

Paths come from git diff --name-status -z. The diff uses --text and
--no-textconv, and lines split at newlines only. A test-only change that
edits an assertion or adds skip, only or todo is T1. A file list that
disagrees with the diff is T2-hard.

The reviewer signal is only the Greptile Review check from greptile-apps
on the current head SHA. A failed, missing, pending or stale check, or a
check from another app, has not passed and raises the tier one step, never
past T2-hard. A pass never lowers a tier. greptile.json, .greptile/**,
.coderabbit.yaml and .coderabbit.yml are T2-hard.

Co-authored-by: Gabe <gpavanello@thefork.com>
@gabe-bots

gabe-bots Bot commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@greptile-apps

greptile-apps Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Critical impact] Adds infrastructure that gates pull request merges.

Satisfy the required slow-test markers before merging; the workflow-tier classification issue is a non-blocking advisory defect.

Fix All in CursorFindings

  1. P2 Disabled tests get weaker tiers ▶
  2. P2 Process tests lack slow markers ▶

Summary

Adds an advisory risk classifier, base-branch classification workflow, classifier tests, and an unused general-review helper.

  • Each pull request gets a deterministic risk tier.
  • A script creates a separate Claude review report for a pull request.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  PR[PR opened or updated] --> Tests[Read-only job runs classifier tests]
  PR --> Tier[Privileged job uses base-branch rules and classifier]
  Tier --> Data[Read PR diff and current Greptile check]
  Data --> Classify[Choose advisory risk tier]
  Classify --> Label[Update risk label]
  Classify --> Check[Post successful or neutral risk check]
Loading

Reviews (1) · Last reviewed commit: "risk: close tier bypasses and read Grept..." · Reviewed by Greptile

Comment on lines +279 to +283
added_keys = {_key(l) for l in _meaningful(f.added)}
for line in _meaningful(f.removed):
if not (BUMPABLE.search(_key(line)) and _key(line) in added_keys):
return Reason("T2-hard", "workflow-weakened", f"`{f.path}` removes `{line.strip()[:80]}`")
return Reason("T2-soft", "workflow-additive", f"`{f.path}`: additive edit or pinned version bump")

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 Disabled tests get weaker tiers

Adding continue-on-error: true or if: false to an existing test job produces no removed lines, so workflow_reason returns T2-soft. Either addition can weaken the test job in .github/workflows/test.yml, yet the advisory report treats it like a new job rather than a change that always requires owner review. Check these additions before returning T2-soft, and add regression tests.

Fix in Cursor Fix in Claude Code

Comment on lines +316 to +319
def test_cli_on_a_git_repo(tmp_path):
def git(*args):
subprocess.run(["git", "-c", "user.name=t", "-c", "user.email=t@t", *args], cwd=tmp_path, check=True,
capture_output=True)

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 Process tests lack slow markers

test_cli_on_a_git_repo and the tests that call _pr_repo start Git without @pytest.mark.slow. The repository requires that marker, or a module-level equivalent, on every test that starts a process. Mark these tests before merging; the same pattern appears in the quoted-path and .gitattributes tests.

Context Used: CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Cursor Fix in Claude Code

A pass also needs the latest greptile-apps[bot] summary on this head
with Confidence Score at least 4/5, and no P0 or P1 inline comment from
that bot on this commit. Missing, unparseable, another author, or another
SHA is not a pass and still raises the tier one step, never past T2-hard.

The claude-code-mode#47 review (score 0/5, three P1 comments) is the
fixture and does not pass. The tier job fetches the check, the issue
comments and the review comments with GET. issues: read is the new scope.

Co-authored-by: Gabe <gpavanello@thefork.com>
@gabe4coding
gabe4coding merged commit 2fcc23e into main Oct 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant