# How to Verify the Integrity of Case Graph Data in reverse-skill

> Verify case graph data integrity in reverse-skill. Run review_case.py to parse evidence, validate references, and confirm SHA-256 hashes match disk files.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: how-to-guide
- Published: 2026-08-30

---

**TLDR:** Run `python3 skills/case-review/scripts/review_case.py work/<case> --verify-hashes` to parse Markdown evidence files, validate cross-references, and confirm that recorded SHA-256 digests match the actual artifact files on disk.

The reverse-skill framework stores forensic investigations as structured Markdown collections under `work/<case>`, connecting evidence, findings, and timelines into a traceability graph. To ensure this graph remains internally consistent and that binary artifacts have not been corrupted or tampered with, the repository provides a dedicated verification CLI located at [`skills/case-review/scripts/review_case.py`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/case-review/scripts/review_case.py).

## Understanding the Case Graph Structure

A reverse-skill case is not a single file but a directory tree containing ancillary documents and evidence. The reviewer expects to find files such as [`workitems.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/workitems.md), [`timeline.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/timeline.md), [`scope.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/scope.md), plus individual evidence records under `evidence/*.md` and report sections under `report/**/*.md`. Together, these Markdown files form a graph where nodes (evidence items) link to work items, timeline events, and final report sections.

## The Three-Stage Verification Pipeline

The [`review_case.py`](https://github.com/zhaoxuya520/reverse-skill/blob/main/review_case.py) script implements a three-step validation pipeline defined in the source code between lines 36 and 158.

### Parse and Validate Markdown Files

In the first stage, the tool uses regular-expression helpers such as `EVIDENCE_ID` and `FIELD_LINE` (defined in the parsing functions around lines 79-158) to extract IDs and fields from each Markdown file. It checks for required metadata fields, validates that field values belong to allowed sets, and ensures that cross-references between files—for example, an evidence ID cited in a work item—actually exist.

### Verify Artifact Hashes (SHA-256 Integrity)

When invoked with `--verify-hashes`, the script enters the `verify_artifact` function (lines 67-84). For every evidence record containing a `content_hash` (SHA-256) and an `artifact_path`, the tool computes the real digest of the referenced file and compares it to the recorded hash. Any mismatch is flagged as an integrity error, indicating potential corruption or modification since the evidence was logged.

### Build Traceability and Detect Orphaned Evidence

The `build_traceability` function (lines 36-48) constructs a dictionary mapping each `evidence_id` to the set of work items, timeline events, and report references that cite it. After mapping the entire case, the reviewer warns about any evidence that remains unreferenced, ensuring that every piece of data contributes to the investigation narrative.

## Running the Case Review CLI

The entry point and argument handling are defined in the `main` function (lines 40-45). You can invoke the reviewer from the repository root using Python 3.

Verify a case with full hash checking and strict failure mode:

```bash
python3 skills/case-review/scripts/review_case.py work/mycase \
    --verify-hashes --strict --format markdown

```

Generate machine-readable JSON output for CI pipelines:

```bash
python3 skills/case-review/scripts/review_case.py work/mycase \
    --verify-hashes --strict --format json > review.json

```

Before running the reviewer, ensure your evidence includes hash metadata by using the helper script with the `-ArtifactPath` parameter:

```bash
powershell -File skills/scripts/append-evidence.ps1 -CaseRoot work/mycase `
    -Id E-001 -Title "Suspicious DLL" -ReproCommand "dir /s suspicious.dll" `
    -ArtifactPath work/mycase/evidence/files/suspicious.dll \
    -Severity high -Status observed

```

This PowerShell command creates a new evidence markdown file that records both the relative `artifact_path` and the SHA-256 `content_hash` of the binary, which the reviewer will later verify.

## Command-Line Options Explained

The CLI supports several flags that control verification depth:

- **`--verify-hashes`** – Enables the cryptographic integrity check described in `verify_artifact`. Without this flag, the reviewer skips SHA-256 comparison.
- **`--strict`** – Upgrades all warnings (such as unreferenced evidence) to fatal errors. Use this in CI pipelines to enforce policy compliance.
- **`--format markdown|json`** – Selects human-readable Markdown output for terminal review or JSON for downstream automation.

## Interpreting Review Results

When the reviewer completes its analysis, it emits a report listing `error` or `warning` entries. Errors include hash mismatches, missing required fields, or broken cross-references. Warnings typically indicate orphaned evidence that is not cited by any work item or report. When all errors disappear and the status reads `PASS`, the case graph is deemed integral and ready for hand-off or further automation.

## Summary

- **Case Structure:** reverse-skill stores investigations as Markdown graphs under `work/<case>`, linking evidence, findings, and timelines.
- **Verification Tool:** The [`skills/case-review/scripts/review_case.py`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/case-review/scripts/review_case.py) CLI parses files, validates references, and checks SHA-256 hashes.
- **Key Functions:** `verify_artifact` (lines 67-84) handles hash verification, while `build_traceability` (lines 36-48) maps evidence citations.
- **Workflow:** Use `append-evidence.ps1` with `-ArtifactPath` to record hashes, then run the reviewer with `--verify-hashes` and optionally `--strict` for CI integration.
- **Success Criteria:** A `PASS` status with zero errors confirms that the case graph is logically consistent and cryptographically verified.

## Frequently Asked Questions

### What specific files does the case reviewer validate?

The reviewer scans ancillary files including [`workitems.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/workitems.md), [`timeline.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/timeline.md), and [`scope.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/scope.md), as well as individual evidence records under `evidence/*.md` and report sections under `report/**/*.md`. It extracts metadata using regex patterns like `EVIDENCE_ID` and `FIELD_LINE` to ensure required fields are present and correctly formatted.

### How does the SHA-256 hash verification work?

When you provide the `--verify-hashes` flag, the script executes the `verify_artifact` function. For each evidence record containing both a `content_hash` and an `artifact_path`, the tool reads the referenced file from disk, computes its SHA-256 digest using Python's `hashlib`, and compares the result to the stored hash. Any discrepancy is reported as an integrity error.

### What is the difference between standard mode and `--strict` mode?

Standard mode reports broken cross-references, missing fields, and unreferenced evidence as warnings while still returning a success exit code if no hard errors exist. The `--strict` flag treats every warning (including orphaned evidence) as a fatal error, causing the script to exit with a non-zero status. This behavior is essential for CI/CD pipelines that must fail builds when case policy is violated.

### Can I verify a single artifact hash without running the full reviewer?

Yes. While the recommended workflow uses the full reviewer, you can manually check an individual file's hash using Python's standard library to compare against the `content_hash` value stored in the corresponding evidence Markdown file:

```bash
python3 -c "
import hashlib, pathlib
p = pathlib.Path('work/mycase/evidence/files/suspicious.dll')
print(hashlib.sha256(p.read_bytes()).hexdigest())
"

```