@seanyao/roll 3.618.3 → 3.620.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.
@@ -1,363 +0,0 @@
1
- # Full Contract Reference
2
-
3
- This file preserves the detailed contract extracted from SKILL.md. Read it when the hub points here for exact workflow steps, templates, rubrics, or recovery branches.
4
-
5
- ---
6
-
7
- # Sentinel
8
-
9
- **Smart Patrol Inspector** - Scheduled, randomized, cost-controlled patrol and acceptance checks for production systems.
10
-
11
- ## When Not to Use
12
-
13
- - One-off debugging of a reported bug (use `$roll-debug`)
14
- - Full-coverage regression testing (sentinel samples, does not cover)
15
- - Dev/staging environment checks (use CI tests instead)
16
- - Pre-commit self-review of diffs (use `$roll-.review`)
17
-
18
- ## Core Principle
19
-
20
- ```
21
- ┌─────────────────────────────────────────────────────────────┐
22
- │ Smart Patrol Logic │
23
- ├─────────────────────────────────────────────────────────────┤
24
- │ │
25
- │ Not full-coverage checks! Think of it like a security │
26
- │ guard on patrol: │
27
- │ │
28
- │ 🕐 Scheduled Triggers - Auto-patrol on schedule │
29
- │ └── "Patrol once every 6 hours" │
30
- │ │
31
- │ 🎲 Random Sampling - Different samples each time │
32
- │ └── "Check Stories 1-10 this time, 50-60 next time" │
33
- │ │
34
- │ 💰 Cost Control - AI checks are expensive, use sparingly │
35
- │ └── "Only check 10 each time, not all 100" │
36
- │ │
37
- │ 🎯 BACKLOG-Based - Validate against requirements │
38
- │ └── "US-001 says login works, so verify login" │
39
- │ │
40
- └─────────────────────────────────────────────────────────────┘
41
- ```
42
-
43
- ## Patrol Strategy
44
-
45
- ### Sampling Logic
46
-
47
- ```javascript
48
- // Sampling logic for each patrol
49
- function selectSamples(backlog, strategy = 'smart') {
50
- const completedStories = backlog.filter(s => s.status === '✅');
51
-
52
- switch(strategy) {
53
- case 'random':
54
- // Fully random: randomly select N from all completed Stories
55
- return shuffle(completedStories).slice(0, 10);
56
-
57
- case 'weighted':
58
- // Weighted random: prioritize recently modified and frequently used
59
- return completedStories
60
- .sort((a, b) => b.lastModified - a.lastModified)
61
- .slice(0, 5) // 5 most recent
62
- .concat(shuffle(completedStories).slice(0, 5)); // + 5 random
63
-
64
- case 'coverage':
65
- // Coverage sampling: ensure different modules are all covered
66
- const byModule = groupBy(completedStories, 'module');
67
- return Object.values(byModule).map(
68
- stories => randomPick(stories)
69
- );
70
- }
71
- }
72
- ```
73
-
74
- ### Cost Control
75
-
76
- | Strategy | Sample Size | Frequency | Use Case |
77
- |----------|-------------|-----------|----------|
78
- | **Light** | 5 Stories | Once daily | Stable period |
79
- | **Normal** | 10 Stories | Every 6 hours | General monitoring |
80
- | **Intensive** | 20 Stories | Every hour | Post-release period |
81
- | **Full** | All | Once weekly | Weekly patrol |
82
-
83
- ```yaml
84
- # sentinel.config.yml
85
- cost_control:
86
- daily_budget: 100 # AI call budget
87
-
88
- light_patrol:
89
- samples: 5
90
- schedule: "0 9 * * *" # Daily at 9am
91
-
92
- normal_patrol:
93
- samples: 10
94
- schedule: "0 */6 * * *" # Every 6 hours
95
-
96
- # Intensive patrol after deployment
97
- post_deploy:
98
- trigger: "after_deploy"
99
- samples: 20
100
- duration: "2h" # Lasts 2 hours
101
- ```
102
-
103
- ### Uncertainty Handling
104
-
105
- ```javascript
106
- // Systems have uncertainty; a single check may be inaccurate.
107
- // Use multiple random checks to increase confidence.
108
-
109
- class UncertaintyHandler {
110
- // Track check result history
111
- history = new Map(); // storyId -> [check1, check2, ...]
112
-
113
- // Determine if an issue is real
114
- isRealIssue(storyId, currentResult) {
115
- const pastResults = this.history.get(storyId) || [];
116
- pastResults.push(currentResult);
117
-
118
- // Only consider it a real issue if it fails 3 times consecutively
119
- const recent3 = pastResults.slice(-3);
120
- if (recent3.every(r => r.status === 'FAIL')) {
121
- return true; // Real issue
122
- }
123
-
124
- // If it fails occasionally, it may be intermittent; keep observing
125
- if (recent3.filter(r => r.status === 'FAIL').length === 1) {
126
- return false; // Likely intermittent, don't alert yet
127
- }
128
-
129
- return false;
130
- }
131
- }
132
- ```
133
-
134
- ## When to Patrol
135
-
136
- ### Scheduled Patrols
137
-
138
- ```bash
139
- # Daily patrol - randomly check a few each day
140
- $roll-sentinel patrol --mode=normal
141
-
142
- # Late-night patrol - full check during off-peak hours
143
- $roll-sentinel patrol --mode=full --schedule="0 3 * * *"
144
-
145
- # Weekend walkthrough - check the week's accumulation on Sunday
146
- $roll-sentinel patrol --mode=weekly --schedule="0 10 * * 0"
147
- ```
148
-
149
- ### Event-Triggered
150
-
151
- ```bash
152
- # Intensive patrol for 2 hours after deployment
153
- $roll-sentinel patrol --mode=intensive --duration=2h --after-deploy
154
-
155
- # Emergency check after an alert
156
- $roll-sentinel patrol --mode=focus --target=US-XXX
157
- ```
158
-
159
- ## Patrol Report
160
-
161
- ```markdown
162
- ## 🛡️ Sentinel Patrol Report #247
163
- **Time**: 2024-01-15 14:00 UTC
164
- **Patrol ID**: patrol-20240115-1400
165
- **Mode**: Normal (Random Sampling)
166
-
167
- ### 📊 Sampling Info
168
- | Metric | Value |
169
- |--------|-------|
170
- | Total Stories | 150 |
171
- | Sample Size | 10 |
172
- | Sampling Rate | 6.7% |
173
- | Cost Estimate | $0.07 |
174
-
175
- ### 🎲 Random Sample
176
- | # | Story | Module | Last Checked | Result |
177
- |---|-------|--------|--------------|--------|
178
- | 1 | US-LOGIN-001 | Auth | 6h ago | ✅ |
179
- | 2 | US-STORY-042 | Content | 12h ago | ✅ |
180
- | 3 | US-AUDIO-015 | Player | 2h ago | 🟡* |
181
- | 4 | US-SEARCH-003 | Search | 18h ago | ✅ |
182
- | 5 | ... | ... | ... | ... |
183
-
184
- \* US-AUDIO-015: Occasional playback stuttering (2nd occurrence, under observation)
185
-
186
- ### 🔴 Issues Found
187
- None (no confirmed issues found in this sample)
188
-
189
- ### 📈 Patrol Statistics (7 days)
190
- | Metric | Value |
191
- |--------|-------|
192
- | Total Patrols | 28 |
193
- | Stories Checked | 280 |
194
- | Issues Found | 3 |
195
- | False Positives | 1 |
196
- | Coverage | 85% of all stories |
197
-
198
- ### 💰 Cost Report
199
- | Item | Usage |
200
- |------|-------|
201
- | AI Checks | 280 calls |
202
- | Playwright Runs | 28 sessions |
203
- | Total Cost | $2 |
204
- | Budget Used | 15% of monthly |
205
- ```
206
-
207
- ## Smart Detection Logic
208
-
209
- ### Pattern 1: Intermittent vs Real Issue
210
-
211
- ```javascript
212
- // Don't alert on the first failure; look at the trend
213
- const checks = [
214
- { time: 'T-6h', status: 'PASS' },
215
- { time: 'T-12h', status: 'FAIL' }, // Intermittent?
216
- { time: 'T-18h', status: 'PASS' },
217
- { time: 'Now', status: 'FAIL' }, // Failed again!
218
- ];
219
-
220
- // 2 consecutive failures → Create Issue
221
- if (lastN(checks, 2).all(c => c.status === 'FAIL')) {
222
- createBacklogItem('FIX-XXX');
223
- }
224
- // Occasional failure → Log for observation
225
- else if (checks.filter(c => c.status === 'FAIL').length <= 1) {
226
- logForObservation('Might be flaky, continue monitoring');
227
- }
228
- ```
229
-
230
- ### Pattern 2: Hotspot Detection
231
-
232
- ```javascript
233
- // Some Stories frequently show issues when sampled.
234
- // Automatically increase their check frequency.
235
-
236
- const hotSpots = analyzeHistory();
237
- // hotSpots = [
238
- // { story: 'US-AUDIO-015', failRate: 0.3 }, // 30% failure rate
239
- // { story: 'US-SEARCH-003', failRate: 0.1 },
240
- // ]
241
-
242
- // Increase weight for hotspots
243
- if (hotSpots.some(h => h.story === selectedStory)) {
244
- // If it's a hotspot, even if not randomly selected, add extra check probability
245
- if (Math.random() < 0.3) {
246
- extraCheck(story);
247
- }
248
- }
249
- ```
250
-
251
- ## Cost Optimization
252
-
253
- ### Tiered Checking
254
-
255
- ```
256
- Level 1: Lightweight Check (cheap)
257
- └── HTTP ping / API health check
258
- └── Cost: $0.001 per check
259
-
260
- Level 2: Functional Check (moderate)
261
- └── Playwright critical path
262
- └── Cost: $0.01 per check
263
-
264
- Level 3: AI Deep Check (expensive)
265
- └── AI-powered content quality analysis
266
- └── Cost: $0.07 per check
267
-
268
- Strategy:
269
- - Each patrol: 90% Level 1 + 10% Level 2
270
- - Once weekly: Level 3 deep inspection
271
- ```
272
-
273
- ### Smart Batching
274
-
275
- ```javascript
276
- // Batch checks to reduce cost.
277
- // Instead of 10 separate checks, open one browser for all 10.
278
-
279
- async function batchCheck(stories) {
280
- const browser = await chromium.launch();
281
- const context = await browser.newContext();
282
-
283
- // Reuse browser session to check multiple Stories
284
- for (const story of stories) {
285
- const page = await context.newPage();
286
- await checkStory(page, story);
287
- await page.close();
288
- }
289
-
290
- await browser.close();
291
- // Cost: 1 session for 10 checks
292
- }
293
- ```
294
-
295
- ## Workflow: Find Issue → Backlog
296
-
297
- ```
298
- ┌─────────────────────────────────────────────────────────────┐
299
- │ Issue Discovery Workflow via Patrol │
300
- ├─────────────────────────────────────────────────────────────┤
301
- │ │
302
- │ 1. Sentinel Patrol (scheduled random sampling) │
303
- │ └── Sample: US-AUDIO-015 │
304
- │ │
305
- │ 2. Check Result │
306
- │ └── Status: FAIL (playback stuttering) │
307
- │ │
308
- │ 3. Uncertainty Check │
309
- │ └── Check history: this is the 2nd failure │
310
- │ └── 1st was 6h ago (possibly intermittent) │
311
- │ └── Decision: continue observing, don't create Issue │
312
- │ │
313
- │ 4. Next Patrol │
314
- │ └── US-AUDIO-015 sampled again (hotspot weighting) │
315
- │ └── Status: FAIL (failed again!) │
316
- │ └── Check history: 2 consecutive failures │
317
- │ └── Decision: create FIX-AUDIO-015 │
318
- │ │
319
- │ 5. Create Backlog Item │
320
- │ └── Add FIX-AUDIO-015 to .roll/backlog.md │
321
- │ └── Status: 📋 Todo │
322
- │ └── Awaiting human fix │
323
- │ │
324
- │ 6. Human Fix │
325
- │ └── User: "Fix FIX-AUDIO-015" │
326
- │ └── $roll-fix FIX-AUDIO-015 │
327
- │ │
328
- │ 7. Verification │
329
- │ └── Next patrol will prioritize verifying this FIX │
330
- │ └── Status: ✅ Fixed │
331
- │ │
332
- └─────────────────────────────────────────────────────────────┘
333
- ```
334
-
335
- ## Integration with Other Skills
336
-
337
- ```
338
- ┌─────────────────────────────────────────────────────────────┐
339
- │ Complete Monitoring System │
340
- ├─────────────────────────────────────────────────────────────┤
341
- │ │
342
- │ $roll-sentinel patrol Scheduled random patrol (main) │
343
- │ ↓ │
344
- │ Issue found? ──┬── Yes ──→ Create BACKLOG item │
345
- │ │ Await $roll-fix │
346
- │ │ │
347
- │ └── No ──→ Continue patrolling │
348
- │ │
349
- │ $roll-debug On-demand deep diagnosis (aux) │
350
- │ (When Sentinel finds an issue, manually trigger deep dive) │
351
- │ │
352
- │ $roll-build Post-fix regression verify │
353
- │ │
354
- └─────────────────────────────────────────────────────────────┘
355
- ```
356
-
357
- ## Best Practices
358
-
359
- 1. **Don't do full-coverage checks** - Expensive and unnecessary
360
- 2. **Random + Hotspots** - Balance coverage and cost
361
- 3. **Multi-check confirmation** - Avoid false positives from intermittent failures
362
- 4. **Budget control** - Set daily/monthly AI call limits
363
- 5. **Progressive intensity** - Light during stable periods, Intensive after releases