jfind

Canonical findings + evidence schema — Ed25519-signed, Merkle-rooted, deterministic JSON

v1.0.0
Linux

Quick Start

Install via jcli (recommended)

jcli install jfind

Sign-and-verify smoke test

jfind new-key --out /tmp/jfind.key             # fresh Ed25519 keypair
jfind sign --key /tmp/jfind.key finding.json   # sign in place
jfind verify finding.json                       # exit 0
sed -i 's/AWS/AwS/' finding.json
jfind verify finding.json                       # exit 3 — signature broken

What it does

jfind is the contract between every tool in the cli.johlem.net suite and the consulting deliverable layer (complymap, dossier, inciclass, roigen, tiberscope). It defines a single versioned shape — jfind/v1 for findings, jfind-bundle/v1 for engagement-scoped bundles — and ships the library + CLI to validate, sign, merge, filter, and report on it.

Subcommands

CommandWhat it does
jfind validate <file…>Schema + signature + custody chain. Warns on unknown vocabulary, exits 3 on integrity failure.
jfind verify <file…>Strict signature + chain check. Missing signature is a hard error (exit 3).
jfind sign --key <path> <file>Sign a finding or bundle in place. Bundles auto-sign every contained finding first, then sign the Merkle root.
jfind merge <bundle…> -o <path>Engagement-scoped, deterministic dedupe. Same inputs → byte-identical output.
jfind filter <bundle>Sub-bundle by --severity high.., --since, --tool, --category. Output on stdout.
jfind stats <bundle> [--format json]Counts by severity, category, tool, asset type.
jfind new-key --out <path>Fresh Ed25519 keypair. Private seed → file (mode 0600); public key → stdout.

Schema (jfind/v1)

{
  "schema": "jfind/v1",
  "finding_id": "<uuid-v4>",
  "tool": "credsweep",
  "tool_version": "1.2.2",
  "timestamp": "2026-06-10T12:00:00Z",
  "title": "AWS secret key committed to git history",
  "severity":   "info|low|medium|high|critical",
  "confidence": "low|medium|high|confirmed",
  "category":   "credential-exposure",
  "asset":      { "type": "file", "identifier": "...", "owner": "client:..." },
  "mitre":      { "tactics": ["TA0006"], "techniques": ["T1552.001"] },
  "controls":   [ { "framework": "DORA", "ref": "Art.9", "rts": "RTS 2024/1774 Art.11" } ],
  "evidence":   [ { "kind": "file", "path": "...", "sha256": "...", "blake3": "...", "bytes": 1234 } ],
  "remediation": "...",
  "raw":         { /* opaque, producer-specific */ },
  "provenance":  { "host": "...", "engagement_id": "ENG-...", "chain": [ ... ] },
  "signature":   { "alg": "ed25519", "pubkey": "<b64>", "sig": "<b64>" }
}

Exit codes

CodeMeaning
0Ok
1Reserved for downstream tools (e.g. complymap gap)
2Usage error (clap)
3Integrity / signature / parse failure

Touches / Produces / Gates

Build from source

cd tools/jfind/rust
cargo build --release
cargo test                                  # 3 unit + 8 integration tests

Toolchain pin: Rust 1.85.0. Dependencies are all in the suite-permitted allowlist (serde, clap, chrono, uuid, sha2, blake3, ed25519-dalek, base64, anyhow, thiserror).