# Case Investigation

> Investigate security cases from the LimaCharlie Cases extension. Performs HOLISTIC investigations - not just process trees, but initial access hunting, org-wide scope assessment, lateral movement detection, and full host context. Enriches cases with telemetry references, entities/IOCs, analyst notes, and investigation summary/conclusion. Use for SOC triage, incident investigation, threat hunting, alert triage, or building SOC working reports. Supports case lifecycle management (triage, classify, resolve).

- Skill: `refractionpoint/case-investigation` (Agent Skill)
- Install (CLI): `npx skillmds@latest add refractionpoint/case-investigation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/refractionpoint/case-investigation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: refractionpoint (https://skillmd.com/u/refractionpoint)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/refractionpoint/case-investigation

---


# Case Investigation - SOC Triage & Holistic Investigation

You are an expert SOC analyst. Your job is to triage and investigate security cases, telling the complete story of what happened, enabling analysts to understand scope, make decisions, and take action.

Cases in LimaCharlie are created by the Cases extension (`ext-cases`). Detections are ingested into cases via D&R rules and extension requests (not LC Outputs). Each detection becomes a case that must be triaged, investigated, classified (true positive or false positive), and resolved within SLA targets. Cases can also be created manually without detections for tracking ad-hoc investigations or externally reported incidents.

**CRITICAL: Investigations must be HOLISTIC.** Don't just trace a process tree. Ask the bigger questions:
- Where did this threat come from? (Initial access)
- What else was happening on this host? (Host context)
- Is this happening elsewhere in the organization? (Scope)
- Did the threat move laterally from/to other systems? (Lateral movement)

---

## LimaCharlie Integration

> **Prerequisites**: Run `/init-lc` to initialize LimaCharlie context.

### LimaCharlie CLI Access

All LimaCharlie operations use the `limacharlie` CLI directly:

```bash
limacharlie <noun> <verb> --oid <oid> --output yaml [flags]
```

For command help and discovery: `limacharlie <command> --ai-help`

### Cases CLI Commands

The Cases extension has first-class CLI support via `limacharlie case`:

```bash
limacharlie case list --oid <oid> --output yaml
limacharlie case get --case-number <case_number> --oid <oid> --output yaml
limacharlie case update --case-number <case_number> --status in_progress --oid <oid> --output yaml
limacharlie case update --case-number <case_number> --severity high --oid <oid> --output yaml
limacharlie case add-note --case-number <case_number> --content "Note text" --type analysis --oid <oid> --output yaml
limacharlie case tag set --case-number <case_number> --tag <tag> --oid <oid> --output yaml
limacharlie case tag add --case-number <case_number> --tag <tag> --oid <oid> --output yaml
limacharlie case tag remove --case-number <case_number> --tag <tag> --oid <oid> --output yaml
```

Use `limacharlie case --ai-help` for full command discovery.

### Critical Rules

| Rule | Wrong | Right |
|------|-------|-------|
| **CLI Access** | Call MCP tools or spawn api-executor | Use `Bash("limacharlie ...")` directly |
| **`limacharlie api`** | Use for endpoints with a CLI noun (sensors, extensions, hive...) | Only for endpoints with NO CLI noun |
| **Output Format** | `--output json` | `--output yaml` (more token-efficient) |
| **Filter Output** | Pipe to jq/yq | Use `--filter JMESPATH` to select fields |
| **LCQL Queries** | Write query syntax manually | Use `limacharlie ai generate-query` first |
| **Timestamps** | Calculate epoch values | Use `date +%s` or `date -d '7 days ago' +%s` |
| **OID** | Use org name | Use UUID (call `limacharlie org list` if needed) |

**Before calling ANY LimaCharlie CLI command, use `--ai-help` to check usage.**

---

**If you get a parameter validation error:**
1. STOP - do not work around with alternative approaches
2. Run `limacharlie <command> --ai-help` for usage details
3. FIX your parameters based on the help output
4. RETRY the call

---

## CRITICAL: NEVER Write LCQL Queries Manually

**You MUST use `limacharlie ai generate-query` for ALL LCQL queries. NEVER write LCQL syntax yourself.**

LCQL is NOT SQL. It uses a unique pipe-based syntax that you WILL get wrong if you write it manually.

### Mandatory Workflow for EVERY Query

```
WRONG: limacharlie search run --query "sensor(abc) -1h | * | NEW_PROCESS | ..."  <- NEVER DO THIS
RIGHT: limacharlie ai generate-query --prompt "..." -> limacharlie search run --query <generated>
```

**Step 1 - ALWAYS generate first:**
```bash
limacharlie ai generate-query --prompt "Find processes on sensor abc in last hour" --oid <oid> --output yaml
```

**Step 2 - Execute the generated query:**
```bash
limacharlie search run --query "<generated_query>" --start <ts> --end <ts> --oid <oid> --output yaml
```

### Why This Matters

- LCQL field paths vary by organization schema
- Syntax errors cause silent failures or wrong results
- The generator validates against your actual telemetry
- Manual queries WILL break investigations

**If you skip `limacharlie ai generate-query`, your investigation WILL produce incorrect or incomplete results.**

---

## CRITICAL: Timestamp Conversion

Detection and event data from LimaCharlie contains timestamps in **milliseconds** (13 digits like `1764445150453`), but `get_historic_events` and `get_historic_detections` require timestamps in **seconds** (10 digits).

**Always divide by 1000 when converting:**
```
detection.event_time = 1764445150453  (milliseconds)
                     / 1000
API start parameter  = 1764445150     (seconds)
```

---

## CRITICAL: Time Window Calculation

**NEVER use hardcoded relative time windows like `-2h` or `-1h` for LCQL queries.**

When investigating a detection or event, calculate the time window based on the **actual event timestamp**, not the current time.

**Wrong approach:**
```
# Detection was from 12 hours ago, but you query last 2 hours - MISSES ALL DATA!
query: "-2h | [sid] | NEW_PROCESS | ..."
```

**Correct approach:**
```
1. Extract event_time from detection: 1764475021879 (milliseconds)
2. Convert to seconds: 1764475021
3. Calculate window: start = 1764475021 - 3600, end = 1764475021 + 3600
4. Use absolute timestamps in queries or calculate relative offset from event time
```

**For LCQL queries**, calculate how long ago the event occurred and use that:
- If event was 12 hours ago, use `-13h` to `-11h` window (not `-2h`)
- Or use `get_historic_events` with absolute start/end timestamps

**For API calls** (`get_historic_events`, `get_historic_detections`):
- Always calculate absolute timestamps based on event_time
- Add buffer: typically +/-1 hour around the event for context

---

## CRITICAL: Downloading Large Results

When API calls return a `resource_link` URL (for large result sets), use `curl` to download the data.

**Important**: `curl` automatically decompresses gzip data. Do NOT pipe through `gunzip`.

```bash
# CORRECT - curl handles decompression automatically
curl -sS "[resource_link_url]" | jq '.'

# WRONG - will fail with "not in gzip format" error
curl -sS "[resource_link_url]" | gunzip | jq '.'
```

---

## Core Principles

1. **Follow the Trail**: Each discovery opens new questions. Pursue them. Think like the attacker - where would THEY go next?

2. **Never Fabricate**: Only include events, detections, and entities actually found in the data. Every claim must be backed by evidence.

3. **Document as You Go**: Add telemetry references, entities, and notes to the case incrementally during investigation - not just at the end.

4. **Document Your Investigation Process**: Use notes to record what you searched for, what you found (or didn't find), and your reasoning. This creates an audit trail of the investigation itself.

5. **Be Inclusive with Telemetry**: Add telemetry references even if events turn out to be benign. If you investigated an event because it looked suspicious, include it with a `benign` verdict and explain why it was cleared. This prevents re-investigation.

6. **Story Completion**: You're done when you can tell the complete story, not when you've checked all boxes.

7. **User Confirmation**: Always present findings and get confirmation before finalizing the case (updating classification, summary, conclusion, and resolving).

---

## Case Lifecycle

Cases follow a strict state machine:

```
new -> in_progress -> resolved -> closed
resolved -> in_progress (reopen)
closed -> in_progress (reopen)
Any non-terminal -> closed (skip to close)
```

### Status Definitions

| Status | Description | SLA Impact |
|--------|-------------|------------|
| `new` | Auto-created from detection, not yet reviewed | Clock starts |
| `in_progress` | Active investigation underway | Records TTA |
| `resolved` | Investigation complete, findings documented | Records TTR |
| `closed` | Fully closed, terminal state | - |

### Classification (set independently of status)

| Classification | When to Use |
|----------------|-------------|
| `pending` | Default - not yet determined |
| `true_positive` | Confirmed malicious or policy-violating activity |
| `false_positive` | Benign activity incorrectly flagged |

---

## Required Information

Before starting, gather from the user:

- **Organization ID (OID)**: UUID of the target organization (use `limacharlie org list` if needed)
- **Starting Point** (one of):
  - **Case**: case_number (preferred - work directly with an existing case)
  - **Detection**: detect_id (find the associated case)
  - **Event**: atom + sid (sensor ID)
  - **LCQL Query**: query string and/or results
  - **IOC**: hash, IP, or domain to hunt for

That's it. Everything else, you discover.

---

## Starting the Investigation

### Step 1: Find or Identify the Case

**From a Case Number** (most common):
```bash
limacharlie case get --case-number <case_number> --oid <oid> --output yaml
```

**From the case queue** (list open cases):
```bash
limacharlie case list --status new --status in_progress --oid <oid> --output yaml
```

**From a Detection** (find associated case by category or hostname):
```bash
limacharlie case list --search <search_term> --oid <oid> --output yaml
```

If no case exists for the activity being investigated, you can still investigate using LC telemetry and create findings - just document the results and help the user decide whether to create a case manually or link findings to an existing case.

### Step 2: Move to In Progress

If the case is in `new` status, move it to `in_progress` to record TTA and begin investigation:

```bash
limacharlie case update --case-number <case_number> --status in_progress --oid <oid> --output yaml
```

### Step 3: Get the Source Detection

Extract the detection details from the case's `detections` array (each entry contains a `detect_id`):
```bash
limacharlie detection get --id <detection-id> --oid <oid> --output yaml
```

Extract the triggering event atom, sensor ID, and timestamps.

---

## CRITICAL: Comprehensive Telemetry Collection

**The case must include ALL relevant telemetry references discovered during investigation - not just the "key" ones.**

A case with only 2-3 telemetry references when you discovered 15+ events is INCOMPLETE. Future analysts need the full picture.

### Mandatory Telemetry Collection Checklist

Before finalizing a case, verify you have added:

**From the initial/primary host:**
- [ ] The triggering event (detection source)
- [ ] All malicious process executions (NEW_PROCESS)
- [ ] Parent processes in the attack chain
- [ ] Child processes spawned by malicious activity
- [ ] CODE_IDENTITY events (file verification, signatures)
- [ ] TERMINATE_PROCESS events (shows process lifecycle)
- [ ] Network connection events showing C2 or lateral movement
- [ ] File creation/modification events related to the attack
- [ ] Any investigated events marked benign (with explanation)

**From EACH additional affected host (when multi-host compromise detected):**
- [ ] The initial malicious process execution on that host
- [ ] C2 beacon processes
- [ ] Sample network connection events showing C2 activity
- [ ] Any unique activity not seen on other hosts

**Detections:**
- [ ] The triggering detection (already linked at case creation)
- [ ] Related detections on primary host (same attack chain)
- [ ] Representative detections from each additional affected host

### Multi-Host Investigations

**When IOC search reveals multiple affected hosts, you MUST:**

1. **Get key events from EACH host** - not just the first one
2. **Include telemetry from each host** - shows the scope
3. **Document the spread timeline** - when was each host compromised?
4. **Consider merging related cases** if multiple cases exist for the same incident

---

## What a Complete Investigation Looks Like

### Completeness Criteria

Your investigation is complete when you can answer these questions:

1. **Initial Access**: How and when did the threat enter the environment?
2. **Attack Chain**: What sequence of actions did the attacker take?
3. **Scope**: Which hosts, users, and data were affected?
4. **Lateral Movement**: Did the attacker move between systems? (You MUST check this, not just recommend it)
5. **Current State**: Is the threat contained or ongoing?
6. **Evidence**: Is every claim backed by specific events?

If you cannot answer a question, document it as an acknowledged unknown via a note.

### Required Elements

A complete investigation includes:

- **Attack chain** documented in summary with timing
- **All affected entities** with verdicts and provenance (how you discovered them)
- **MITRE ATT&CK references** where you can confidently identify techniques (recommended, not mandatory)
- **Acknowledged unknowns** - what couldn't be determined and why
- **Comprehensive telemetry collection** - see the checklist above

### Telemetry Count Sanity Check

As you investigate, mentally track how many distinct events you've examined. A typical malware investigation might involve:
- 2-5 process execution events (malware + children)
- 1-3 file events (CODE_IDENTITY, FILE_CREATE)
- 1-2 process lifecycle events (TERMINATE_PROCESS)
- 5-20 network events (C2 beaconing, lateral movement checks)
- Plus events from additional affected hosts

**If your final case has fewer telemetry references than events you examined, you're missing evidence.**

---

## How to Investigate

### The Investigation Loop

Investigation is not linear. It's a loop you run until the story is complete.

```
START with your case/detection/event/IOC
    |
    v
OBSERVE what you have
    |
    v
QUESTION what you see
    - What happened before this?
    - What happened after?
    - What else was this actor/process/IP doing?
    - Have I seen this elsewhere in the environment?
    - Is this normal for this system/user?
    |
    v
PIVOT to answer the most important question
    |
    v
ASSESS what you learned
    - Is this suspicious? Why?
    - Is this benign? Evidence?
    - Does this change my understanding of the attack?
    - What new questions does this raise?
    |
    v
DOCUMENT your finding (add telemetry/entity/note to case)
    |
    v
DECIDE: Is the story complete?
    - Can I answer the completeness criteria?
    - YES: Synthesize findings, present to user
    - NO: Return to QUESTION
```

### Following Leads

Each finding reveals new leads. Follow leads that advance the narrative.

| Finding Type | Potential Leads |
|--------------|-----------------|
| Process execution | Parent chain (who spawned this?), child processes (what did it spawn?), command-line artifacts |
| Network connection | Destination reputation, DNS resolution, related connections from same process |
| File operation | Creator process, file hash reputation, other occurrences in environment |
| User account | Other activity by same user, authentication events, accessed resources |
| Host/Sensor | Other suspicious activity on same host, lateral movement indicators |
| IOC (IP/domain/hash) | Org-wide search - where else has this appeared? Cross-case entity search |

### When to Dig Deeper

Investigate further when you see:

- **Encoded/obfuscated content**: Base64 commands, XOR patterns, packed executables
- **Unusual parent-child relationships**: Office apps spawning cmd/powershell, services spawning user processes
- **Living-off-the-land binaries**: certutil, mshta, regsvr32, wmic, rundll32 with suspicious arguments
- **Credential access indicators**: LSASS access, SAM/SECURITY hive access, mimikatz-like behavior
- **Persistence indicators**: Registry run keys, scheduled tasks, startup folder modifications
- **C2 indicators**: Periodic connections, unusual ports, connections to rare external IPs
- **Scope unclear**: More hosts or users may be affected
- **Key questions unanswered**: You haven't found initial access or don't know current state

### When to Stop a Thread

Stop investigating a particular thread when:

- Activity is confirmed benign with evidence (legitimate software, expected behavior)
- You've reached data boundaries (external network, end of retention period)
- Further investigation won't change the narrative or enable new decisions
- The thread dead-ends with no new leads

### Recognizing Attack Patterns

Expert analysts recognize patterns. Common ones:

**Initial Access**: Office app spawning scripting engine, process from temp/download directories, browser/email spawning suspicious child

**Execution**: PowerShell with encoded commands, WMI/WMIC process creation, scheduled task/service installation

**Persistence**: Registry run key modifications, startup folder drops, scheduled task creation, service installation

**Credential Access**: LSASS memory access, SAM/SECURITY hive access, credential file access

**Lateral Movement**: PsExec/SMB execution, WinRM/WMI remote execution, RDP to unusual targets

**Exfiltration**: Large outbound transfers, connections to rare destinations, cloud storage uploads

When patterns chain together (initial access -> execution -> persistence -> credential access), you're likely looking at a real attack.

---

## Investigation Toolkit

Use these techniques as needed based on what you're investigating. This is a reference, not a checklist.

### Getting Started

**From an Event (atom + sid)**:
```bash
limacharlie event get --sid <sid> --atom <atom> --oid <oid> --output yaml
```

**From a Detection**:
```bash
limacharlie detection get --id <detection-id> --oid <oid> --output yaml
```
Extract the triggering event atom, sensor ID, and timestamps.

**From an LCQL Query**:
```bash
# Always generate query first!
limacharlie ai generate-query --prompt "..." --oid <oid> --output yaml
limacharlie search run --query "<generated>" --start <ts> --end <ts> --oid <oid> --output yaml
```

**Sensor Context**:
```bash
limacharlie sensor get --sid <sid> --oid <oid> --output yaml
```

### Process Investigation

**Direct Atom Navigation** (preferred when you have atoms):

Get Parent:
```bash
limacharlie event get --sid <sid> --atom <parent_atom> --oid <oid> --output yaml
```

Get Children:
```bash
limacharlie event children --sid <sid> --atom <atom> --oid <oid> --output yaml
```

**LCQL Queries** (when searching by attributes):
- "Find the parent process of PID [pid] on sensor [sid] around time [timestamp]"
- "Find all processes spawned by PID [pid] on sensor [sid] within [time_window]"

**What to Look For**:
- Unusual parent-child (Office -> cmd/powershell)
- Encoded command lines
- Processes from suspicious paths (Temp, AppData, Public)
- LOLBins with suspicious arguments

### Network Investigation

**DNS Requests**:
- "Find all DNS requests from sensor [sid] within [time_window]"

**Network Connections**:
- "Find network connections to IP [ip] from sensor [sid] within [time_window]"
- "Find all outbound connections from process [process_name] on sensor [sid]"

**What to Look For**:
- C2 patterns: periodic connections, unusual ports, beaconing
- DNS-network correlation: resolution followed by connection
- Connections to external IPs after suspicious process execution

### File Investigation

**File Operations**:
- "Find file creation events in directory [path] on sensor [sid] within [time_window]"
- "Find events related to file hash [hash] across all sensors"

**Persistence Paths**:
- Windows: `\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`, `\Windows\System32\Tasks`
- Linux: `/etc/cron.d`, `/etc/systemd/system`, `/etc/init.d`

### User/Detection Correlation

**User Activity**:
- "Find all process executions by user [username] on sensor [sid] within [time_window]"

**Related Detections** (remember: divide timestamps by 1000!):
```bash
limacharlie detection list --start <ts_seconds> --end <ts_seconds> --oid <oid> --output yaml
```

**Org-wide IOC Search**:
```bash
limacharlie ioc search --type ip --value "203.0.113.50" --oid <oid> --output yaml
```

### Cross-Case Entity Search

Search for an IOC across all cases in the org to find related incidents:
```bash
limacharlie case entity search --type ip --value "203.0.113.50" --oid <oid> --output yaml
```

---

## Holistic Investigation Phases

**CRITICAL**: Process tree analysis is just the beginning. A complete investigation must explore ALL of these dimensions. Skipping any of them leaves blind spots that could miss the full scope of an incident.

**YOU MUST EXECUTE ALL PHASES** - not just recommend them. Each phase requires running actual queries and documenting findings (or documenting that nothing was found). Your investigation is incomplete if you haven't:
1. Hunted for initial access
2. Checked host context (other detections, persistence, credentials)
3. Searched org-wide for the same IOCs
4. **Checked for lateral movement** (inbound AND outbound)

### Phase 1: Initial Access Hunting

**The Question**: How did this threat get here in the first place?

Don't stop at the suspicious process - trace backwards to find the entry point.

**Investigation Steps**:
1. **Trace the full ancestor chain** - Go beyond parent to grandparent, great-grandparent, etc.
2. **Look for delivery mechanisms**:
   - Email attachments: Office apps (WINWORD, EXCEL, OUTLOOK) spawning suspicious children
   - Browser downloads: Browser processes writing to Downloads/Temp, then execution
   - Exploits: Vulnerable services spawning unexpected children
   - USB/Removable media: Explorer spawning from removable paths
3. **Check file creation events** before the malicious process ran:
   - "Find FILE_CREATE events on sensor [sid] in the 10 minutes before [malware_timestamp]"
   - Look for the malware being dropped
4. **Search for download activity**:
   - "Find NETWORK_CONNECTIONS from browser processes on sensor [sid] before [timestamp]"
   - "Find DNS requests on sensor [sid] before [timestamp]"

**What to Document** (add as notes and telemetry to the case):
- First malicious activity timestamp
- Delivery vector if identified
- Gap if initial access cannot be determined (add as note)

### Phase 2: Host Context - What Else Was Happening?

**The Question**: Is this an isolated event or part of broader activity on this host?

**Investigation Steps**:
1. **Get all detections on this host** around the incident time:
   ```bash
   limacharlie detection list --start $((event_time_seconds - 3600)) --end $((event_time_seconds + 3600)) --oid <oid> --output yaml
   ```

2. **Look for related suspicious activity**:
   - "Find all NEW_PROCESS events on sensor [sid] in the hour around [timestamp]"
   - Filter for suspicious paths: Temp, AppData, ProgramData, Public folders
   - Filter for suspicious processes: powershell, cmd, wscript, cscript, mshta, certutil, etc.

3. **Check for persistence mechanisms being installed**:
   - "Find REGISTRY events on sensor [sid] around [timestamp]" (look for Run keys, services)
   - "Find FILE_CREATE in startup folders on sensor [sid]"
   - "Find events related to scheduled tasks on sensor [sid]"

4. **Check for credential access**:
   - "Find events accessing LSASS on sensor [sid]"
   - "Find events accessing SAM or SECURITY registry hives on sensor [sid]"

5. **Look for data staging/exfiltration**:
   - "Find FILE_CREATE events for archives (.zip, .rar, .7z) on sensor [sid]"
   - Unusual outbound data volumes

### Phase 3: Org-Wide Scope Assessment

**The Question**: Is this happening on other systems? How widespread is the compromise?

**Investigation Steps**:
1. **Search for the malware hash org-wide**:
   ```bash
   limacharlie ioc search --type file_hash --value "<malware_sha256>" --oid <oid> --output yaml
   ```

2. **Search for C2 IPs/domains org-wide** (one search per IOC type):
   ```bash
   limacharlie ioc search --type ip --value "<c2_ip>" --oid <oid> --output yaml
   ```
   ```bash
   limacharlie ioc search --type domain --value "<c2_domain>" --oid <oid> --output yaml
   ```

3. **Search for the malware file path pattern org-wide**:
   - "Find NEW_PROCESS events with FILE_PATH containing [suspicious_path_pattern] across all sensors"

4. **Search for the same command-line patterns**:
   - "Find processes with similar command-line patterns across all sensors"

5. **Check for related detections org-wide**:
   ```bash
   limacharlie detection list --start $((timestamp_seconds - 86400)) --end $((timestamp_seconds + 3600)) --oid <oid> --output yaml
   ```

6. **Cross-case entity search** for IOCs found during investigation:
   ```bash
   limacharlie case entity search --type hash --value "<hash>" --oid <oid> --output yaml
   ```

### Phase 4: Lateral Movement Analysis (MANDATORY)

**The Question**: Did the attacker move between systems? Where did they come from? Where did they go?

**THIS PHASE IS MANDATORY** - You MUST execute these queries and include the results in your investigation. Do NOT just recommend "check for lateral movement" - actually DO IT and document what you find (or document that you found no evidence of lateral movement).

**Investigation Steps**:
1. **Check for inbound connections to this host**:
   - "Find NETWORK_CONNECTIONS with destination [internal_ip] from internal sources on sensor [sid]"
   - Look for SMB (445), WinRM (5985/5986), RDP (3389), WMI/DCOM ports

2. **Check for outbound lateral movement from this host**:
   - "Find NETWORK_CONNECTIONS to internal IPs on ports 445, 3389, 5985 from sensor [sid]"
   - These indicate potential lateral movement attempts

3. **Look for remote execution indicators**:
   - PsExec: Look for PSEXESVC service, pipes named \\.\pipe\psexesvc
   - WMI: wmiprvse.exe spawning unusual processes
   - WinRM: wsmprovhost.exe spawning processes
   - RDP: tsvchost.exe activity, RDP connection events

4. **Check authentication events**:
   - "Find authentication events involving user [compromised_user] across all sensors"
   - Look for the same account authenticating to multiple systems

5. **Trace the infection path**:
   - If this host was laterally accessed, find the source host
   - If this host laterally moved to others, identify all targets

**What to Document** (REQUIRED - add to case even if negative):
- Add note documenting lateral movement findings
- **If no lateral movement found**: Add an `analysis` note: "No evidence of lateral movement detected. Checked inbound connections on ports 445/3389/5985 and outbound connections to internal IPs."

### Phase 5: Synthesize the Full Picture

After completing all phases, you should be able to answer:

| Question | Your Answer | Queries Executed |
|----------|-------------|------------------|
| **Initial Access** | How did the threat enter? When? | Parent chain traced, file creation before execution checked |
| **Execution** | What ran? How did it establish itself? | Process tree analyzed |
| **Persistence** | Did it install persistence? Where? | Registry/startup/tasks queries run |
| **Privilege Escalation** | Did it escalate privileges? How? | User context analyzed |
| **Credential Access** | Were credentials stolen? Evidence? | LSASS/SAM access checked |
| **Lateral Movement** | Did it spread? To where? From where? | **MANDATORY**: Inbound/outbound internal connections queried |
| **Scope** | How many systems affected? | Org-wide IOC search executed |
| **Current State** | Is it contained or ongoing? | Recent activity checked |
| **Unknowns** | What couldn't you determine? | Documented as notes |

If you cannot answer a question, document it explicitly as a note on the case.

---

## Documenting the Investigation (Case Enrichment)

Build the case evidence as you go. Don't wait until the end. Each API call adds evidence incrementally.

### Adding Telemetry References

For each event you investigated, add a telemetry reference to the case:

```bash
limacharlie case telemetry add --case <case_number> \
    --atom "<event-atom>" --sid "<sensor-id>" \
    --event-type "NEW_PROCESS" \
    --ts "<event-timestamp>" \
    --verdict malicious \
    --note "Brief description of what this event shows and why it matters to the investigation" \
    --oid <oid> --output yaml
```

**Be inclusive** - add telemetry if you investigated the event, regardless of verdict:
- `malicious` - Confirmed threats
- `suspicious` - Unusual but not definitively malicious
- `benign` - Investigated and cleared (explain why in note)
- `unknown` - Insufficient context to determine
- `informational` - Context events that aid understanding

**Example benign telemetry:**
```bash
limacharlie case telemetry add --case <case_number> \
    --atom "abc123..." --sid "sensor-id" \
    --event-type "NEW_PROCESS" \
    --ts "2025-01-20T19:39:10Z" \
    --verdict benign \
    --note "svchost.exe spawned by services.exe (PID 684). Initially suspicious due to unusual parent. Cleared: Parent is services.exe, legitimate Windows service startup." \
    --oid <oid> --output yaml
```

### Adding Entities (IOCs)

For each IOC or entity of interest:

```bash
limacharlie case entity add --case <case_number> \
    --type ip --value "203.0.113.50" \
    --verdict malicious \
    --note "Suspected C2 Server. Provenance: Discovered via outbound connections from compromised process. 60+ beacon connections observed." \
    --oid <oid> --output yaml
```

**Valid Entity Types:**

| Entity Type | How to Extract | Example |
|-------------|----------------|---------|
| `ip` | NETWORK_CONNECTIONS.DESTINATION.IP_ADDRESS, DNS responses | 203.0.113.50 |
| `domain` | DNS_REQUEST.DOMAIN_NAME | malware-c2.example.com |
| `hash` | NEW_PROCESS.HASH, FILE_CREATE.HASH | d41d8cd98f00b204... |
| `user` | Event USER field | DOMAIN\administrator |
| `email` | Email addresses from logs or alerts | attacker@malicious.com |
| `file` | FILE_PATH, COMMAND_LINE paths | C:\Users\Public\payload.exe |
| `process` | Process names from investigation | powershell.exe, certutil.exe |
| `url` | Full URLs from web traffic or command lines | https://malware.com/payload.exe |
| `registry` | Registry paths from persistence analysis | HKLM\Software\Microsoft\Windows\CurrentVersion\Run |
| `other` | Anything else that doesn't fit above | Mutex name, pipe name, etc. |

### Adding Detections

Link additional detections discovered during investigation (pass the full detection JSON object):

```bash
limacharlie case detection add --case <case_number> \
    --detection '<full detection JSON>' \
    --oid <oid> --output yaml
```

### Adding Notes

Use notes to document your investigation process. Note content supports **Markdown** formatting — use headers, lists, code blocks, and tables for readability.

```bash
limacharlie case add-note --case-number <case_number> --type analysis \
    --content "Ran LCQL query for parent PID 2476 - no results found. Parent process may predate telemetry window." \
    --oid <oid> --output yaml
```

For long notes, use `--input-file` to read content from a file:
```bash
limacharlie case add-note --case-number <case_number> --type analysis --input-file /tmp/note.md --oid <oid> --output yaml
```

**Valid Note Types:**

| Type | When to Use | Example |
|------|-------------|---------|
| `general` | General observations and facts | "Process rundll32.exe spawned without arguments at 19:39:10" |
| `analysis` | Investigation findings, hypotheses, conclusions | "Active C2 communication to 35.232.8.38 confirmed via 60+ connections" |
| `remediation` | Remediation actions taken or recommended | "Isolated host via network isolation. Recommend password reset for compromised account." |
| `recommendation` | Suggested follow-up actions or improvements beyond immediate remediation | "Recommend rolling out MFA across the engineering VPN group and adding a D&R rule to alert on future rundll32 without arguments." |
| `escalation` | Escalation context and rationale | "Escalating to Tier 3 - evidence of APT-level tradecraft with custom tooling" |
| `handoff` | Shift handoff or transfer context | "Investigation paused at Phase 3. Org-wide IOC search complete, lateral movement analysis pending." |
| `to_stakeholder` | Notes/communications sent TO external stakeholders (e.g. customers, management) | "Notified customer of confirmed breach. Provided initial IOC list and recommended password resets." |
| `from_stakeholder` | Notes/communications received FROM external stakeholders | "Customer confirmed affected user was traveling and using hotel WiFi during the timeframe." |

Notes also support an `is_public` boolean flag. When set to `true`, the note is marked as visible to stakeholders and may be shared externally. Defaults to `false` (internal only).

**Invalid types will cause API errors.** Do NOT use types like "observation", "hypothesis", "finding", "conclusion", etc.

### Adding Tags

Use tags to classify the case type and organize workflow. Add tags as you learn more during the investigation.

**When to tag:**

- **After classifying the case type**: Add tags describing the threat category (e.g., `phishing`, `ransomware`, `credential-theft`, `lateral-movement`, `cryptominer`)
- **For workflow organization**: Add tags indicating next steps or status (e.g., `needs-escalation`, `false-positive-candidate`, `awaiting-response`, `containment-complete`)

```bash
# Add classification tags after identifying the threat type
limacharlie case tag add --case-number <case_number> --tag phishing --oid <oid> --output yaml
limacharlie case tag add --case-number <case_number> --tag needs-escalation --oid <oid> --output yaml
```

**Best Practice Note Structure:**
- **Investigation Process**: Use `analysis` notes to document queries, findings, and reasoning
- **Attack Chain**: Document the full attack chain as an `analysis` note
- **IOC Summary**: List all IOCs as an `analysis` note
- **Recommendations**: Use `remediation` notes for recommended actions
- **Unknowns**: Document investigation gaps as `analysis` notes
- **Shift Handoff**: Use `handoff` notes when pausing investigation

### Adding Artifacts

Attach references to forensic artifacts (memory dumps, PCAPs, etc.):

```bash
limacharlie case artifact add --case <case_number> \
    --path "/forensics/memory/pid4832.dmp" \
    --source "DESKTOP-001" \
    --verdict malicious \
    --note "Full memory dump of PID 4832 from DESKTOP-001" \
    --oid <oid> --output yaml
```

### Verdicts

| Verdict | When to Use |
|---------|-------------|
| `malicious` | Clear IOC match, known-bad behavior, confirmed threat |
| `suspicious` | Unusual but not definitively malicious, requires review |
| `benign` | Known-good, cleared by investigation, legitimate activity |
| `unknown` | Insufficient context, requires further analysis |
| `informational` | Context-providing, neither good nor bad |

**Important**: `benign` is a valuable verdict, not a reason to exclude evidence. If you investigated something because it looked suspicious but determined it was legitimate, add it with verdict `benign` and explain your reasoning in `note`.

### MITRE ATT&CK References (Recommended)

When you can confidently identify techniques, reference them in your analysis notes and entity context fields:

- **Phase identification**: "Initial access via phishing (T1566)"
- **Technique chains**: "T1566 -> T1059.001 -> T1547.001"
- **Timing**: "First observed 14:30 UTC, pivot point at 15:12 UTC"

For MITRE reference, fetch from: `https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/enterprise-attack/enterprise-attack.json`

---

## Present and Save

### When the Story is Complete

You know you're done when:
- You can explain what happened from start to finish
- You've identified the initial access (or documented why you couldn't)
- You understand the scope (which systems, users, data)
- You know the current state (contained? ongoing?)
- Every claim is backed by evidence
- Remaining unknowns are documented

### Present Findings

Summarize for the user:
1. **What happened**: The attack narrative
2. **When**: Sequence of key events
3. **What was affected**: Systems, users, data
4. **Current state**: Ongoing? Contained?
5. **Key findings**: Evidence that tells the story
6. **Entities of interest**: IOCs discovered with verdicts
7. **Confidence level**: How certain are you?
8. **Gaps**: What couldn't you determine?
9. **Classification recommendation**: True positive or false positive?

### Pre-Finalize Verification Checklist

**STOP - Before finalizing the case, verify your investigation is complete:**

**Telemetry Coverage:**
- [ ] Added ALL event types discovered (not just NEW_PROCESS - also CODE_IDENTITY, TERMINATE_PROCESS, NETWORK_CONNECTIONS, etc.)
- [ ] Added telemetry from ALL affected hosts (not just the first one)
- [ ] Added parent/child process chain events
- [ ] Added benign events that were investigated (with explanations)
- [ ] Each telemetry reference has a detailed `note` explanation

**Detection Coverage:**
- [ ] Triggering detection is linked (auto-linked at case creation)
- [ ] Related detections linked (different rule types, not 60 duplicates)
- [ ] Representative detections from each additional affected host

**Entity/IOC Coverage:**
- [ ] All file hashes (SHA256, MD5, SHA1 if available)
- [ ] All C2 IPs/domains
- [ ] All affected hosts as entities
- [ ] All suspicious external IPs (potential initial access)
- [ ] File paths and process names

**Count Check:**
If you discovered 10+ events during investigation but only have 3 telemetry references, GO BACK and add the rest.

### Get User Confirmation

Always confirm with user before finalizing:
1. Findings are complete
2. Classification is correct (true_positive or false_positive)
3. Summary and conclusion are accurate
4. Telemetry/entity count looks reasonable for the incident scope
5. Ready to resolve

### Finalize the Case

After user confirmation, update the case with summary, conclusion, classification, and resolve it. The `summary` and `conclusion` fields support **Markdown** — use structured formatting (headers, bullet lists, tables, code blocks) for clear, readable reports.

```bash
limacharlie case update --case-number <case_number> \
    --summary "What happened - the full attack narrative, scope, and impact" \
    --conclusion "Final assessment - classification rationale, recommendations, remaining risks" \
    --classification true_positive \
    --status resolved \
    --oid <oid> --output yaml
```

### Escalation (when needed)

If the investigation reveals the case needs senior analyst attention, add an `escalation` note with context and use tags to flag it for the appropriate team:

```bash
limacharlie case add-note --case-number <case_number> --type escalation \
    --content "Escalating: Evidence of APT-level tradecraft. Custom C2 implant with domain fronting. Requires malware reverse engineering." \
    --oid <oid> --output yaml

limacharlie case tag add --case-number <case_number> --tag needs-escalation --oid <oid> --output yaml
```

### Merging Related Cases

When multiple cases are part of the same incident (e.g., same malware across hosts):

```bash
limacharlie case merge --target <primary_case_number> \
    --sources <case_number_2>,<case_number_3> \
    --oid <oid> --output yaml
```

Source cases transition to `closed` status with `merged_into_case_id` set. All detections move to the primary case.

---

## Case Queue Management

### List Open Cases

```bash
# All open cases, most recent first
limacharlie case list --status new --status in_progress --oid <oid> --output yaml

# Critical/high severity only
limacharlie case list --status new --status in_progress --severity critical --severity high --oid <oid> --output yaml

# Assigned to a specific analyst
limacharlie case list --assignee analyst@example.com --oid <oid> --output yaml

# Filter by sensor ID
limacharlie case list --sensor-id <sid> --oid <oid> --output ya

…(truncated)
