Skip to content
Development
Command

/audit

Audit an existing codebase. Detects stack, finds gaps, creates tasks, generates PROJECT.md.

From plugin
7044 skills69 agents44 commands
shell
$ npx -y skills add avelikiy/great_cto --agent claude-code

Ships with great-cto. Installing the plugin gets this command.

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/audit

Context preview

What this command does when you run it.

Audit an existing codebase. Detects stack, finds gaps, creates tasks, generates PROJECT.md.

Command definition

audit.md
description: "Audit an existing codebase. Detects stack, finds gaps, creates tasks, generates PROJECT.md."
argument-hint: "[optional: 'eval' | 'lint' | focus area, e.g. 'focus on security']"
user-invocable: true
allowed-tools: Read, Write, Bash, Glob, Grep, Agent
model: sonnet

You are the Great CTO audit command for **existing projects**.

Fast by default (v1.0.43+): phases 1-4 run in parallel via sub-agents + CVE scan cached 24h. Typical runtime ~1-1.5 min on medium projects. No separate refresh mode — just re-run `/audit`.

**Findings discipline (v1.0.106).** Every finding in the audit report carries **severity** (low / med / high / critical) **+ one-line evidence with file:line or a concrete metric**. Adjectives without numbers are not findings; handwavy claims without file references are guesses, not findings. See `skills/great_cto/prose-style.md` (RULE-H citation, RULE-08 claim calibration, RULE-03 concrete vs abstract).

Action: `eval` — run eval harness

If argument is `eval` (i.e. `/audit eval`):

EVAL_DIR="tests/eval"
ls "$EVAL_DIR"/EVAL-*.md 2>/dev/null | sort || echo "NO_EVALS"

If no eval files found:

No eval cases in tests/eval/.
Run /audit to create initial eval cases, or see tests/eval/ for the format.

If eval files exist — for each `EVAL-*.md`: 1. Read the file — extract `## Assertions` bash block 2. Run each assertion 3. Collect PASS / FAIL / WARN per assertion 4. Report summary:

/audit eval — Eval Harness Results

EVAL-001 CRUD endpoint:       PASS (3/3)
EVAL-002 Auth service:        PASS (4/4)
EVAL-003 Discovery guard:     WARN (manual verification needed)
EVAL-004 Hotfix nano:         PASS (2/2)
EVAL-005 Security block:      FAIL (1/3) — CSO report missing

Score: 4/5 passing | 1 failing | 1 manual

FAILURES:
  EVAL-005: docs/security/CSO-*.md not found
  → Run the auth-service eval scenario first to generate the artifact

MANUAL CHECKS:
  EVAL-003: discovery guard behavior requires live /start run

Exit after eval report. Do NOT proceed with normal audit.

---

Action: `lint` — scan artefacts against anti-pattern blocklist

If argument is `lint` (i.e. `/audit lint`):

Scans `docs/architecture/`, `docs/threat-models/`, `docs/releases/SBOM-*.json`, `docs/postmortems/`, `.great_cto/verdicts/` against rules in `skills/great_cto/references/anti-patterns.md`. Advisory findings, not blocking. Respects `<!-- anti-pattern-waiver: <rule-id> reason:<why> -->` lines.

python3 - <<'PY' 2>/dev/null
import os, re, glob, json
from pathlib import Path

FINDINGS = []

def flag(rule, path, line_no, snippet):
    FINDINGS.append((rule, path, line_no, snippet.strip()[:120]))

def has_waiver(line, rule):
    return f"anti-pattern-waiver: {rule}" in line

def scan_file(path, rules):
    try:
        lines = Path(path).read_text(encoding='utf-8', errors='ignore').splitlines()
    except Exception: return
    text = "\n".join(lines)
    for rule_id, pattern, needs_section, section_pattern in rules:
        if needs_section:
            # Structural rule: section MUST exist
            if not re.search(section_pattern, text, re.I | re.M):
                flag(rule_id, path, 0, f"missing section: {section_pattern}")
            continue
        for i, line in enumerate(lines, 1):
            if re.search(pattern, line, re.I) and not has_waiver(line, rule_id):
                flag(rule_id, path, i, line)

# ARCH rules
ARCH_RULES = [
    ("A1", None, True,  r"^##\s+(Non-goals?|Out of scope)"),
    ("A2", r"\b(scalable|reliable|performant|robust|cutting-edge|best-in-class|world-class)\b", False, None),
    ("A3", r"\b(a database|a queue|a cache|some storage|some database)\b", False, None),
    ("A4", r"(monitoring|logging|tracing|observability).{0,30}(later|phase 2|TODO|future)", False, None),
    ("A6", r"\b(rewrite|greenfield)\b", False, None),  # pair with missing Migration manually
]
for p in glob.glob("docs/architecture/ARCH-*.md"):
    scan_file(p, ARCH_RULES)
    # A8: Security section exists but too thin
    try:
        t = Path(p).read_text()
        m = re.search(r"^##\s+Security\s*\n(.*?)(?=^##|\Z)", t, re.M|re.S)
        if m and len(m.group(1).strip().splitlines()) < 3:
            flag("A8", p, 0, "Security section is < 3 lines")
    except: pass

# Threat model rules
TM_RULES = [
    ("T1", r"mitigation.*:.*\b(validation|sanitis[ae]tion)\s*$", False, None),
    ("T3", None, True, r"^##\s+Accepted risks?"),
    ("T4", None, True, r"(mermaid|```mermaid|flowchart|graph\s+(LR|TD))"),
]
for p in glob.glob("docs/threat-models/TM-*.md"):
    scan_file(p, TM_RULES)

# SBOM rules (JSON)
for p in glob.glob("docs/releases/SBOM-*.json"):
    try:
        data = json.loads(Path(p).read_text())
        comps = data.get("components", [])
        if len(comps) < 5:
            flag("S1", p, 0, f"only {len(comps)} components — tool may not have run")
        if comps and not any("hashes" in c for c in comps[:10]):
            flag("S2", p, 0, "no integrity hashes on components")
        range_versions = [c for c in comps if re.search(r"[\^~>*]", str(c.get("version","")))]
        if range_versions:
            flag("S3", p, 0, f"{len(range_versions)} components with version ranges (should be pinned)")
    except Exception: pass

# PM rules
PM_RULES = [
    ("P1", r"root cause.{0,40}\b(human error|operator (mistake|error)|user error)\b", False, None),
]
for p in glob.glob("docs/postmortems/PM-*.md"):
    scan_file(p, PM_RULES)

# PM-SEC must have Notification log
for p in glob.glob("docs/postmortems/PM-SEC-*.md"):
    t = Path(p).read_text(errors='ignore')
    if not re.search(r"^##\s+Notification log", t, re.M|re.I):
        flag("P6", p, 0, "PM-SEC missing Notification log section")

# Cross-doc link rot (L1–L4) — scan all docs/**/*.md
import time
ALL_DOCS = glob.glob("docs/**/*.md", recursive=True)
DOC_SET = set(os.path.abspath(p) for p in ALL_DOCS)
# Build inline-ref inventory for L2 (name -> absolute path)
ARTEFACT_INDEX = {}
for p in ALL_DO
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withgreat-cto

Don't buy software. Get the work done. GreatCTO ships AI autopilots that run a whole business function — medical coding, legal docs, procurement, accounting, IT, tax — from intake to outcome. A qualified human signs only the judgment calls. Live connectors, built-in compliance.

Get the whole plugin, auto-invoked
Stats
70
Stars
0
Views
12
Forks
Active
Maintenance
JavaScript
Language
MIT
License
54m ago
Last commit
4mo ago
Created

Repo: avelikiy/great_cto