Claude
Skills
Sign in
Back

x-ray

Included with Lifetime
$97 forever

Generates an x-ray.md pre-audit report covering overview, enhanced threat model (protocol-type profiling, git-weighted attack surfaces, temporal risk analysis, composability dependency mapping), invariants, integrations, docs quality, test analysis, and developer/git history. Triggers on 'x-ray', 'audit readiness', 'readiness report', 'pre-audit report', 'prep this protocol', 'protocol prep', 'summarize this protocol'.

Securityscripts

What this skill does


# X-Ray

Generate an `x-ray/` folder at the project root containing all output files. Pipeline: 3 steps, always sequential.

`$SKILL_DIR` = the directory containing this SKILL.md file. Resolve it from the path you loaded this skill from (e.g. if this file is at `/path/to/x-ray/SKILL.md`, then `$SKILL_DIR` = `/path/to/x-ray`).

## Progress tracking (MANDATORY)

Before doing anything else, call TodoWrite with these 3 todos (all `pending`):

1. `Phase 1: Enumerate & measure codebase`
2. `Phase 2: Read sources, classify entry points, synthesize invariants`
3. `Phase 3: Write x-ray report files`

Transitions (update via TodoWrite — never batch):
- Mark Phase 1 `in_progress` immediately, before running `enumerate.sh`.
- When Step 1's parallel batch returns, in ONE TodoWrite call mark Phase 1 `completed` and Phase 2 `in_progress`.
- When Step 2 (including 2b–2g) finishes, in ONE TodoWrite call mark Phase 2 `completed` and Phase 3 `in_progress`.
- After all Step 3 output files are written, mark Phase 3 `completed`.

Rule: exactly one todo is `in_progress` at any time. Status updates happen the moment a phase starts or ends.

## Step 1: Enumerate & Measure

If the user specifies a path, use it as project root. Otherwise use cwd. If no `.sol` files or `foundry.toml`/`hardhat.config.*` at root, check one level deep.

**Source directory detection**: Auto-detect from `foundry.toml` (`src = "..."`) or `hardhat.config.*`. If no config, try both `src/` and `contracts/`. Read `foundry.toml` first if present.

**Run enumeration** (single Bash call — includes output directory creation):
```bash
mkdir -p [project-root]/x-ray && bash $SKILL_DIR/scripts/enumerate.sh [project-root] [src-dir]
```

**Immediately after**, launch ALL of the following in a single message (parallel):

**0. Version check** (foreground):
- Read the local `VERSION` file from `$SKILL_DIR/VERSION`
- Bash `curl -sf https://raw.githubusercontent.com/pashov/skills/main/x-ray/VERSION`
- If the remote VERSION fetch succeeds and differs from local, print `⚠️ You are not using the latest version. Please upgrade for best security coverage. See https://github.com/pashov/skills`. If it fails, skip silently.

**1. Coverage** (`run_in_background: true`):

For Foundry:
```bash
cd [project-root] && forge coverage 2>&1 || (echo "RETRYING_WITH_IR_MINIMUM" && forge coverage --ir-minimum 2>&1)
```

For Hardhat:
```bash
cd [project-root] && npx hardhat coverage 2>&1
```

If toolchain is not installed (e.g., `forge: command not found`, `npx: command not found`, missing `node_modules/`), the coverage command will fail. This is expected — test *existence* is already captured by enumeration in the step above. Coverage failure does NOT mean tests are absent.

**2. Git security analysis + JSON read** (foreground, single Bash call):
```bash
cd [project-root] && python3 $SKILL_DIR/scripts/analyze_git_security.py --repo . --src-dir [src-dir] --json x-ray/git-security-analysis.json 2>&1 && cat x-ray/git-security-analysis.json
```

The JSON has 7 sections: `repo_shape`, `fix_candidates`, `dangerous_area_changes`, `late_changes`, `forked_deps`, `tech_debt`, `dev_patterns`.

**3. Preload reference files** (2 parallel Read calls — these must be in context before Step 2d/3a):
- `$SKILL_DIR/references/threats.md` — threat profiles, temporal threats, composability threats
- `$SKILL_DIR/references/templates.md` — output template, entry points template, architecture guide

**4. Spec/whitepaper detection** (1 Glob: `**/{whitepaper,spec,design,protocol,architecture,overview,README}*.{pdf,md}` excluding `node_modules/`, `lib/`, `x-ray/`, `test/`). Skip user-facing docs (tutorials, API refs, changelogs, contribution guides). Then apply size-aware handling:

- **Path A (≤5 docs, each ≤300 lines):** Include them as Read calls in Step 2's parallel message. Direct reads — no subagent needed.
- **Path B (>5 docs OR any doc >300 lines):** Launch a single subagent (`model: "sonnet"`) that reads ALL doc files and returns a structured extraction (max 200 lines). Subagent prompt:
  ```
  Read each doc file listed below. Extract ONLY security-relevant information into this format:
  Files: [list of doc file paths]

  Return this exact structure:
  ### Doc-Stated Global Invariants
  [Bullet list of every invariant, constraint, or guarantee the docs claim must hold globally across calls. Treated like NatSpec-stated invariants by Step 2g — routed directly to §2 / §3 / §4 of invariants.md by shape, NOT into §1 (Enforced Guards, which is per-call preconditions only).]
  ### Actor Definitions
  [Each actor/role with stated permissions and trust level]
  ### Trust Assumptions
  [What the protocol assumes about external systems, oracles, admins, users]
  ### Cross-System Flows
  [How value/data moves between contracts or external systems]
  ### Economic Properties
  [Fee structures, reward mechanisms, tokenomics, bounded parameters]
  ### Key Design Decisions
  [Explicit "we chose X over Y because Z" statements]

  Rules: Quote the source doc for each claim. Omit sections with no relevant content. Max 200 lines total.
  ```
  Include this subagent in Step 1's parallel message. Its output feeds Step 3 report writing.

For both paths, extract only: doc-stated global invariants, actor definitions, cross-system flows, trust assumptions, economic properties, key design decisions. Tag all spec-derived claims in the report with `(per spec)` so auditors know what is code-verified vs spec-stated. Doc-stated global invariants feed Step 2g's NatSpec routing step — they route to §2 / §3 / §4 of `invariants.md` by shape, NOT to §1 (Enforced Guards).

ALL calls (coverage, git analysis, reference reads, spec glob) MUST appear in the same message. Proceed to Step 2 without waiting for forge coverage.

## Step 2: Read Source Files + Entry Point Scan (SINGLE message, ALL tool calls parallel)

CRITICAL: Every tool call — Bash, Agent, Read, Grep — MUST be issued in ONE message so they run concurrently. This includes source file reads, the entry point grep scan, and any spec doc detected in Step 1 (they are all independent).

### Scope Filtering
- Skip interfaces: `interfaces/` dirs or filenames `I` + uppercase letter
- Skip vendored libs: Uniswap FullMath/TickMath, OZ copies
- When uncertain, include it but exclude from scope table

### Path A: ≤20 source files (direct reads)
One Read call per file. Do NOT read README, docs, or foundry.toml (already read in Step 1).

**Extract per file:** contract type & inheritance, roles & access control, value-holding state vars, external calls, fund flows, invariant comments, assert/require, backwards-compatibility indicators (see below), **delta writes** (per function: storage variables and the symbolic delta applied — e.g. `Δ(totalSupply) = +shares, Δ(balanceOf[msg.sender]) = +shares` — same-basic-block only, no cross-function inference; inherited helpers like OZ `_mint`/`_burn` may be resolved only when their effect on `balanceOf`/`_totalSupply` is semantically unambiguous), **guard predicates** (every `require`/`assert`/`if-revert` that references a storage variable, quoted verbatim with line number; skip guards that reference only function parameters), **enum/one-shot transitions** (every `require(state == X); ...; state = Y` pair, recorded as `X@Lx → Y@Ly` — include one-shot latches like `require(addr == address(0)); addr = concrete`).

### Path B: >20 source files (parallel subagents)

**Tier 1 — Small files (≤120 lines):** Batch into single Bash `cat` call.

**Tier 2 — Large files (>120 lines):** Group by subsystem. Launch **one subagent per subsystem** (`model: "sonnet"`, up to 5, max ~10 files each). Subagent prompt:
```
Read each file listed below and return a structured summary. Do NOT analyze — just extract facts.
Files: [list of file paths]
For EACH file, return this exact format:
### [filename]
- **Type**: contract | library | abstract
- **Inherits**: [parent contracts]
- **Imports**: [imported libraries/contracts]
- **Roles
Files: 8
Size: 224.8 KB
Complexity: 68/100
Category: Security

Related in Security