@sniper.ai/core 3.2.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/memory-curator.md +112 -0
- package/agents/retro-analyst.md +61 -9
- package/checklists/plan.yaml +1 -1
- package/checklists/retro.yaml +15 -0
- package/config.template.yaml +10 -1
- package/package.json +1 -1
- package/protocols/feature.yaml +12 -1
- package/protocols/full.yaml +24 -3
- package/protocols/refactor.yaml +12 -1
- package/schemas/learning.schema.yaml +128 -0
- package/schemas/protocol.schema.yaml +15 -2
- package/schemas/retro.schema.yaml +4 -0
- package/schemas/signal.schema.yaml +9 -1
- package/skills/sniper-flow/SKILL.md +45 -13
- package/skills/sniper-init/SKILL.md +5 -0
- package/skills/sniper-learn/SKILL.md +140 -0
- package/skills/sniper-review/SKILL.md +11 -0
- package/templates/custom-protocol.yaml +33 -3
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
write_scope:
|
|
3
|
+
- ".sniper/memory/"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Memory Curator
|
|
7
|
+
|
|
8
|
+
You are a SNIPER memory curator agent. You manage the lifecycle of project learnings — consolidating, validating, and pruning the learning store.
|
|
9
|
+
|
|
10
|
+
## Responsibilities
|
|
11
|
+
|
|
12
|
+
1. **Consolidation** — Merge duplicate or overlapping learnings
|
|
13
|
+
2. **Contradiction Detection** — Find conflicting learnings and flag for resolution
|
|
14
|
+
3. **Staleness Check** — Flag learnings that haven't been applied or reinforced recently
|
|
15
|
+
4. **Spec Drift Detection** — Check if learnings still apply after spec/architecture changes
|
|
16
|
+
5. **Signal Migration** — Convert legacy signals to learning records
|
|
17
|
+
6. **Pruning** — Archive old deprecated learnings
|
|
18
|
+
|
|
19
|
+
## Invocation
|
|
20
|
+
|
|
21
|
+
You are spawned:
|
|
22
|
+
- As the optional `curate` phase in protocols (after retro)
|
|
23
|
+
- On-demand via `/sniper-learn --review`
|
|
24
|
+
- Automatically when active learning count exceeds 30
|
|
25
|
+
|
|
26
|
+
## Curation Process
|
|
27
|
+
|
|
28
|
+
### 1. Consolidation
|
|
29
|
+
|
|
30
|
+
1. Read all learnings from `.sniper/memory/learnings/` with `status: active` or `status: validated`
|
|
31
|
+
2. Group learnings by overlapping `scope` (same agents, phases, or file patterns)
|
|
32
|
+
3. Within each group, compare `learning` text for semantic similarity
|
|
33
|
+
4. If two or more learnings describe the same pattern:
|
|
34
|
+
- Merge into the learning with the highest confidence
|
|
35
|
+
- Combine `reinforced_by` and `applied_in` arrays
|
|
36
|
+
- Set confidence to the max of the merged learnings
|
|
37
|
+
- Add history entry: `event: merged`, listing merged learning IDs
|
|
38
|
+
- Set merged learnings to `status: deprecated`, `superseded_by: <winner_id>`
|
|
39
|
+
|
|
40
|
+
### 2. Contradiction Detection
|
|
41
|
+
|
|
42
|
+
1. For each pair of active learnings, check if:
|
|
43
|
+
- The `anti_pattern` of one matches the `correction` of another
|
|
44
|
+
- The `learning` text directly contradicts another learning
|
|
45
|
+
2. If a contradiction is found:
|
|
46
|
+
- Add each learning's ID to the other's `contradicted_by` array
|
|
47
|
+
- Reduce confidence by 0.1 on the older learning
|
|
48
|
+
- Add history entry: `event: contradicted`
|
|
49
|
+
- If both learnings have confidence >= 0.7, present the conflict to the user for resolution
|
|
50
|
+
|
|
51
|
+
### 3. Staleness Check
|
|
52
|
+
|
|
53
|
+
1. Determine the last 5 protocol IDs from `.sniper/retros/` (sorted by date)
|
|
54
|
+
2. For each active learning:
|
|
55
|
+
- If the learning's `applied_in` does not include any of the last 5 protocol IDs AND the learning has not been reinforced in the last 90 days:
|
|
56
|
+
- Flag as stale
|
|
57
|
+
- Read current `docs/spec.md` and `docs/architecture.md`
|
|
58
|
+
- Assess whether the learning still applies to the current project state
|
|
59
|
+
- If clearly outdated, set `status: deprecated` with history entry
|
|
60
|
+
- If uncertain, reduce confidence by 0.05 and add history entry: `event: confidence_adjusted`
|
|
61
|
+
|
|
62
|
+
### 4. Spec Drift Detection
|
|
63
|
+
|
|
64
|
+
1. For each active learning with `scope.files` defined:
|
|
65
|
+
- Run `git log --since=<learning.updated_at> --name-only -- docs/spec.md docs/architecture.md` to check for changes
|
|
66
|
+
- If spec/architecture has changed since the learning was last updated:
|
|
67
|
+
- Read the current spec/architecture
|
|
68
|
+
- Assess if the learning still applies
|
|
69
|
+
- If clearly invalidated: set `status: deprecated` with history entry
|
|
70
|
+
- If unclear: flag for human review, add history note
|
|
71
|
+
|
|
72
|
+
### 5. Signal Migration
|
|
73
|
+
|
|
74
|
+
1. Read all files from `.sniper/memory/signals/`
|
|
75
|
+
2. For each signal file:
|
|
76
|
+
- Create a learning record:
|
|
77
|
+
- `source.type`: map from signal type (`ci_failure` → `ci_failure`, `pr_review_comment` → `pr_review`, `production_error` → `ci_failure`, `manual` → `human`)
|
|
78
|
+
- `confidence`: 0.4 for CI/PR signals, 0.9 for manual
|
|
79
|
+
- `learning`: signal's `learning` field, or `summary` if no learning
|
|
80
|
+
- `scope.files`: signal's `affected_files`
|
|
81
|
+
- Write to `.sniper/memory/learnings/L-{date}-{hash}.yaml`
|
|
82
|
+
- Delete the original signal file
|
|
83
|
+
3. Log: "Migrated N signals to learnings"
|
|
84
|
+
|
|
85
|
+
### 6. Pruning
|
|
86
|
+
|
|
87
|
+
1. Find deprecated learnings where `updated_at` is more than 180 days ago
|
|
88
|
+
2. Move these files to `.sniper/memory/archive/`
|
|
89
|
+
3. Log: "Archived N deprecated learnings"
|
|
90
|
+
|
|
91
|
+
## Output
|
|
92
|
+
|
|
93
|
+
After curation, write a summary to stdout:
|
|
94
|
+
```
|
|
95
|
+
Curation complete:
|
|
96
|
+
- Consolidated: N learnings merged into M
|
|
97
|
+
- Contradictions: N pairs flagged
|
|
98
|
+
- Stale: N learnings flagged
|
|
99
|
+
- Spec drift: N learnings reviewed
|
|
100
|
+
- Migrated: N signals → learnings
|
|
101
|
+
- Archived: N deprecated learnings
|
|
102
|
+
- Active learnings: N (confidence avg: X.XX)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Rules
|
|
106
|
+
|
|
107
|
+
- NEVER delete a learning without archiving it first
|
|
108
|
+
- NEVER auto-deprecate human-sourced learnings (confidence >= 0.9) — flag for review instead
|
|
109
|
+
- ALWAYS write history entries for every status or confidence change
|
|
110
|
+
- Write scope is `.sniper/memory/` only — never modify project code or other SNIPER directories
|
|
111
|
+
- Cap consolidation at 10 merges per run to avoid over-aggressive pruning
|
|
112
|
+
- When uncertain about staleness or spec drift, err on the side of keeping the learning
|
package/agents/retro-analyst.md
CHANGED
|
@@ -18,7 +18,7 @@ You are a SNIPER retro analyst agent. You run automated retrospectives after pro
|
|
|
18
18
|
|
|
19
19
|
## Invocation
|
|
20
20
|
|
|
21
|
-
You are
|
|
21
|
+
You are spawned as part of the `retro` phase in protocols (full, feature, refactor).
|
|
22
22
|
The orchestrator provides you with the `protocol_id` (e.g., `SNPR-20260307-a3f2`) and protocol type.
|
|
23
23
|
|
|
24
24
|
## Analysis Process
|
|
@@ -61,23 +61,75 @@ findings:
|
|
|
61
61
|
- Keep the report concise — under 1000 tokens
|
|
62
62
|
- Compare against previous retros if they exist to track trends
|
|
63
63
|
|
|
64
|
+
## Learning Extraction
|
|
65
|
+
|
|
66
|
+
After generating the retro report, extract learnings into the unified learning store:
|
|
67
|
+
|
|
68
|
+
1. For each `action_item` in the retro findings, create a learning record:
|
|
69
|
+
- `id`: `L-{YYYYMMDD}-{4-char-hex}`
|
|
70
|
+
- `status: active`
|
|
71
|
+
- `confidence: 0.5`
|
|
72
|
+
- `source.type: retro`
|
|
73
|
+
- `source.protocol_id: {protocol_id}`
|
|
74
|
+
- `source.detail`: context from the retro finding
|
|
75
|
+
- `learning`: the action item text
|
|
76
|
+
- `scope`: infer from context — which phase failed (→ `scope.phases`), which agents were involved (→ `scope.agents`), which files were touched (→ `scope.files`)
|
|
77
|
+
- Write to `.sniper/memory/learnings/L-{date}-{hash}.yaml`
|
|
78
|
+
|
|
79
|
+
2. For each `needs_improvement` item that is **specific and actionable** (not vague like "better communication"):
|
|
80
|
+
- Create a learning at `confidence: 0.4`
|
|
81
|
+
- Same format as above
|
|
82
|
+
|
|
83
|
+
3. **Cap at 5 learnings per retro** to avoid noise. Prioritize by specificity and actionability.
|
|
84
|
+
|
|
85
|
+
4. Record the created learning IDs in the retro report under `findings.learning_ids`.
|
|
86
|
+
|
|
87
|
+
## Learning Effectiveness Check
|
|
88
|
+
|
|
89
|
+
After extracting new learnings, check effectiveness of previously applied learnings:
|
|
90
|
+
|
|
91
|
+
1. Read all active learnings from `.sniper/memory/learnings/` where `applied_in` contains any recent protocol ID (including the current one)
|
|
92
|
+
2. For each such learning, check if the related problem recurred:
|
|
93
|
+
- Gate failures in the learning's scoped phase?
|
|
94
|
+
- CI failures in the learning's scoped files?
|
|
95
|
+
- Human rejection feedback mentioning the same pattern?
|
|
96
|
+
3. **No recurrence** → increase confidence by +0.05, add history entry:
|
|
97
|
+
```yaml
|
|
98
|
+
- timestamp: <ISO 8601>
|
|
99
|
+
event: validated_by_absence
|
|
100
|
+
detail: "No recurrence in {protocol_id}"
|
|
101
|
+
confidence_delta: +0.05
|
|
102
|
+
```
|
|
103
|
+
4. **Recurrence despite the learning** → decrease confidence by -0.2, add history entry:
|
|
104
|
+
```yaml
|
|
105
|
+
- timestamp: <ISO 8601>
|
|
106
|
+
event: recurrence_detected
|
|
107
|
+
detail: "Problem recurred in {protocol_id} despite learning"
|
|
108
|
+
confidence_delta: -0.2
|
|
109
|
+
```
|
|
110
|
+
Flag for human review by adding to findings.
|
|
111
|
+
5. If confidence drops below 0.2 after adjustment, set `status: deprecated`.
|
|
112
|
+
|
|
64
113
|
## Signal Analysis
|
|
65
114
|
|
|
66
|
-
During the retrospective, analyze external signals:
|
|
115
|
+
During the retrospective, analyze external signals from both legacy and new stores:
|
|
67
116
|
|
|
68
|
-
1. Read `.sniper/memory/signals/` for signal records
|
|
69
|
-
2.
|
|
70
|
-
3.
|
|
71
|
-
4.
|
|
72
|
-
5.
|
|
117
|
+
1. Read `.sniper/memory/signals/` for legacy signal records (if any exist)
|
|
118
|
+
2. Read `.sniper/memory/learnings/` for existing learnings
|
|
119
|
+
3. Correlate signals with protocol phases: which CI failures occurred during which phase?
|
|
120
|
+
4. Identify recurring patterns: are the same files or tests failing repeatedly?
|
|
121
|
+
5. If legacy signals exist, note in the retro report: "Legacy signals detected. Run `/sniper-learn --review` to migrate to learnings."
|
|
122
|
+
6. Include signal summary in the retro report under a `signals_analyzed` section:
|
|
73
123
|
```yaml
|
|
74
124
|
signals_analyzed:
|
|
75
125
|
total: <count>
|
|
76
126
|
by_type:
|
|
77
127
|
ci_failure: <count>
|
|
78
128
|
pr_review_comment: <count>
|
|
79
|
-
|
|
80
|
-
|
|
129
|
+
learnings_checked: <count>
|
|
130
|
+
effectiveness:
|
|
131
|
+
validated: <count>
|
|
132
|
+
recurrence: <count>
|
|
81
133
|
```
|
|
82
134
|
|
|
83
135
|
## Velocity Tracking
|
package/checklists/plan.yaml
CHANGED
|
@@ -22,7 +22,7 @@ checks:
|
|
|
22
22
|
|
|
23
23
|
- id: open_questions
|
|
24
24
|
description: No unresolved open questions remain
|
|
25
|
-
check: "!grep:.sniper/artifacts/{protocol_id}
|
|
25
|
+
check: "!grep:.sniper/artifacts/{protocol_id}/plan.md:\\*\\*TBD\\*\\*|\\*\\*TODO\\*\\*|\\*\\*OPEN\\*\\*"
|
|
26
26
|
blocking: false
|
|
27
27
|
|
|
28
28
|
- id: token_budget
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: retro
|
|
2
|
+
description: Gate checks for the retrospective phase
|
|
3
|
+
|
|
4
|
+
checks:
|
|
5
|
+
- id: retro_report_exists
|
|
6
|
+
description: Retro report file exists
|
|
7
|
+
type: file_exists
|
|
8
|
+
path: ".sniper/retros/{protocol_id}.yaml"
|
|
9
|
+
blocking: true
|
|
10
|
+
|
|
11
|
+
- id: velocity_updated
|
|
12
|
+
description: Velocity data updated
|
|
13
|
+
type: file_exists
|
|
14
|
+
path: ".sniper/memory/velocity.yaml"
|
|
15
|
+
blocking: true
|
package/config.template.yaml
CHANGED
|
@@ -24,6 +24,7 @@ agents:
|
|
|
24
24
|
- code-reviewer
|
|
25
25
|
- gate-reviewer
|
|
26
26
|
- retro-analyst
|
|
27
|
+
- memory-curator
|
|
27
28
|
|
|
28
29
|
# Cognitive mixins applied to agents during scaffolding
|
|
29
30
|
# Format: agent-name: [mixin1, mixin2]
|
|
@@ -148,9 +149,17 @@ plugins: []
|
|
|
148
149
|
# workspace:
|
|
149
150
|
# ref: "../.sniper-workspace"
|
|
150
151
|
|
|
152
|
+
# Learning store configuration
|
|
153
|
+
learning:
|
|
154
|
+
max_per_retro: 5 # Cap learnings created per retro
|
|
155
|
+
min_confidence: 0.4 # Threshold for composition into agent prompts
|
|
156
|
+
composition_limit: 10 # Max learnings composed per agent
|
|
157
|
+
staleness_threshold: 5 # Protocols without application before flagging
|
|
158
|
+
archive_after_days: 180 # Days after deprecation before archiving
|
|
159
|
+
|
|
151
160
|
# Visibility settings
|
|
152
161
|
visibility:
|
|
153
162
|
live_status: true # Maintain .sniper/live-status.yaml
|
|
154
163
|
checkpoints: true # Write phase checkpoints
|
|
155
164
|
cost_tracking: true # Track token usage
|
|
156
|
-
auto_retro: true
|
|
165
|
+
# auto_retro: true # DEPRECATED — use retro phase in protocols instead
|
package/package.json
CHANGED
package/protocols/feature.yaml
CHANGED
|
@@ -54,4 +54,15 @@ phases:
|
|
|
54
54
|
outputs:
|
|
55
55
|
- .sniper/artifacts/{protocol_id}/review-report.md
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
- name: retro
|
|
58
|
+
description: Retrospective — extract learnings, update velocity, check learning effectiveness
|
|
59
|
+
agents:
|
|
60
|
+
- retro-analyst
|
|
61
|
+
spawn_strategy: single
|
|
62
|
+
gate:
|
|
63
|
+
checklist: retro
|
|
64
|
+
human_approval: false
|
|
65
|
+
outputs:
|
|
66
|
+
- .sniper/retros/{protocol_id}.yaml
|
|
67
|
+
- .sniper/memory/velocity.yaml
|
|
68
|
+
- .sniper/memory/learnings/
|
package/protocols/full.yaml
CHANGED
|
@@ -4,11 +4,11 @@ budget: 2000000 # 2M tokens
|
|
|
4
4
|
|
|
5
5
|
phases:
|
|
6
6
|
- name: discover
|
|
7
|
-
description: Research
|
|
7
|
+
description: Research and analyze codebase to produce discovery spec
|
|
8
8
|
agents:
|
|
9
9
|
- analyst
|
|
10
10
|
spawn_strategy: single # One agent, no team needed
|
|
11
|
-
interactive_review: true # User reviews spec
|
|
11
|
+
interactive_review: true # User reviews spec before architecture begins
|
|
12
12
|
gate:
|
|
13
13
|
checklist: discover
|
|
14
14
|
human_approval: true
|
|
@@ -73,4 +73,25 @@ phases:
|
|
|
73
73
|
outputs:
|
|
74
74
|
- .sniper/artifacts/{protocol_id}/review-report.md
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
- name: retro
|
|
77
|
+
description: Retrospective — extract learnings, update velocity, check learning effectiveness
|
|
78
|
+
agents:
|
|
79
|
+
- retro-analyst
|
|
80
|
+
spawn_strategy: single
|
|
81
|
+
gate:
|
|
82
|
+
checklist: retro
|
|
83
|
+
human_approval: false
|
|
84
|
+
outputs:
|
|
85
|
+
- .sniper/retros/{protocol_id}.yaml
|
|
86
|
+
- .sniper/memory/velocity.yaml
|
|
87
|
+
- .sniper/memory/learnings/
|
|
88
|
+
|
|
89
|
+
- name: curate
|
|
90
|
+
description: Review and consolidate learnings (skipped if not needed)
|
|
91
|
+
agents:
|
|
92
|
+
- memory-curator
|
|
93
|
+
spawn_strategy: single
|
|
94
|
+
skip_if: learning_count < 30 AND last_curation_within_5_protocols
|
|
95
|
+
gate:
|
|
96
|
+
checklist: none
|
|
97
|
+
human_approval: false
|
package/protocols/refactor.yaml
CHANGED
|
@@ -40,4 +40,15 @@ phases:
|
|
|
40
40
|
outputs:
|
|
41
41
|
- .sniper/artifacts/{protocol_id}/review-report.md
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
- name: retro
|
|
44
|
+
description: Retrospective — extract learnings, update velocity, check learning effectiveness
|
|
45
|
+
agents:
|
|
46
|
+
- retro-analyst
|
|
47
|
+
spawn_strategy: single
|
|
48
|
+
gate:
|
|
49
|
+
checklist: retro
|
|
50
|
+
human_approval: false
|
|
51
|
+
outputs:
|
|
52
|
+
- .sniper/retros/{protocol_id}.yaml
|
|
53
|
+
- .sniper/memory/velocity.yaml
|
|
54
|
+
- .sniper/memory/learnings/
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
$schema: "https://json-schema.org/draft/2020-12/schema"
|
|
2
|
+
$id: "https://sniper.ai/schemas/learning"
|
|
3
|
+
title: Learning Record
|
|
4
|
+
description: Schema for SNIPER learning records — unified store for project-specific learnings captured from retros, human feedback, CI failures, PR reviews, and gate failures.
|
|
5
|
+
type: object
|
|
6
|
+
required:
|
|
7
|
+
- id
|
|
8
|
+
- status
|
|
9
|
+
- confidence
|
|
10
|
+
- created_at
|
|
11
|
+
- source
|
|
12
|
+
- learning
|
|
13
|
+
properties:
|
|
14
|
+
id:
|
|
15
|
+
type: string
|
|
16
|
+
pattern: "^L-\\d{8}-[a-f0-9]{4}$"
|
|
17
|
+
description: "Unique learning ID in format L-YYYYMMDD-XXXX (4-char hex suffix)."
|
|
18
|
+
status:
|
|
19
|
+
type: string
|
|
20
|
+
enum: [draft, active, validated, deprecated]
|
|
21
|
+
description: Lifecycle status of the learning.
|
|
22
|
+
confidence:
|
|
23
|
+
type: number
|
|
24
|
+
minimum: 0.0
|
|
25
|
+
maximum: 1.0
|
|
26
|
+
description: "Confidence score (0.0–1.0). Changes over time based on reinforcement, contradictions, and decay."
|
|
27
|
+
created_at:
|
|
28
|
+
type: string
|
|
29
|
+
format: date-time
|
|
30
|
+
description: When the learning was first created.
|
|
31
|
+
updated_at:
|
|
32
|
+
type: string
|
|
33
|
+
format: date-time
|
|
34
|
+
description: When the learning was last modified.
|
|
35
|
+
expires_at:
|
|
36
|
+
type: string
|
|
37
|
+
format: date-time
|
|
38
|
+
description: "Optional expiration date. Null means never expires."
|
|
39
|
+
|
|
40
|
+
# Origin
|
|
41
|
+
source:
|
|
42
|
+
type: object
|
|
43
|
+
required:
|
|
44
|
+
- type
|
|
45
|
+
properties:
|
|
46
|
+
type:
|
|
47
|
+
type: string
|
|
48
|
+
enum: [retro, human, ci_failure, pr_review, gate_failure]
|
|
49
|
+
description: How this learning entered the system.
|
|
50
|
+
protocol_id:
|
|
51
|
+
type: string
|
|
52
|
+
description: "Protocol ID that generated this learning (null for human-submitted)."
|
|
53
|
+
detail:
|
|
54
|
+
type: string
|
|
55
|
+
description: Context about how the learning was discovered.
|
|
56
|
+
additionalProperties: false
|
|
57
|
+
|
|
58
|
+
# The learning itself
|
|
59
|
+
learning:
|
|
60
|
+
type: string
|
|
61
|
+
description: The core insight or lesson learned.
|
|
62
|
+
anti_pattern:
|
|
63
|
+
type: string
|
|
64
|
+
description: What to avoid — the behavior that caused the problem.
|
|
65
|
+
correction:
|
|
66
|
+
type: string
|
|
67
|
+
description: What to do instead — the recommended approach.
|
|
68
|
+
|
|
69
|
+
# Scoping
|
|
70
|
+
scope:
|
|
71
|
+
type: object
|
|
72
|
+
properties:
|
|
73
|
+
agents:
|
|
74
|
+
type: array
|
|
75
|
+
items: { type: string }
|
|
76
|
+
description: "Agent personas this learning applies to. Null = all agents."
|
|
77
|
+
phases:
|
|
78
|
+
type: array
|
|
79
|
+
items: { type: string }
|
|
80
|
+
description: "Protocol phases this learning applies to. Null = all phases."
|
|
81
|
+
files:
|
|
82
|
+
type: array
|
|
83
|
+
items: { type: string }
|
|
84
|
+
description: "Glob patterns for relevant files. Null = all files."
|
|
85
|
+
additionalProperties: false
|
|
86
|
+
|
|
87
|
+
# Effectiveness tracking
|
|
88
|
+
applied_in:
|
|
89
|
+
type: array
|
|
90
|
+
items: { type: string }
|
|
91
|
+
description: Protocol IDs where this learning was composed into agent prompts.
|
|
92
|
+
reinforced_by:
|
|
93
|
+
type: array
|
|
94
|
+
items: { type: string }
|
|
95
|
+
description: Event or learning IDs that confirm this learning.
|
|
96
|
+
contradicted_by:
|
|
97
|
+
type: array
|
|
98
|
+
items: { type: string }
|
|
99
|
+
description: Learning IDs that contradict this learning.
|
|
100
|
+
superseded_by:
|
|
101
|
+
type: string
|
|
102
|
+
description: "If deprecated, the learning ID that replaced this one."
|
|
103
|
+
|
|
104
|
+
# Audit trail
|
|
105
|
+
history:
|
|
106
|
+
type: array
|
|
107
|
+
items:
|
|
108
|
+
type: object
|
|
109
|
+
required:
|
|
110
|
+
- timestamp
|
|
111
|
+
- event
|
|
112
|
+
properties:
|
|
113
|
+
timestamp:
|
|
114
|
+
type: string
|
|
115
|
+
format: date-time
|
|
116
|
+
event:
|
|
117
|
+
type: string
|
|
118
|
+
enum: [created, reinforced, contradicted, deprecated, validated_by_absence, recurrence_detected, confidence_adjusted, merged, human_confirmed, human_invalidated]
|
|
119
|
+
actor:
|
|
120
|
+
type: string
|
|
121
|
+
description: "Who triggered this event (agent name or 'human')."
|
|
122
|
+
detail:
|
|
123
|
+
type: string
|
|
124
|
+
confidence_delta:
|
|
125
|
+
type: number
|
|
126
|
+
description: "Change in confidence from this event (e.g., +0.1, -0.2)."
|
|
127
|
+
additionalProperties: false
|
|
128
|
+
additionalProperties: false
|
|
@@ -54,7 +54,9 @@ properties:
|
|
|
54
54
|
properties:
|
|
55
55
|
checklist:
|
|
56
56
|
type: string
|
|
57
|
-
description:
|
|
57
|
+
description: >
|
|
58
|
+
Name of the checklist to evaluate at the gate.
|
|
59
|
+
Use "none" to skip checklist evaluation (phase still completes normally).
|
|
58
60
|
human_approval:
|
|
59
61
|
type: boolean
|
|
60
62
|
description: Whether a human must approve the gate before proceeding.
|
|
@@ -93,8 +95,19 @@ properties:
|
|
|
93
95
|
type: string
|
|
94
96
|
description: Description of the coordination requirement.
|
|
95
97
|
additionalProperties: false
|
|
98
|
+
skip_if:
|
|
99
|
+
type: string
|
|
100
|
+
description: >
|
|
101
|
+
Predicate expression that, when true, causes this phase to be skipped.
|
|
102
|
+
Available variables: learning_count (active learnings),
|
|
103
|
+
last_curation_within_N_protocols (boolean).
|
|
104
|
+
Example: "learning_count < 30 AND last_curation_within_5_protocols"
|
|
96
105
|
additionalProperties: false
|
|
97
106
|
auto_retro:
|
|
98
107
|
type: boolean
|
|
99
|
-
|
|
108
|
+
deprecated: true
|
|
109
|
+
description: >
|
|
110
|
+
DEPRECATED — Use a 'retro' phase in the phases list instead.
|
|
111
|
+
When true, spawns retro-analyst after protocol completion. Retained for
|
|
112
|
+
backward compatibility with custom protocols that don't define a retro phase.
|
|
100
113
|
additionalProperties: false
|
|
@@ -78,6 +78,10 @@ properties:
|
|
|
78
78
|
description: Concrete action items for future runs.
|
|
79
79
|
items:
|
|
80
80
|
type: string
|
|
81
|
+
learning_ids:
|
|
82
|
+
type: array
|
|
83
|
+
items: { type: string }
|
|
84
|
+
description: IDs of learnings created from this retro's findings.
|
|
81
85
|
velocity:
|
|
82
86
|
type: object
|
|
83
87
|
description: Velocity metrics for this execution, used for budget calibration.
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
$schema: "https://json-schema.org/draft/2020-12/schema"
|
|
2
2
|
$id: "https://sniper.ai/schemas/signal"
|
|
3
3
|
title: External Signal Record
|
|
4
|
-
|
|
4
|
+
deprecated: true
|
|
5
|
+
superseded_by: learning.schema.yaml
|
|
6
|
+
description: >
|
|
7
|
+
DEPRECATED — Superseded by learning.schema.yaml.
|
|
8
|
+
This schema is retained for backward compatibility. Existing signal files in
|
|
9
|
+
.sniper/memory/signals/ will be migrated to learnings by the memory-curator
|
|
10
|
+
agent on first run. Use /sniper-learn --review to trigger migration.
|
|
11
|
+
Original description: Schema for SNIPER signal records that capture learnings
|
|
12
|
+
from CI failures, PR reviews, and production errors.
|
|
5
13
|
type: object
|
|
6
14
|
required:
|
|
7
15
|
- type
|
|
@@ -63,10 +63,11 @@ For each phase in the protocol, execute these 5 steps:
|
|
|
63
63
|
### Execute
|
|
64
64
|
|
|
65
65
|
1. Determine spawn strategy from protocol phase definition (`single`, `sequential`, `parallel`, or `team`)
|
|
66
|
-
2. Spawn agents
|
|
67
|
-
3.
|
|
68
|
-
4.
|
|
69
|
-
5.
|
|
66
|
+
2. Spawn **ONLY** the agents listed in the protocol phase's `agents` array — no more, no fewer. Do NOT infer additional agents from the phase description or outputs. The `agents` list is the single source of truth for who participates in each phase.
|
|
67
|
+
3. Spawn agents per [Reference: Spawn Strategies](#reference-spawn-strategies)
|
|
68
|
+
4. Monitor via TaskList — if an agent is blocked, investigate and guide via SendMessage
|
|
69
|
+
5. If an agent crashes: note the failure, continue with remaining agents
|
|
70
|
+
6. After all parallel agents complete: coordinate worktree merges per [Reference: Merge Coordination](#reference-merge-coordination)
|
|
70
71
|
|
|
71
72
|
### Checkpoint
|
|
72
73
|
|
|
@@ -108,8 +109,8 @@ After the `solve` phase completes, populate the `stories` array in `.sniper/live
|
|
|
108
109
|
2. Update `.sniper/live-status.yaml` with `status: completed`
|
|
109
110
|
3. Update `.sniper/artifacts/{protocol_id}/meta.yaml` with final status, token usage, commits, agents used
|
|
110
111
|
4. Update `.sniper/artifacts/registry.md` entry from `in_progress` to `completed`
|
|
111
|
-
5. Present summary: phases completed, gate results, token usage
|
|
112
|
-
6. If `auto_retro: true` in
|
|
112
|
+
5. Present summary: phases completed, gate results, token usage, learnings created
|
|
113
|
+
6. **Backward compatibility:** If the protocol has `auto_retro: true` but no `retro` phase in its phases list (custom protocols), spawn retro-analyst as a single-agent phase before completing
|
|
113
114
|
|
|
114
115
|
## Cost Tracking
|
|
115
116
|
|
|
@@ -143,9 +144,26 @@ For each agent in the phase, build the full prompt by layering these sources. Ea
|
|
|
143
144
|
| 2. Mixins | `.claude/personas/cognitive/<mixin>.md` (from `config.agents.mixins.<agent>`) | WARN — skip mixin, continue |
|
|
144
145
|
| 3. Domain knowledge | `.sniper/knowledge/manifest.yaml` → referenced files (from agent's `knowledge_sources` frontmatter) | SKIP — no knowledge section |
|
|
145
146
|
| 4. Workspace conventions | `.sniper-workspace/config.yaml` → `shared.conventions` and `shared.anti_patterns` | SKIP — no workspace section |
|
|
146
|
-
| 5.
|
|
147
|
+
| 5. Learnings | `.sniper/memory/learnings/` → scoped, confidence-ranked, top 10 | SKIP — no learnings |
|
|
147
148
|
|
|
148
|
-
|
|
149
|
+
**Learning Composition (Layer 5):**
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Filter: status IN (active, validated), confidence >= 0.4
|
|
153
|
+
Match: scope.agents includes <current_agent> OR scope.agents is null
|
|
154
|
+
Match: scope.phases includes <current_phase> OR scope.phases is null
|
|
155
|
+
Match: scope.files overlaps with <agent_ownership_paths> OR scope.files is null
|
|
156
|
+
Rank: confidence DESC, updated_at DESC
|
|
157
|
+
Limit: 10
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Confidence bands: `>= 0.7` = HIGH, `0.4–0.7` = MEDIUM.
|
|
161
|
+
|
|
162
|
+
After composing learnings into the prompt, record the current protocol ID in each learning's `applied_in` array (write the updated learning file back).
|
|
163
|
+
|
|
164
|
+
**Backward compatibility:** If `.sniper/memory/signals/` contains files but `.sniper/memory/learnings/` is empty or doesn't exist, fall back to the old Layer 5 behavior (read signals, top 10 by `affected_files` and `relevance_tags`). Log a warning: "Legacy signals detected. Run `/sniper-learn --review` to migrate."
|
|
165
|
+
|
|
166
|
+
The composed prompt = base definition + concatenated mixin content + `## Domain Knowledge` section + `## Workspace Conventions` section + `## Anti-Patterns (Workspace)` section + `## Learnings` section (formatted as `- [HIGH] {learning}. Anti-pattern: {anti_pattern}. Instead: {correction}.` or `- [MEDIUM] {learning}.`).
|
|
149
167
|
|
|
150
168
|
Replace all `{protocol_id}` placeholders in the composed prompt with the actual protocol ID.
|
|
151
169
|
|
|
@@ -192,9 +210,23 @@ When a phase has `interactive_review: true`:
|
|
|
192
210
|
- **Edit directly** — user modifies plan files, says "done", re-validate via gate
|
|
193
211
|
4. Only advance after explicit user approval
|
|
194
212
|
|
|
195
|
-
## Reference: Retrospective
|
|
213
|
+
## Reference: Retrospective (Legacy)
|
|
214
|
+
|
|
215
|
+
> **Note:** The retro is now a first-class phase in protocols (full, feature, refactor). This reference is retained for backward compatibility with custom protocols using `auto_retro: true`.
|
|
216
|
+
|
|
217
|
+
When `auto_retro: true` and no `retro` phase exists in the protocol:
|
|
218
|
+
1. Spawn `retro-analyst` as a single-agent phase with: protocol ID, checkpoint history, gate results, cost data
|
|
219
|
+
2. The retro-analyst writes a report to `.sniper/retros/{protocol_id}.yaml`, extracts learnings to `.sniper/memory/learnings/`, updates `.sniper/memory/velocity.yaml`, and checks effectiveness of previously applied learnings
|
|
220
|
+
3. Run the retro gate checklist (retro report exists + velocity updated)
|
|
221
|
+
|
|
222
|
+
## Reference: Review Gate Feedback Capture
|
|
223
|
+
|
|
224
|
+
When a user selects "Request changes" during an interactive review:
|
|
196
225
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
226
|
+
1. Ask: "What should be changed and why?"
|
|
227
|
+
2. Parse the response for actionable learnings — patterns and rules, not one-off fixes
|
|
228
|
+
3. If the feedback describes a generalizable pattern (not just "fix line 42"):
|
|
229
|
+
- Create a learning with `source.type: human`, `confidence: 0.9`
|
|
230
|
+
- Scope to the current phase and relevant agents
|
|
231
|
+
- Write to `.sniper/memory/learnings/`
|
|
232
|
+
4. Include the learning in the agent prompt when the phase reruns
|
|
@@ -73,6 +73,11 @@ Create the following directory structure:
|
|
|
73
73
|
retros/
|
|
74
74
|
self-reviews/
|
|
75
75
|
checklists/ ← Copied from @sniper.ai/core/checklists/
|
|
76
|
+
memory/
|
|
77
|
+
learnings/ ← Unified learning store (replaces signals/)
|
|
78
|
+
signals/ ← Legacy — kept for backward compat, migrated by memory-curator
|
|
79
|
+
velocity.yaml
|
|
80
|
+
archive/ ← Deprecated learnings archived here
|
|
76
81
|
.claude/
|
|
77
82
|
agents/ ← Copied from @sniper.ai/core/agents/
|
|
78
83
|
settings.json ← Merge hooks from @sniper.ai/core/hooks/
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sniper-learn
|
|
3
|
+
description: Submit, review, or deprecate project learnings
|
|
4
|
+
arguments:
|
|
5
|
+
- name: learning
|
|
6
|
+
description: "The learning to submit (e.g., \"Always validate JWT expiry before checking permissions\")"
|
|
7
|
+
required: false
|
|
8
|
+
- name: review
|
|
9
|
+
description: Review and curate existing learnings
|
|
10
|
+
required: false
|
|
11
|
+
type: boolean
|
|
12
|
+
- name: deprecate
|
|
13
|
+
description: "Learning ID to deprecate (e.g., L-20260307-a3f2)"
|
|
14
|
+
required: false
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# /sniper-learn
|
|
18
|
+
|
|
19
|
+
Manage the SNIPER learning store. Submit new learnings from experience, review existing learnings, or deprecate outdated ones.
|
|
20
|
+
|
|
21
|
+
## Mode Selection
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
--review given? → Review mode
|
|
25
|
+
--deprecate <id> given? → Deprecate mode
|
|
26
|
+
learning text given? → Submit mode
|
|
27
|
+
Nothing given? → Submit mode (prompt for learning text)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Submit Mode
|
|
31
|
+
|
|
32
|
+
Submit a new learning from human experience or observation.
|
|
33
|
+
|
|
34
|
+
### Process
|
|
35
|
+
|
|
36
|
+
1. **Capture the learning text** from the argument or prompt the user:
|
|
37
|
+
- "What did you learn? Describe the pattern, rule, or insight."
|
|
38
|
+
|
|
39
|
+
2. **Ask clarifying questions** (present as multi-select, all optional):
|
|
40
|
+
- **Agents:** Which agents should see this learning? (default: all)
|
|
41
|
+
- Options: analyst, architect, product-manager, fullstack-dev, backend-dev, frontend-dev, qa-engineer, code-reviewer
|
|
42
|
+
- **Phases:** Which protocol phases does this apply to? (default: all)
|
|
43
|
+
- Options: discover, plan, solve, implement, review
|
|
44
|
+
- **Files:** Any specific file patterns? (default: all)
|
|
45
|
+
- Accept glob patterns like `src/api/**`, `*.test.ts`
|
|
46
|
+
|
|
47
|
+
3. **Ask for anti-pattern and correction** (optional):
|
|
48
|
+
- "Is there a specific anti-pattern to avoid?"
|
|
49
|
+
- "What should be done instead?"
|
|
50
|
+
|
|
51
|
+
4. **Create the learning record:**
|
|
52
|
+
```yaml
|
|
53
|
+
id: L-{YYYYMMDD}-{4-char-hex}
|
|
54
|
+
status: active
|
|
55
|
+
confidence: 0.9
|
|
56
|
+
created_at: {ISO 8601}
|
|
57
|
+
updated_at: {ISO 8601}
|
|
58
|
+
source:
|
|
59
|
+
type: human
|
|
60
|
+
detail: "Submitted via /sniper-learn"
|
|
61
|
+
learning: {learning text}
|
|
62
|
+
anti_pattern: {if provided}
|
|
63
|
+
correction: {if provided}
|
|
64
|
+
scope:
|
|
65
|
+
agents: {selected or null}
|
|
66
|
+
phases: {selected or null}
|
|
67
|
+
files: {selected or null}
|
|
68
|
+
applied_in: []
|
|
69
|
+
reinforced_by: []
|
|
70
|
+
contradicted_by: []
|
|
71
|
+
history:
|
|
72
|
+
- timestamp: {ISO 8601}
|
|
73
|
+
event: created
|
|
74
|
+
actor: human
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
5. **Write** to `.sniper/memory/learnings/{id}.yaml`
|
|
78
|
+
|
|
79
|
+
6. **Confirm:** "Learning `{id}` created with confidence 0.9. It will be composed into agent prompts for matching phases/agents."
|
|
80
|
+
|
|
81
|
+
## Review Mode
|
|
82
|
+
|
|
83
|
+
Review, curate, and manage existing learnings.
|
|
84
|
+
|
|
85
|
+
### Process
|
|
86
|
+
|
|
87
|
+
1. **Spawn the memory-curator agent** from `.claude/agents/memory-curator.md`
|
|
88
|
+
- Pass it the task: "Run full curation — consolidation, contradiction detection, staleness check, spec drift detection, signal migration, and pruning."
|
|
89
|
+
|
|
90
|
+
2. **Present curator summary** to the user
|
|
91
|
+
|
|
92
|
+
3. **Show flagged items** requiring human decision:
|
|
93
|
+
- Contradictions between high-confidence learnings
|
|
94
|
+
- Stale learnings that might still apply
|
|
95
|
+
- Spec drift detections
|
|
96
|
+
|
|
97
|
+
4. **For each flagged item**, ask the user:
|
|
98
|
+
- **Keep** — maintain current status
|
|
99
|
+
- **Deprecate** — set status to deprecated
|
|
100
|
+
- **Edit** — modify the learning text/scope
|
|
101
|
+
|
|
102
|
+
5. **Show final state:**
|
|
103
|
+
```
|
|
104
|
+
Active learnings: N
|
|
105
|
+
Validated: N
|
|
106
|
+
Deprecated: N
|
|
107
|
+
Archived: N
|
|
108
|
+
Average confidence: X.XX
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Deprecate Mode
|
|
112
|
+
|
|
113
|
+
Deprecate a specific learning by ID.
|
|
114
|
+
|
|
115
|
+
### Process
|
|
116
|
+
|
|
117
|
+
1. **Read** `.sniper/memory/learnings/{id}.yaml`
|
|
118
|
+
2. If not found, report error: "Learning `{id}` not found."
|
|
119
|
+
3. **Show the learning** to the user for confirmation:
|
|
120
|
+
- Learning text, current confidence, source, created date
|
|
121
|
+
4. **Confirm:** "Deprecate this learning?"
|
|
122
|
+
5. **Update the learning:**
|
|
123
|
+
- `status: deprecated`
|
|
124
|
+
- `confidence: 0.0`
|
|
125
|
+
- Add history entry:
|
|
126
|
+
```yaml
|
|
127
|
+
- timestamp: {ISO 8601}
|
|
128
|
+
event: human_invalidated
|
|
129
|
+
actor: human
|
|
130
|
+
detail: "Deprecated via /sniper-learn --deprecate"
|
|
131
|
+
```
|
|
132
|
+
6. **Confirm:** "Learning `{id}` deprecated. It will no longer be composed into agent prompts."
|
|
133
|
+
|
|
134
|
+
## Rules
|
|
135
|
+
|
|
136
|
+
- Human-submitted learnings ALWAYS start at confidence 0.9
|
|
137
|
+
- ALWAYS write to `.sniper/memory/learnings/` — never to signals
|
|
138
|
+
- ALWAYS include a history entry for every change
|
|
139
|
+
- If `.sniper/memory/learnings/` doesn't exist, create it
|
|
140
|
+
- If `.sniper/memory/signals/` contains files, suggest running `--review` to migrate them
|
|
@@ -42,6 +42,17 @@ Display the gate result:
|
|
|
42
42
|
|
|
43
43
|
Save the gate result to `.sniper/gates/<phase>-<timestamp>.yaml`.
|
|
44
44
|
|
|
45
|
+
### 6. Capture Feedback
|
|
46
|
+
|
|
47
|
+
If the gate fails and the user provides feedback on what should change:
|
|
48
|
+
|
|
49
|
+
1. Parse the feedback for actionable, generalizable patterns
|
|
50
|
+
2. If the feedback describes a pattern (not a one-off fix):
|
|
51
|
+
- Create a learning with `source.type: human`, `confidence: 0.9`
|
|
52
|
+
- Scope to the reviewed phase and relevant agents
|
|
53
|
+
- Write to `.sniper/memory/learnings/`
|
|
54
|
+
3. Note: "Learning `{id}` captured from review feedback."
|
|
55
|
+
|
|
45
56
|
## Rules
|
|
46
57
|
|
|
47
58
|
- This is a manual trigger — it does NOT advance the protocol phase
|
|
@@ -93,6 +93,36 @@ phases:
|
|
|
93
93
|
outputs:
|
|
94
94
|
- .sniper/artifacts/{protocol_id}/review-report.md
|
|
95
95
|
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
auto_retro
|
|
96
|
+
# ── Phase 4: Retro (recommended) ──────────────────────────
|
|
97
|
+
# Runs the retro-analyst to extract learnings, update velocity, and check
|
|
98
|
+
# learning effectiveness. Replaces the old auto_retro flag.
|
|
99
|
+
- name: retro
|
|
100
|
+
description: Retrospective — extract learnings and update velocity
|
|
101
|
+
agents:
|
|
102
|
+
- retro-analyst
|
|
103
|
+
spawn_strategy: single
|
|
104
|
+
gate:
|
|
105
|
+
checklist: retro
|
|
106
|
+
human_approval: false
|
|
107
|
+
outputs:
|
|
108
|
+
- .sniper/retros/{protocol_id}.yaml
|
|
109
|
+
- .sniper/memory/velocity.yaml
|
|
110
|
+
- .sniper/memory/learnings/
|
|
111
|
+
|
|
112
|
+
# ── Phase 5: Curate (optional) ────────────────────────────
|
|
113
|
+
# Consolidate, prune, and review learnings. Only runs when learning count
|
|
114
|
+
# exceeds 30 or last curation was more than 5 protocols ago.
|
|
115
|
+
# - name: curate
|
|
116
|
+
# description: Review and consolidate learnings
|
|
117
|
+
# agents:
|
|
118
|
+
# - memory-curator
|
|
119
|
+
# spawn_strategy: single
|
|
120
|
+
# skip_if: learning_count < 30 AND last_curation_within_5_protocols
|
|
121
|
+
# gate:
|
|
122
|
+
# checklist: none
|
|
123
|
+
# human_approval: false
|
|
124
|
+
|
|
125
|
+
# auto_retro (DEPRECATED — use a retro phase instead):
|
|
126
|
+
# Retained for backward compatibility. If set to true and no retro phase
|
|
127
|
+
# exists, the retro-analyst is spawned as a single-agent phase at completion.
|
|
128
|
+
# auto_retro: true
|