Skill: Patterns
Purpose
Browse and search recurring patterns discovered across analyses. Patterns are auto-extracted after each analysis archive and represent behaviors that appear consistently in the data.
When to Use
- User says
/patternsor "what patterns have we seen?" - During analysis, to check if a finding matches a known pattern
- At session start, to remind the user of established behaviors
Invocation
/patterns — list patterns for the active dataset
/patterns --global — list patterns across all datasets
/patterns search={term} — search patterns by keyword
/patterns {id} — show full details for a specific pattern
Instructions
Step 0: Determine Active Dataset
Before loading patterns, identify the active dataset:
- Read
.knowledge/active.yamlto get the active dataset name - If the file doesn't exist or is empty, default to checking all datasets
- Use this dataset name when filtering patterns and referencing dataset-specific files
This ensures you're searching patterns for the correct dataset and providing accurate context.
Step 1: Load Patterns
- Check if
.knowledge/analyses/_patterns.yamlexists:- If it doesn't exist: "No patterns recorded yet. The pattern system initializes after your first analysis is archived."
- If it exists but is empty: "No patterns recorded yet. Complete 2-3 analyses and recurring patterns will emerge."
- If
--globalflag: also check and read.knowledge/global/cross_dataset_observations.yaml(same existence checks apply). - Load pattern data from existing files.
Step 2: Execute Command
List patterns (/patterns):
- Filter to active dataset (unless
--global) - Sort by occurrences descending (most established first)
- Display as a table: type, description, occurrences, confidence, last seen
- Show total count
Show specific (/patterns {id}):
- Display: description, type, all evidence (with analysis IDs), dimensions, metrics, suggested investigation
- Offer: "Want to investigate this pattern further?"
Search (/patterns search={term}):
- Search across description, dimensions, metrics, tags
- Use flexible matching: include synonyms and related terms (e.g., "mobile" matches "device", "platform")
- Display matching patterns as a table
- If no matches: suggest related terms or broader searches
- Always explain why you found/didn't find matches
Global (/patterns --global):
- Include cross-dataset observations alongside per-dataset patterns
- Note which dataset each pattern was observed in
Step 3: Contextual Suggestions
After displaying patterns:
- "Want to check if {pattern} still holds in the current data?"
- "Want to use {pattern} as context for a new analysis?"
- "This pattern was last seen {N} days ago — may need revalidation."
For empty state (0 patterns): Keep the empty-state response short and practical. Cover:
- Why no patterns exist (need 2+ analyses with consistent findings)
- How many analyses are currently archived
- What happens after completing more analyses
- 1-2 suggested next actions
Avoid lengthy explanations of how the pattern system works — users want quick answers when nothing exists yet.
Pattern Extraction (Auto)
After each analysis archive (triggered by archive-analysis skill), scan the new analysis for potential patterns:
- Compare new findings to existing patterns:
- If a finding matches an existing pattern → increment occurrences, update last_seen
- If a finding is new but could extend a pattern → add as evidence
- Look for NEW patterns:
- Same metric behavior across 2+ analyses → candidate pattern
- Same segment consistently outperforming → candidate pattern
- Recurring anomaly at similar times → candidate pattern
- Write updated patterns back to
_patterns.yaml
Minimum 2 occurrences to create a pattern. Single-occurrence findings are just findings, not patterns.
Edge Cases
- No patterns: Suggest running more analyses
- Stale patterns (last_seen >60 days): Flag as potentially outdated
- Contradictory patterns: Flag and suggest investigation
- Too many patterns (>50): Show top 20 by occurrences, offer pagination