@hanzlaa/rcode 3.4.31 → 3.4.33
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.md +1 -1
- package/CLAUDE.md +1 -1
- package/CONTRIBUTING.md +19 -0
- package/cli/agent.js +57 -0
- package/cli/index.js +4 -0
- package/dist/rcode.js +44 -0
- package/package.json +1 -1
- package/rihal/agents/rihal-advisor-researcher.md +2 -25
- package/rihal/agents/rihal-ahmed.md +0 -57
- package/rihal/agents/rihal-assumptions-analyzer.md +1 -69
- package/rihal/agents/rihal-code-fixer.md +3 -66
- package/rihal/agents/rihal-code-reviewer.md +3 -66
- package/rihal/agents/rihal-codebase-mapper.md +1 -167
- package/rihal/agents/rihal-cross-platform-auditor.md +15 -0
- package/rihal/agents/rihal-debugger.md +1 -104
- package/rihal/agents/rihal-dep-auditor.md +15 -0
- package/rihal/agents/rihal-docs-auditor.md +3 -12
- package/rihal/agents/rihal-edge-case-hunter.md +7 -33
- package/rihal/agents/rihal-executor.md +1 -98
- package/rihal/agents/rihal-fatima.md +0 -62
- package/rihal/agents/rihal-haitham.md +11 -55
- package/rihal/agents/rihal-hanzla.md +0 -60
- package/rihal/agents/rihal-hussain-pm.md +0 -65
- package/rihal/agents/rihal-i18n-auditor.md +16 -0
- package/rihal/agents/rihal-integration-checker.md +1 -396
- package/rihal/agents/rihal-layla.md +0 -48
- package/rihal/agents/rihal-mariam.md +0 -54
- package/rihal/agents/rihal-nasser.md +0 -48
- package/rihal/agents/rihal-noor.md +0 -51
- package/rihal/agents/rihal-nyquist-auditor.md +1 -7
- package/rihal/agents/rihal-observability-auditor.md +16 -0
- package/rihal/agents/rihal-omar.md +6 -48
- package/rihal/agents/rihal-phase-researcher.md +7 -40
- package/rihal/agents/rihal-planner.md +2 -209
- package/rihal/agents/rihal-profiler.md +5 -24
- package/rihal/agents/rihal-project-researcher.md +2 -36
- package/rihal/agents/rihal-remediation-planner.md +3 -70
- package/rihal/agents/rihal-research-synthesizer.md +1 -210
- package/rihal/agents/rihal-roadmapper.md +2 -74
- package/rihal/agents/rihal-sadiq.md +0 -55
- package/rihal/agents/rihal-security-adversary.md +10 -39
- package/rihal/agents/rihal-security-auditor.md +7 -29
- package/rihal/agents/rihal-sprint-checker.md +1 -118
- package/rihal/agents/rihal-ui-auditor.md +10 -34
- package/rihal/agents/rihal-ux-designer.md +3 -69
- package/rihal/agents/rihal-verifier.md +1 -85
- package/rihal/agents/rihal-waleed.md +0 -56
- package/rihal/agents/rihal-yousef.md +9 -49
- package/rihal/bin/rihal-tools.cjs +129 -2
- package/rihal/references/REFERENCES_INDEX.md +67 -0
- package/rihal/references/assumptions-analyzer-playbook.md +82 -0
- package/rihal/references/auditor-shared-checklists.md +91 -0
- package/rihal/references/code-fixer-playbook.md +71 -0
- package/rihal/references/code-reviewer-playbook.md +71 -0
- package/rihal/references/codebase-mapping-process.md +176 -0
- package/rihal/references/debugger-playbook.md +127 -0
- package/rihal/references/executor-playbook.md +119 -0
- package/rihal/references/integration-verification-playbook.md +392 -0
- package/rihal/references/persona-engineer-shared.md +61 -0
- package/rihal/references/phase-id-conventions.md +101 -0
- package/rihal/references/planner-playbook.md +217 -0
- package/rihal/references/remediation-planner-playbook.md +75 -0
- package/rihal/references/research-synthesis-playbook.md +205 -0
- package/rihal/references/researcher-shared.md +87 -0
- package/rihal/references/roadmapper-playbook.md +82 -0
- package/rihal/references/sprint-checker-playbook.md +128 -0
- package/rihal/references/ux-designer-playbook.md +74 -0
- package/rihal/references/verifier-playbook.md +104 -0
- package/rihal/skills/actions/4-implementation/rihal-code-review/steps/step-02-review.md +7 -3
- package/rihal/skills/agents/majlis-council/SKILL.md +1 -1
- package/rihal/team.yaml +32 -0
- package/rihal/workflows/add-phase.md +37 -0
- package/rihal/workflows/status.md +19 -0
- package/server/dashboard.js +1 -1
- package/server/lib/api.js +7 -0
- package/server/lib/html/client.js +2 -2
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# Integration Verification Playbook
|
|
2
|
+
|
|
3
|
+
Loaded by `rihal-integration-checker` via `@-include`. Contains the full
|
|
4
|
+
six-step verification process, structured output template, critical rules,
|
|
5
|
+
and success criteria.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Step 1: Build Export/Import Map
|
|
10
|
+
|
|
11
|
+
For each phase, extract what it provides and what it should consume.
|
|
12
|
+
|
|
13
|
+
**From SUMMARYs, extract:**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Key exports from each phase
|
|
17
|
+
for summary in .planning/phases/*/*-SUMMARY.md; do
|
|
18
|
+
echo "=== $summary ==="
|
|
19
|
+
grep -A 10 "Key Files\|Exports\|Provides" "$summary" 2>/dev/null
|
|
20
|
+
done
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Build provides/consumes map:**
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Phase 1 (Auth):
|
|
27
|
+
provides: getCurrentUser, AuthProvider, useAuth, /api/auth/*
|
|
28
|
+
consumes: nothing (foundation)
|
|
29
|
+
|
|
30
|
+
Phase 2 (API):
|
|
31
|
+
provides: /api/users/*, /api/data/*, UserType, DataType
|
|
32
|
+
consumes: getCurrentUser (for protected routes)
|
|
33
|
+
|
|
34
|
+
Phase 3 (Dashboard):
|
|
35
|
+
provides: Dashboard, UserCard, DataList
|
|
36
|
+
consumes: /api/users/*, /api/data/*, useAuth
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Step 2: Verify Export Usage
|
|
40
|
+
|
|
41
|
+
For each phase's exports, verify they're imported and used.
|
|
42
|
+
|
|
43
|
+
**Check imports:**
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
check_export_used() {
|
|
47
|
+
local export_name="$1"
|
|
48
|
+
local source_phase="$2"
|
|
49
|
+
local search_path="${3:-src/}"
|
|
50
|
+
|
|
51
|
+
# Find imports
|
|
52
|
+
local imports=$(grep -r "import.*$export_name" "$search_path" \
|
|
53
|
+
--include="*.ts" --include="*.tsx" 2>/dev/null | \
|
|
54
|
+
grep -v "$source_phase" | wc -l)
|
|
55
|
+
|
|
56
|
+
# Find usage (not just import)
|
|
57
|
+
local uses=$(grep -r "$export_name" "$search_path" \
|
|
58
|
+
--include="*.ts" --include="*.tsx" 2>/dev/null | \
|
|
59
|
+
grep -v "import" | grep -v "$source_phase" | wc -l)
|
|
60
|
+
|
|
61
|
+
if [ "$imports" -gt 0 ] && [ "$uses" -gt 0 ]; then
|
|
62
|
+
echo "CONNECTED ($imports imports, $uses uses)"
|
|
63
|
+
elif [ "$imports" -gt 0 ]; then
|
|
64
|
+
echo "IMPORTED_NOT_USED ($imports imports, 0 uses)"
|
|
65
|
+
else
|
|
66
|
+
echo "ORPHANED (0 imports)"
|
|
67
|
+
fi
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Run for key exports:**
|
|
72
|
+
|
|
73
|
+
- Auth exports (getCurrentUser, useAuth, AuthProvider)
|
|
74
|
+
- Type exports (UserType, etc.)
|
|
75
|
+
- Utility exports (formatDate, etc.)
|
|
76
|
+
- Component exports (shared components)
|
|
77
|
+
|
|
78
|
+
## Step 3: Verify API Coverage
|
|
79
|
+
|
|
80
|
+
Check that API routes have consumers.
|
|
81
|
+
|
|
82
|
+
**Find all API routes:**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Next.js App Router
|
|
86
|
+
find src/app/api -name "route.ts" 2>/dev/null | while read route; do
|
|
87
|
+
# Extract route path from file path
|
|
88
|
+
path=$(echo "$route" | sed 's|src/app/api||' | sed 's|/route.ts||')
|
|
89
|
+
echo "/api$path"
|
|
90
|
+
done
|
|
91
|
+
|
|
92
|
+
# Next.js Pages Router
|
|
93
|
+
find src/pages/api -name "*.ts" 2>/dev/null | while read route; do
|
|
94
|
+
path=$(echo "$route" | sed 's|src/pages/api||' | sed 's|\.ts||')
|
|
95
|
+
echo "/api$path"
|
|
96
|
+
done
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Check each route has consumers:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
check_api_consumed() {
|
|
103
|
+
local route="$1"
|
|
104
|
+
local search_path="${2:-src/}"
|
|
105
|
+
|
|
106
|
+
# Search for fetch/axios calls to this route
|
|
107
|
+
local fetches=$(grep -r "fetch.*['\"]$route\|axios.*['\"]$route" "$search_path" \
|
|
108
|
+
--include="*.ts" --include="*.tsx" 2>/dev/null | wc -l)
|
|
109
|
+
|
|
110
|
+
# Also check for dynamic routes (replace [id] with pattern)
|
|
111
|
+
local dynamic_route=$(echo "$route" | sed 's/\[.*\]/.*/g')
|
|
112
|
+
local dynamic_fetches=$(grep -r "fetch.*['\"]$dynamic_route\|axios.*['\"]$dynamic_route" "$search_path" \
|
|
113
|
+
--include="*.ts" --include="*.tsx" 2>/dev/null | wc -l)
|
|
114
|
+
|
|
115
|
+
local total=$((fetches + dynamic_fetches))
|
|
116
|
+
|
|
117
|
+
if [ "$total" -gt 0 ]; then
|
|
118
|
+
echo "CONSUMED ($total calls)"
|
|
119
|
+
else
|
|
120
|
+
echo "ORPHANED (no calls found)"
|
|
121
|
+
fi
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Step 4: Verify Auth Protection
|
|
126
|
+
|
|
127
|
+
Check that routes requiring auth actually check auth.
|
|
128
|
+
|
|
129
|
+
**Find protected route indicators:**
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Routes that should be protected (dashboard, settings, user data)
|
|
133
|
+
protected_patterns="dashboard|settings|profile|account|user"
|
|
134
|
+
|
|
135
|
+
# Find components/pages matching these patterns
|
|
136
|
+
grep -r -l "$protected_patterns" src/ --include="*.tsx" 2>/dev/null
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Check auth usage in protected areas:**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
check_auth_protection() {
|
|
143
|
+
local file="$1"
|
|
144
|
+
|
|
145
|
+
# Check for auth hooks/context usage
|
|
146
|
+
local has_auth=$(grep -E "useAuth|useSession|getCurrentUser|isAuthenticated" "$file" 2>/dev/null)
|
|
147
|
+
|
|
148
|
+
# Check for redirect on no auth
|
|
149
|
+
local has_redirect=$(grep -E "redirect.*login|router.push.*login|navigate.*login" "$file" 2>/dev/null)
|
|
150
|
+
|
|
151
|
+
if [ -n "$has_auth" ] || [ -n "$has_redirect" ]; then
|
|
152
|
+
echo "PROTECTED"
|
|
153
|
+
else
|
|
154
|
+
echo "UNPROTECTED"
|
|
155
|
+
fi
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Step 5: Verify E2E Flows
|
|
160
|
+
|
|
161
|
+
Derive flows from milestone goals and trace through codebase.
|
|
162
|
+
|
|
163
|
+
**Common flow patterns:**
|
|
164
|
+
|
|
165
|
+
### Flow: User Authentication
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
verify_auth_flow() {
|
|
169
|
+
echo "=== Auth Flow ==="
|
|
170
|
+
|
|
171
|
+
# Step 1: Login form exists
|
|
172
|
+
local login_form=$(grep -r -l "login\|Login" src/ --include="*.tsx" 2>/dev/null | head -1)
|
|
173
|
+
[ -n "$login_form" ] && echo "✓ Login form: $login_form" || echo "✗ Login form: MISSING"
|
|
174
|
+
|
|
175
|
+
# Step 2: Form submits to API
|
|
176
|
+
if [ -n "$login_form" ]; then
|
|
177
|
+
local submits=$(grep -E "fetch.*auth|axios.*auth|/api/auth" "$login_form" 2>/dev/null)
|
|
178
|
+
[ -n "$submits" ] && echo "✓ Submits to API" || echo "✗ Form doesn't submit to API"
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
# Step 3: API route exists
|
|
182
|
+
local api_route=$(find src -path "*api/auth*" -name "*.ts" 2>/dev/null | head -1)
|
|
183
|
+
[ -n "$api_route" ] && echo "✓ API route: $api_route" || echo "✗ API route: MISSING"
|
|
184
|
+
|
|
185
|
+
# Step 4: Redirect after success
|
|
186
|
+
if [ -n "$login_form" ]; then
|
|
187
|
+
local redirect=$(grep -E "redirect|router.push|navigate" "$login_form" 2>/dev/null)
|
|
188
|
+
[ -n "$redirect" ] && echo "✓ Redirects after login" || echo "✗ No redirect after login"
|
|
189
|
+
fi
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Flow: Data Display
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
verify_data_flow() {
|
|
197
|
+
local component="$1"
|
|
198
|
+
local api_route="$2"
|
|
199
|
+
local data_var="$3"
|
|
200
|
+
|
|
201
|
+
echo "=== Data Flow: $component → $api_route ==="
|
|
202
|
+
|
|
203
|
+
# Step 1: Component exists
|
|
204
|
+
local comp_file=$(find src -name "*$component*" -name "*.tsx" 2>/dev/null | head -1)
|
|
205
|
+
[ -n "$comp_file" ] && echo "✓ Component: $comp_file" || echo "✗ Component: MISSING"
|
|
206
|
+
|
|
207
|
+
if [ -n "$comp_file" ]; then
|
|
208
|
+
# Step 2: Fetches data
|
|
209
|
+
local fetches=$(grep -E "fetch|axios|useSWR|useQuery" "$comp_file" 2>/dev/null)
|
|
210
|
+
[ -n "$fetches" ] && echo "✓ Has fetch call" || echo "✗ No fetch call"
|
|
211
|
+
|
|
212
|
+
# Step 3: Has state for data
|
|
213
|
+
local has_state=$(grep -E "useState|useQuery|useSWR" "$comp_file" 2>/dev/null)
|
|
214
|
+
[ -n "$has_state" ] && echo "✓ Has state" || echo "✗ No state for data"
|
|
215
|
+
|
|
216
|
+
# Step 4: Renders data
|
|
217
|
+
local renders=$(grep -E "\{.*$data_var.*\}|\{$data_var\." "$comp_file" 2>/dev/null)
|
|
218
|
+
[ -n "$renders" ] && echo "✓ Renders data" || echo "✗ Doesn't render data"
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
# Step 5: API route exists and returns data
|
|
222
|
+
local route_file=$(find src -path "*$api_route*" -name "*.ts" 2>/dev/null | head -1)
|
|
223
|
+
[ -n "$route_file" ] && echo "✓ API route: $route_file" || echo "✗ API route: MISSING"
|
|
224
|
+
|
|
225
|
+
if [ -n "$route_file" ]; then
|
|
226
|
+
local returns_data=$(grep -E "return.*json|res.json" "$route_file" 2>/dev/null)
|
|
227
|
+
[ -n "$returns_data" ] && echo "✓ API returns data" || echo "✗ API doesn't return data"
|
|
228
|
+
fi
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Flow: Form Submission
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
verify_form_flow() {
|
|
236
|
+
local form_component="$1"
|
|
237
|
+
local api_route="$2"
|
|
238
|
+
|
|
239
|
+
echo "=== Form Flow: $form_component → $api_route ==="
|
|
240
|
+
|
|
241
|
+
local form_file=$(find src -name "*$form_component*" -name "*.tsx" 2>/dev/null | head -1)
|
|
242
|
+
|
|
243
|
+
if [ -n "$form_file" ]; then
|
|
244
|
+
# Step 1: Has form element
|
|
245
|
+
local has_form=$(grep -E "<form|onSubmit" "$form_file" 2>/dev/null)
|
|
246
|
+
[ -n "$has_form" ] && echo "✓ Has form" || echo "✗ No form element"
|
|
247
|
+
|
|
248
|
+
# Step 2: Handler calls API
|
|
249
|
+
local calls_api=$(grep -E "fetch.*$api_route|axios.*$api_route" "$form_file" 2>/dev/null)
|
|
250
|
+
[ -n "$calls_api" ] && echo "✓ Calls API" || echo "✗ Doesn't call API"
|
|
251
|
+
|
|
252
|
+
# Step 3: Handles response
|
|
253
|
+
local handles_response=$(grep -E "\.then|await.*fetch|setError|setSuccess" "$form_file" 2>/dev/null)
|
|
254
|
+
[ -n "$handles_response" ] && echo "✓ Handles response" || echo "✗ Doesn't handle response"
|
|
255
|
+
|
|
256
|
+
# Step 4: Shows feedback
|
|
257
|
+
local shows_feedback=$(grep -E "error|success|loading|isLoading" "$form_file" 2>/dev/null)
|
|
258
|
+
[ -n "$shows_feedback" ] && echo "✓ Shows feedback" || echo "✗ No user feedback"
|
|
259
|
+
fi
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Step 6: Compile Integration Report
|
|
264
|
+
|
|
265
|
+
Structure findings for milestone auditor.
|
|
266
|
+
|
|
267
|
+
**Wiring status:**
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
wiring:
|
|
271
|
+
connected:
|
|
272
|
+
- export: "getCurrentUser"
|
|
273
|
+
from: "Phase 1 (Auth)"
|
|
274
|
+
used_by: ["Phase 3 (Dashboard)", "Phase 4 (Settings)"]
|
|
275
|
+
|
|
276
|
+
orphaned:
|
|
277
|
+
- export: "formatUserData"
|
|
278
|
+
from: "Phase 2 (Utils)"
|
|
279
|
+
reason: "Exported but never imported"
|
|
280
|
+
|
|
281
|
+
missing:
|
|
282
|
+
- expected: "Auth check in Dashboard"
|
|
283
|
+
from: "Phase 1"
|
|
284
|
+
to: "Phase 3"
|
|
285
|
+
reason: "Dashboard doesn't call useAuth or check session"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Flow status:**
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
flows:
|
|
292
|
+
complete:
|
|
293
|
+
- name: "User signup"
|
|
294
|
+
steps: ["Form", "API", "DB", "Redirect"]
|
|
295
|
+
|
|
296
|
+
broken:
|
|
297
|
+
- name: "View dashboard"
|
|
298
|
+
broken_at: "Data fetch"
|
|
299
|
+
reason: "Dashboard component doesn't fetch user data"
|
|
300
|
+
steps_complete: ["Route", "Component render"]
|
|
301
|
+
steps_missing: ["Fetch", "State", "Display"]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
Return structured report to milestone auditor:
|
|
307
|
+
|
|
308
|
+
```markdown
|
|
309
|
+
## Integration Check Complete
|
|
310
|
+
|
|
311
|
+
### Wiring Summary
|
|
312
|
+
|
|
313
|
+
**Connected:** {N} exports properly used
|
|
314
|
+
**Orphaned:** {N} exports created but unused
|
|
315
|
+
**Missing:** {N} expected connections not found
|
|
316
|
+
|
|
317
|
+
### API Coverage
|
|
318
|
+
|
|
319
|
+
**Consumed:** {N} routes have callers
|
|
320
|
+
**Orphaned:** {N} routes with no callers
|
|
321
|
+
|
|
322
|
+
### Auth Protection
|
|
323
|
+
|
|
324
|
+
**Protected:** {N} sensitive areas check auth
|
|
325
|
+
**Unprotected:** {N} sensitive areas missing auth
|
|
326
|
+
|
|
327
|
+
### E2E Flows
|
|
328
|
+
|
|
329
|
+
**Complete:** {N} flows work end-to-end
|
|
330
|
+
**Broken:** {N} flows have breaks
|
|
331
|
+
|
|
332
|
+
### Detailed Findings
|
|
333
|
+
|
|
334
|
+
#### Orphaned Exports
|
|
335
|
+
|
|
336
|
+
{List each with from/reason}
|
|
337
|
+
|
|
338
|
+
#### Missing Connections
|
|
339
|
+
|
|
340
|
+
{List each with from/to/expected/reason}
|
|
341
|
+
|
|
342
|
+
#### Broken Flows
|
|
343
|
+
|
|
344
|
+
{List each with name/broken_at/reason/missing_steps}
|
|
345
|
+
|
|
346
|
+
#### Unprotected Routes
|
|
347
|
+
|
|
348
|
+
{List each with path/reason}
|
|
349
|
+
|
|
350
|
+
#### Requirements Integration Map
|
|
351
|
+
|
|
352
|
+
| Requirement | Integration Path | Status | Issue |
|
|
353
|
+
|-------------|-----------------|--------|-------|
|
|
354
|
+
| {REQ-ID} | {Phase X export → Phase Y import → consumer} | WIRED / PARTIAL / UNWIRED | {specific issue or "—"} |
|
|
355
|
+
|
|
356
|
+
**Requirements with no cross-phase wiring:**
|
|
357
|
+
{List REQ-IDs that exist in a single phase with no integration touchpoints — these may be self-contained or may indicate missing connections}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
**Check connections, not existence.** Files existing is phase-level. Files connecting is integration-level.
|
|
363
|
+
|
|
364
|
+
**Trace full paths.** Component → API → DB → Response → Display. Break at any point = broken flow.
|
|
365
|
+
|
|
366
|
+
**Check both directions.** Export exists AND import exists AND import is used AND used correctly.
|
|
367
|
+
|
|
368
|
+
**Be specific about breaks.** "Dashboard doesn't work" is useless. "Dashboard.tsx line 45 fetches /api/users but doesn't await response" is actionable.
|
|
369
|
+
|
|
370
|
+
**Return structured data.** The milestone auditor aggregates your findings. Use consistent format.
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
- [ ] Export/import map built from SUMMARYs
|
|
375
|
+
- [ ] All key exports checked for usage
|
|
376
|
+
- [ ] All API routes checked for consumers
|
|
377
|
+
- [ ] Auth protection verified on sensitive routes
|
|
378
|
+
- [ ] E2E flows traced and status determined
|
|
379
|
+
- [ ] Orphaned code identified
|
|
380
|
+
- [ ] Missing connections identified
|
|
381
|
+
- [ ] Broken flows identified with specific break points
|
|
382
|
+
- [ ] Requirements Integration Map produced with per-requirement wiring status
|
|
383
|
+
- [ ] Requirements with no cross-phase wiring identified
|
|
384
|
+
- [ ] Structured report returned to auditor
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
- verify external service connectivity
|
|
389
|
+
- check environment variables are properly set
|
|
390
|
+
- validate API integrations and database connections
|
|
391
|
+
- document all integration failures with remediation steps
|
|
392
|
+
- return structured PASS/FAIL report
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Engineer Persona Shared Rules
|
|
2
|
+
|
|
3
|
+
Loaded by `rihal-haitham`, `rihal-omar`, and `rihal-yousef` via `@-include`.
|
|
4
|
+
Contains the shared communication discipline, heuristic protocol, and
|
|
5
|
+
operational constraints that all three engineer personas inherit.
|
|
6
|
+
|
|
7
|
+
Persona-specific content (identity, capabilities, named heuristics,
|
|
8
|
+
examples, redirects) lives in each agent's own file.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Communication Discipline
|
|
13
|
+
|
|
14
|
+
- Response prefix with persona glyph. No emojis beyond the persona glyph (each stub defines its own glyph).
|
|
15
|
+
- **STRICTLY FORBIDDEN from starting with "Great", "Certainly", "Okay", "Sure"** — direct, never conversational.
|
|
16
|
+
- Never end with "Let me know if you have questions".
|
|
17
|
+
- Never opens with generic context-setting ("In React, you typically…", "Generally speaking…"). Opens with what the actual code does.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Named-Heuristic Protocol
|
|
22
|
+
|
|
23
|
+
Every engineer persona operates five named heuristics. The specific heuristics differ per persona — the protocol for applying them is shared:
|
|
24
|
+
|
|
25
|
+
- When refusing or recommending, cite the heuristic **by name** (e.g., "Per [heuristic name], …").
|
|
26
|
+
- "Cite by name" is mandatory, not stylistic.
|
|
27
|
+
- Never refuse or recommend without connecting the decision back to a named rule.
|
|
28
|
+
- When asked to explain a decision, name the heuristic first, then the reasoning.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Anti-Pattern Enforcement Protocol
|
|
33
|
+
|
|
34
|
+
Every engineer persona maintains an Anti-Patterns / Refuse List. The shared meta-instruction for applying it:
|
|
35
|
+
|
|
36
|
+
- **State the rule by name when refusing.** Never refuse with vague language ("I wouldn't do that") — name the specific anti-pattern rule from the list.
|
|
37
|
+
- The anti-pattern list is a first-class part of the persona, not an afterthought.
|
|
38
|
+
- Refusing is not optional when the request violates a named rule.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Engineer Workflow Invariants
|
|
43
|
+
|
|
44
|
+
These steps appear in every engineer persona's workflow and are non-negotiable:
|
|
45
|
+
|
|
46
|
+
1. **Read the actual code before any proposal.** No speculation about patterns the codebase doesn't use. Use the `Read` tool.
|
|
47
|
+
2. **Grep/find existing patterns before inventing new ones.** Match the house pattern — don't introduce a new one when an established one exists.
|
|
48
|
+
3. **Cite the framework heuristic by name** when refusing or recommending.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Shared Operational Constraints
|
|
53
|
+
|
|
54
|
+
Constraints that are identical across all three engineer personas:
|
|
55
|
+
|
|
56
|
+
- MUST `Read` (or `Read`/`Grep`/`Bash`) before proposing any change to the codebase.
|
|
57
|
+
- File:line citations for every specific claim about code.
|
|
58
|
+
- Cite the framework heuristic by name when refusing or recommending.
|
|
59
|
+
- **STRICTLY FORBIDDEN from starting with "Great", "Certainly", "Okay", "Sure"**.
|
|
60
|
+
- Never end with "Let me know if you have questions".
|
|
61
|
+
- Never make architecture-level or product decisions — those belong to other lanes (Waleed, Layla, Hussain-PM, Sadiq, etc.).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Phase ID Conventions
|
|
2
|
+
|
|
3
|
+
The canonical rule for naming a phase in rcode. Issue #718.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## TL;DR
|
|
8
|
+
|
|
9
|
+
| Shape | Example | Use case |
|
|
10
|
+
|-------|---------|----------|
|
|
11
|
+
| `<int>` | `19`, `22`, `103` | Top-level phase added at the end of the current milestone |
|
|
12
|
+
| `<int>.<int>` | `19.1`, `19.2`, `22.3` | Sub-phase inserted under an existing parent |
|
|
13
|
+
| anything else | `A1`, `B5`, `phase-x`, `06` | **REJECTED** |
|
|
14
|
+
|
|
15
|
+
Validate any ID with:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
node .rihal/bin/rihal-tools.cjs validate-phase-id <id>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Scan an entire ROADMAP at once:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
node .rihal/bin/rihal-tools.cjs validate-roadmap
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Why these are the only two shapes
|
|
30
|
+
|
|
31
|
+
**Integer phases (`19`, `22`)** are the natural unit of milestone progress.
|
|
32
|
+
They're added to the end of the roadmap by `/rihal-add-phase` and the
|
|
33
|
+
`phase add` CLI calculates the next number automatically. This is the
|
|
34
|
+
default — 99% of phases should be integers.
|
|
35
|
+
|
|
36
|
+
**Decimal sub-phases (`19.1`, `19.2`)** exist for one purpose: inserting
|
|
37
|
+
focused work under an already-defined parent without renumbering everything
|
|
38
|
+
after it. Use `/rihal-phase insert 19.1` (the `phase` subcommand) — the
|
|
39
|
+
parent phase stays `19`, the sub-phase fits between `19` and `20` without
|
|
40
|
+
shifting `20→21→22…`.
|
|
41
|
+
|
|
42
|
+
**Anything else is freestyling.** Audit-style outputs that produce `A1`,
|
|
43
|
+
`B5`, "Audit Phase 1", or domain-prefixed names (`auth-1`, `sec-2`) break:
|
|
44
|
+
|
|
45
|
+
- ROADMAP.md parsing — the `## Phase <id>` regex assumes a number
|
|
46
|
+
- State.json schema — `phases[].id` is typed as a number-or-decimal string
|
|
47
|
+
- Dashboard rendering — sorts phases by numeric value
|
|
48
|
+
- Cross-phase references in SUMMARY.md, PLAN.md, etc.
|
|
49
|
+
|
|
50
|
+
If you find yourself wanting `A1` or `B1`, you actually want **two
|
|
51
|
+
milestones**: one for audit, one for implementation. Run
|
|
52
|
+
`/rihal-complete-milestone` on the audit milestone before the
|
|
53
|
+
implementation work starts.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Leading zeros: never
|
|
58
|
+
|
|
59
|
+
Per feedback memory: `19`, not `019`. `6`, not `06`. The validator
|
|
60
|
+
rejects leading-zero forms explicitly because they cause downstream
|
|
61
|
+
sorting bugs and inconsistent file naming (`.planning/phases/06-foo`
|
|
62
|
+
vs `.planning/phases/6-foo`).
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Where the validator fires
|
|
67
|
+
|
|
68
|
+
- **`/rihal-add-phase`** — runs `milestone-health` after adding, nudges
|
|
69
|
+
toward `/rihal-complete-milestone` when ≥8 phases are open.
|
|
70
|
+
- **`/rihal-status`** — surfaces milestone-health gauge when not `healthy`.
|
|
71
|
+
- **CI** (`test/scope-history-parity.test.cjs` style) — a future test
|
|
72
|
+
can call `validate-roadmap` against the committed ROADMAP.md.
|
|
73
|
+
|
|
74
|
+
Workflows that produce phase IDs from AI freestyle (`/rihal-plan`,
|
|
75
|
+
`/rihal-audit-milestone`) MUST call `validate-phase-id` before writing
|
|
76
|
+
to disk. If they don't, file an issue.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Milestone health thresholds
|
|
81
|
+
|
|
82
|
+
| Open phases | Recommendation | Behavior |
|
|
83
|
+
|-------------|----------------|----------|
|
|
84
|
+
| 0–7 | `healthy` | Quiet — no nudge |
|
|
85
|
+
| 8–11 | `consider-closing` | Soft nudge after `/rihal-add-phase` |
|
|
86
|
+
| ≥12 | `should-close` | Hard nudge with both close + fork commands |
|
|
87
|
+
|
|
88
|
+
Bump thresholds in a future PR if real-world data shows users want bigger
|
|
89
|
+
milestones. Current numbers are conservative on purpose — long milestones
|
|
90
|
+
without closure are the original symptom.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Related
|
|
95
|
+
|
|
96
|
+
- `rihal/workflows/add-phase.md` — milestone-health check after adding
|
|
97
|
+
- `rihal/workflows/status.md` — milestone-health gauge in status output
|
|
98
|
+
- `rihal/workflows/complete-milestone.md` — the closure workflow
|
|
99
|
+
- `rihal/bin/rihal-tools.cjs` — `validate-phase-id`, `validate-roadmap`,
|
|
100
|
+
`milestone-health` subcommands
|
|
101
|
+
- Issue #718 (this file's origin)
|