ruvnet-kb-first 5.0.0
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/LICENSE +21 -0
- package/README.md +674 -0
- package/SKILL.md +740 -0
- package/bin/kb-first.js +123 -0
- package/install/init-project.sh +435 -0
- package/install/install-global.sh +257 -0
- package/install/kb-first-autodetect.sh +108 -0
- package/install/kb-first-command.md +80 -0
- package/install/kb-first-skill.md +262 -0
- package/package.json +87 -0
- package/phases/00-assessment.md +529 -0
- package/phases/01-storage.md +194 -0
- package/phases/01.5-hooks-setup.md +521 -0
- package/phases/02-kb-creation.md +413 -0
- package/phases/03-persistence.md +125 -0
- package/phases/04-visualization.md +170 -0
- package/phases/05-integration.md +114 -0
- package/phases/06-scaffold.md +130 -0
- package/phases/07-build.md +493 -0
- package/phases/08-verification.md +597 -0
- package/phases/09-security.md +512 -0
- package/phases/10-documentation.md +613 -0
- package/phases/11-deployment.md +670 -0
- package/phases/testing.md +713 -0
- package/scripts/1.5-hooks-verify.sh +252 -0
- package/scripts/8.1-code-scan.sh +58 -0
- package/scripts/8.2-import-check.sh +42 -0
- package/scripts/8.3-source-returns.sh +52 -0
- package/scripts/8.4-startup-verify.sh +65 -0
- package/scripts/8.5-fallback-check.sh +63 -0
- package/scripts/8.6-attribution.sh +56 -0
- package/scripts/8.7-confidence.sh +56 -0
- package/scripts/8.8-gap-logging.sh +70 -0
- package/scripts/9-security-audit.sh +202 -0
- package/scripts/init-project.sh +395 -0
- package/scripts/verify-enforcement.sh +167 -0
- package/src/commands/hooks.js +361 -0
- package/src/commands/init.js +315 -0
- package/src/commands/phase.js +372 -0
- package/src/commands/score.js +380 -0
- package/src/commands/status.js +193 -0
- package/src/commands/verify.js +286 -0
- package/src/index.js +56 -0
- package/src/mcp-server.js +412 -0
- package/templates/attention-router.ts +534 -0
- package/templates/code-analysis.ts +683 -0
- package/templates/federated-kb-learner.ts +649 -0
- package/templates/gnn-engine.ts +1091 -0
- package/templates/intentions.md +277 -0
- package/templates/kb-client.ts +905 -0
- package/templates/schema.sql +303 -0
- package/templates/sona-config.ts +312 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 1.5 Hooks Verify - Complete hook verification suite
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# Runs all hook verification checks for Phase 1.5
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== Phase 1.5: RuVector Hooks Verification ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
PASS_COUNT=0
|
|
13
|
+
FAIL_COUNT=0
|
|
14
|
+
SKIP_COUNT=0
|
|
15
|
+
|
|
16
|
+
# Track results
|
|
17
|
+
declare -a RESULTS
|
|
18
|
+
|
|
19
|
+
check_result() {
|
|
20
|
+
local name="$1"
|
|
21
|
+
local status="$2"
|
|
22
|
+
local message="$3"
|
|
23
|
+
|
|
24
|
+
if [ "$status" = "PASS" ]; then
|
|
25
|
+
PASS_COUNT=$((PASS_COUNT + 1))
|
|
26
|
+
RESULTS+=("✅ $name: $message")
|
|
27
|
+
elif [ "$status" = "FAIL" ]; then
|
|
28
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
29
|
+
RESULTS+=("❌ $name: $message")
|
|
30
|
+
else
|
|
31
|
+
SKIP_COUNT=$((SKIP_COUNT + 1))
|
|
32
|
+
RESULTS+=("⏭️ $name: $message")
|
|
33
|
+
fi
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# ============================================
|
|
37
|
+
# Check 1: Hooks directory exists
|
|
38
|
+
# ============================================
|
|
39
|
+
echo "1. Checking hooks directory..."
|
|
40
|
+
|
|
41
|
+
if [ -d "$HOME/.claude/hooks" ]; then
|
|
42
|
+
check_result "Hooks Directory" "PASS" "~/.claude/hooks exists"
|
|
43
|
+
else
|
|
44
|
+
check_result "Hooks Directory" "FAIL" "~/.claude/hooks not found"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# ============================================
|
|
48
|
+
# Check 2: Hook scripts exist
|
|
49
|
+
# ============================================
|
|
50
|
+
echo "2. Checking hook scripts..."
|
|
51
|
+
|
|
52
|
+
HOOKS_FOUND=0
|
|
53
|
+
for hook in pre_tool_use post_tool_use session_end; do
|
|
54
|
+
if [ -f "$HOME/.claude/hooks/${hook}.py" ]; then
|
|
55
|
+
HOOKS_FOUND=$((HOOKS_FOUND + 1))
|
|
56
|
+
fi
|
|
57
|
+
done
|
|
58
|
+
|
|
59
|
+
if [ $HOOKS_FOUND -eq 3 ]; then
|
|
60
|
+
check_result "Hook Scripts" "PASS" "All 3 hook scripts found"
|
|
61
|
+
elif [ $HOOKS_FOUND -gt 0 ]; then
|
|
62
|
+
check_result "Hook Scripts" "FAIL" "Only $HOOKS_FOUND/3 hook scripts found"
|
|
63
|
+
else
|
|
64
|
+
check_result "Hook Scripts" "FAIL" "No hook scripts found"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# ============================================
|
|
68
|
+
# Check 3: Hook scripts are executable
|
|
69
|
+
# ============================================
|
|
70
|
+
echo "3. Checking hook permissions..."
|
|
71
|
+
|
|
72
|
+
EXEC_COUNT=0
|
|
73
|
+
for hook in pre_tool_use post_tool_use session_end; do
|
|
74
|
+
if [ -x "$HOME/.claude/hooks/${hook}.py" ]; then
|
|
75
|
+
EXEC_COUNT=$((EXEC_COUNT + 1))
|
|
76
|
+
fi
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
if [ $EXEC_COUNT -eq 3 ]; then
|
|
80
|
+
check_result "Hook Permissions" "PASS" "All hooks are executable"
|
|
81
|
+
elif [ $EXEC_COUNT -gt 0 ]; then
|
|
82
|
+
check_result "Hook Permissions" "FAIL" "$EXEC_COUNT/3 hooks executable"
|
|
83
|
+
else
|
|
84
|
+
check_result "Hook Permissions" "FAIL" "No hooks are executable"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# ============================================
|
|
88
|
+
# Check 4: Hook scripts have valid Python syntax
|
|
89
|
+
# ============================================
|
|
90
|
+
echo "4. Checking hook syntax..."
|
|
91
|
+
|
|
92
|
+
SYNTAX_OK=0
|
|
93
|
+
for hook in pre_tool_use post_tool_use session_end; do
|
|
94
|
+
if [ -f "$HOME/.claude/hooks/${hook}.py" ]; then
|
|
95
|
+
if python3 -m py_compile "$HOME/.claude/hooks/${hook}.py" 2>/dev/null; then
|
|
96
|
+
SYNTAX_OK=$((SYNTAX_OK + 1))
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
done
|
|
100
|
+
|
|
101
|
+
if [ $SYNTAX_OK -eq 3 ]; then
|
|
102
|
+
check_result "Hook Syntax" "PASS" "All hooks pass syntax check"
|
|
103
|
+
elif [ $SYNTAX_OK -gt 0 ]; then
|
|
104
|
+
check_result "Hook Syntax" "FAIL" "$SYNTAX_OK/3 hooks have valid syntax"
|
|
105
|
+
else
|
|
106
|
+
check_result "Hook Syntax" "SKIP" "No hooks to check"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# ============================================
|
|
110
|
+
# Check 5: Settings.json has hooks configured
|
|
111
|
+
# ============================================
|
|
112
|
+
echo "5. Checking settings.json..."
|
|
113
|
+
|
|
114
|
+
SETTINGS_FILE="$HOME/.claude/settings.json"
|
|
115
|
+
|
|
116
|
+
if [ -f "$SETTINGS_FILE" ]; then
|
|
117
|
+
if grep -q '"hooks"' "$SETTINGS_FILE" 2>/dev/null; then
|
|
118
|
+
# Check for specific hook types
|
|
119
|
+
HOOK_TYPES=$(python3 -c "
|
|
120
|
+
import json
|
|
121
|
+
try:
|
|
122
|
+
with open('$SETTINGS_FILE') as f:
|
|
123
|
+
s = json.load(f)
|
|
124
|
+
hooks = s.get('hooks', {})
|
|
125
|
+
print(len(hooks.keys()))
|
|
126
|
+
except:
|
|
127
|
+
print(0)
|
|
128
|
+
" 2>/dev/null || echo "0")
|
|
129
|
+
|
|
130
|
+
if [ "$HOOK_TYPES" -ge 3 ]; then
|
|
131
|
+
check_result "Settings Hooks" "PASS" "All 3 hook types configured"
|
|
132
|
+
elif [ "$HOOK_TYPES" -gt 0 ]; then
|
|
133
|
+
check_result "Settings Hooks" "FAIL" "Only $HOOK_TYPES hook types configured"
|
|
134
|
+
else
|
|
135
|
+
check_result "Settings Hooks" "FAIL" "Hooks key exists but empty"
|
|
136
|
+
fi
|
|
137
|
+
else
|
|
138
|
+
check_result "Settings Hooks" "FAIL" "No hooks key in settings.json"
|
|
139
|
+
fi
|
|
140
|
+
else
|
|
141
|
+
check_result "Settings Hooks" "FAIL" "~/.claude/settings.json not found"
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# ============================================
|
|
145
|
+
# Check 6: PreToolUse hook returns valid JSON
|
|
146
|
+
# ============================================
|
|
147
|
+
echo "6. Testing PreToolUse hook..."
|
|
148
|
+
|
|
149
|
+
if [ -f "$HOME/.claude/hooks/pre_tool_use.py" ]; then
|
|
150
|
+
OUTPUT=$(echo '{"tool_name": "Write", "tool_input": {"file_path": "test.ts"}}' | \
|
|
151
|
+
python3 "$HOME/.claude/hooks/pre_tool_use.py" 2>/dev/null || echo "ERROR")
|
|
152
|
+
|
|
153
|
+
if echo "$OUTPUT" | python3 -c "import json, sys; json.load(sys.stdin)" 2>/dev/null; then
|
|
154
|
+
DECISION=$(echo "$OUTPUT" | python3 -c "import json, sys; print(json.load(sys.stdin).get('decision', ''))" 2>/dev/null)
|
|
155
|
+
if [ "$DECISION" = "continue" ] || [ "$DECISION" = "block" ]; then
|
|
156
|
+
check_result "PreToolUse Test" "PASS" "Returns valid JSON with decision"
|
|
157
|
+
else
|
|
158
|
+
check_result "PreToolUse Test" "FAIL" "Missing or invalid decision field"
|
|
159
|
+
fi
|
|
160
|
+
else
|
|
161
|
+
check_result "PreToolUse Test" "FAIL" "Does not return valid JSON"
|
|
162
|
+
fi
|
|
163
|
+
else
|
|
164
|
+
check_result "PreToolUse Test" "SKIP" "Hook script not found"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# ============================================
|
|
168
|
+
# Check 7: ReasoningBank exists and has patterns
|
|
169
|
+
# ============================================
|
|
170
|
+
echo "7. Checking ReasoningBank..."
|
|
171
|
+
|
|
172
|
+
REASONING_DB=".swarm/memory.db"
|
|
173
|
+
|
|
174
|
+
if [ -f "$REASONING_DB" ]; then
|
|
175
|
+
PATTERN_COUNT=$(sqlite3 "$REASONING_DB" "SELECT COUNT(*) FROM reasoning_memory WHERE namespace = 'kb_first_patterns';" 2>/dev/null || echo "0")
|
|
176
|
+
|
|
177
|
+
if [ "$PATTERN_COUNT" -ge 5 ]; then
|
|
178
|
+
check_result "ReasoningBank" "PASS" "$PATTERN_COUNT KB-First patterns found"
|
|
179
|
+
elif [ "$PATTERN_COUNT" -gt 0 ]; then
|
|
180
|
+
check_result "ReasoningBank" "FAIL" "Only $PATTERN_COUNT patterns (need ≥5)"
|
|
181
|
+
else
|
|
182
|
+
check_result "ReasoningBank" "FAIL" "No KB-First patterns seeded"
|
|
183
|
+
fi
|
|
184
|
+
else
|
|
185
|
+
# Check alternative location
|
|
186
|
+
GLOBAL_DB="$HOME/.claude-flow/memory.db"
|
|
187
|
+
if [ -f "$GLOBAL_DB" ]; then
|
|
188
|
+
PATTERN_COUNT=$(sqlite3 "$GLOBAL_DB" "SELECT COUNT(*) FROM reasoning_memory WHERE namespace = 'kb_first_patterns';" 2>/dev/null || echo "0")
|
|
189
|
+
|
|
190
|
+
if [ "$PATTERN_COUNT" -ge 5 ]; then
|
|
191
|
+
check_result "ReasoningBank" "PASS" "$PATTERN_COUNT patterns in global DB"
|
|
192
|
+
else
|
|
193
|
+
check_result "ReasoningBank" "FAIL" "Global DB has $PATTERN_COUNT patterns"
|
|
194
|
+
fi
|
|
195
|
+
else
|
|
196
|
+
check_result "ReasoningBank" "SKIP" "ReasoningBank not initialized"
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# ============================================
|
|
201
|
+
# Check 8: RuVector CLI available
|
|
202
|
+
# ============================================
|
|
203
|
+
echo "8. Checking RuVector CLI..."
|
|
204
|
+
|
|
205
|
+
if command -v npx >/dev/null 2>&1; then
|
|
206
|
+
if npx @ruvector/cli --version >/dev/null 2>&1; then
|
|
207
|
+
VERSION=$(npx @ruvector/cli --version 2>/dev/null || echo "unknown")
|
|
208
|
+
check_result "RuVector CLI" "PASS" "Version $VERSION"
|
|
209
|
+
else
|
|
210
|
+
check_result "RuVector CLI" "SKIP" "Not installed (optional)"
|
|
211
|
+
fi
|
|
212
|
+
else
|
|
213
|
+
check_result "RuVector CLI" "SKIP" "npx not available"
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
# ============================================
|
|
217
|
+
# Summary
|
|
218
|
+
# ============================================
|
|
219
|
+
echo ""
|
|
220
|
+
echo "================================================"
|
|
221
|
+
echo "RESULTS SUMMARY"
|
|
222
|
+
echo "================================================"
|
|
223
|
+
echo ""
|
|
224
|
+
|
|
225
|
+
for result in "${RESULTS[@]}"; do
|
|
226
|
+
echo "$result"
|
|
227
|
+
done
|
|
228
|
+
|
|
229
|
+
echo ""
|
|
230
|
+
echo "================================================"
|
|
231
|
+
|
|
232
|
+
TOTAL=$((PASS_COUNT + FAIL_COUNT))
|
|
233
|
+
|
|
234
|
+
if [ $FAIL_COUNT -eq 0 ] && [ $PASS_COUNT -ge 5 ]; then
|
|
235
|
+
echo "PASS: All critical checks passed ($PASS_COUNT passed, $SKIP_COUNT skipped)"
|
|
236
|
+
exit 0
|
|
237
|
+
elif [ $FAIL_COUNT -eq 0 ]; then
|
|
238
|
+
echo "PARTIAL: Some checks passed ($PASS_COUNT passed, $SKIP_COUNT skipped)"
|
|
239
|
+
echo ""
|
|
240
|
+
echo "Run the following to complete setup:"
|
|
241
|
+
echo " npx @ruvector/cli hooks init"
|
|
242
|
+
echo " npx @ruvector/cli hooks install"
|
|
243
|
+
exit 0
|
|
244
|
+
else
|
|
245
|
+
echo "FAIL: $FAIL_COUNT check(s) failed"
|
|
246
|
+
echo ""
|
|
247
|
+
echo "To fix, run:"
|
|
248
|
+
echo " npx @ruvector/cli hooks init"
|
|
249
|
+
echo " npx @ruvector/cli hooks install"
|
|
250
|
+
echo " npx @ruvector/cli reasoningbank seed --kb-first"
|
|
251
|
+
exit 1
|
|
252
|
+
fi
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.1 Code Scan - No hardcoded values in domain logic
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# This script scans for hardcoded numeric values in domain files.
|
|
6
|
+
# All values should come from KB queries.
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
echo "=== 8.1 Code Scan: No Hardcoded Values ==="
|
|
11
|
+
echo ""
|
|
12
|
+
|
|
13
|
+
VIOLATIONS=0
|
|
14
|
+
DOMAIN_DIR="src/domain"
|
|
15
|
+
|
|
16
|
+
if [ ! -d "$DOMAIN_DIR" ]; then
|
|
17
|
+
echo "Domain directory not found: $DOMAIN_DIR"
|
|
18
|
+
echo "SKIPPED - No domain files to scan"
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
echo "Scanning $DOMAIN_DIR for hardcoded values..."
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
# Pattern: variable = 0.XX or similar numeric assignments
|
|
26
|
+
while IFS= read -r file; do
|
|
27
|
+
matches=$(grep -nE "= [0-9]+\.[0-9]+" "$file" 2>/dev/null || true)
|
|
28
|
+
if [ -n "$matches" ]; then
|
|
29
|
+
echo "VIOLATION in $file:"
|
|
30
|
+
echo "$matches" | while read -r line; do
|
|
31
|
+
echo " $line"
|
|
32
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
33
|
+
done
|
|
34
|
+
echo ""
|
|
35
|
+
fi
|
|
36
|
+
done < <(find "$DOMAIN_DIR" -name "*.ts" -o -name "*.js")
|
|
37
|
+
|
|
38
|
+
# Also check for magic numbers in conditionals
|
|
39
|
+
while IFS= read -r file; do
|
|
40
|
+
matches=$(grep -nE "(> [0-9]+|< [0-9]+|>= [0-9]+|<= [0-9]+|== [0-9]+)" "$file" 2>/dev/null | grep -v "\.length" || true)
|
|
41
|
+
if [ -n "$matches" ]; then
|
|
42
|
+
echo "POTENTIAL MAGIC NUMBER in $file:"
|
|
43
|
+
echo "$matches" | head -5
|
|
44
|
+
echo ""
|
|
45
|
+
fi
|
|
46
|
+
done < <(find "$DOMAIN_DIR" -name "*.ts" -o -name "*.js")
|
|
47
|
+
|
|
48
|
+
echo "================================================"
|
|
49
|
+
if [ $VIOLATIONS -eq 0 ]; then
|
|
50
|
+
echo "PASS: No hardcoded values found"
|
|
51
|
+
exit 0
|
|
52
|
+
else
|
|
53
|
+
echo "FAIL: $VIOLATIONS hardcoded value(s) found"
|
|
54
|
+
echo ""
|
|
55
|
+
echo "Fix: Replace hardcoded values with KB queries:"
|
|
56
|
+
echo " const rate = await kb.search('withdrawal rate');"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.2 Import Check - All domain files import KB
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# Every domain file must import the KB module.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.2 Import Check: KB Import Required ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
VIOLATIONS=0
|
|
13
|
+
DOMAIN_DIR="src/domain"
|
|
14
|
+
|
|
15
|
+
if [ ! -d "$DOMAIN_DIR" ]; then
|
|
16
|
+
echo "Domain directory not found: $DOMAIN_DIR"
|
|
17
|
+
echo "SKIPPED - No domain files to check"
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "Checking KB imports in $DOMAIN_DIR..."
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
while IFS= read -r file; do
|
|
25
|
+
if ! grep -q "from.*kb\|import.*kb\|require.*kb" "$file" 2>/dev/null; then
|
|
26
|
+
echo "MISSING KB IMPORT: $file"
|
|
27
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
28
|
+
fi
|
|
29
|
+
done < <(find "$DOMAIN_DIR" -name "*.ts" -o -name "*.js")
|
|
30
|
+
|
|
31
|
+
echo ""
|
|
32
|
+
echo "================================================"
|
|
33
|
+
if [ $VIOLATIONS -eq 0 ]; then
|
|
34
|
+
echo "PASS: All domain files import KB"
|
|
35
|
+
exit 0
|
|
36
|
+
else
|
|
37
|
+
echo "FAIL: $VIOLATIONS file(s) missing KB import"
|
|
38
|
+
echo ""
|
|
39
|
+
echo "Fix: Add to each domain file:"
|
|
40
|
+
echo " import { kb } from '../kb';"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.3 Source Returns - All functions return kbSources
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# Every domain function must include kbSources in its return.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.3 Source Returns: kbSources Required ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
VIOLATIONS=0
|
|
13
|
+
DOMAIN_DIR="src/domain"
|
|
14
|
+
|
|
15
|
+
if [ ! -d "$DOMAIN_DIR" ]; then
|
|
16
|
+
echo "Domain directory not found: $DOMAIN_DIR"
|
|
17
|
+
echo "SKIPPED - No domain files to check"
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "Checking kbSources in return statements..."
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
while IFS= read -r file; do
|
|
25
|
+
# Count functions that have return statements
|
|
26
|
+
RETURN_COUNT=$(grep -c "return {" "$file" 2>/dev/null || echo "0")
|
|
27
|
+
|
|
28
|
+
# Count returns that include kbSources
|
|
29
|
+
SOURCE_COUNT=$(grep -c "kbSources" "$file" 2>/dev/null || echo "0")
|
|
30
|
+
|
|
31
|
+
if [ "$RETURN_COUNT" -gt 0 ] && [ "$SOURCE_COUNT" -lt "$RETURN_COUNT" ]; then
|
|
32
|
+
echo "MISSING kbSources in $file"
|
|
33
|
+
echo " Returns: $RETURN_COUNT, With sources: $SOURCE_COUNT"
|
|
34
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
35
|
+
fi
|
|
36
|
+
done < <(find "$DOMAIN_DIR" -name "*.ts" -o -name "*.js")
|
|
37
|
+
|
|
38
|
+
echo ""
|
|
39
|
+
echo "================================================"
|
|
40
|
+
if [ $VIOLATIONS -eq 0 ]; then
|
|
41
|
+
echo "PASS: All returns include kbSources"
|
|
42
|
+
exit 0
|
|
43
|
+
else
|
|
44
|
+
echo "FAIL: $VIOLATIONS file(s) missing kbSources"
|
|
45
|
+
echo ""
|
|
46
|
+
echo "Fix: Add kbSources to every return:"
|
|
47
|
+
echo " return {"
|
|
48
|
+
echo " result: data,"
|
|
49
|
+
echo " kbSources: sources"
|
|
50
|
+
echo " };"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.4 Startup Verify - Entry point verifies KB connection
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# The application entry point must verify KB connection before starting.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.4 Startup Verify: KB Connection Check ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
# Find entry point
|
|
13
|
+
ENTRY_POINT=""
|
|
14
|
+
for file in "src/index.ts" "src/index.js" "src/main.ts" "src/app.ts" "index.ts" "index.js"; do
|
|
15
|
+
if [ -f "$file" ]; then
|
|
16
|
+
ENTRY_POINT="$file"
|
|
17
|
+
break
|
|
18
|
+
fi
|
|
19
|
+
done
|
|
20
|
+
|
|
21
|
+
if [ -z "$ENTRY_POINT" ]; then
|
|
22
|
+
echo "No entry point found"
|
|
23
|
+
echo "SKIPPED - Create src/index.ts or similar"
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
echo "Checking entry point: $ENTRY_POINT"
|
|
28
|
+
echo ""
|
|
29
|
+
|
|
30
|
+
# Check for verifyConnection call
|
|
31
|
+
if grep -q "verifyConnection\|verifyKb\|checkKb\|kb\.verify\|kb\.connect" "$ENTRY_POINT"; then
|
|
32
|
+
echo "Found KB verification call"
|
|
33
|
+
|
|
34
|
+
# Check for proper error handling
|
|
35
|
+
if grep -q "process.exit(1)\|throw\|reject" "$ENTRY_POINT"; then
|
|
36
|
+
echo "Found error handling"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "================================================"
|
|
39
|
+
echo "PASS: Entry point verifies KB and handles errors"
|
|
40
|
+
exit 0
|
|
41
|
+
else
|
|
42
|
+
echo ""
|
|
43
|
+
echo "================================================"
|
|
44
|
+
echo "FAIL: KB verification exists but no error handling"
|
|
45
|
+
echo ""
|
|
46
|
+
echo "Fix: Add process.exit(1) on KB failure:"
|
|
47
|
+
echo " if (!kbOk) {"
|
|
48
|
+
echo " console.error('KB unavailable');"
|
|
49
|
+
echo " process.exit(1);"
|
|
50
|
+
echo " }"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
else
|
|
54
|
+
echo ""
|
|
55
|
+
echo "================================================"
|
|
56
|
+
echo "FAIL: No KB verification at startup"
|
|
57
|
+
echo ""
|
|
58
|
+
echo "Fix: Add to entry point:"
|
|
59
|
+
echo " const kbOk = await kb.verifyConnection();"
|
|
60
|
+
echo " if (!kbOk) {"
|
|
61
|
+
echo " console.error('KB unavailable');"
|
|
62
|
+
echo " process.exit(1);"
|
|
63
|
+
echo " }"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.5 Fallback Check - No || DEFAULT patterns
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# Domain logic must not use fallback defaults. KB is the source of truth.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.5 Fallback Check: No Default Values ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
VIOLATIONS=0
|
|
13
|
+
DOMAIN_DIR="src/domain"
|
|
14
|
+
|
|
15
|
+
if [ ! -d "$DOMAIN_DIR" ]; then
|
|
16
|
+
echo "Domain directory not found: $DOMAIN_DIR"
|
|
17
|
+
echo "SKIPPED - No domain files to check"
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "Checking for fallback patterns in $DOMAIN_DIR..."
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
# Pattern: || followed by a default value
|
|
25
|
+
PATTERNS=(
|
|
26
|
+
'\|\| DEFAULT'
|
|
27
|
+
'\|\| \[\]'
|
|
28
|
+
'\|\| \{\}'
|
|
29
|
+
'\|\| null'
|
|
30
|
+
'\|\| 0'
|
|
31
|
+
'\|\| ""'
|
|
32
|
+
'\|\| '\'''\'''
|
|
33
|
+
'\?\? \[\]'
|
|
34
|
+
'\?\? \{\}'
|
|
35
|
+
'\?\? 0'
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
for pattern in "${PATTERNS[@]}"; do
|
|
39
|
+
while IFS= read -r file; do
|
|
40
|
+
matches=$(grep -n "$pattern" "$file" 2>/dev/null || true)
|
|
41
|
+
if [ -n "$matches" ]; then
|
|
42
|
+
echo "FALLBACK PATTERN in $file:"
|
|
43
|
+
echo "$matches" | while read -r line; do
|
|
44
|
+
echo " $line"
|
|
45
|
+
VIOLATIONS=$((VIOLATIONS + 1))
|
|
46
|
+
done
|
|
47
|
+
fi
|
|
48
|
+
done < <(find "$DOMAIN_DIR" -name "*.ts" -o -name "*.js")
|
|
49
|
+
done
|
|
50
|
+
|
|
51
|
+
echo ""
|
|
52
|
+
echo "================================================"
|
|
53
|
+
if [ $VIOLATIONS -eq 0 ]; then
|
|
54
|
+
echo "PASS: No fallback patterns found"
|
|
55
|
+
exit 0
|
|
56
|
+
else
|
|
57
|
+
echo "FAIL: Fallback patterns detected"
|
|
58
|
+
echo ""
|
|
59
|
+
echo "Fix: Remove fallbacks, require KB to have the data:"
|
|
60
|
+
echo " // BAD: const rate = kbRate || 0.04;"
|
|
61
|
+
echo " // GOOD: const rate = kbRate; // KB required"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.6 Attribution - All KB nodes have source_expert
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# Every KB node must be attributed to an expert source.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.6 Attribution: Expert Sources Required ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
if [ -z "$DATABASE_URL" ]; then
|
|
13
|
+
echo "DATABASE_URL not set"
|
|
14
|
+
echo "SKIPPED - Cannot connect to database"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
echo "Checking KB node attribution..."
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
# Count nodes without attribution
|
|
22
|
+
RESULT=$(psql "$DATABASE_URL" -t -c "
|
|
23
|
+
SELECT
|
|
24
|
+
COUNT(*) as total,
|
|
25
|
+
SUM(CASE WHEN source_expert IS NULL OR source_expert = '' THEN 1 ELSE 0 END) as missing
|
|
26
|
+
FROM kb_nodes;
|
|
27
|
+
" 2>/dev/null || echo "0|0")
|
|
28
|
+
|
|
29
|
+
TOTAL=$(echo "$RESULT" | cut -d'|' -f1 | tr -d ' ')
|
|
30
|
+
MISSING=$(echo "$RESULT" | cut -d'|' -f2 | tr -d ' ')
|
|
31
|
+
|
|
32
|
+
if [ "$TOTAL" = "0" ]; then
|
|
33
|
+
echo "No KB nodes found"
|
|
34
|
+
echo "SKIPPED - KB is empty"
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
PERCENTAGE=$((100 - (MISSING * 100 / TOTAL)))
|
|
39
|
+
|
|
40
|
+
echo "Total nodes: $TOTAL"
|
|
41
|
+
echo "Missing attribution: $MISSING"
|
|
42
|
+
echo "Attribution rate: $PERCENTAGE%"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "================================================"
|
|
45
|
+
|
|
46
|
+
if [ "$MISSING" -eq 0 ]; then
|
|
47
|
+
echo "PASS: All nodes have expert attribution"
|
|
48
|
+
exit 0
|
|
49
|
+
else
|
|
50
|
+
echo "FAIL: $MISSING node(s) missing attribution"
|
|
51
|
+
echo ""
|
|
52
|
+
echo "Fix: Update nodes with source_expert:"
|
|
53
|
+
echo " UPDATE kb_nodes SET source_expert = 'Expert Name'"
|
|
54
|
+
echo " WHERE source_expert IS NULL;"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.7 Confidence - All KB nodes have confidence scores
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# Every KB node must have a confidence score (0.0 - 1.0).
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.7 Confidence: Confidence Scores Required ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
if [ -z "$DATABASE_URL" ]; then
|
|
13
|
+
echo "DATABASE_URL not set"
|
|
14
|
+
echo "SKIPPED - Cannot connect to database"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
echo "Checking KB node confidence scores..."
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
# Check for nodes without confidence
|
|
22
|
+
RESULT=$(psql "$DATABASE_URL" -t -c "
|
|
23
|
+
SELECT
|
|
24
|
+
COUNT(*) as total,
|
|
25
|
+
SUM(CASE WHEN confidence IS NULL OR confidence = 0 THEN 1 ELSE 0 END) as missing,
|
|
26
|
+
COALESCE(AVG(confidence), 0) as avg_confidence
|
|
27
|
+
FROM kb_nodes;
|
|
28
|
+
" 2>/dev/null || echo "0|0|0")
|
|
29
|
+
|
|
30
|
+
TOTAL=$(echo "$RESULT" | cut -d'|' -f1 | tr -d ' ')
|
|
31
|
+
MISSING=$(echo "$RESULT" | cut -d'|' -f2 | tr -d ' ')
|
|
32
|
+
AVG=$(echo "$RESULT" | cut -d'|' -f3 | tr -d ' ')
|
|
33
|
+
|
|
34
|
+
if [ "$TOTAL" = "0" ]; then
|
|
35
|
+
echo "No KB nodes found"
|
|
36
|
+
echo "SKIPPED - KB is empty"
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
echo "Total nodes: $TOTAL"
|
|
41
|
+
echo "Missing confidence: $MISSING"
|
|
42
|
+
echo "Average confidence: $AVG"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "================================================"
|
|
45
|
+
|
|
46
|
+
if [ "$MISSING" -eq 0 ]; then
|
|
47
|
+
echo "PASS: All nodes have confidence scores"
|
|
48
|
+
exit 0
|
|
49
|
+
else
|
|
50
|
+
echo "FAIL: $MISSING node(s) missing confidence"
|
|
51
|
+
echo ""
|
|
52
|
+
echo "Fix: Update nodes with confidence:"
|
|
53
|
+
echo " UPDATE kb_nodes SET confidence = 0.85"
|
|
54
|
+
echo " WHERE confidence IS NULL OR confidence = 0;"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|