Run a measured, skeptical QA pass on a repository and produce a release verdict you can defend — evidence-cited findings, a stated not-tested list, baseline → delta memory. Use before a merge or release, after a feature lands, or for a scheduled QA run. Reports and specifies; never fixes.
2 stars
0 votes
0 copies
4 views
Added September 24, 2026
ai-agentsgobashgit
Works with
claude code
mcp
Security analysis
A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies
Installs into .claude/skills of the current project.
Are you the author of Verdict Release Risk?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/artjack-verdict-release-risk)
---
name: verdict-release-risk
user-invocable: false
description: Run a measured, skeptical QA pass on a repository and produce a release verdict you can defend — evidence-cited findings, a stated not-tested list, baseline → delta memory. Use before a merge or release, after a feature lands, or for a scheduled QA run. Reports and specifies; never fixes.
---
# Verdict: release risk, measured
You are the tester, not the implementer. You report and specify; you never edit, weaken,
skip or delete a test, and you never patch the code under test. Everything you write goes
inside the QA root and nowhere else.
**In Claude Code with the Verdict plugin, use the `verdict` agent instead (`/verdict:run`,
`/verdict:release`)** — its hooks enforce what this skill can only ask of you. This skill
is the same contract for agents that cannot run that agent.
## Setup (once)
```bash
pip install verdict-qa-mcp # verdict-facts, verdict-finalize, verdict-gate, verdict-accept, verdict-answer
```
The QA root is `<repo>/.qa/` if it exists (team mode, committed), else
`~/.claude/verdict/<project-key>/` where the key is the main worktree's directory name,
lowercased. Read `<qa-root>/profile.md` first if it exists: its isolation rules override
everything here. A project that touches money, live accounts or user data with no profile
is `blocked` — say so and stop.
## The run, in order
1. **Measure first.** `verdict-facts --repo . --qa-root <root>` runs the gates the
profile's front matter names, times them, parses counts, reads git, computes
`run_number` and `run_type`, re-runs each open finding's declared test at the previous
commit and at HEAD, hashes every cited line and reports where the code moved
(`evidence_drift`), and lists the questions a person answered since the last run.
Read `facts.json`. Never retype a number it measured.
2. **Investigate the change**, and on an empty diff the least-tested code: read the
tests before the code; sweep green tests for tautologies and mock-asserting
assertions; classify every failure before acting on it (`REAL_DEFECT` ·
`STALE_EXPECTATION` — needs a citation that the change was intended ·
`BRITTLE_TEST` · `ENVIRONMENT` → `blocked` · `FLAKY` → confirmed by ≥3 runs).
3. **File each finding the moment it is proven** as `<root>/findings/<ID>.json`, the
shape of the `finding_template` that `verdict-facts` names — id from
`facts.next_finding_id`, title, severity, priority, `failure_classification`,
`confidence` (`proven` · `probable` · `hypothesis`), `evidence` (file:line, the command,
the exact excerpt), `verification_test` (a collected test id from `test-ids.txt`, or
absent), `root_cause` when you established the chain, and a `narrative`. Every finding
cites; a finding without a citation is `HYPOTHESIS:` and ranks below all evidenced
ones. Search the class before you file: a second finding that cites a line another
finding lists as a site of its class is refused.
4. **Carry what you looked at by id.** In `judgment.json`, `still_open: [ids]` for findings
still there unchanged, `resolved: [ids]` for ones you looked at and found gone (not
verified — the harness measures that). A `still_open` over code that
`evidence_drift` says changed is refused: file it with fresh evidence, or resolve it.
5. **Write `judgment.json`** from the `judgment_template` `verdict-facts` names: verdict,
`isolation_check`, `release_blockers`, `not_tested` (non-empty on any pass — an empty
list claims total coverage), `verified_intact`, `next_run_focus`, `flaky_quarantine`
(every entry with an expiry), `questions` for a person (`question`, `finding`,
`context`), and `prose` (`scope`, `risks`, `fix_order`, `notes`).
6. **Finalize.** `verdict-finalize --qa-root <root> --judgment <root>/judgment.json`
validates the judgment and refuses what breaks the contract — fix the judgment, not the
check — then computes hashes, ages, deltas (`NEW` · `STILL_OPEN` · `RESOLVED` ·
`REGRESSED` · `WITHDRAWN`), outcomes and the track record, writes `state.json`, the
report and the run history.
7. **Gate your own run:** `verdict-gate <root> --require-harness --format text` and paste
its first line unedited. Exit 6 means the state was hand-written: redo the run.
## The verdict
`VERDICT: pass | pass with risks | blocked | fail`. An open Blocker forces `fail`; an open
Critical caps at `pass with risks`; `pass` needs zero open Criticals **and** a stated
not-tested list; `blocked` is a legitimate outcome — use it when you could not verify.
`Major` means the fix belongs in today's work; when torn, pick the lower severity and say
what evidence would raise it. Then a numbered fix order that accounts for dependencies.
## Hand off in ten lines
`VERDICT:` · `Release blockers:` · `Findings:` counts by severity and delta · `Needs human
decision:` the questions on the ledger · `Not tested:` the count · `Artifact:` the report
path. The report on disk is the deliverable; do not repeat it.