---
title: "Audit a repo, service, or release"
description: "How to audit a repo, service, or release with the same cards: scope, read order, missing controls, accepted risk, and the report shape."
canonical: "https://goodcodereview.com/audit"
updated: "2026-11-06"
---

# Audit a repo, service, or release

An audit is a review of a whole input, with a scope and a report. It uses the same cards and the same verdicts. It adds no criteria and certifies nothing: it is not a SOC 2, ISO 27001, or other compliance attestation.

- Scope: run the entry level, then the stable `function`, `module`, `service`, and `system` cards whose `applies_when` holds for the code you read. Skip `change` and `incident` cards unless asked, and `production` cards unless the input includes a release or launch. Also check the draft cards in [the draft cards](https://goodcodereview.com/.well-known/agent-skills/good-code-review/references/drafts.md), and the pack for each language present, and report their `FAIL`s under Draft findings. For a test suite, scope by the `testing` concern. Name the levels, the concerns, and the card-set version on the verdict line: the `metadata.version` in `SKILL.md`, plus the commit from `git -C <skill folder> rev-parse --short HEAD` when you have a checkout.
- Read order when the input is too large: entry points, then code that touches the network, a process, the file system, or a secret, then auth, then the build and release path, then the tests. Name the paths you read and list what you did not examine. A sampled audit cannot prove that a problem is absent.
- A missing control is a `FAIL` of the card that requires it, with evidence `absent in <paths>`: name the search or the command you ran over the whole input, not only the files you sampled. A platform setting, such as branch protection or secret scanning, is evidence when you quote the command or API output. If every `block` `FAIL` is a missing process control, say so on the verdict line.
- Tag each finding by source: `vetted`, `pack`, `draft`, or `no-card`. Only a stable card counts in the ledger, and a stable pack card counts as `pack`; a draft pack card is `draft`. A real defect that no card covers is `no-card`: list it under Product bugs, outside the ledger.
- Severity is the card's and never changes. When the input makes a `FAIL` smaller than the card assumes, such as a retry rule on a single-user CLI, add `impact: low` and the reason on that line.
- Accepted risk: write `accepted by <owner> until <date>` on the line. The `FAIL` stays in the report and in the counts.
- A missing best practice with no affected user, resource, or boundary is a hardening note, not a `FAIL`. Name who or what is harmed and the line that harms them, or keep it out of the ledger.
- Say plainly when the audit is partial: sampled, scoped to some paths or levels, or cut short by a budget. After a sample, never write that the input is clean or fully covered. Write what you read and what you did not.
- Adversarial mode, when asked: after the ledger, give each `FAIL` to a fresh reader that did not write it and has only the code and the card. The reader tries to refute the finding. Keep a `FAIL` only when the reader cannot refute it from a line it read, and require a refutation to cite code. Report the dropped findings as a count. Use a different model for the reader when you can, because one model tends to agree with its own work.
- Empirical mode, when asked: for each `FAIL` or `PASS` whose card names a tool gate or another check you can run, run it on the input and quote its output or exit code as the evidence. Mark a finding you could not run `could not check` and give the reason. Run code from the input only in a sandbox with no network.
- End with counts by severity and by source, Proposed changes (group findings into changes, each sized S, M, or L), Product bugs, Dropped candidates (a count), Could not check, and Not examined. To re-test, repeat the audit on the same input and name the first run's card-set version.
