| name | investigation-workflow |
| description | REQUIRED when the user says "start investigation", "investigate", "analyze case", "Read case-templates/manifest.json", references a manifest.json, or provides a SAVVYDFIR-MCP case_id. Defines the 5-phase DFIR methodology from evidence mounting through report generation, with mandatory tools, decision points, and quality gates that the report coverage gate enforces. |
| allowed-tools | ["Bash"] |
Investigation Workflow - 5-Phase DFIR Methodology
This workflow is an investigation loop, not a checklist. The parent agent keeps the case hypothesis, decides pivots, writes the narrative, and analyzes large artifacts inline using the heuristic slice delivered in each tool response. Durable CSV/storage handles keep raw data out of context.
MANDATORY TOOLS (gate-enforced - report will not finalize without these)
The evaluate_ir_coverage_gate enforces tool coverage before generate_report. Enforcement strength varies by tool:
| Tool | Enforcement | Why it's mandatory | Common skip-pattern that we explicitly reject |
|---|
list_processes, scan_processes, scan_network | Presence + opportunistic success (failed retry triggers re-run) | Universal memory baseline | Skipping any breaks DKOM detection |
extract_mft_timeline, summarize_evtx, extract_registry_run_keys, get_amcache, extract_prefetch | Presence + opportunistic success | Universal disk baseline | "Memory was enough" reasoning |
sigma_hunt (Chainsaw rule engine) | Hard success - requires exit_code 0, duration > 0, audit completion hash, AND durable Chainsaw output (output_path or finding_ids_generated populated) | Rule-based EVTX detection. sigma_scan is an internal anomaly post-processor - NOT a substitute. Run2 evidence: calling only sigma_scan produces zero rule-based detections. | Calling sigma_scan and skipping sigma_hunt |
Conditional detect_injection, list_dlls, analyze_vss, extract_shimcache, extract_srum | Triggered by psscan-only PIDs, network followup PIDs, anti-forensics signals | Same enforcement as their class above | Ignoring next_required_tool returned by earlier tools |
Enforcement specifics:
- Hard success (sigma_hunt): the gate's
_needs_sigma_hunt_run rejects failed, timed-out, zero-duration, or output-less runs. There is no presence-only fallback.
- Presence + opportunistic success (everything else): the gate accepts the tool if its name appears in executions. BUT if any matching execution has populated success metadata (exit_code/duration_seconds) AND none of them succeeded, the gate demands a retry. This protects legacy fixtures while still catching new failures.
If the parent agent attempts generate_report before these are satisfied, the gate returns next_required_tool - call THAT tool, do not retry generate_report.
Non-Negotiables
- Use MCP tools for forensic work. Shell fallback is only for classifying a tool gap.
- Keep large artifacts out of parent context. Read EVTX, MFT, Registry, Amcache, Prefetch, and timeline data through their handle (
csv_path, storage_path, or raw artifact directory) via run_analysis - never dump rows into the chat.
- Analyze each large artifact inline using the
applicable_heuristics slice in its tool response (the 8 mapped KBs: mft, evtx, prefetch, amcache, registry, srum, sigma, memory). Artifact-specialist Task spawn is retired (the 32K output ceiling truncated 7/8 prior runs); see the Orchestration Contract below. Synthesis/corroboration/timeline specialists remain opt-in only.
- After analyzing, the parent calls
record_analysis_lane(..., assigned_agent="main-agent", ...) with validated execution and finding IDs.
- If a parser returns
needs_extract_windows_artifacts=true, call extract_windows_artifacts(...) and rerun the parser on the durable /cases/<case_id>/artifacts/raw/... path.
- If
artifact_persistence.status="transient" but csv_path exists, the CSV is still the data handle. Delegate on the handle; do not manually extract with icat or direct dotnet.
- Full integrity hashing is deferred in fast IR unless manifest hashes exist, evidence access is inconsistent, or the operator asks for it.
Analysis Orchestration Contract (DO NOT STALL)
The hook system blocks the parent's next non-bypass tool call until the artifact's
lane is recorded via record_analysis_lane(...). Main-agent inline analysis
is the primary path per W1.6.1 + W1.7 architecture; specialist Task spawn is
opt-in for cross-artifact isolation only (synthesis/corroboration). Always finish
with the recording step in the same turn.
Primary path - Main-agent inline analysis
- Read the
applicable_heuristics block in the extraction tool's response.
The W1.7 heuristic-injection layer delivers the relevant slice from
.claude/agents/<artifact>-analyst.md directly in the payload, with a
ctx_id (CTX-NNN) for provenance.
- Read the durable handle (
csv_path, storage_path, raw artifact directory).
- Run focused
run_analysis(data_path=<handle>, query=...) queries shaped by
the heuristics. Each call gets an execution_id + audit row.
- Persist evidence-backed conclusions via
submit_finding(...) or
add_finding(...). Cite the heuristic via heuristic_context_refs=["CTX-N"].
- Call
record_analysis_lane(case_id=..., lane_id=<exact id from the hook>, status="COMPLETE" or "COMPLETE_WITH_GAPS", assigned_agent="main-agent", execution_ids=[...], finding_ids=[...], summary=<one sentence>).
For multi-artifact hypothesis formation: call prepare_hypothesis_context(case_id)
to receive a ranked bundle (volatile + detection + heuristic CTX-cited slices),
then record_hypotheses(case_id, hypotheses=[...]) to persist your hypotheses
for audit. For pivot-loop depth, call get_heuristic(artifact, topic).
Synthesis SOP - main-agent inline (MANDATORY before generate_report)
Per W1.7 Run 2 review 2026-05-24 - delegate synthesis
is opt-in; do not wait for @synthesis-analyst. Run 2 produced 0 CONFIRMED
because the specialist Task hung and the operator was forced into
allow_partial=True, which previously bypassed quality gates.
After all 4 prereq lanes (memory, disk_execution_persistence, event_auth,
timeline_correlation) reach COMPLETE or COMPLETE_WITH_GAPS:
compare_disk_and_memory(case_id) - MANDATORY.
find_temporal_clusters(case_id, window_seconds=300, min_sources=2, min_events=3).
- For each 3+ source cluster, promote via
submit_finding(...) with:
evidence_kind="inference" (NOT "corroborated" - valid enum is
OBSERVATION / INFERENCE / HYPOTHESIS / REJECTED only),
corroborated_by=[<F-NNN finding_ids>],
status="CONFIRMED",
source_execution_id=<resolved audit row>,
alternative_hypothesis=<benign explanation>,
evidence_against_it=[<specific observations>],
disposition="ruled_out" (or "not_applicable" + reason).
not_resolved / partially_plausible will NOT promote to CONFIRMED.
Response includes confirmed_eligibility: {eligible, missing, gate_blocks}
- read it; resubmit if
eligible: false and you wanted CONFIRMED.
record_analysis_lane(lane_id="synthesis_corroboration", assigned_agent="main-agent", status="COMPLETE", execution_ids=[...], finding_ids=[<promoted ids>], summary=...).
Opt-in escape hatch - Task subagent spawn
ONLY for cross-artifact synthesis or corroboration that benefits from context
isolation:
- Spawn
@synthesis-analyst, @corroboration-analyst, or @timeline-analyst
via Task(...) synchronously (run_in_background=false). When Task returns,
the subagent has finished - there is no "still running" state.
- Parse the subagent's JSON and call
record_analysis_lane(..., assigned_agent=<that-specialist>, ...) in the same response.
Do NOT spawn artifact specialists (@mft-analyst, @evtx-analyst, etc.) -
they're retired from default orchestration per W1.6.1 (32K Task ceiling caused
truncation in 7/8 prior runs). Artifact analysis stays inline.
Hard rules (apply to BOTH paths)
- Strict lane match. The hook clears the lane only when the recorded
lane_id
equals the pending lane_id exactly. Wrong lane = trigger unprocessed = next
non-bypass tool call blocks again.
- Same turn. Run analysis +
record_analysis_lane in the same response.
- No artifact collection before recording. Once a lane is pending, do not call
extract_*, summarize_*, get_amcache, etc. until the lane is recorded.
- Multiple lanes queue serially. If after recording one lane another is pending
(e.g.
summarize_evtx triggers event_auth), handle that next.
- Free-text "investigation summary" is not a completion. Producing a chat
summary instead of
generate_report(...) leaves the case IN_PROGRESS with no
report.json. The acceptance criterion is reports/{case_id}/report.html
written by generate_report.
If you ever feel "I should wait for the user before checking" - you are wrong.
Run the analysis, record the lane, and continue.
Specialist Contract
Specialists return compact JSON, not prose dumps. The SubagentStop hook enforces this contract when a delegate is pending.
{
"lane_id": "event_auth",
"status": "COMPLETE_WITH_GAPS",
"assigned_agent": "evtx-analyst",
"execution_ids": ["E-004"],
"finding_ids": ["F-012"],
"data_gaps": [],
"anti_forensics_warnings": [],
"unresolved_discrepancies": [],
"next_pivots": [],
"summary": "One sentence lane summary.",
"confidence_notes": []
}
The parent validates IDs with read_state(case_id) before record_analysis_lane(...).
If a specialist cannot access the artifact, cannot create findings, or finds that the evidence is unavailable/unsupported, it still returns this JSON with status="COMPLETE_WITH_GAPS" and at least one data_gaps entry. Do not silently summarize unavailable evidence.
Phase 1: Evidence Preparation
start_investigation(manifest_path)
environment_preflight(case_id)
mount_image(image_path) and note mount_status, access_mode, tsk_device_path, mount_path, and next_tools
load_memory(dump_path)
- Gate: evidence is mounted/loaded, or the missing piece is honestly classified
Phase 2: Artifact Collection
Heavy dotnet tools can saturate the 4-vCPU server. Use summaries and handles. Keep response_format="summary" by default; request response_format="detailed" only for narrow row drill-down after a specialist identifies the exact question.
Group A - run together when safe:
list_processes(dump_path)
scan_processes(dump_path)
scan_network(dump_path)
Analyze the memory lane inline: read the applicable_heuristics (memory) slice, run_analysis over the process/network handles to confirm suspicious processes/network/C2, submit_finding each conclusion, then record_analysis_lane(lane_id="memory", assigned_agent="main-agent", ...).
Group B - run one at a time or in small safe batches:
detect_injection(dump_path)
get_amcache(image_path)
extract_prefetch(image_path)
list_deleted_files(image_path)
extract_mft_timeline(image_path) -> analyze inline (mft heuristics; lane timeline_correlation)
summarize_evtx(image_path, channel="Security") -> analyze inline (evtx heuristics; lane event_auth)
extract_registry_run_keys(image_path) -> analyze inline (registry heuristics; lane disk_execution_persistence)
get_amcache(image_path) -> analyze inline (amcache heuristics; lane disk_execution_persistence)
extract_prefetch(image_path) -> analyze inline (prefetch heuristics; lane disk_execution_persistence)
extract_srum(image_path) when SRUM exists or exfil volume matters -> analyze inline (srum heuristics; lane timeline_correlation)
- File-access bundle - REQUIRED when
investigative_taxonomy.dispute_type ∈
{intrusion_response, data_exfiltration, insider_threat, financial_fraud,
policy_violation, ransomware} AND Windows is in scope (the coverage gate
enforces this; start_investigation lists them in next_required_tools +
mandatory_tools_for_report_gate): extract_shellbags, extract_lnk_files,
extract_jump_lists, extract_browser_history, extract_registry_fileaccess.
Do NOT stop at extraction - run_analysis + submit_finding per CSV (stack
LNK + ShellBag + RecentDocs for file ACCESS; browser downloads for an
initial-access vector). On non-Windows/mount-less images they record a
documented-absence result (the gate accepts that); they are sequential dotnet
(except sqlite browser_history) so expect a longer Phase 2.
Analyze each handle inline - read its applicable_heuristics slice, run_analysis for focused pivots, submit_finding, then record_analysis_lane:
- MFT (lane
timeline_correlation): timestomping, M-before-C copies, sequence anomalies, deletion bursts, staging directories, suspicious ADS.
- EVTX (lane
event_auth): 1102/104 log clearing, 4648 -> 5140/5145 lateral movement, RDP reconnects, Defender 1116/1117, Sysmon process/network chains, event-log gaps.
- Registry / Amcache / Prefetch / ShimCache / PCA (lane
disk_execution_persistence): persistence, service installs, Run keys, execution inventory + run counts, multi-path execution, renamed binaries, SHA-1s, missing-artifact gaps.
- SRUM (lane
timeline_correlation): per-application network volume, deleted/unresolved executables, exfiltration/lateral-movement support.
- Browser (when collected; FK-only, no heuristic slice): download/referrer history, suspicious extensions, sync artifacts, initial-access pivots.
Gate: major artifact lanes are either specialist-owned or explicitly recorded by the parent with a data gap.
Phase 3: Detection and Corroboration
sigma_scan(case_id) and/or sigma_hunt(...)
- Review CRITICAL/HIGH hits first and follow
pivot_suggestion
compare_disk_and_memory(case_id)
- Analyze Sigma results inline (sigma heuristics): triage false positives, explain zero-hit limitations when evidence was wiped, map confirmed detections to ATT&CK (lane
timeline_correlation).
- Corroborate inline: stress-test confirmed/active findings across disk, memory, event, and timeline evidence; downgrade weak claims;
flag_discrepancy on contradictions. (@corroboration-analyst Task spawn is opt-in only.)
Gate: critical/high anomalies are investigated, and contradictions are resolved or documented as open leads.
Phase 4: Deep Dive and Pivots
- Follow pivots from anomalies and specialist summaries
run_analysis(data_path, query) for focused CSV questions
build_timeline(source_path, case_id) when timelines help answer a hypothesis
query_timeline(plaso_path, start, end) around key attacker windows
flag_discrepancy(...) when evidence contradicts a claim
Phase 5: Report and Graph
read_state(case_id)
get_findings(case_id, finding_status="ACTIVE")
get_investigation_gates(case_id)
- If urgent partial triage is acceptable, document gaps; otherwise finish missing specialist records
generate_report(case_id)
generate_graph(case_id)
- If graph was generated after report, rerun
generate_report(case_id) so report.json no longer says graph_missing
Decision Points
- Blind mode: do not use known IOCs; discover independently.
- Seeded mode: use IOCs to prioritize while still collecting broadly.
sigma_scan returns 0 hits: decide whether this is true negative, missing evidence, or detector limitation.
- Corroboration downgrades a finding: update the narrative and confidence.
- Anti-forensics warning: recommend recovery pivots such as
analyze_vss and keep report status honest.