hool-cli 0.6.2 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/claude/be-dev.md +9 -1
- package/agents/claude/be-tech-lead.md +8 -0
- package/agents/claude/fe-dev.md +9 -1
- package/agents/claude/fe-tech-lead.md +8 -0
- package/agents/claude/forensic.md +8 -0
- package/agents/claude/governor.md +8 -0
- package/agents/claude/qa.md +8 -0
- package/dist/adapters/adapters.test.d.ts +1 -0
- package/dist/adapters/adapters.test.js +189 -0
- package/dist/adapters/adapters.test.js.map +1 -0
- package/dist/adapters/claude-code.js +22 -13
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/core/scaffold.d.ts +3 -0
- package/dist/core/scaffold.js +88 -10
- package/dist/core/scaffold.js.map +1 -1
- package/dist/core/scaffold.test.d.ts +1 -0
- package/dist/core/scaffold.test.js +329 -0
- package/dist/core/scaffold.test.js.map +1 -0
- package/dist/core/templates.js +2 -2
- package/dist/core/templates.js.map +1 -1
- package/dist/core/templates.test.d.ts +1 -0
- package/dist/core/templates.test.js +146 -0
- package/dist/core/templates.test.js.map +1 -0
- package/dist/e2e.test.d.ts +1 -0
- package/dist/e2e.test.js +161 -0
- package/dist/e2e.test.js.map +1 -0
- package/dist/index.js +5 -23
- package/dist/index.js.map +1 -1
- package/dist/mcps/mcps.test.d.ts +1 -0
- package/dist/mcps/mcps.test.js +110 -0
- package/dist/mcps/mcps.test.js.map +1 -0
- package/hooks/inject-pl-context.sh +22 -3
- package/hooks/suggest-compact.sh +8 -12
- package/hooks/track-prompt-count.sh +24 -22
- package/package.json +13 -3
- package/prompts/agents/05-fe-tech-lead.md +5 -2
- package/prompts/agents/06-be-tech-lead.md +5 -2
- package/prompts/agents/08-be-dev.md +4 -1
- package/prompts/agents/08-fe-dev.md +4 -1
- package/prompts/agents/10-qa.md +1 -0
- package/prompts/agents/11-forensic.md +1 -0
- package/prompts/agents/governor.md +3 -2
- package/prompts/orchestrator.md +130 -38
- package/prompts/skills/01-brainstorm.md +5 -0
- package/prompts/skills/02-spec.md +5 -0
- package/prompts/skills/03-design.md +5 -0
- package/prompts/skills/04-architecture.md +5 -0
- package/settings/be-dev.json +17 -0
- package/settings/be-tech-lead.json +17 -0
- package/settings/fe-dev.json +17 -0
- package/settings/fe-tech-lead.json +17 -0
- package/settings/forensic.json +17 -0
- package/settings/governor.json +17 -0
- package/settings/qa.json +17 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { MCP_REGISTRY, getRequiredMcps, getRequiredMcpNames } from './registry.js';
|
|
3
|
+
import { checkAndInstallMcps } from './installer.js';
|
|
4
|
+
describe('MCP_REGISTRY', () => {
|
|
5
|
+
it('contains context7, playwright, deepwiki', () => {
|
|
6
|
+
expect(MCP_REGISTRY).toHaveProperty('context7');
|
|
7
|
+
expect(MCP_REGISTRY).toHaveProperty('playwright');
|
|
8
|
+
expect(MCP_REGISTRY).toHaveProperty('deepwiki');
|
|
9
|
+
});
|
|
10
|
+
it('each entry has name, installCommand, configEntry', () => {
|
|
11
|
+
for (const [key, mcp] of Object.entries(MCP_REGISTRY)) {
|
|
12
|
+
expect(mcp.name).toBe(key);
|
|
13
|
+
expect(mcp.installCommand).toBeTruthy();
|
|
14
|
+
expect(mcp.configEntry).toHaveProperty('command');
|
|
15
|
+
expect(mcp.configEntry).toHaveProperty('args');
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
describe('getRequiredMcps', () => {
|
|
20
|
+
it('returns context7 + deepwiki + playwright for web-app', () => {
|
|
21
|
+
const mcps = getRequiredMcps('web-app');
|
|
22
|
+
const names = mcps.map(m => m.name);
|
|
23
|
+
expect(names).toContain('context7');
|
|
24
|
+
expect(names).toContain('deepwiki');
|
|
25
|
+
expect(names).toContain('playwright');
|
|
26
|
+
});
|
|
27
|
+
it('returns context7 + deepwiki for cli-tool (no playwright)', () => {
|
|
28
|
+
const mcps = getRequiredMcps('cli-tool');
|
|
29
|
+
const names = mcps.map(m => m.name);
|
|
30
|
+
expect(names).toContain('context7');
|
|
31
|
+
expect(names).toContain('deepwiki');
|
|
32
|
+
expect(names).not.toContain('playwright');
|
|
33
|
+
});
|
|
34
|
+
it('returns context7 + deepwiki + playwright for browser-game', () => {
|
|
35
|
+
const mcps = getRequiredMcps('browser-game');
|
|
36
|
+
const names = mcps.map(m => m.name);
|
|
37
|
+
expect(names).toContain('playwright');
|
|
38
|
+
});
|
|
39
|
+
it('returns context7 + deepwiki for api-only', () => {
|
|
40
|
+
const mcps = getRequiredMcps('api-only');
|
|
41
|
+
const names = mcps.map(m => m.name);
|
|
42
|
+
expect(names).toEqual(['context7', 'deepwiki']);
|
|
43
|
+
});
|
|
44
|
+
it('returns McpDefinition objects with full config', () => {
|
|
45
|
+
const mcps = getRequiredMcps('web-app');
|
|
46
|
+
for (const mcp of mcps) {
|
|
47
|
+
expect(mcp).toHaveProperty('name');
|
|
48
|
+
expect(mcp).toHaveProperty('installCommand');
|
|
49
|
+
expect(mcp).toHaveProperty('configEntry');
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe('getRequiredMcpNames', () => {
|
|
54
|
+
it('returns string array of MCP names', () => {
|
|
55
|
+
const names = getRequiredMcpNames('web-app');
|
|
56
|
+
expect(names).toEqual(['context7', 'deepwiki', 'playwright']);
|
|
57
|
+
});
|
|
58
|
+
it('returns context7 + deepwiki for desktop', () => {
|
|
59
|
+
expect(getRequiredMcpNames('desktop')).toEqual(['context7', 'deepwiki']);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('checkAndInstallMcps', () => {
|
|
63
|
+
function createMockAdapter(installed = new Set()) {
|
|
64
|
+
return {
|
|
65
|
+
platform: 'claude-code',
|
|
66
|
+
injectInstructions: vi.fn(),
|
|
67
|
+
installMcp: vi.fn(),
|
|
68
|
+
isMcpInstalled: vi.fn(async (name) => installed.has(name)),
|
|
69
|
+
getCompletionMessage: vi.fn(() => ''),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const config = {
|
|
73
|
+
platform: 'claude-code',
|
|
74
|
+
projectType: 'cli-tool',
|
|
75
|
+
projectDir: '/tmp/test',
|
|
76
|
+
promptsDir: '/tmp/test/prompts',
|
|
77
|
+
mode: 'interactive',
|
|
78
|
+
};
|
|
79
|
+
it('returns already-installed for pre-installed MCPs', async () => {
|
|
80
|
+
const adapter = createMockAdapter(new Set(['context7', 'deepwiki']));
|
|
81
|
+
const results = await checkAndInstallMcps(adapter, config);
|
|
82
|
+
expect(results).toHaveLength(2);
|
|
83
|
+
expect(results.every(r => r.status === 'already-installed')).toBe(true);
|
|
84
|
+
expect(adapter.installMcp).not.toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
it('installs missing MCPs', async () => {
|
|
87
|
+
const adapter = createMockAdapter(new Set(['context7'])); // deepwiki missing
|
|
88
|
+
const results = await checkAndInstallMcps(adapter, config);
|
|
89
|
+
const deepwikiResult = results.find(r => r.name === 'deepwiki');
|
|
90
|
+
expect(deepwikiResult?.status).toBe('installed');
|
|
91
|
+
expect(adapter.installMcp).toHaveBeenCalledOnce();
|
|
92
|
+
});
|
|
93
|
+
it('handles install failure gracefully', async () => {
|
|
94
|
+
const adapter = createMockAdapter();
|
|
95
|
+
adapter.installMcp.mockRejectedValue(new Error('Network error'));
|
|
96
|
+
const results = await checkAndInstallMcps(adapter, config);
|
|
97
|
+
expect(results.every(r => r.status === 'failed')).toBe(true);
|
|
98
|
+
expect(results[0].error).toBe('Network error');
|
|
99
|
+
});
|
|
100
|
+
it('processes all required MCPs for project type', async () => {
|
|
101
|
+
const webConfig = { ...config, projectType: 'web-app' };
|
|
102
|
+
const adapter = createMockAdapter();
|
|
103
|
+
const results = await checkAndInstallMcps(adapter, webConfig);
|
|
104
|
+
const names = results.map(r => r.name);
|
|
105
|
+
expect(names).toContain('context7');
|
|
106
|
+
expect(names).toContain('deepwiki');
|
|
107
|
+
expect(names).toContain('playwright');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=mcps.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcps.test.js","sourceRoot":"","sources":["../../src/mcps/mcps.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,24 @@
|
|
|
4
4
|
# Outputs JSON with additionalContext to remind the PL of its identity and state
|
|
5
5
|
|
|
6
6
|
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo '.')"
|
|
7
|
+
METRICS_FILE="$PROJECT_ROOT/.hool/operations/metrics.md"
|
|
8
|
+
|
|
9
|
+
# Ensure metrics file exists with default counters
|
|
10
|
+
if [ ! -f "$METRICS_FILE" ]; then
|
|
11
|
+
mkdir -p "$(dirname "$METRICS_FILE")"
|
|
12
|
+
cat > "$METRICS_FILE" <<'EOF'
|
|
13
|
+
# HOOL Metrics
|
|
14
|
+
- Agent dispatches: 0
|
|
15
|
+
- Tool calls: 0
|
|
16
|
+
- User prompts: 0
|
|
17
|
+
EOF
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Increment user prompts counter
|
|
21
|
+
CURRENT_PROMPTS=$(grep -o 'User prompts: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*')
|
|
22
|
+
CURRENT_PROMPTS=${CURRENT_PROMPTS:-0}
|
|
23
|
+
NEXT_PROMPTS=$((CURRENT_PROMPTS + 1))
|
|
24
|
+
sed -i '' "s/User prompts: ${CURRENT_PROMPTS}/User prompts: ${NEXT_PROMPTS}/" "$METRICS_FILE"
|
|
7
25
|
|
|
8
26
|
# Read current phase
|
|
9
27
|
PHASE="unknown"
|
|
@@ -80,10 +98,11 @@ if [ -f "$PROJECT_ROOT/.hool/operations/inconsistencies.md" ]; then
|
|
|
80
98
|
INCONSISTENCIES=$(grep -c '^- ' "$PROJECT_ROOT/.hool/operations/inconsistencies.md" 2>/dev/null | tr -d '\n' || echo "0")
|
|
81
99
|
fi
|
|
82
100
|
|
|
83
|
-
# Check governor dispatch count
|
|
101
|
+
# Check governor dispatch count from metrics.md
|
|
84
102
|
DISPATCH_COUNT=0
|
|
85
|
-
if [ -f "$
|
|
86
|
-
DISPATCH_COUNT=$(
|
|
103
|
+
if [ -f "$METRICS_FILE" ]; then
|
|
104
|
+
DISPATCH_COUNT=$(grep -o 'Agent dispatches: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*' || echo "0")
|
|
105
|
+
DISPATCH_COUNT=${DISPATCH_COUNT:-0}
|
|
87
106
|
fi
|
|
88
107
|
GOVERNOR_DUE=""
|
|
89
108
|
if [ "$DISPATCH_COUNT" -gt 0 ] && [ $(( DISPATCH_COUNT % 3 )) -ge 2 ]; then
|
package/hooks/suggest-compact.sh
CHANGED
|
@@ -5,27 +5,23 @@
|
|
|
5
5
|
# Strategic compaction between phases preserves better context.
|
|
6
6
|
|
|
7
7
|
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo '.')"
|
|
8
|
-
|
|
9
|
-
mkdir -p "$METRICS_DIR"
|
|
10
|
-
|
|
11
|
-
COUNTER_FILE="$METRICS_DIR/tool-call-count.txt"
|
|
8
|
+
METRICS_FILE="$PROJECT_ROOT/.hool/operations/metrics.md"
|
|
12
9
|
THRESHOLD="${HOOL_COMPACT_THRESHOLD:-50}"
|
|
13
10
|
|
|
14
|
-
# Read
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
echo "$NEXT" > "$COUNTER_FILE"
|
|
11
|
+
# Read tool call count from metrics.md (format: "- Tool calls: N")
|
|
12
|
+
COUNT=$(grep -o 'Tool calls: [0-9]*' "$METRICS_FILE" 2>/dev/null | grep -o '[0-9]*')
|
|
13
|
+
COUNT="${COUNT:-0}"
|
|
18
14
|
|
|
19
15
|
# Suggest at threshold
|
|
20
|
-
if [ "$
|
|
16
|
+
if [ "$COUNT" -eq "$THRESHOLD" ]; then
|
|
21
17
|
echo "HOOL: ${THRESHOLD} tool calls reached. Consider running /compact if you're between phases or tasks." >&2
|
|
22
18
|
fi
|
|
23
19
|
|
|
24
20
|
# Suggest every 25 calls after threshold
|
|
25
|
-
if [ "$
|
|
26
|
-
OVER=$((
|
|
21
|
+
if [ "$COUNT" -gt "$THRESHOLD" ]; then
|
|
22
|
+
OVER=$((COUNT - THRESHOLD))
|
|
27
23
|
if [ $((OVER % 25)) -eq 0 ]; then
|
|
28
|
-
echo "HOOL: ${
|
|
24
|
+
echo "HOOL: ${COUNT} tool calls. Good checkpoint for /compact if context feels stale." >&2
|
|
29
25
|
fi
|
|
30
26
|
fi
|
|
31
27
|
|
|
@@ -1,39 +1,41 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Hook: Track
|
|
2
|
+
# Hook: Track tool calls + agent dispatches in metrics.md, trigger governor every 3 dispatches
|
|
3
3
|
# Type: PostToolUse
|
|
4
4
|
# Outputs JSON with additionalContext when governor should run
|
|
5
5
|
|
|
6
6
|
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo '.')"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
METRICS_FILE="$PROJECT_ROOT/.hool/operations/metrics.md"
|
|
8
|
+
|
|
9
|
+
# Ensure metrics file exists with default counters
|
|
10
|
+
if [ ! -f "$METRICS_FILE" ]; then
|
|
11
|
+
mkdir -p "$(dirname "$METRICS_FILE")"
|
|
12
|
+
cat > "$METRICS_FILE" <<'EOF'
|
|
13
|
+
# HOOL Metrics
|
|
14
|
+
- Agent dispatches: 0
|
|
15
|
+
- Tool calls: 0
|
|
16
|
+
- User prompts: 0
|
|
17
|
+
EOF
|
|
17
18
|
fi
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
# Increment tool calls counter
|
|
21
|
+
CURRENT_TOOLS=$(grep -o 'Tool calls: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*')
|
|
22
|
+
CURRENT_TOOLS=${CURRENT_TOOLS:-0}
|
|
23
|
+
NEXT_TOOLS=$((CURRENT_TOOLS + 1))
|
|
24
|
+
sed -i '' "s/Tool calls: ${CURRENT_TOOLS}/Tool calls: ${NEXT_TOOLS}/" "$METRICS_FILE"
|
|
23
25
|
|
|
24
|
-
#
|
|
25
|
-
# Read from stdin to check tool name
|
|
26
|
+
# Read stdin to check tool name
|
|
26
27
|
INPUT=$(cat)
|
|
27
28
|
TOOL_NAME=$(echo "$INPUT" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"tool_name"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
|
|
28
29
|
|
|
29
30
|
if [ "$TOOL_NAME" = "Agent" ]; then
|
|
30
|
-
# Increment
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
# Increment agent dispatches counter
|
|
32
|
+
CURRENT_DISPATCHES=$(grep -o 'Agent dispatches: [0-9]*' "$METRICS_FILE" | grep -o '[0-9]*')
|
|
33
|
+
CURRENT_DISPATCHES=${CURRENT_DISPATCHES:-0}
|
|
34
|
+
NEXT_DISPATCHES=$((CURRENT_DISPATCHES + 1))
|
|
35
|
+
sed -i '' "s/Agent dispatches: ${CURRENT_DISPATCHES}/Agent dispatches: ${NEXT_DISPATCHES}/" "$METRICS_FILE"
|
|
34
36
|
|
|
35
37
|
# Check if divisible by 3
|
|
36
|
-
if [ $((
|
|
38
|
+
if [ $((NEXT_DISPATCHES % 3)) -eq 0 ]; then
|
|
37
39
|
# Output JSON to inject governor reminder into conversation
|
|
38
40
|
cat <<'JSONEOF'
|
|
39
41
|
{
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hool-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Agent-Driven SDLC — scaffold and configure HOOL for any project",
|
|
5
5
|
"bin": {
|
|
6
6
|
"hool": "./dist/index.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsc",
|
|
10
|
+
"test": "vitest run",
|
|
11
|
+
"test:watch": "vitest",
|
|
10
12
|
"dev": "tsx src/index.ts",
|
|
11
13
|
"prepublishOnly": "npm run build && rm -rf ./prompts ./agents ./rules ./hooks ./settings && cp -R ../hool-mini/prompts ./prompts && cp -R ../hool-mini/agents ./agents && cp -R ../hool-mini/rules ./rules && cp -R ../hool-mini/hooks ./hooks && cp -R ../hool-mini/settings ./settings"
|
|
12
14
|
},
|
|
@@ -27,7 +29,8 @@
|
|
|
27
29
|
"devDependencies": {
|
|
28
30
|
"@types/node": "^20.11.0",
|
|
29
31
|
"tsx": "^4.7.0",
|
|
30
|
-
"typescript": "^5.4.0"
|
|
32
|
+
"typescript": "^5.4.0",
|
|
33
|
+
"vitest": "^4.0.18"
|
|
31
34
|
},
|
|
32
35
|
"type": "module",
|
|
33
36
|
"license": "MIT",
|
|
@@ -35,7 +38,14 @@
|
|
|
35
38
|
"type": "git",
|
|
36
39
|
"url": "git+https://github.com/the-wise-agents/hool.git"
|
|
37
40
|
},
|
|
38
|
-
"keywords": [
|
|
41
|
+
"keywords": [
|
|
42
|
+
"agent",
|
|
43
|
+
"sdlc",
|
|
44
|
+
"ai",
|
|
45
|
+
"cli",
|
|
46
|
+
"scaffold",
|
|
47
|
+
"autonomous"
|
|
48
|
+
],
|
|
39
49
|
"engines": {
|
|
40
50
|
"node": ">=18"
|
|
41
51
|
}
|
|
@@ -136,13 +136,13 @@ How logging works. Where logs go. How to read them.
|
|
|
136
136
|
- .hool/phases/05-fe-scaffold/fe-lld.md — LLD compliance check
|
|
137
137
|
- .hool/phases/07-test-plan/test-plan.md — test coverage check
|
|
138
138
|
- .hool/memory/fe-dev/hot.md — what FE Dev has been doing
|
|
139
|
-
- .hool/
|
|
139
|
+
- .hool/checklists/code-review.md — baseline review checklist (security, performance, a11y, API design)
|
|
140
140
|
- .hool/memory/fe-tech-lead/best-practices.md — project-specific patterns (organic checklist items)
|
|
141
141
|
### Writes
|
|
142
142
|
- .hool/operations/inconsistencies.md — INC-XXX entries for any issues found
|
|
143
143
|
### Process
|
|
144
144
|
1. Read the code FE Dev produced for the task
|
|
145
|
-
2. Load and run the baseline checklist from `.hool/
|
|
145
|
+
2. Load and run the baseline checklist from `.hool/checklists/code-review.md` (skip BE-only items)
|
|
146
146
|
3. Also check project-specific patterns from your `best-practices.md`
|
|
147
147
|
4. Run the 6-point review checklist:
|
|
148
148
|
- **Contract compliance** — API calls match .hool/phases/04-architecture/contracts/ (endpoints, methods, request/response shapes, status codes handled)
|
|
@@ -156,6 +156,9 @@ How logging works. Where logs go. How to read them.
|
|
|
156
156
|
- Code inconsistency found -> write to .hool/operations/inconsistencies.md with INC-XXX format
|
|
157
157
|
- Doc inconsistency found (spec says X, contract says Y) -> escalate to Product Lead via .hool/operations/inconsistencies.md
|
|
158
158
|
|
|
159
|
+
## Forbidden Actions
|
|
160
|
+
- NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
|
|
161
|
+
|
|
159
162
|
## Work Log
|
|
160
163
|
### Tags
|
|
161
164
|
- [ARCH-FE] — FE architectural decision -> best-practices.md
|
|
@@ -157,13 +157,13 @@ Order matters. List in execution order:
|
|
|
157
157
|
- .hool/phases/02-spec/spec.md (and features/ if split) — acceptance criteria check
|
|
158
158
|
- .hool/phases/07-test-plan/test-plan.md — test coverage check
|
|
159
159
|
- .hool/memory/be-dev/hot.md — what BE Dev has been doing
|
|
160
|
-
- .hool/
|
|
160
|
+
- .hool/checklists/code-review.md — baseline review checklist (security, performance, a11y, API design)
|
|
161
161
|
- .hool/memory/be-tech-lead/best-practices.md — project-specific patterns (organic checklist items)
|
|
162
162
|
### Writes
|
|
163
163
|
- .hool/operations/inconsistencies.md — INC-XXX entries for any issues found
|
|
164
164
|
### Process
|
|
165
165
|
1. Read the code BE Dev produced for the task
|
|
166
|
-
2. Load and run the baseline checklist from `.hool/
|
|
166
|
+
2. Load and run the baseline checklist from `.hool/checklists/code-review.md` (skip FE-only items)
|
|
167
167
|
3. Also check project-specific patterns from your `best-practices.md`
|
|
168
168
|
4. Run the 6-point review checklist:
|
|
169
169
|
- **Contract compliance** — response shapes, status codes, error codes match .hool/phases/04-architecture/contracts/ exactly
|
|
@@ -177,6 +177,9 @@ Order matters. List in execution order:
|
|
|
177
177
|
- Code inconsistency found -> write to .hool/operations/inconsistencies.md with INC-XXX format
|
|
178
178
|
- Doc inconsistency found (spec says X, contract says Y) -> escalate to Product Lead via .hool/operations/inconsistencies.md
|
|
179
179
|
|
|
180
|
+
## Forbidden Actions
|
|
181
|
+
- NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
|
|
182
|
+
|
|
180
183
|
## Work Log
|
|
181
184
|
### Tags
|
|
182
185
|
- [ARCH-BE] — BE architectural decision -> best-practices.md
|
|
@@ -58,7 +58,7 @@ If you believe your own process or rules should change based on experience, esca
|
|
|
58
58
|
5. **Logs**: Every request, DB query, and error gets a log statement.
|
|
59
59
|
6. **Contracts**: Your API responses MUST match .hool/phases/04-architecture/contracts/ exactly. Field names, types, status codes — zero deviation.
|
|
60
60
|
7. **Schema**: Your queries MUST work with .hool/phases/04-architecture/schema.md. Never modify schema without logging an inconsistency.
|
|
61
|
-
8. **
|
|
61
|
+
8. **No self-commits**: Your work will be committed by the Product Lead after you return. Focus on the implementation, not version control.
|
|
62
62
|
9. **Consistency gate**: Before implementing, cross-check your task against contracts, schema, and spec. If you find ANY inconsistency between docs, DO NOT proceed — log to .hool/operations/inconsistencies.md.
|
|
63
63
|
|
|
64
64
|
## Test Execution Requirement (MANDATORY)
|
|
@@ -133,6 +133,9 @@ logger.info('query result:', result) // log the shape, not the data (PII risk
|
|
|
133
133
|
- Need a schema change -> DON'T make it. Log to .hool/operations/inconsistencies.md for BE Tech Lead to review
|
|
134
134
|
- Architecture seems wrong -> DON'T change it. Log to .hool/operations/inconsistencies.md for BE Tech Lead to review
|
|
135
135
|
|
|
136
|
+
## Forbidden Actions
|
|
137
|
+
- NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
|
|
138
|
+
|
|
136
139
|
## Work Log
|
|
137
140
|
### Tags
|
|
138
141
|
- [BE-IMPL] — endpoint/service implemented
|
|
@@ -56,7 +56,7 @@ If you believe your own process or rules should change based on experience, esca
|
|
|
56
56
|
5. **Logs**: Every significant user action and API call gets a log statement.
|
|
57
57
|
6. **Design fidelity**: Your UI MUST match .hool/phases/03-design/cards/. Compare visually.
|
|
58
58
|
7. **Contracts**: Your API calls MUST use the shapes from .hool/phases/04-architecture/contracts/ exactly.
|
|
59
|
-
8. **
|
|
59
|
+
8. **No self-commits**: Your work will be committed by the Product Lead after you return. Focus on the implementation, not version control.
|
|
60
60
|
9. **Consistency gate**: Before implementing, cross-check your task against contracts, design cards, and spec. If you find ANY inconsistency between docs, DO NOT proceed — log to .hool/operations/inconsistencies.md.
|
|
61
61
|
|
|
62
62
|
## Test Execution Requirement (MANDATORY)
|
|
@@ -122,6 +122,9 @@ logger.info('useEffect fired') // use React DevTools
|
|
|
122
122
|
- Design seems wrong -> DON'T change design. Log to .hool/operations/inconsistencies.md for FE Tech Lead to review
|
|
123
123
|
- Need a BE endpoint that doesn't exist -> DON'T build it. Log to .hool/operations/inconsistencies.md for FE Tech Lead to review
|
|
124
124
|
|
|
125
|
+
## Forbidden Actions
|
|
126
|
+
- NEVER run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
|
|
127
|
+
|
|
125
128
|
## Work Log
|
|
126
129
|
### Tags
|
|
127
130
|
- [FE-IMPL] — component/page implemented
|
package/prompts/agents/10-qa.md
CHANGED
|
@@ -264,6 +264,7 @@ Log the score in your work log: `[QA-SCORE] [total]/100 — [verdict]`
|
|
|
264
264
|
- Don't review code quality. That's the Tech Lead's job.
|
|
265
265
|
- Don't suggest architectural changes.
|
|
266
266
|
- Don't modify source code.
|
|
267
|
+
- Don't run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return.
|
|
267
268
|
|
|
268
269
|
## MCP Tools Available
|
|
269
270
|
- playwright: E2E testing, screenshot capture, browser automation
|
|
@@ -108,6 +108,7 @@ Don't fabricate a root cause. Honesty saves time.
|
|
|
108
108
|
- Don't apply fixes — document them for devs.
|
|
109
109
|
- Don't refactor surrounding code.
|
|
110
110
|
- Don't make architectural recommendations.
|
|
111
|
+
- Don't run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return.
|
|
111
112
|
|
|
112
113
|
## MCP Tools Available
|
|
113
114
|
- playwright: reproduce UI bugs in browser
|
|
@@ -28,10 +28,11 @@ Agents self-enforce rules, but self-enforcement fails (as observed: Product Lead
|
|
|
28
28
|
- `.hool/operations/needs-human-review.md` — escalate structural/prompt changes
|
|
29
29
|
|
|
30
30
|
### Forbidden Actions
|
|
31
|
-
- **NEVER** modify agent prompts (`.
|
|
31
|
+
- **NEVER** modify agent prompts (`.claude/agents/`) — escalate to `.hool/operations/needs-human-review.md`
|
|
32
32
|
- **NEVER** remove or modify existing entries in `.hool/operations/governor-rules.md` — append only (unless a rule is provably wrong, in which case escalate to human)
|
|
33
33
|
- **NEVER** edit application code (`src/`, `tests/`)
|
|
34
34
|
- **NEVER** modify `.hool/operations/task-board.md` or `.hool/operations/current-phase.md` — that's the Product Lead's job
|
|
35
|
+
- **NEVER** run git commands (add, commit, push, etc.) — the Product Lead commits your work after you return
|
|
35
36
|
|
|
36
37
|
## Audit Process
|
|
37
38
|
|
|
@@ -69,7 +70,7 @@ On each invocation:
|
|
|
69
70
|
When writing to `.hool/memory/<agent>/governor-feedback.md`:
|
|
70
71
|
|
|
71
72
|
```markdown
|
|
72
|
-
- [GOV-FEEDBACK] 2026-03-08: You edited .
|
|
73
|
+
- [GOV-FEEDBACK] 2026-03-08: You edited .claude/agents/ directly → You must NEVER modify your own prompts. Escalate to .hool/operations/needs-human-review.md instead.
|
|
73
74
|
- [GOV-FEEDBACK] 2026-03-08: You did not check client-preferences.md before making tech stack decisions → Always load .hool/operations/client-preferences.md and honour user preferences.
|
|
74
75
|
```
|
|
75
76
|
|