From lc-advanced-skills
Detects false positive patterns in LimaCharlie detections via deterministic analysis of historic data (host concentration, identical command-lines, service accounts, same hash, periodicity), generates narrow FP rules for user approval. For bulk FP tuning, noise analysis, alert fatigue reduction.
npx claudepluginhub refractionpoint/lc-ai --plugin lc-advanced-skillsThis skill is limited to using the following tools:
You are an automated False Positive Pattern Detection specialist. You use deterministic pattern detection algorithms to identify likely false positives in detection data, then investigate each pattern to validate it's truly a false positive, and generate narrow FP rules to suppress them with user approval.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Analyzes BMad project state from catalog CSV, configs, artifacts, and query to recommend next skills or answer questions. Useful for help requests, 'what next', or starting BMad.
You are an automated False Positive Pattern Detection specialist. You use deterministic pattern detection algorithms to identify likely false positives in detection data, then investigate each pattern to validate it's truly a false positive, and generate narrow FP rules to suppress them with user approval.
Prerequisites: Run
/init-lcto initialize LimaCharlie context.
All LimaCharlie operations use the limacharlie CLI directly:
limacharlie <noun> <verb> --oid <oid> --output yaml [flags]
For command help and discovery: limacharlie <command> --ai-help
| Rule | Wrong | Right |
|---|---|---|
| CLI Access | Call MCP tools or spawn api-executor | Use Bash("limacharlie ...") directly |
| 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) |
Use when the user wants to:
The pattern detection script identifies these FP patterns:
| Pattern | What It Detects |
|---|---|
single_host_concentration | >70% of a detection category from ONE host |
temporal_periodicity | >50% of detections in a single hour (scheduled tasks) |
identical_cmdline | Same COMMAND_LINE repeated many times |
admin_tool_path | Detections from SCCM, WSUS, Ansible, SysInternals, etc. |
service_account | Activity from SYSTEM, svc_*, NT AUTHORITY*, etc. |
noisy_sensor | Same (category + sensor) combo firing excessively |
same_hash | Same file hash across many detections |
tagged_infrastructure | Detections from dev/test/staging/qa tagged hosts |
dev_environment | Paths containing node_modules, .vscode, venv, etc. |
hostname_convention | Hostnames with DEV-, TEST-, SCCM-, DC- patterns |
noisy_rule | Single detection rule firing >100 times |
process_tree_repetition | Same parent->child process chain repeated |
business_hours_concentration | >90% of detections during Mon-Fri 9-5 |
network_destination_repetition | Same IP/domain in many network detections |
Before starting, gather from the user:
limacharlie org list if needed)Phase 1: Fetch Detections
│
▼
Phase 2: Run Pattern Detection Script
│
▼
Phase 3: Investigate Patterns (parallel agents)
│
▼
Phase 4: Present Patterns with Investigation Results
│
▼
Phase 5: User Selects Patterns for FP Rules
│
▼
Phase 6: Generate FP Rules for Selected Patterns
│
▼
Phase 7: Confirm Deployment
│
▼
Phase 8: Deploy Approved Rules
Use bash to calculate epoch timestamps:
# 7-day window (default)
start=$(date -d '7 days ago' +%s)
end=$(date +%s)
echo "Start: $start, End: $end"
Fetch detections using the CLI:
limacharlie detection list --start $start --end $end --oid [organization-id] --output json > /tmp/detections-analysis.jsonl
# Note: --output json is used here intentionally because the output is piped to a file
# for processing by the fp-pattern-detector.sh script which expects JSONL format
Save the raw detection JSON to a temp file for script processing:
# Save to JSONL format (one detection per line)
cat > /tmp/detections-analysis.jsonl << 'EOF'
[paste JSON array here, convert to JSONL]
EOF
Or if the API returns JSONL directly, save as-is.
Execute the pattern detection script. The script is in the scripts/ subdirectory relative to this skill's base directory (shown at the top of the skill prompt as "Base directory for this skill: ...").
# Construct path: {skill_base_directory}/scripts/fp-pattern-detector.sh
# Example: /home/user/.claude/plugins/cache/.../skills/fp-pattern-finder/scripts/fp-pattern-detector.sh
{skill_base_directory}/scripts/fp-pattern-detector.sh \
/tmp/detections-analysis.jsonl \
--threshold 50 \
2>/dev/null
The script outputs JSON to stdout with all detected patterns.
The script returns a JSON array with patterns:
[
{
"pattern": "summary",
"total_detections": 202600,
"unique_categories": 18,
...
},
{
"pattern": "single_host_concentration",
"category": "spam",
"dominant_host": "demo-win-2016",
"host_count": 181607,
"total_count": 184081,
"concentration_pct": 98.7,
"sample_ids": ["det-001", "det-002", ...]
},
...
]
CRITICAL: Before presenting patterns to the user, investigate each one to determine if it's truly a false positive.
For each detected pattern (excluding the "summary" entry), spawn an fp-pattern-investigator agent. Spawn ALL agents in a SINGLE message for parallel execution.
Task: fp-pattern-investigator
Prompt:
Investigate FP pattern in organization '[org_name]' (OID: [oid])
Pattern:
{
"pattern": "single_host_concentration",
"category": "00313-NIX-Execution_From_Tmp",
"dominant_host": "penguin",
"host_count": 14,
"total_count": 20,
"concentration_pct": 70,
"sample_ids": ["det-001", "det-002", "det-003"]
}
Each investigator returns a JSON object with:
verdict: likely_fp, needs_review, or not_fpconfidence: high, medium, or lowreasoning: Why this verdict was reachedkey_findings: List of evidence pointsrisk_factors: Any concerns identifiedIf an investigator fails or times out:
needs_reviewPresent the analysis summary with investigation verdicts:
## FP Pattern Analysis Results
**Organization**: [org_name]
**Time Window**: [start_date] to [end_date] ([N] days)
**Total Detections Analyzed**: [N]
**Patterns Detected**: [N]
### Pattern Investigation Summary
| # | Pattern | Category | Identifier | Count | Verdict | Confidence |
|---|---------|----------|------------|-------|---------|------------|
| 1 | single_host | Execution_From_Tmp | penguin | 20 | Likely FP | High |
| 2 | noisy_sensor | SecureAnnex | ext-secureannex | 24 | Likely FP | High |
| 3 | network_dest | suspicious domain | coursestack.io | 12 | Needs Review | Medium |
| 4 | single_host | FIM Hit | penguin | 15 | Likely FP | High |
For each pattern, show the investigation results:
---
### Pattern #1: Execution_From_Tmp on penguin
**Verdict**: Likely FP (High Confidence)
**Investigation Findings**:
- All 20 executions are from `/tmp/go-build*` paths - Go compiler temp directories
- Host is tagged `chromebook`, `max` - appears to be a developer workstation
- Parent processes are all `go` or `test` binaries
- No suspicious network connections or persistence attempts detected
**Risk Factors**: None identified
**Detection Count**: 20 (28% of total)
---
### Pattern #2: SecureAnnex alerts on ext-secureannex
**Verdict**: Likely FP (High Confidence)
**Investigation Findings**:
- Sensor hostname `ext-secureannex` is an extension adapter sensor
- Tagged `ext:ext-secureannex`, `lc:system` - infrastructure sensor
- All detections are Chrome extension risk assessments from expected scanning activity
- This is the SecureAnnex extension analyzer doing its job
**Risk Factors**: None identified
**Detection Count**: 24 (34% of total)
---
### Pattern #3: suspicious limacharlie domain
**Verdict**: Needs Review (Medium Confidence)
**Investigation Findings**:
- Domain `limacharlie.coursestack.io` appears to be a training platform
- Multiple employee devices connecting to this domain
- No obvious malicious indicators in the connections
**Risk Factors**:
- Cannot confirm domain ownership/legitimacy via automated check
- Recommend manual verification that this is an authorized training platform
**Detection Count**: 12 (17% of total)
Organize patterns into sections:
Use AskUserQuestion with multi-select to let the user choose which patterns to create FP rules for:
Which patterns would you like to create FP rules for?
Options (multi-select):
[ ] Pattern #1: Execution_From_Tmp on penguin (Likely FP)
[ ] Pattern #2: SecureAnnex on ext-secureannex (Likely FP)
[ ] Pattern #3: suspicious domain coursestack.io (Needs Review)
[ ] Pattern #4: FIM Hit on penguin (Likely FP)
[ ] None - cancel without creating rules
If user selects a pattern with verdict not_fp or needs_review, show a warning:
WARNING: You selected Pattern #3 which has verdict "Needs Review".
The investigation could not confirm this is a false positive.
Are you sure you want to create an FP rule for this pattern?
NEVER create blanket rules that match only on cat (category).
A rule that matches just the category will suppress ALL detections of that type, including real threats. This creates false negatives which are worse than false positives.
Every FP rule MUST include at least TWO conditions:
Prefer THREE conditions when investigation identifies specific patterns.
BAD (too broad - will cause false negatives):
# NEVER DO THIS
detection:
op: is
path: cat
value: "00313-NIX-Execution_From_Tmp"
GOOD (narrow - only suppresses the specific FP pattern):
detection:
op: and
rules:
- op: is
path: cat
value: "00313-NIX-Execution_From_Tmp"
- op: is
path: routing/hostname
value: penguin
- op: contains
path: detect/event/FILE_PATH
value: "/tmp/go-build"
The fp-pattern-investigator returns fp_rule_hints with recommended conditions. Use these hints to build the narrowest possible rule:
"fp_rule_hints": {
"recommended_conditions": [
{"path": "cat", "op": "is", "value": "00313-NIX-Execution_From_Tmp"},
{"path": "routing/hostname", "op": "is", "value": "penguin"},
{"path": "detect/event/FILE_PATH", "op": "contains", "value": "/tmp/go-build"}
],
"narrowest_identifier": "/tmp/go-build"
}
Single Host + File Path Pattern:
detection:
op: and
rules:
- op: is
path: cat
value: "[category]"
- op: is
path: routing/hostname
value: "[hostname]"
- op: contains
path: detect/event/FILE_PATH
value: "[path-pattern]"
Single Host + Command-Line Pattern:
detection:
op: and
rules:
- op: is
path: cat
value: "[category]"
- op: is
path: routing/hostname
value: "[hostname]"
- op: contains
path: detect/event/COMMAND_LINE
value: "[cmdline-pattern]"
Noisy Sensor + Event Type:
detection:
op: and
rules:
- op: is
path: cat
value: "[category]"
- op: is
path: routing/sid
value: "[sensor-id]"
Network Destination:
detection:
op: and
rules:
- op: is
path: cat
value: "[category]"
- op: is
path: detect/event/DOMAIN_NAME
value: "[exact-domain]"
Same Hash + Host:
detection:
op: and
rules:
- op: is
path: cat
value: "[category]"
- op: is
path: routing/hostname
value: "[hostname]"
- op: is
path: detect/event/HASH
value: "[hash]"
Service Account + Host:
detection:
op: and
rules:
- op: is
path: cat
value: "[category]"
- op: is
path: routing/hostname
value: "[hostname]"
- op: is
path: detect/event/USER_NAME
value: "[user-name]"
fp-auto-[pattern-type]-[identifier]-[YYYYMMDD]
Examples:
fp-auto-host-demo-win-2016-20251210fp-auto-cmdline-wmiprvse-secured-20251210fp-auto-svcacct-system-20251210Before presenting to user, validate the rule syntax:
cat > /tmp/detect.yaml << 'EOF'
<fp_rule_detection_logic>
EOF
cat > /tmp/respond.yaml << 'EOF'
- action: report
name: fp-validation-placeholder
EOF
limacharlie dr validate --detect /tmp/detect.yaml --respond /tmp/respond.yaml --oid [organization-id]
Present all generated rules for final review:
## Proposed FP Rules
### Rule #1: fp-auto-host-penguin-gobuild-20251215
**For Pattern**: Execution_From_Tmp on penguin
**Investigation Verdict**: Likely FP (High)
```yaml
detection:
op: and
rules:
- op: is
path: cat
value: "00313-NIX-Execution_From_Tmp"
- op: is
path: routing/hostname
value: penguin
- op: contains
path: detect/event/FILE_PATH
value: "/tmp/go-build"
Validation: Valid Note: 3 conditions ensure only Go build activity on penguin is suppressed.
For Pattern: SecureAnnex on ext-secureannex Investigation Verdict: Likely FP (High)
detection:
op: and
rules:
- op: starts with
path: cat
value: "SecureAnnex"
- op: is
path: routing/sid
value: "54cd8807-fd6b-431b-ba43-4d1aa9bf4aa8"
Validation: Valid Note: Sensor ID (sid) is highly specific - 2 conditions sufficient for sensor-based rules.
### 7.2 Ask for Deployment Confirmation
Ready to deploy [N] FP rules?
Options:
**NEVER deploy without explicit user approval.**
---
## Phase 8: Deploy Approved Rules
### 8.1 Deploy Each Rule
For each approved rule, deploy using the CLI:
```bash
cat > /tmp/fp-rule.yaml << 'EOF'
<rule-logic-yaml>
EOF
limacharlie fp set --key [rule-name] --input-file /tmp/fp-rule.yaml --oid [organization-id]
## FP Rules Deployed Successfully
| Rule Name | Status |
|-----------|--------|
| fp-auto-host-penguin-20251215 | Deployed |
| fp-auto-sensor-secureannex-20251215 | Deployed |
**Total Rules Deployed**: 2
**Recommended Next Steps**:
1. Monitor detection volume over the next 24-48 hours
2. Verify expected reduction in noisy alerts
3. If issues arise, use `limacharlie fp delete <name> --oid <oid>` to remove specific rules
4. Re-run this analysis in a week to find new patterns
User: "Find and fix false positive patterns in my detections from the last week"
Assistant:
limacharlie org list --output yaml to get OIDlimacharlie detection listfp-pattern-detector.sh scriptfp-pattern-investigator agents in parallelAskUserQuestion (multi-select) for user to select patternsAskUserQuestion for deployment confirmation--threshold 25detect/event/ prefix for event fields)--threshold 100needs_reviewThe FP pattern detection script is bundled with this skill in the scripts/ subdirectory. The skill's base directory is provided at the top of the skill prompt.
Path: {skill_base_directory}/scripts/fp-pattern-detector.sh
Usage:
{skill_base_directory}/scripts/fp-pattern-detector.sh <detections.jsonl> [--threshold N] [--host-pct N] [--sample-size N]
Output: JSON array to stdout, logs to stderr