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,70 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 8.8 Gap Logging - Missing queries logged to kb_gaps
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-01
|
|
4
|
+
#
|
|
5
|
+
# The application must log queries that KB cannot answer.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "=== 8.8 Gap Logging: Unanswered Queries ==="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
# Check 1: kb_gaps table exists
|
|
13
|
+
if [ -n "$DATABASE_URL" ]; then
|
|
14
|
+
echo "Checking database for kb_gaps table..."
|
|
15
|
+
|
|
16
|
+
TABLE_EXISTS=$(psql "$DATABASE_URL" -t -c "
|
|
17
|
+
SELECT EXISTS (
|
|
18
|
+
SELECT FROM information_schema.tables
|
|
19
|
+
WHERE table_name = 'kb_gaps'
|
|
20
|
+
);
|
|
21
|
+
" 2>/dev/null | tr -d ' ')
|
|
22
|
+
|
|
23
|
+
if [ "$TABLE_EXISTS" != "t" ]; then
|
|
24
|
+
echo ""
|
|
25
|
+
echo "================================================"
|
|
26
|
+
echo "FAIL: kb_gaps table does not exist"
|
|
27
|
+
echo ""
|
|
28
|
+
echo "Fix: Create the gaps table:"
|
|
29
|
+
echo " CREATE TABLE kb_gaps ("
|
|
30
|
+
echo " id SERIAL PRIMARY KEY,"
|
|
31
|
+
echo " query TEXT NOT NULL,"
|
|
32
|
+
echo " context JSONB,"
|
|
33
|
+
echo " created_at TIMESTAMP DEFAULT NOW()"
|
|
34
|
+
echo " );"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
echo "kb_gaps table exists"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Check 2: Code has gap logging implementation
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Checking source code for gap logging..."
|
|
44
|
+
|
|
45
|
+
GAP_LOGGING_FOUND=false
|
|
46
|
+
|
|
47
|
+
if grep -rq "logGap\|kb_gaps\|insertGap\|recordGap" . --include="*.ts" --include="*.js" 2>/dev/null; then
|
|
48
|
+
echo "Gap logging found in source files"
|
|
49
|
+
GAP_LOGGING_FOUND=true
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo ""
|
|
53
|
+
echo "================================================"
|
|
54
|
+
|
|
55
|
+
if [ "$GAP_LOGGING_FOUND" = true ]; then
|
|
56
|
+
echo "PASS: Gap logging implemented"
|
|
57
|
+
exit 0
|
|
58
|
+
else
|
|
59
|
+
echo "FAIL: No gap logging found"
|
|
60
|
+
echo ""
|
|
61
|
+
echo "Fix: Add gap logging to KB queries:"
|
|
62
|
+
echo " async function queryKB(query: string) {"
|
|
63
|
+
echo " const result = await kb.search(query);"
|
|
64
|
+
echo " if (!result || result.length === 0) {"
|
|
65
|
+
echo " await logGap(query);"
|
|
66
|
+
echo " }"
|
|
67
|
+
echo " return result;"
|
|
68
|
+
echo " }"
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 9 Security Audit - Complete security verification suite
|
|
3
|
+
# Version 1.0.0 | Created 2026-01-02
|
|
4
|
+
#
|
|
5
|
+
# Runs all security checks for Phase 9
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
echo "╔═══════════════════════════════════════════════════════════════╗"
|
|
10
|
+
echo "║ Phase 9: Security Audit Suite ║"
|
|
11
|
+
echo "╚═══════════════════════════════════════════════════════════════╝"
|
|
12
|
+
echo ""
|
|
13
|
+
|
|
14
|
+
PASS_COUNT=0
|
|
15
|
+
FAIL_COUNT=0
|
|
16
|
+
WARN_COUNT=0
|
|
17
|
+
|
|
18
|
+
check_result() {
|
|
19
|
+
local name="$1"
|
|
20
|
+
local status="$2"
|
|
21
|
+
local message="$3"
|
|
22
|
+
|
|
23
|
+
if [ "$status" = "PASS" ]; then
|
|
24
|
+
PASS_COUNT=$((PASS_COUNT + 1))
|
|
25
|
+
echo "✅ $name: $message"
|
|
26
|
+
elif [ "$status" = "FAIL" ]; then
|
|
27
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
28
|
+
echo "❌ $name: $message"
|
|
29
|
+
else
|
|
30
|
+
WARN_COUNT=$((WARN_COUNT + 1))
|
|
31
|
+
echo "⚠️ $name: $message"
|
|
32
|
+
fi
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# ============================================
|
|
36
|
+
# 9.1 Dependency Audit
|
|
37
|
+
# ============================================
|
|
38
|
+
echo ""
|
|
39
|
+
echo "=== 9.1 Dependency Audit ==="
|
|
40
|
+
|
|
41
|
+
if [ -f "package.json" ]; then
|
|
42
|
+
AUDIT_RESULT=$(npm audit --json 2>/dev/null || echo '{"metadata":{"vulnerabilities":{"critical":0,"high":0}}}')
|
|
43
|
+
CRITICAL=$(echo "$AUDIT_RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('metadata',{}).get('vulnerabilities',{}).get('critical',0))" 2>/dev/null || echo "0")
|
|
44
|
+
HIGH=$(echo "$AUDIT_RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('metadata',{}).get('vulnerabilities',{}).get('high',0))" 2>/dev/null || echo "0")
|
|
45
|
+
|
|
46
|
+
if [ "$CRITICAL" = "0" ] && [ "$HIGH" = "0" ]; then
|
|
47
|
+
check_result "Dependencies" "PASS" "No critical/high vulnerabilities"
|
|
48
|
+
else
|
|
49
|
+
check_result "Dependencies" "FAIL" "$CRITICAL critical, $HIGH high vulnerabilities"
|
|
50
|
+
fi
|
|
51
|
+
else
|
|
52
|
+
check_result "Dependencies" "WARN" "No package.json found"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# ============================================
|
|
56
|
+
# 9.3 SQL Injection Prevention
|
|
57
|
+
# ============================================
|
|
58
|
+
echo ""
|
|
59
|
+
echo "=== 9.3 SQL Injection Prevention ==="
|
|
60
|
+
|
|
61
|
+
SQL_VIOLATIONS=0
|
|
62
|
+
|
|
63
|
+
# Check for template literals in SQL
|
|
64
|
+
if grep -rqE "(SELECT|INSERT|UPDATE|DELETE).*\\\$\{" src/ 2>/dev/null; then
|
|
65
|
+
check_result "SQL Injection" "FAIL" "Template literals found in SQL queries"
|
|
66
|
+
SQL_VIOLATIONS=$((SQL_VIOLATIONS + 1))
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Check for string concatenation in queries
|
|
70
|
+
if grep -rqE "query\s*\(\s*['\"].*\+\s*" src/ 2>/dev/null; then
|
|
71
|
+
check_result "SQL Concat" "WARN" "String concatenation in queries detected"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
if [ $SQL_VIOLATIONS -eq 0 ]; then
|
|
75
|
+
check_result "SQL Injection" "PASS" "No SQL injection patterns found"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# ============================================
|
|
79
|
+
# 9.4 Authentication & Authorization
|
|
80
|
+
# ============================================
|
|
81
|
+
echo ""
|
|
82
|
+
echo "=== 9.4 Authentication & Authorization ==="
|
|
83
|
+
|
|
84
|
+
# Check for password hashing
|
|
85
|
+
if grep -rq "bcrypt\|argon2\|scrypt" package.json 2>/dev/null; then
|
|
86
|
+
check_result "Password Hashing" "PASS" "Secure hashing library found"
|
|
87
|
+
else
|
|
88
|
+
check_result "Password Hashing" "WARN" "No password hashing library found"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Check for secure cookies
|
|
92
|
+
if grep -rq "httpOnly.*true" src/ 2>/dev/null || grep -rq "secure.*true" src/ 2>/dev/null; then
|
|
93
|
+
check_result "Secure Cookies" "PASS" "Secure cookie flags found"
|
|
94
|
+
else
|
|
95
|
+
check_result "Secure Cookies" "WARN" "Secure cookie flags not found"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Check for auth middleware
|
|
99
|
+
if grep -rq "requireAuth\|isAuthenticated\|authMiddleware\|passport\|jwt" src/ 2>/dev/null; then
|
|
100
|
+
check_result "Auth Middleware" "PASS" "Authentication middleware found"
|
|
101
|
+
else
|
|
102
|
+
check_result "Auth Middleware" "WARN" "No authentication middleware detected"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# ============================================
|
|
106
|
+
# 9.5 Secrets Management
|
|
107
|
+
# ============================================
|
|
108
|
+
echo ""
|
|
109
|
+
echo "=== 9.5 Secrets Management ==="
|
|
110
|
+
|
|
111
|
+
SECRETS_VIOLATIONS=0
|
|
112
|
+
|
|
113
|
+
# Check for hardcoded passwords
|
|
114
|
+
if grep -rqE "password\s*=\s*['\"][^'\"]+['\"]" src/ --include="*.ts" --include="*.js" 2>/dev/null | grep -v "process.env\|\.env\|example\|template\|test" | head -1; then
|
|
115
|
+
check_result "Hardcoded Password" "FAIL" "Potential hardcoded password found"
|
|
116
|
+
SECRETS_VIOLATIONS=$((SECRETS_VIOLATIONS + 1))
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Check for hardcoded API keys
|
|
120
|
+
if grep -rqE "(api_key|apiKey|API_KEY)\s*=\s*['\"][^'\"]{20,}['\"]" src/ --include="*.ts" --include="*.js" 2>/dev/null | grep -v "process.env\|\.env"; then
|
|
121
|
+
check_result "Hardcoded API Key" "FAIL" "Potential hardcoded API key found"
|
|
122
|
+
SECRETS_VIOLATIONS=$((SECRETS_VIOLATIONS + 1))
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
# Check .gitignore for .env
|
|
126
|
+
if grep -q "^\.env$" .gitignore 2>/dev/null; then
|
|
127
|
+
check_result ".env in .gitignore" "PASS" ".env is properly ignored"
|
|
128
|
+
else
|
|
129
|
+
check_result ".env in .gitignore" "FAIL" ".env is NOT in .gitignore"
|
|
130
|
+
SECRETS_VIOLATIONS=$((SECRETS_VIOLATIONS + 1))
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# Check for .env files in git
|
|
134
|
+
if git ls-files 2>/dev/null | grep -q "\.env$"; then
|
|
135
|
+
check_result ".env in git" "FAIL" ".env file is tracked in git!"
|
|
136
|
+
SECRETS_VIOLATIONS=$((SECRETS_VIOLATIONS + 1))
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
if [ $SECRETS_VIOLATIONS -eq 0 ]; then
|
|
140
|
+
check_result "Secrets" "PASS" "No secret management issues found"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# ============================================
|
|
144
|
+
# 9.6 API Security
|
|
145
|
+
# ============================================
|
|
146
|
+
echo ""
|
|
147
|
+
echo "=== 9.6 API Security ==="
|
|
148
|
+
|
|
149
|
+
# Check for rate limiting
|
|
150
|
+
if grep -rq "rateLimit\|rate-limit\|throttle" src/ package.json 2>/dev/null; then
|
|
151
|
+
check_result "Rate Limiting" "PASS" "Rate limiting implemented"
|
|
152
|
+
else
|
|
153
|
+
check_result "Rate Limiting" "WARN" "No rate limiting found"
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# Check for CORS
|
|
157
|
+
if grep -rq "cors" package.json 2>/dev/null; then
|
|
158
|
+
check_result "CORS" "PASS" "CORS library found"
|
|
159
|
+
else
|
|
160
|
+
check_result "CORS" "WARN" "No CORS configuration found"
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
# Check for input validation
|
|
164
|
+
if grep -rq "zod\|joi\|yup\|class-validator" package.json 2>/dev/null; then
|
|
165
|
+
check_result "Input Validation" "PASS" "Input validation library found"
|
|
166
|
+
else
|
|
167
|
+
check_result "Input Validation" "WARN" "No input validation library found"
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Check for helmet (security headers)
|
|
171
|
+
if grep -rq "helmet" package.json 2>/dev/null; then
|
|
172
|
+
check_result "Security Headers" "PASS" "Helmet (security headers) found"
|
|
173
|
+
else
|
|
174
|
+
check_result "Security Headers" "WARN" "Helmet not found"
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# ============================================
|
|
178
|
+
# Summary
|
|
179
|
+
# ============================================
|
|
180
|
+
echo ""
|
|
181
|
+
echo "═══════════════════════════════════════════════════════════════"
|
|
182
|
+
echo "SECURITY AUDIT SUMMARY"
|
|
183
|
+
echo "═══════════════════════════════════════════════════════════════"
|
|
184
|
+
echo ""
|
|
185
|
+
echo " Passed: $PASS_COUNT"
|
|
186
|
+
echo " Warnings: $WARN_COUNT"
|
|
187
|
+
echo " Failed: $FAIL_COUNT"
|
|
188
|
+
echo ""
|
|
189
|
+
|
|
190
|
+
if [ $FAIL_COUNT -eq 0 ]; then
|
|
191
|
+
echo "✅ SECURITY AUDIT PASSED"
|
|
192
|
+
echo ""
|
|
193
|
+
if [ $WARN_COUNT -gt 0 ]; then
|
|
194
|
+
echo "Note: $WARN_COUNT warning(s) should be reviewed before production."
|
|
195
|
+
fi
|
|
196
|
+
exit 0
|
|
197
|
+
else
|
|
198
|
+
echo "❌ SECURITY AUDIT FAILED"
|
|
199
|
+
echo ""
|
|
200
|
+
echo "Fix all failures before proceeding to Phase 10."
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# KB-First Project Initialization Script
|
|
3
|
+
# Creates a new KB-First application scaffold
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Colors
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
GREEN='\033[0;32m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
BLUE='\033[0;34m'
|
|
12
|
+
NC='\033[0m'
|
|
13
|
+
|
|
14
|
+
echo -e "${BLUE}╔═══════════════════════════════════════╗${NC}"
|
|
15
|
+
echo -e "${BLUE}║ KB-First v3.0 Project Init ║${NC}"
|
|
16
|
+
echo -e "${BLUE}╚═══════════════════════════════════════╝${NC}"
|
|
17
|
+
echo ""
|
|
18
|
+
|
|
19
|
+
# Get project name
|
|
20
|
+
if [ -z "$1" ]; then
|
|
21
|
+
read -p "Project name: " PROJECT_NAME
|
|
22
|
+
else
|
|
23
|
+
PROJECT_NAME=$1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Validate project name
|
|
27
|
+
if [[ ! "$PROJECT_NAME" =~ ^[a-z0-9-]+$ ]]; then
|
|
28
|
+
echo -e "${RED}Error: Project name must be lowercase alphanumeric with hyphens${NC}"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Get domain topic
|
|
33
|
+
if [ -z "$2" ]; then
|
|
34
|
+
read -p "Domain topic (e.g., 'retirement planning'): " DOMAIN_TOPIC
|
|
35
|
+
else
|
|
36
|
+
DOMAIN_TOPIC=$2
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Select pattern
|
|
40
|
+
echo ""
|
|
41
|
+
echo "Select intelligence pattern:"
|
|
42
|
+
echo " 1) Decision Web (GNN) - When decisions cascade"
|
|
43
|
+
echo " 2) Combinatorial Routing (Attention) - When routing to experts"
|
|
44
|
+
echo " 3) Scenario Learning (SONA) - When learning from outcomes"
|
|
45
|
+
echo " 4) Continuous Optimization (Attention+SONA) - For ongoing monitoring"
|
|
46
|
+
echo ""
|
|
47
|
+
read -p "Pattern [1-4]: " PATTERN_CHOICE
|
|
48
|
+
|
|
49
|
+
case $PATTERN_CHOICE in
|
|
50
|
+
1) PATTERN="decision-web" ;;
|
|
51
|
+
2) PATTERN="combinatorial-routing" ;;
|
|
52
|
+
3) PATTERN="scenario-learning" ;;
|
|
53
|
+
4) PATTERN="continuous-optimization" ;;
|
|
54
|
+
*) echo -e "${RED}Invalid choice${NC}"; exit 1 ;;
|
|
55
|
+
esac
|
|
56
|
+
|
|
57
|
+
echo ""
|
|
58
|
+
echo -e "${GREEN}Creating project: $PROJECT_NAME${NC}"
|
|
59
|
+
echo -e "Domain: $DOMAIN_TOPIC"
|
|
60
|
+
echo -e "Pattern: $PATTERN"
|
|
61
|
+
echo ""
|
|
62
|
+
|
|
63
|
+
# Create directory structure
|
|
64
|
+
mkdir -p "$PROJECT_NAME"/{src/{kb,domain,api/routes,components,pages,intelligence},visualization,scripts}
|
|
65
|
+
|
|
66
|
+
# Create KB_ENFORCEMENT.md
|
|
67
|
+
cat > "$PROJECT_NAME/KB_ENFORCEMENT.md" << 'EOF'
|
|
68
|
+
# KB ENFORCEMENT RULES
|
|
69
|
+
|
|
70
|
+
This document defines the rules for KB-First development.
|
|
71
|
+
ALL code must comply with these rules.
|
|
72
|
+
|
|
73
|
+
## Rule 1: No Hardcoded Domain Logic
|
|
74
|
+
Every domain value comes from the KB.
|
|
75
|
+
|
|
76
|
+
❌ WRONG:
|
|
77
|
+
```typescript
|
|
78
|
+
const withdrawalRate = 0.04;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
✅ CORRECT:
|
|
82
|
+
```typescript
|
|
83
|
+
const rateResult = await kb.search("withdrawal rate");
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Rule 2: Every Domain Function Queries KB
|
|
87
|
+
Every file in src/domain/ MUST import from ../kb
|
|
88
|
+
|
|
89
|
+
## Rule 3: All Responses Include kbSources
|
|
90
|
+
Traceability is mandatory.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
return {
|
|
94
|
+
data: result,
|
|
95
|
+
kbSources: sources
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Rule 4: Startup Verification Required
|
|
100
|
+
App exits if KB unavailable.
|
|
101
|
+
|
|
102
|
+
## Rule 5: No Fallback Logic
|
|
103
|
+
KB is the source of truth.
|
|
104
|
+
|
|
105
|
+
❌ WRONG:
|
|
106
|
+
```typescript
|
|
107
|
+
const rules = kb.get() || DEFAULT_RULES;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
✅ CORRECT:
|
|
111
|
+
```typescript
|
|
112
|
+
const rules = kb.get();
|
|
113
|
+
if (!rules) throw new Error("KB unavailable");
|
|
114
|
+
```
|
|
115
|
+
EOF
|
|
116
|
+
|
|
117
|
+
# Create package.json
|
|
118
|
+
cat > "$PROJECT_NAME/package.json" << EOF
|
|
119
|
+
{
|
|
120
|
+
"name": "$PROJECT_NAME",
|
|
121
|
+
"version": "1.0.0",
|
|
122
|
+
"description": "KB-First application for $DOMAIN_TOPIC",
|
|
123
|
+
"main": "dist/index.js",
|
|
124
|
+
"scripts": {
|
|
125
|
+
"build": "tsc",
|
|
126
|
+
"start": "node dist/index.js",
|
|
127
|
+
"dev": "ts-node src/index.ts",
|
|
128
|
+
"verify": "./scripts/verify-enforcement.sh",
|
|
129
|
+
"test": "jest"
|
|
130
|
+
},
|
|
131
|
+
"keywords": ["kb-first", "$PATTERN"],
|
|
132
|
+
"dependencies": {
|
|
133
|
+
"pg": "^8.11.0"
|
|
134
|
+
},
|
|
135
|
+
"devDependencies": {
|
|
136
|
+
"@types/node": "^20.0.0",
|
|
137
|
+
"@types/pg": "^8.10.0",
|
|
138
|
+
"typescript": "^5.0.0",
|
|
139
|
+
"ts-node": "^10.9.0"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
EOF
|
|
143
|
+
|
|
144
|
+
# Create tsconfig.json
|
|
145
|
+
cat > "$PROJECT_NAME/tsconfig.json" << 'EOF'
|
|
146
|
+
{
|
|
147
|
+
"compilerOptions": {
|
|
148
|
+
"target": "ES2020",
|
|
149
|
+
"module": "commonjs",
|
|
150
|
+
"lib": ["ES2020"],
|
|
151
|
+
"outDir": "./dist",
|
|
152
|
+
"rootDir": "./src",
|
|
153
|
+
"strict": true,
|
|
154
|
+
"esModuleInterop": true,
|
|
155
|
+
"skipLibCheck": true,
|
|
156
|
+
"forceConsistentCasingInFileNames": true,
|
|
157
|
+
"resolveJsonModule": true,
|
|
158
|
+
"declaration": true
|
|
159
|
+
},
|
|
160
|
+
"include": ["src/**/*"],
|
|
161
|
+
"exclude": ["node_modules", "dist"]
|
|
162
|
+
}
|
|
163
|
+
EOF
|
|
164
|
+
|
|
165
|
+
# Create entry point
|
|
166
|
+
cat > "$PROJECT_NAME/src/index.ts" << 'EOF'
|
|
167
|
+
import { kb } from './kb';
|
|
168
|
+
|
|
169
|
+
async function main() {
|
|
170
|
+
console.log('Starting KB-First application...');
|
|
171
|
+
|
|
172
|
+
// RULE 4: Verify KB first
|
|
173
|
+
console.log('Verifying knowledge base connection...');
|
|
174
|
+
const health = await kb.verifyConnection();
|
|
175
|
+
|
|
176
|
+
if (!health.healthy) {
|
|
177
|
+
console.error('KB unavailable:', health.error);
|
|
178
|
+
console.error('Cannot start application without knowledge base.');
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log(`KB ready: ${health.nodeCount} nodes`);
|
|
183
|
+
|
|
184
|
+
// Initialize application
|
|
185
|
+
// TODO: Add your application initialization here
|
|
186
|
+
|
|
187
|
+
console.log('Application started successfully');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
main().catch((error) => {
|
|
191
|
+
console.error('Startup failed:', error);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
});
|
|
194
|
+
EOF
|
|
195
|
+
|
|
196
|
+
# Create KB types
|
|
197
|
+
cat > "$PROJECT_NAME/src/kb/types.ts" << 'EOF'
|
|
198
|
+
export interface KBNode {
|
|
199
|
+
id: string;
|
|
200
|
+
namespace: string;
|
|
201
|
+
path: string;
|
|
202
|
+
title: string;
|
|
203
|
+
content: string | null;
|
|
204
|
+
sourceExpert: string;
|
|
205
|
+
sourceUrl: string;
|
|
206
|
+
confidence: number;
|
|
207
|
+
metadata: Record<string, unknown>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export interface KBSource {
|
|
211
|
+
nodeId: string;
|
|
212
|
+
expert: string;
|
|
213
|
+
url: string;
|
|
214
|
+
confidence: number;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface KBResponse<T> {
|
|
218
|
+
data: T;
|
|
219
|
+
kbSources: KBSource[];
|
|
220
|
+
confidence: number;
|
|
221
|
+
gap: boolean;
|
|
222
|
+
gapReason?: string;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface KBHealth {
|
|
226
|
+
healthy: boolean;
|
|
227
|
+
nodeCount: number;
|
|
228
|
+
gapCount: number;
|
|
229
|
+
error?: string;
|
|
230
|
+
}
|
|
231
|
+
EOF
|
|
232
|
+
|
|
233
|
+
# Create KB index
|
|
234
|
+
cat > "$PROJECT_NAME/src/kb/index.ts" << 'EOF'
|
|
235
|
+
import { Pool } from 'pg';
|
|
236
|
+
import { KBNode, KBResponse, KBSource, KBHealth } from './types';
|
|
237
|
+
|
|
238
|
+
const pool = new Pool({
|
|
239
|
+
connectionString: process.env.DATABASE_URL
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
export async function verifyConnection(): Promise<KBHealth> {
|
|
243
|
+
try {
|
|
244
|
+
const result = await pool.query(`
|
|
245
|
+
SELECT
|
|
246
|
+
(SELECT COUNT(*) FROM kb_nodes) as node_count,
|
|
247
|
+
(SELECT COUNT(*) FROM kb_gaps) as gap_count
|
|
248
|
+
`);
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
healthy: true,
|
|
252
|
+
nodeCount: parseInt(result.rows[0].node_count),
|
|
253
|
+
gapCount: parseInt(result.rows[0].gap_count)
|
|
254
|
+
};
|
|
255
|
+
} catch (error) {
|
|
256
|
+
return {
|
|
257
|
+
healthy: false,
|
|
258
|
+
nodeCount: 0,
|
|
259
|
+
gapCount: 0,
|
|
260
|
+
error: error.message
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export async function search(
|
|
266
|
+
query: string,
|
|
267
|
+
namespace: string
|
|
268
|
+
): Promise<KBResponse<KBNode[]>> {
|
|
269
|
+
// TODO: Implement with your embedding solution
|
|
270
|
+
throw new Error('Implement search with your embedding provider');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export async function logGap(query: string, namespace: string): Promise<void> {
|
|
274
|
+
await pool.query(`
|
|
275
|
+
INSERT INTO kb_gaps (namespace, query, created_at)
|
|
276
|
+
VALUES ($1, $2, NOW())
|
|
277
|
+
`, [namespace, query]);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export const kb = {
|
|
281
|
+
verifyConnection,
|
|
282
|
+
search,
|
|
283
|
+
logGap
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
export * from './types';
|
|
287
|
+
EOF
|
|
288
|
+
|
|
289
|
+
# Create verification script
|
|
290
|
+
cat > "$PROJECT_NAME/scripts/verify-enforcement.sh" << 'SCRIPT'
|
|
291
|
+
#!/bin/bash
|
|
292
|
+
# KB-First Enforcement Verification
|
|
293
|
+
|
|
294
|
+
echo "=== KB-First Verification ==="
|
|
295
|
+
|
|
296
|
+
errors=0
|
|
297
|
+
|
|
298
|
+
# Rule 1: No hardcoded values
|
|
299
|
+
echo "Checking for hardcoded values..."
|
|
300
|
+
if grep -rqE "= 0\.[0-9]+" src/domain/ 2>/dev/null; then
|
|
301
|
+
echo " ❌ Found hardcoded decimals in domain/"
|
|
302
|
+
errors=$((errors + 1))
|
|
303
|
+
else
|
|
304
|
+
echo " ✅ No hardcoded decimals"
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
# Rule 2: All domain files import kb
|
|
308
|
+
echo "Checking KB imports..."
|
|
309
|
+
for file in src/domain/*.ts; do
|
|
310
|
+
if [ -f "$file" ] && ! grep -q "from.*kb" "$file"; then
|
|
311
|
+
echo " ❌ $file does not import from kb/"
|
|
312
|
+
errors=$((errors + 1))
|
|
313
|
+
fi
|
|
314
|
+
done
|
|
315
|
+
|
|
316
|
+
# Rule 4: Entry point verification
|
|
317
|
+
echo "Checking entry point..."
|
|
318
|
+
if grep -q "verifyConnection" src/index.ts; then
|
|
319
|
+
echo " ✅ Entry point verifies KB"
|
|
320
|
+
else
|
|
321
|
+
echo " ❌ Entry point missing KB verification"
|
|
322
|
+
errors=$((errors + 1))
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
echo ""
|
|
326
|
+
if [ $errors -eq 0 ]; then
|
|
327
|
+
echo "✅ All checks passed!"
|
|
328
|
+
else
|
|
329
|
+
echo "❌ $errors error(s) found"
|
|
330
|
+
exit 1
|
|
331
|
+
fi
|
|
332
|
+
SCRIPT
|
|
333
|
+
|
|
334
|
+
chmod +x "$PROJECT_NAME/scripts/verify-enforcement.sh"
|
|
335
|
+
|
|
336
|
+
# Create checkpoint file
|
|
337
|
+
cat > "$PROJECT_NAME/kb-checkpoint.json" << EOF
|
|
338
|
+
{
|
|
339
|
+
"project": "$PROJECT_NAME",
|
|
340
|
+
"domain": "$DOMAIN_TOPIC",
|
|
341
|
+
"pattern": "$PATTERN",
|
|
342
|
+
"currentPhase": 1,
|
|
343
|
+
"completedPhases": [],
|
|
344
|
+
"startedAt": "$(date -Iseconds)",
|
|
345
|
+
"kbStats": {
|
|
346
|
+
"experts": 0,
|
|
347
|
+
"nodes": 0,
|
|
348
|
+
"qualityScore": 0
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
EOF
|
|
352
|
+
|
|
353
|
+
# Create README
|
|
354
|
+
cat > "$PROJECT_NAME/README.md" << EOF
|
|
355
|
+
# $PROJECT_NAME
|
|
356
|
+
|
|
357
|
+
A KB-First application for **$DOMAIN_TOPIC**.
|
|
358
|
+
|
|
359
|
+
## Pattern: $PATTERN
|
|
360
|
+
|
|
361
|
+
## Quick Start
|
|
362
|
+
|
|
363
|
+
\`\`\`bash
|
|
364
|
+
# Install dependencies
|
|
365
|
+
npm install
|
|
366
|
+
|
|
367
|
+
# Set database URL
|
|
368
|
+
export DATABASE_URL="postgresql://..."
|
|
369
|
+
|
|
370
|
+
# Run verification
|
|
371
|
+
npm run verify
|
|
372
|
+
|
|
373
|
+
# Start development
|
|
374
|
+
npm run dev
|
|
375
|
+
\`\`\`
|
|
376
|
+
|
|
377
|
+
## KB Enforcement
|
|
378
|
+
|
|
379
|
+
This project follows KB-First rules. See \`KB_ENFORCEMENT.md\`.
|
|
380
|
+
|
|
381
|
+
## Phase Progress
|
|
382
|
+
|
|
383
|
+
Check \`kb-checkpoint.json\` for current build progress.
|
|
384
|
+
EOF
|
|
385
|
+
|
|
386
|
+
echo ""
|
|
387
|
+
echo -e "${GREEN}✅ Project created successfully!${NC}"
|
|
388
|
+
echo ""
|
|
389
|
+
echo "Next steps:"
|
|
390
|
+
echo " 1. cd $PROJECT_NAME"
|
|
391
|
+
echo " 2. npm install"
|
|
392
|
+
echo " 3. Set DATABASE_URL environment variable"
|
|
393
|
+
echo " 4. Follow the 8-phase build process in SKILL.md"
|
|
394
|
+
echo ""
|
|
395
|
+
echo -e "${BLUE}Current phase: 1 (Storage Setup)${NC}"
|