dossier
Reporting layer — jfind / complymap inputs → johlem-branded HTML / Markdown / Document IR
v1.0.1Quick Start
Install via jcli
jcli install dossier
End-to-end pipeline (suite tools → complymap → dossier)
# 1. Collect findings from the suite — each emits jfind/v1 NDJSON.
credsweep --path . --output jfind > /tmp/a.ndjson
urlrecon --target client.example --output jfind > /tmp/b.ndjson
phishprobe --url 'https://suspect…' --output jfind > /tmp/c.ndjson
specter analyze /tmp/sample.bin --output jfind > /tmp/d.ndjson
avwatch check --path /etc --output jfind > /tmp/e.ndjson
cat /tmp/{a,b,c,d,e}.ndjson > /tmp/engagement.ndjson
# 2. Enrich each finding's controls[] via complymap.
complymap map /tmp/engagement.ndjson -f dora,nis2,iso27001,cssf -o /tmp/mapped.json
# 3. Render the client-ready report.
dossier render /tmp/mapped.json --template gap-assessment --signed -o /tmp/report.html
# 4. Convert to PDF with your tool of choice.
wkhtmltopdf /tmp/report.html /tmp/report.pdf
# or: weasyprint /tmp/report.html /tmp/report.pdf
# or: open report.html in a browser → File → Save as PDF
What it does
dossier is the reporting layer of the cli.johlem.net consulting layer. Whatever
shape the engagement collected (a single jfind finding, a bundle, an NDJSON stream, or a
pre-computed complymap-gap matrix), dossier walks it through a named template
and emits a johlem-branded HTML document, a CommonMark Markdown export, or a stable Document-IR
JSON intermediate.
- Three output shapes, one pass.
--format html(default) for the client-ready deliverable;--format mdfor email / chat / pandoc downstream;--format irfor operators who want to swap in their own renderer (ReportLab, Typst, LaTeX). - johlem-branded by default. The CSS lives in
src/render/style.rsand matches the consulting-layer spec exactly: A4 paper, 20mm margins, red#E8350Abrand colour for H1 rules and table headers, alternating row backgrounds, Courier 8pt code blocks, page-number footer, "Confidentiel" watermark. - Five templates. Three implemented in v1.0 (gap-assessment, pentest, incident); two stubs reserved for v1.1 (phishing-takedown, roi-summary).
- Chain of custody. Pass
--signedand the cover gets aBundle SHA-256:line carrying the hex digest of the input bytes. Cryptographic signing of the bundle itself is the job ofjfind sign; dossier only echoes the hash on the cover. - Offline-only. No network, no Anthropic API, no SaaS dependency. Templates are compiled in. Style is compiled in. Even fonts are system fallbacks.
Subcommands
| Command | What it does |
|---|---|
dossier render <input> -t <template> -F <fmt> | Render the input through a template; emit HTML, Markdown, or IR JSON. |
dossier toc | List the available templates with ready / stub status. |
dossier ir <input> -t <template> | Shortcut for render -F ir — emits just the Document-IR JSON. |
Templates
| Template | Status | Sections |
|---|---|---|
gap-assessment |
ready | cover · exec summary · scope · methodology · gap matrix table · per-finding cards · appendix (chain of custody) |
pentest |
ready | cover · exec summary · scope · methodology · per-finding cards · recommendations |
incident |
ready | cover · exec summary · DORA Art. 18 classification checklist · DORA Art. 19 notification clock (T+24h / T+72h / T+1m) · per-finding cards |
phishing-takedown |
stub (v1.1) | (depends on openclaw artefacts) |
roi-summary |
stub (v1.1) | (depends on roigen — Phase 3) |
Document IR (dossier-ir/v1)
The IR is the stable JSON intermediate between input parsing and rendering. Templates lower
their content into a flat sequence of Section → Block records that
any sane renderer (HTML, Markdown, future PDF, an operator's ReportLab pipeline) can walk in
one pass. The block taxonomy is small on purpose:
Paragraph — prose
Code — monospace block (Courier 8pt)
Callout — severity-stamped box
Table — header row + data rows
List — ordered or bulleted
Definitions — key / value pairs
Finding — severity, asset, controls, evidence, remediation
PageBreak — renderers that honour them place a break
Html — opaque HTML fragment (covers, special layouts)
Pipe dossier ir bundle.json | jq to inspect the IR before rendering — useful
when adding a new template or debugging field mapping.
Style spec (matches consulting-layer spec §3.2)
- A4 paper, 20mm margins
- Body text
#0a0a0a, grey#cccrules - H1 15pt bold + red HR
#E8350A· H2 13pt · H3 11pt - Code Courier 8pt on
#f5f5f5 - Tables:
#E8350Aheader + white text, alternating#f9f9f9/ white - Cover: red HR 3pt + 24pt title + 12pt subtitle + HR + 9pt meta + PageBreak
- Header / footer: grey HRs, title left, page number right, "Confidentiel" bottom-left
Exit codes
| Code | Meaning |
|---|---|
0 | Ok |
2 | Usage error (clap) |
3 | Runtime — bad input file, schema parse failure, unknown / stub template, unknown format |
Touches / Produces / Gates
- Touches (read-only): the input file you point it at.
- Touches (write): only the
-o <PATH>destination. - Produces: HTML (text/html), Markdown (text/markdown), or Document-IR JSON.
- Gates: none. dossier is fully offline — no network, no Anthropic API.
Roadmap (v1.1+)
- Native Rust PDF output (likely
genpdforprintpdf) so the operator can produce the PDF deliverable without piping through wkhtmltopdf / weasyprint. phishing-takedowntemplate — consumes openclaw artefacts.roi-summarytemplate — consumesroigen(Phase 3) Register-of-Information output.- Embedded severity / coverage charts (currently text tables only).
- Per-control "detailed evidence" sub-section under each gap matrix row.
Build from source
cd tools/dossier/rust
cargo build --release # ./target/release/dossier
cargo test # 12 integration tests
Toolchain pin: Rust 1.85.0. Dependencies: clap, serde,
serde_json, chrono, sha2, hex,
anyhow, thiserror, and the in-repo jfind +
complymap library crates.
Compliance crosswalk
This table lists controls where dossier's output
may form part of the evidence set presented to an assessor. It does not
claim dossier alone satisfies any framework — every
control still requires assessor judgment and typically evidence from other sources.
Schema: compliance-crosswalk/v1 ·
Machine-readable: tools/dossier/compliance.json
ISO27001 — ISO/IEC 27001:2022
| Ref | Name | How | Coverage |
|---|---|---|---|
A.5.24 |
Information security incident management planning and preparation | incident template renders IR playbook artefacts as HTML / Markdown / dossier-ir. | supports |
A.5.35 |
Independent review of information security | pentest template renders external-assessment deliverables. | supports |
A.8.34 |
Protection of information systems during audit and testing | pentest template includes rules-of-engagement + engagement-window sections. | supports |
DORA — Digital Operational Resilience Act
| Ref | Name | How | Coverage |
|---|---|---|---|
Art. 6 |
ICT risk-management framework | gap-assessment template is fed by complymap's gap matrix. | supports |
Art. 24 |
Advanced testing (TLPT) | pentest template consumes tiberscope brief + plan artefacts. | supports |
Release artefacts & provenance
Every signed release ships with checksum + signature sidecars plus a CycloneDX SBOM. Enterprise procurement can pin third-party components without unpacking the binary.
-
manifest.json— pinned SHA-256 +.sigURL + SBOM URL per platform -
johlem-release.pub— Ed25519 public key used bysignify -V(fingerprint:4532510f…6748, pinned injcli verify) CHANGELOG.md— semver-tagged release notes- Security contact:
security@johlem.net