XingLo SkillSearch

DFIR 调查报告与 PDF 生成

用于调查流水线的最终交付阶段,将 case_context.md、各资产分析报告和全局关联报告组织成统一的案件报告。报告结构包含执行摘要、调查范围、分析过程、关键发现、结论、验证状态、建议和附件,并保留严重度、证据标签和人工确认信息;生成过程中会执行 evidence verification,确保正文引用能够对应真实 export 文件。随后调用内置 Markdown→HTML→WeasyPrint 脚本生成样式化 PDF,支持告警块、严重度标识、编号章节和代码区,同时保持离线字体和无远程资源依赖,便于在隔离的取证环境中直接形成客户交付件。

在 AI 中使用此 Skill将本页链接复制给 AI,即可让 AI 获取完整 Skill 内容并按此执行
安全提示: 本站 Skill 均经 ChatGPT 最新模型扫描,未发现恶意脚本及危险指令、未检出已知恶意行为特征,但不保证绝对安全,使用即表示接受此风险

Skill 文件

版本 20260601 · dc3f1eeab1961e7f0d39681bd161cdba

references/
skills/
case-evidence-verify/
scripts/
SKILL.md
---
name: case-report
description: Assemble DFIR analysis and correlation outputs into a final Markdown report, verify evidence citations, and render PDF output.
---


## XingLo Standalone Package Notes

The report renderer is bundled as `scripts/generate_pdf_report.py`. Evidence-verification instructions are bundled under `references/skills/case-evidence-verify/guide.md`; when `/case-evidence-verify` is not separately installed, follow that local guide at the verification step.

# Skill: case-report — Phase 4 Final Report (verify → write → PDF)

## Overview

Final phase of the investigation pipeline. Assembles the client-facing report from the per-asset
analyses and the correlation report, verifies every evidence citation, and renders the styled PDF.
Invoked standalone with `/case-report` (after `/case-correlate`) or as the last step of `/case-investigate`.

**Inputs:** `./context/case_context.md`, `./analysis/{CASE_ID}-global-correlation-report.md`,
all `./analysis/{CASE_ID}-{ASSET_ID}-analysis-report.md`.
**Outputs:** `./reports/{CASE_ID}-final-report.md` (+ `.pdf`), `./analysis/{CASE_ID}-evidence-verification.md`.

---

## Role & Operating Rules

**Role:** Professional DFIR report writer operating the SANS SIFT Workstation. Expert in technical
DFIR reporting, executive communication, report structure, ATT&CK-based incident narrative, and
uncertainty handling. You run the reporting phase only — you assemble the client-facing report from
already-validated inputs; you do not parse, analyze, or correlate.

**Rules:**

- MUST source the report ONLY from the accepted incident context (`./context/case_context.md`), the
  per-asset analysis reports, and the global correlation report. MUST NOT invent evidence, findings,
  or conclusions absent from those inputs, and MUST NOT re-derive findings from raw `./export/`
  (assemble, don't re-investigate).
- MUST NOT make legal determinations or adjudicate liability/criminality. Report the technical facts
  and their support; adjudication is human-only. Attribution stops at the account/host level (see the
  global no-person-attribution rule in `CLAUDE.md`); this report is always a DRAFT until a named
  examiner signs off.
- MUST reason through the cross-asset narrative before drafting the Executive Summary and Analysis
  sections (they synthesize across all annexes and the global correlation report). Use extended
  thinking as the scratchpad; never compress multi-asset reasoning into a bare statement.
- MUST write the report itself ONLY under `./reports/`. The only writes to `./analysis/` are made by
  the embedded `/case-evidence-verify` step (Step 2): the evidence-verification verdict file, plus the
  regenerated Evidence Index and findings-ledger `evidence[]` projections (deterministic projections of
  each asset's `evidence.jsonl` registry — never the analytic body of a report). Read-only on `./export/`,
  `./audit/`, `sources/`, and the analytic content of the analysis reports (consistent with the Notes below).

---

## Step 1 — Write the final report

Set the phase marker first (keeps `./export` read-only):

```bash
CASE_ROOT="$(pwd)"; mkdir -p "$CASE_ROOT/analysis" "$CASE_ROOT/audit"
printf 'report\n' > "$CASE_ROOT/audit/.dfir_phase"
```

Write `./reports/{CASE_ID}-final-report.md`. **The pipeline always produces a DRAFT.** Begin the file
with this status/sign-off block verbatim (leave `author_of_record`, `human_validated_by`, `validated_at`
EMPTY — only a human fills them; the PDF generator watermarks the report until `author_of_record` is set):

```markdown
> [!WARNING] STATUS: DRAFT — AI-ASSISTED, NOT YET VALIDATED. AI assists analysis; a human examiner is
> the final authority. This report is not validated and is not court-ready until a named examiner has
> independently verified the findings and signed below.

| Sign-off | Value |
|----------|-------|
| author_of_record | |
| human_validated_by | |
| validated_at (UTC) | |
```

Then the sections:

### Executive Summary
- Non-technical audience (CISO, legal, executives); max 1 page
- What happened, confirmed impact, urgency and current status; plain language, no jargon

### Introduction
- Brief description of the incident as reported
- Investigation objectives and the Incident Window
- Sources analyzed: every asset_id, hostname, and evidence type

### Analysis
- Root cause (initial access vector, first evidence)
- Attack narrative in chronological order, each event tied to specific evidence (artifact type,
  timestamp, asset)
- Only the most significant technical details; avoid raw command output
- Exfiltration: what data was accessed or taken, where evidence supports it

### Conclusions
- Bullet points; confirmed facts only — no speculation

### Validation Status
- State plainly that findings are AI-assisted and **pending independent human validation**.
- Report the count of findings whose `human_validated_by` is still empty (from the findings ledgers,
  surfaced by `/case-evidence-verify` in Step 2). Until a human validates and signs off, every finding
  here is a lead pending verification, not an adjudicated conclusion.

### Recommendations
- Immediate containment, medium-term hardening, long-term process improvements

### Annexes
- One annex per asset: embed the full `{CASE_ID}-{ASSET_ID}-analysis-report.md`
- Label each: `Annex A — {ASSET_ID} ({HOSTNAME}) Analysis`

The final report references asset-level evidence by annex; `EV-<asset>-NNNNN` tags are an analysis-layer
construct and are not renumbered here.

### Markdown styling conventions (rendered by the PDF generator)

Write plain markdown; the generator maps these conventions to styled components automatically:

- **Severity badges** — a table cell whose entire content is `CRITICAL` / `HIGH` / `MEDIUM` /
  `LOW` / `INFO` / `BENIGN` renders as a colored badge. Put the bare word in its own column.
- **Alert callouts** — a blockquote becomes an alert box. Lead with `[!WARNING]`, `[!CRITICAL]`,
  `[!NOTE]`, or `[!TIP]` to set the color and title, e.g. `> [!WARNING] Security log cleared at …`.
- **Code blocks** — fenced code (```) renders in the dark monospace box.
- **Section numbers** — every `##` heading is auto-numbered on the cover-styled heading bar.
- Metric-card / process-tree / timeline components are available only via raw HTML embedded in the
  markdown (markdown passes HTML through) — use them sparingly if at all.

---

## Step 2 — Evidence citation verification (Phase 4.5) — `/case-evidence-verify`

Before generating the PDF, run **`/case-evidence-verify`**. It collects every `[EV-<asset>-NNNNN]` tag
cited in the analysis reports, confirms each is defined in an asset's `evidence.jsonl` registry and that
the registry's file exists, regenerates each report's Evidence Index from that registry, and writes
`./analysis/{CASE_ID}-evidence-verification.md` with a PASS/FAIL verdict. On `FAIL`, surface the warning
and the path; do not silently ship an unverifiable report:

```
[WARN] Evidence verification FAILED — N citations unverifiable.
       See ./analysis/{CASE_ID}-evidence-verification.md
```

---

## Step 3 — PDF generation

Render the finished Markdown to a styled PDF. Pass case metadata so the cover page is correct
(otherwise the case id is derived from the filename and the client is blank):

```bash
CASE_ID="{CASE_ID}"
python3 -c "import weasyprint, markdown" 2>/dev/null && \
python3 ~/.claude/skills/case-report/scripts/generate_pdf_report.py \
  "./reports/${CASE_ID}-final-report.md" \
  "./reports/${CASE_ID}-final-report.pdf" \
  --case-id "$CASE_ID" \
  --client "{CLIENT_NAME}"
```

Only runs if both deps are present (`weasyprint`, `markdown`). The generator carries no baked-in
content — it renders only what is in the Markdown file. If deps are missing, deliver the Markdown
report and note the PDF was skipped.

**Draft-not-signed (code wall):** the generator reads the sign-off block. If `author_of_record` is
empty it stamps a diagonal **DRAFT — UNVALIDATED** watermark across every page and marks the cover
classification accordingly — the pipeline cannot emit a clean "final" PDF on its own. Only after a
human examiner fills `author_of_record` (and re-runs this step) does the watermark disappear. The
examiner's name comes from `Lead Examiner` in `context/case_context.md`.

---

## Notes

- Writes the report only to `reports/`. The only `analysis/` writes are the `/case-evidence-verify`
  outputs in Step 2 (verdict file + regenerated Evidence Index / findings-ledger projections); the
  analytic body of every analysis report stays read-only, as do `export/` and the rest of the inputs.
- This is the end of the pipeline. `/case-investigate` stops here.