specweave 1.0.550 → 1.0.552
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/CLAUDE.md +1 -1
- package/bin/specweave.js +23 -1
- package/dist/src/cli/commands/hook.d.ts +15 -0
- package/dist/src/cli/commands/hook.d.ts.map +1 -0
- package/dist/src/cli/commands/hook.js +61 -0
- package/dist/src/cli/commands/hook.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +5 -0
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
- package/dist/src/cli/commands/refresh-plugins.js +11 -1
- package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
- package/dist/src/cli/commands/sync-setup.d.ts.map +1 -1
- package/dist/src/cli/commands/sync-setup.js +7 -3
- package/dist/src/cli/commands/sync-setup.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts +9 -0
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js +9 -3
- package/dist/src/cli/helpers/issue-tracker/project-mapping-wizard.js.map +1 -1
- package/dist/src/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts +18 -2
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/hooks/handlers/hook-router.d.ts +19 -0
- package/dist/src/core/hooks/handlers/hook-router.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/hook-router.js +75 -0
- package/dist/src/core/hooks/handlers/hook-router.js.map +1 -0
- package/dist/src/core/hooks/handlers/index.d.ts +10 -0
- package/dist/src/core/hooks/handlers/index.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/index.js +9 -0
- package/dist/src/core/hooks/handlers/index.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js +73 -0
- package/dist/src/core/hooks/handlers/post-tool-use-analytics.js.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/post-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js +76 -0
- package/dist/src/core/hooks/handlers/post-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-compact.js +77 -0
- package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +11 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js +318 -0
- package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts +9 -0
- package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/session-start.js +111 -0
- package/dist/src/core/hooks/handlers/session-start.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts +16 -0
- package/dist/src/core/hooks/handlers/stop-auto.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-auto.js +122 -0
- package/dist/src/core/hooks/handlers/stop-auto.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts +14 -0
- package/dist/src/core/hooks/handlers/stop-reflect.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js +43 -0
- package/dist/src/core/hooks/handlers/stop-reflect.js.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts +15 -0
- package/dist/src/core/hooks/handlers/stop-sync.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/stop-sync.js +68 -0
- package/dist/src/core/hooks/handlers/stop-sync.js.map +1 -0
- package/dist/src/core/hooks/handlers/types.d.ts +63 -0
- package/dist/src/core/hooks/handlers/types.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/types.js +27 -0
- package/dist/src/core/hooks/handlers/types.js.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts +14 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js +173 -0
- package/dist/src/core/hooks/handlers/user-prompt-submit.js.map +1 -0
- package/dist/src/core/hooks/handlers/utils.d.ts +25 -0
- package/dist/src/core/hooks/handlers/utils.d.ts.map +1 -0
- package/dist/src/core/hooks/handlers/utils.js +64 -0
- package/dist/src/core/hooks/handlers/utils.js.map +1 -0
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +32 -0
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/init/research/types.d.ts +1 -1
- package/dist/src/sync/sync-target-resolver.js.map +1 -1
- package/dist/src/utils/lock-manager.d.ts.map +1 -1
- package/dist/src/utils/lock-manager.js +5 -0
- package/dist/src/utils/lock-manager.js.map +1 -1
- package/dist/src/utils/plugin-copier.d.ts +10 -0
- package/dist/src/utils/plugin-copier.d.ts.map +1 -1
- package/dist/src/utils/plugin-copier.js +63 -35
- package/dist/src/utils/plugin-copier.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/sw-closer.md +3 -2
- package/plugins/specweave/hooks/hooks.json +10 -10
- package/plugins/specweave/skills/code-reviewer/SKILL.md +180 -16
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-comments.md +83 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-silent-failures.md +19 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-spec-compliance.md +19 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-tests.md +101 -0
- package/plugins/specweave/skills/code-reviewer/agents/reviewer-types.md +20 -0
- package/plugins/specweave/skills/done/SKILL.md +56 -21
- package/plugins/specweave/skills/grill/SKILL.md +1 -1
- package/plugins/specweave/skills/team-lead/agents/reviewer-logic.md +19 -0
- package/plugins/specweave/skills/team-lead/agents/reviewer-performance.md +20 -0
- package/plugins/specweave/skills/team-lead/agents/reviewer-security.md +20 -0
- package/src/templates/CLAUDE.md.template +7 -4
- package/plugins/specweave/hooks/README.md +0 -493
- package/plugins/specweave/hooks/_archive/stop-auto-v4-legacy.sh +0 -1319
- package/plugins/specweave/hooks/lib/common-setup.sh +0 -144
- package/plugins/specweave/hooks/lib/hook-errors.sh +0 -414
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh +0 -245
- package/plugins/specweave/hooks/lib/resolve-package.sh +0 -146
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +0 -135
- package/plugins/specweave/hooks/lib/score-increment.sh +0 -87
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +0 -193
- package/plugins/specweave/hooks/lib/update-active-increment.sh +0 -95
- package/plugins/specweave/hooks/lib/update-status-line.sh +0 -233
- package/plugins/specweave/hooks/lib/validate-spec-status.sh +0 -171
- package/plugins/specweave/hooks/llm-judge-validator.sh +0 -219
- package/plugins/specweave/hooks/log-decision.sh +0 -168
- package/plugins/specweave/hooks/pre-compact.sh +0 -64
- package/plugins/specweave/hooks/startup-health-check.sh +0 -64
- package/plugins/specweave/hooks/stop-auto-v5.sh +0 -276
- package/plugins/specweave/hooks/stop-reflect.sh +0 -336
- package/plugins/specweave/hooks/stop-sync.sh +0 -283
- package/plugins/specweave/hooks/tests/test-auto-context-integration.sh +0 -126
- package/plugins/specweave/hooks/tests/test-stop-auto-enriched.sh +0 -128
- package/plugins/specweave/hooks/universal/dispatcher.mjs +0 -336
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +0 -325
- package/plugins/specweave/hooks/universal/hook-wrapper.cmd +0 -26
- package/plugins/specweave/hooks/universal/hook-wrapper.sh +0 -69
- package/plugins/specweave/hooks/universal/run-hook.sh +0 -20
- package/plugins/specweave/hooks/universal/session-start.cmd +0 -16
- package/plugins/specweave/hooks/universal/session-start.ps1 +0 -16
- package/plugins/specweave/hooks/user-prompt-submit.sh +0 -2550
- package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +0 -87
- package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +0 -186
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +0 -83
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +0 -447
- package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +0 -104
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +0 -270
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-duplicate-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +0 -240
- package/plugins/specweave/hooks/v2/guards/interview-enforcement-guard.sh +0 -171
- package/plugins/specweave/hooks/v2/guards/metadata-json-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/skill-chain-enforcement-guard.sh +0 -222
- package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +0 -21
- package/plugins/specweave/hooks/v2/guards/spec-validation-guard.sh +0 -14
- package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +0 -84
- package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +0 -475
- package/plugins/specweave/hooks/v2/guards/tdd-enforcement-guard.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +0 -332
- package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +0 -50
- package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +0 -347
- package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +0 -83
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +0 -268
- package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +0 -104
- package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +0 -165
- package/plugins/specweave/hooks/v2/handlers/status-update.sh +0 -61
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +0 -270
- package/plugins/specweave/hooks/v2/integrations/ado-post-living-docs-update.sh +0 -367
- package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +0 -179
- package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +0 -553
- package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +0 -345
- package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +0 -180
- package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +0 -52
- package/plugins/specweave/hooks/v2/queue/enqueue.sh +0 -81
- package/plugins/specweave/hooks/v2/session-end.sh +0 -139
- package/plugins/specweave/hooks/validate-skill-activations.sh +0 -227
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# interview-enforcement-guard.sh - Enforces Deep Interview completion before spec creation
|
|
3
|
-
#
|
|
4
|
-
# PURPOSE:
|
|
5
|
-
# When Deep Interview Mode is enabled with "enforcement": "strict", this guard
|
|
6
|
-
# BLOCKS spec.md completion until all interview categories have been covered.
|
|
7
|
-
#
|
|
8
|
-
# WORKFLOW ENFORCED:
|
|
9
|
-
# 1. User starts /sw:increment
|
|
10
|
-
# 2. Interview state file created: .specweave/state/interview-{increment-id}.json
|
|
11
|
-
# 3. PM skill marks categories as covered during interview
|
|
12
|
-
# 4. Spec.md writing BLOCKED until all categories are marked complete
|
|
13
|
-
#
|
|
14
|
-
# DETECTION LOGIC:
|
|
15
|
-
# - CHECK: deepInterview.enabled && deepInterview.enforcement == "strict"
|
|
16
|
-
# - CHECK: Interview state file exists and has all categories covered
|
|
17
|
-
# - BLOCK: If categories are missing, show which ones
|
|
18
|
-
# - ALLOW: All categories covered OR enforcement != "strict"
|
|
19
|
-
#
|
|
20
|
-
# @since 1.0.198
|
|
21
|
-
|
|
22
|
-
set -e
|
|
23
|
-
|
|
24
|
-
# Read hook input
|
|
25
|
-
INPUT=$(cat)
|
|
26
|
-
|
|
27
|
-
# Extract file path and tool from input
|
|
28
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // ""')
|
|
29
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .toolInput.file_path // ""')
|
|
30
|
-
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .toolInput.content // ""')
|
|
31
|
-
|
|
32
|
-
# Only check Write operations to spec.md in increment folders
|
|
33
|
-
if [[ "$TOOL_NAME" != "Write" ]]; then
|
|
34
|
-
echo '{"decision":"allow"}'
|
|
35
|
-
exit 0
|
|
36
|
-
fi
|
|
37
|
-
|
|
38
|
-
# Check if this is a spec.md in an increment folder
|
|
39
|
-
if [[ ! "$FILE_PATH" =~ \.specweave/increments/[0-9]{4}-[^/]+/spec\.md$ ]]; then
|
|
40
|
-
echo '{"decision":"allow"}'
|
|
41
|
-
exit 0
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
# Extract increment ID from path
|
|
45
|
-
INCREMENT_ID=$(echo "$FILE_PATH" | grep -oE '[0-9]{4}-[^/]+' | head -1)
|
|
46
|
-
|
|
47
|
-
# Find project root (where .specweave/ is)
|
|
48
|
-
PROJECT_ROOT=$(echo "$FILE_PATH" | sed 's|/.specweave/.*|/|')
|
|
49
|
-
CONFIG_PATH="${PROJECT_ROOT}.specweave/config.json"
|
|
50
|
-
|
|
51
|
-
# Check if Deep Interview Mode is enabled with strict enforcement
|
|
52
|
-
if [[ ! -f "$CONFIG_PATH" ]]; then
|
|
53
|
-
echo '{"decision":"allow"}'
|
|
54
|
-
exit 0
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
DEEP_INTERVIEW_ENABLED=$(jq -r '.planning.deepInterview.enabled // false' "$CONFIG_PATH" 2>/dev/null)
|
|
58
|
-
ENFORCEMENT=$(jq -r '.planning.deepInterview.enforcement // "advisory"' "$CONFIG_PATH" 2>/dev/null)
|
|
59
|
-
|
|
60
|
-
# If not enabled or not strict, allow
|
|
61
|
-
if [[ "$DEEP_INTERVIEW_ENABLED" != "true" ]] || [[ "$ENFORCEMENT" != "strict" ]]; then
|
|
62
|
-
echo '{"decision":"allow"}'
|
|
63
|
-
exit 0
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# Get required categories from config
|
|
67
|
-
REQUIRED_CATEGORIES=$(jq -r '.planning.deepInterview.categories // ["architecture","integrations","ui-ux","performance","security","edge-cases"] | .[]' "$CONFIG_PATH" 2>/dev/null)
|
|
68
|
-
|
|
69
|
-
# Check if this is a template being created (allow templates through)
|
|
70
|
-
TEMPLATE_MARKERS=(
|
|
71
|
-
"[Story Title]"
|
|
72
|
-
"[user type]"
|
|
73
|
-
"[goal]"
|
|
74
|
-
"[benefit]"
|
|
75
|
-
"TEMPLATE FILE"
|
|
76
|
-
"{{RESOLVED_PROJECT}}"
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
for marker in "${TEMPLATE_MARKERS[@]}"; do
|
|
80
|
-
if [[ "$CONTENT" == *"$marker"* ]]; then
|
|
81
|
-
# Template creation - allow
|
|
82
|
-
echo '{"decision":"allow"}'
|
|
83
|
-
exit 0
|
|
84
|
-
fi
|
|
85
|
-
done
|
|
86
|
-
|
|
87
|
-
# Check interview state file
|
|
88
|
-
STATE_DIR="${PROJECT_ROOT}.specweave/state"
|
|
89
|
-
INTERVIEW_STATE="${STATE_DIR}/interview-${INCREMENT_ID}.json"
|
|
90
|
-
|
|
91
|
-
if [[ ! -f "$INTERVIEW_STATE" ]]; then
|
|
92
|
-
# No interview state - BLOCK
|
|
93
|
-
REASON="⛔ **STRICT INTERVIEW ENFORCEMENT: Interview Required**
|
|
94
|
-
|
|
95
|
-
You're attempting to write to spec.md but **Deep Interview has not been conducted**.
|
|
96
|
-
|
|
97
|
-
**Strict Interview Mode is enabled** for this project.
|
|
98
|
-
|
|
99
|
-
Before creating spec.md, you MUST:
|
|
100
|
-
|
|
101
|
-
1. **Start the interview**:
|
|
102
|
-
\`\`\`
|
|
103
|
-
Mark interview started for increment ${INCREMENT_ID}
|
|
104
|
-
\`\`\`
|
|
105
|
-
|
|
106
|
-
2. **Cover all 6 categories** (ask thorough questions):
|
|
107
|
-
- [ ] Architecture - system design, components, data flow
|
|
108
|
-
- [ ] Integrations - external APIs, databases, auth providers
|
|
109
|
-
- [ ] UI/UX - user flows, error handling, accessibility
|
|
110
|
-
- [ ] Performance - load expectations, caching, response times
|
|
111
|
-
- [ ] Security - auth, authorization, data protection
|
|
112
|
-
- [ ] Edge Cases - failures, concurrency, rollback
|
|
113
|
-
|
|
114
|
-
3. **Mark each category as covered**:
|
|
115
|
-
\`\`\`
|
|
116
|
-
Mark architecture covered for ${INCREMENT_ID}: [summary of decisions]
|
|
117
|
-
\`\`\`
|
|
118
|
-
|
|
119
|
-
4. **Then complete the spec** - this guard will allow it.
|
|
120
|
-
|
|
121
|
-
**Why This Matters:**
|
|
122
|
-
Thorough requirements gathering prevents rework. Strict mode ensures all bases are covered before implementation begins.
|
|
123
|
-
|
|
124
|
-
**To disable strict mode** (not recommended):
|
|
125
|
-
Set \`planning.deepInterview.enforcement: \"advisory\"\` in config.json"
|
|
126
|
-
|
|
127
|
-
REASON_ESCAPED=$(echo "$REASON" | jq -Rs .)
|
|
128
|
-
echo "{\"decision\":\"block\",\"reason\":${REASON_ESCAPED}}"
|
|
129
|
-
exit 0
|
|
130
|
-
fi
|
|
131
|
-
|
|
132
|
-
# Interview state exists - check if all categories are covered
|
|
133
|
-
COVERED_CATEGORIES=$(jq -r '.coveredCategories // {} | keys[]' "$INTERVIEW_STATE" 2>/dev/null || echo "")
|
|
134
|
-
|
|
135
|
-
# Find missing categories
|
|
136
|
-
MISSING=""
|
|
137
|
-
for cat in $REQUIRED_CATEGORIES; do
|
|
138
|
-
if ! echo "$COVERED_CATEGORIES" | grep -qx "$cat"; then
|
|
139
|
-
MISSING="$MISSING\n - [ ] $cat"
|
|
140
|
-
fi
|
|
141
|
-
done
|
|
142
|
-
|
|
143
|
-
if [[ -n "$MISSING" ]]; then
|
|
144
|
-
# Some categories not covered - BLOCK
|
|
145
|
-
REASON="⛔ **STRICT INTERVIEW ENFORCEMENT: Incomplete Interview**
|
|
146
|
-
|
|
147
|
-
Interview started but **not all categories have been covered**.
|
|
148
|
-
|
|
149
|
-
**Missing Categories:**
|
|
150
|
-
$MISSING
|
|
151
|
-
|
|
152
|
-
**Covered Categories:**
|
|
153
|
-
$(jq -r '.coveredCategories // {} | to_entries[] | \" - [x] \\(.key): \\(.value.summary // \"covered\")\"' "$INTERVIEW_STATE" 2>/dev/null || echo " (none)")
|
|
154
|
-
|
|
155
|
-
**To Continue:**
|
|
156
|
-
Ask questions about the missing categories, then mark each as covered:
|
|
157
|
-
\`\`\`
|
|
158
|
-
Mark [category] covered for ${INCREMENT_ID}: [summary of what was decided]
|
|
159
|
-
\`\`\`
|
|
160
|
-
|
|
161
|
-
**Why This Matters:**
|
|
162
|
-
Strict Interview Mode ensures comprehensive requirements gathering. Skipping categories leads to rework and missed requirements."
|
|
163
|
-
|
|
164
|
-
REASON_ESCAPED=$(echo "$REASON" | jq -Rs .)
|
|
165
|
-
echo "{\"decision\":\"block\",\"reason\":${REASON_ESCAPED}}"
|
|
166
|
-
exit 0
|
|
167
|
-
fi
|
|
168
|
-
|
|
169
|
-
# All categories covered - ALLOW
|
|
170
|
-
echo '{"decision":"allow"}'
|
|
171
|
-
exit 0
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# metadata-json-guard.sh - DISABLED (v1.0.38)
|
|
3
|
-
#
|
|
4
|
-
# This guard was converted to WARNING-only in v1.0.37, and now completely
|
|
5
|
-
# disabled in v1.0.38 per user feedback: "you MUST NEVER block such operations"
|
|
6
|
-
#
|
|
7
|
-
# Metadata validation should be handled by agents/scripts with proper business logic,
|
|
8
|
-
# not by hooks that can interfere with file operations.
|
|
9
|
-
#
|
|
10
|
-
# This guard now does NOTHING - just allows all operations.
|
|
11
|
-
|
|
12
|
-
set +e
|
|
13
|
-
echo '{"decision":"allow"}'
|
|
14
|
-
exit 0
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# DEPRECATED: v1.0.352 — No longer referenced by /sw:increment SKILL.md
|
|
3
|
-
# The increment skill now uses Agent() delegation (sw-pm, sw-architect, sw-planner agents)
|
|
4
|
-
# instead of Skill() chains with marker-based enforcement.
|
|
5
|
-
# This guard remains on disk for backward compatibility with older cached plugin versions.
|
|
6
|
-
# It can be safely removed in a future version.
|
|
7
|
-
#
|
|
8
|
-
# --- Original documentation below ---
|
|
9
|
-
#
|
|
10
|
-
# skill-chain-enforcement-guard.sh - Enforces skill delegation in /sw:increment
|
|
11
|
-
#
|
|
12
|
-
# PURPOSE:
|
|
13
|
-
# The /sw:increment skill MUST delegate to sub-skills (PM, Architect, Test-Aware-Planner)
|
|
14
|
-
# for creating spec.md, plan.md, and tasks.md. Analytics show the LLM writes these files
|
|
15
|
-
# inline 97% of the time instead of invoking the specialized skills via Skill() calls.
|
|
16
|
-
#
|
|
17
|
-
# This guard BLOCKS direct writes to spec.md, plan.md, and tasks.md from the increment
|
|
18
|
-
# skill unless the corresponding sub-skill has registered its invocation marker.
|
|
19
|
-
#
|
|
20
|
-
# WORKFLOW ENFORCED:
|
|
21
|
-
# 1. /sw:increment creates folder + metadata.json (ALLOWED)
|
|
22
|
-
# 2. /sw:increment MUST invoke Skill("sw:pm") for spec.md
|
|
23
|
-
# 3. /sw:increment MUST invoke Skill("sw:architect") for plan.md
|
|
24
|
-
# 4. /sw:increment MUST delegate to sw-planner agent for tasks.md
|
|
25
|
-
# 5. Each sub-skill writes a marker to .specweave/state/skill-chain-{increment-id}.json
|
|
26
|
-
# 6. This guard checks for that marker before allowing the write
|
|
27
|
-
#
|
|
28
|
-
# DETECTION LOGIC:
|
|
29
|
-
# - ALLOW: metadata.json writes (always)
|
|
30
|
-
# - ALLOW: File has skill invocation marker in state file
|
|
31
|
-
# - ALLOW: File is a template (has template markers)
|
|
32
|
-
# - ALLOW: Config has skillChainEnforcement disabled
|
|
33
|
-
# - BLOCK: Direct spec.md/plan.md/tasks.md writes without skill marker
|
|
34
|
-
#
|
|
35
|
-
# @since 1.0.314
|
|
36
|
-
|
|
37
|
-
set -e
|
|
38
|
-
|
|
39
|
-
# Read hook input
|
|
40
|
-
INPUT=$(cat)
|
|
41
|
-
|
|
42
|
-
# Extract file path and tool from input
|
|
43
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // ""')
|
|
44
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .toolInput.file_path // ""')
|
|
45
|
-
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .toolInput.content // ""')
|
|
46
|
-
|
|
47
|
-
# Only check Write and Edit operations
|
|
48
|
-
if [[ "$TOOL_NAME" != "Write" ]] && [[ "$TOOL_NAME" != "Edit" ]]; then
|
|
49
|
-
echo '{"decision":"allow"}'
|
|
50
|
-
exit 0
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
# Check if this targets an increment folder
|
|
54
|
-
if [[ ! "$FILE_PATH" =~ \.specweave/increments/[0-9]{4}-[^/]+/ ]]; then
|
|
55
|
-
echo '{"decision":"allow"}'
|
|
56
|
-
exit 0
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
# Extract the filename
|
|
60
|
-
FILENAME=$(basename "$FILE_PATH")
|
|
61
|
-
|
|
62
|
-
# Only guard spec.md, plan.md, and tasks.md
|
|
63
|
-
case "$FILENAME" in
|
|
64
|
-
spec.md|plan.md|tasks.md) ;;
|
|
65
|
-
*)
|
|
66
|
-
echo '{"decision":"allow"}'
|
|
67
|
-
exit 0
|
|
68
|
-
;;
|
|
69
|
-
esac
|
|
70
|
-
|
|
71
|
-
# Extract increment ID from path
|
|
72
|
-
INCREMENT_ID=$(echo "$FILE_PATH" | grep -oE '[0-9]{4}-[^/]+' | head -1)
|
|
73
|
-
|
|
74
|
-
# Find project root (where .specweave/ is)
|
|
75
|
-
PROJECT_ROOT=$(echo "$FILE_PATH" | sed 's|/.specweave/.*|/|')
|
|
76
|
-
CONFIG_PATH="${PROJECT_ROOT}.specweave/config.json"
|
|
77
|
-
|
|
78
|
-
# Check if skill chain enforcement is enabled (default: strict)
|
|
79
|
-
ENFORCEMENT="strict"
|
|
80
|
-
if [[ -f "$CONFIG_PATH" ]]; then
|
|
81
|
-
ENFORCEMENT=$(jq -r '.planning.skillChainEnforcement // "strict"' "$CONFIG_PATH" 2>/dev/null)
|
|
82
|
-
if [[ "$ENFORCEMENT" == "off" ]] || [[ "$ENFORCEMENT" == "disabled" ]]; then
|
|
83
|
-
echo '{"decision":"allow"}'
|
|
84
|
-
exit 0
|
|
85
|
-
fi
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
# Template markers — allow template creation through
|
|
89
|
-
TEMPLATE_MARKERS=(
|
|
90
|
-
"[Story Title]"
|
|
91
|
-
"[user type]"
|
|
92
|
-
"[goal]"
|
|
93
|
-
"[benefit]"
|
|
94
|
-
"[Specific, testable criterion]"
|
|
95
|
-
"{{RESOLVED_PROJECT}}"
|
|
96
|
-
"TEMPLATE FILE"
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
# Check if content has template markers (template creation is ALLOWED)
|
|
100
|
-
for marker in "${TEMPLATE_MARKERS[@]}"; do
|
|
101
|
-
if [[ "$CONTENT" == *"$marker"* ]]; then
|
|
102
|
-
echo '{"decision":"allow"}'
|
|
103
|
-
exit 0
|
|
104
|
-
fi
|
|
105
|
-
done
|
|
106
|
-
|
|
107
|
-
# For Edit operations, allow small edits (status updates, checkbox toggles)
|
|
108
|
-
# These are operational updates, not full file creation
|
|
109
|
-
if [[ "$TOOL_NAME" == "Edit" ]]; then
|
|
110
|
-
OLD_STRING=$(echo "$INPUT" | jq -r '.tool_input.old_string // .toolInput.old_string // ""')
|
|
111
|
-
NEW_STRING=$(echo "$INPUT" | jq -r '.tool_input.new_string // .toolInput.new_string // ""')
|
|
112
|
-
OLD_LEN=${#OLD_STRING}
|
|
113
|
-
NEW_LEN=${#NEW_STRING}
|
|
114
|
-
|
|
115
|
-
# Allow small edits (status toggles, checkbox changes, minor corrections)
|
|
116
|
-
# Threshold: edits where both old and new are under 500 chars are likely operational
|
|
117
|
-
if [[ $OLD_LEN -lt 500 ]] && [[ $NEW_LEN -lt 500 ]]; then
|
|
118
|
-
echo '{"decision":"allow"}'
|
|
119
|
-
exit 0
|
|
120
|
-
fi
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
# Determine which skill should have been invoked
|
|
124
|
-
case "$FILENAME" in
|
|
125
|
-
spec.md)
|
|
126
|
-
REQUIRED_SKILL="sw:pm"
|
|
127
|
-
SKILL_LABEL="PM (Product Manager)"
|
|
128
|
-
STATE_KEY="pm_invoked"
|
|
129
|
-
;;
|
|
130
|
-
plan.md)
|
|
131
|
-
REQUIRED_SKILL="sw:architect"
|
|
132
|
-
SKILL_LABEL="Architect"
|
|
133
|
-
STATE_KEY="architect_invoked"
|
|
134
|
-
;;
|
|
135
|
-
tasks.md)
|
|
136
|
-
REQUIRED_SKILL="sw-planner"
|
|
137
|
-
SKILL_LABEL="Planner"
|
|
138
|
-
STATE_KEY="planner_invoked"
|
|
139
|
-
;;
|
|
140
|
-
esac
|
|
141
|
-
|
|
142
|
-
# Check for skill invocation marker
|
|
143
|
-
STATE_DIR="${PROJECT_ROOT}.specweave/state"
|
|
144
|
-
STATE_FILE="${STATE_DIR}/skill-chain-${INCREMENT_ID}.json"
|
|
145
|
-
|
|
146
|
-
if [[ -f "$STATE_FILE" ]]; then
|
|
147
|
-
INVOKED=$(jq -r ".${STATE_KEY} // false" "$STATE_FILE" 2>/dev/null)
|
|
148
|
-
if [[ "$INVOKED" == "true" ]]; then
|
|
149
|
-
echo '{"decision":"allow"}'
|
|
150
|
-
exit 0
|
|
151
|
-
fi
|
|
152
|
-
fi
|
|
153
|
-
|
|
154
|
-
# Check if the file already exists with content (this is an update, not creation)
|
|
155
|
-
# Allow updates to existing files that already have substantive content
|
|
156
|
-
if [[ -f "$FILE_PATH" ]]; then
|
|
157
|
-
EXISTING_SIZE=$(wc -c < "$FILE_PATH" 2>/dev/null || echo "0")
|
|
158
|
-
# If existing file has real content (>200 bytes, not just a template), allow edits
|
|
159
|
-
if [[ "$EXISTING_SIZE" -gt 200 ]]; then
|
|
160
|
-
# But check if this is the first substantive write to a template file
|
|
161
|
-
EXISTING_CONTENT=$(head -5 "$FILE_PATH" 2>/dev/null || echo "")
|
|
162
|
-
HAS_TEMPLATE=false
|
|
163
|
-
for marker in "${TEMPLATE_MARKERS[@]}"; do
|
|
164
|
-
if [[ "$EXISTING_CONTENT" == *"$marker"* ]]; then
|
|
165
|
-
HAS_TEMPLATE=true
|
|
166
|
-
break
|
|
167
|
-
fi
|
|
168
|
-
done
|
|
169
|
-
# If existing file is NOT a template, allow updates (sub-skill already wrote it)
|
|
170
|
-
if [[ "$HAS_TEMPLATE" == "false" ]]; then
|
|
171
|
-
echo '{"decision":"allow"}'
|
|
172
|
-
exit 0
|
|
173
|
-
fi
|
|
174
|
-
fi
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
# BLOCK: No skill invocation marker found
|
|
178
|
-
if [[ "$ENFORCEMENT" == "warn" ]]; then
|
|
179
|
-
# Warn mode: allow but show warning
|
|
180
|
-
REASON="**SKILL CHAIN WARNING**: You are writing ${FILENAME} directly without invoking the ${SKILL_LABEL} skill.
|
|
181
|
-
|
|
182
|
-
Best practice: Use \`Skill({ skill: \"${REQUIRED_SKILL}\", args: \"... for increment ${INCREMENT_ID}\" })\`
|
|
183
|
-
|
|
184
|
-
To suppress: Set \`planning.skillChainEnforcement: \"off\"\` in config.json"
|
|
185
|
-
|
|
186
|
-
REASON_ESCAPED=$(echo "$REASON" | jq -Rs .)
|
|
187
|
-
echo "{\"decision\":\"allow\",\"reason\":${REASON_ESCAPED}}"
|
|
188
|
-
exit 0
|
|
189
|
-
fi
|
|
190
|
-
|
|
191
|
-
# Strict mode: BLOCK
|
|
192
|
-
REASON="SKILL CHAIN ENFORCEMENT: Delegation Required
|
|
193
|
-
|
|
194
|
-
You are attempting to write ${FILENAME} directly. The /sw:increment skill MUST delegate
|
|
195
|
-
to specialized sub-skills instead of writing increment files inline.
|
|
196
|
-
|
|
197
|
-
REQUIRED ACTION for ${FILENAME}:
|
|
198
|
-
Invoke: Skill({ skill: \"${REQUIRED_SKILL}\", args: \"... for increment ${INCREMENT_ID}\" })
|
|
199
|
-
|
|
200
|
-
The ${SKILL_LABEL} skill will:
|
|
201
|
-
1. Register its invocation marker (this unblocks the guard)
|
|
202
|
-
2. Apply specialized expertise (research, architecture, test planning)
|
|
203
|
-
3. Write ${FILENAME} with proper structure and coverage
|
|
204
|
-
|
|
205
|
-
SKILL CHAIN (all 3 MUST be invoked):
|
|
206
|
-
spec.md --> Skill({ skill: \"sw:pm\", args: \"...\" })
|
|
207
|
-
plan.md --> Skill({ skill: \"sw:architect\", args: \"...\" })
|
|
208
|
-
tasks.md --> Agent({ subagent_type: \"sw:sw-planner\", ... })
|
|
209
|
-
|
|
210
|
-
Each skill writes its marker to:
|
|
211
|
-
${STATE_DIR}/skill-chain-${INCREMENT_ID}.json
|
|
212
|
-
|
|
213
|
-
WHY THIS MATTERS:
|
|
214
|
-
Analytics show 82 increment invocations but only 6 PM, 1 Architect, 1 TAP calls.
|
|
215
|
-
Inlining bypasses specialized expertise and produces lower-quality specs.
|
|
216
|
-
|
|
217
|
-
TO DISABLE (not recommended):
|
|
218
|
-
Set planning.skillChainEnforcement: \"off\" in .specweave/config.json"
|
|
219
|
-
|
|
220
|
-
REASON_ESCAPED=$(echo "$REASON" | jq -Rs .)
|
|
221
|
-
echo "{\"decision\":\"block\",\"reason\":${REASON_ESCAPED}}"
|
|
222
|
-
exit 0
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# spec-template-enforcement-guard.sh - DISABLED (v1.0.38)
|
|
3
|
-
#
|
|
4
|
-
# This guard was disabled in v1.0.38 per user feedback and error dashboard
|
|
5
|
-
# analysis showing 322+ false positive tool_failure errors across 92 sessions.
|
|
6
|
-
#
|
|
7
|
-
# The guard blocked legitimate spec.md writes when /sw:increment creates
|
|
8
|
-
# spec.md in a single pass (no template intermediate step).
|
|
9
|
-
#
|
|
10
|
-
# Sibling guards (spec-validation-guard.sh, increment-duplicate-guard.sh)
|
|
11
|
-
# were already disabled for the same reason.
|
|
12
|
-
#
|
|
13
|
-
# Spec template workflow should be encouraged via documentation and skill
|
|
14
|
-
# defaults, not enforced by hooks that block file operations.
|
|
15
|
-
#
|
|
16
|
-
# @since 1.0.167
|
|
17
|
-
# @disabled 1.0.38
|
|
18
|
-
|
|
19
|
-
set +e
|
|
20
|
-
echo '{"decision":"allow"}'
|
|
21
|
-
exit 0
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# spec-validation-guard.sh - DISABLED (v1.0.38)
|
|
3
|
-
#
|
|
4
|
-
# This guard was converted to WARNING-only in v1.0.37, and now completely
|
|
5
|
-
# disabled in v1.0.38 per user feedback: "you MUST NEVER block such operations"
|
|
6
|
-
#
|
|
7
|
-
# Spec validation should be handled by agents/scripts with proper business logic,
|
|
8
|
-
# not by hooks that can interfere with file operations.
|
|
9
|
-
#
|
|
10
|
-
# This guard now does NOTHING - just allows all operations.
|
|
11
|
-
|
|
12
|
-
set +e
|
|
13
|
-
echo '{"decision":"allow"}'
|
|
14
|
-
exit 0
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# status-completion-guard.sh - Prevents direct status changes to "completed"
|
|
3
|
-
#
|
|
4
|
-
# RULE: Increment status should NEVER be changed to "completed" directly!
|
|
5
|
-
#
|
|
6
|
-
# ALLOWED paths to completion:
|
|
7
|
-
# 1. /sw:done command (validates ACs, tests, docs)
|
|
8
|
-
# 2. /sw:auto mode when all tests pass (auto-verified closure)
|
|
9
|
-
#
|
|
10
|
-
# @since 1.0.196
|
|
11
|
-
# @see CLAUDE.md "Status Workflow" section
|
|
12
|
-
|
|
13
|
-
set +e # CRITICAL: Never exit on error - consistent with non-blocking hook principle
|
|
14
|
-
|
|
15
|
-
INPUT=$(cat)
|
|
16
|
-
|
|
17
|
-
# Extract tool parameters
|
|
18
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // .toolName // ""')
|
|
19
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
20
|
-
OLD_STRING=$(echo "$INPUT" | jq -r '.tool_input.old_string // ""')
|
|
21
|
-
NEW_STRING=$(echo "$INPUT" | jq -r '.tool_input.new_string // ""')
|
|
22
|
-
|
|
23
|
-
# Only check Edit operations on metadata.json files
|
|
24
|
-
if [[ "$TOOL_NAME" != "Edit" ]]; then
|
|
25
|
-
echo '{"decision":"allow"}'
|
|
26
|
-
exit 0
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# Only check metadata.json files in increments
|
|
30
|
-
if [[ ! "$FILE_PATH" =~ \.specweave/increments/.*/metadata\.json$ ]]; then
|
|
31
|
-
echo '{"decision":"allow"}'
|
|
32
|
-
exit 0
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
# Check if this is a status change to "completed"
|
|
36
|
-
# Pattern: "status": "active" -> "status": "completed"
|
|
37
|
-
# Or: "status": "paused" -> "status": "completed"
|
|
38
|
-
# Or: "status": "ready_for_review" -> "status": "completed"
|
|
39
|
-
if echo "$NEW_STRING" | grep -qE '"status":\s*"completed"'; then
|
|
40
|
-
# Detect project root via walk-up
|
|
41
|
-
_DIR="$PWD"
|
|
42
|
-
_LIMIT=0
|
|
43
|
-
while [[ "$_DIR" != "/" ]] && [[ ! -f "$_DIR/.specweave/config.json" ]] && [[ $_LIMIT -lt 50 ]]; do
|
|
44
|
-
_DIR=$(dirname "$_DIR")
|
|
45
|
-
_LIMIT=$((_LIMIT + 1))
|
|
46
|
-
done
|
|
47
|
-
_ROOT="$_DIR"
|
|
48
|
-
|
|
49
|
-
# Check if auto-mode is active with verified completion
|
|
50
|
-
AUTO_STATE_FILE="$_ROOT/.specweave/state/auto/session.json"
|
|
51
|
-
if [[ -f "$AUTO_STATE_FILE" ]]; then
|
|
52
|
-
AUTO_STATUS=$(jq -r '.status // "unknown"' "$AUTO_STATE_FILE" 2>/dev/null || echo "unknown")
|
|
53
|
-
AUTO_VERIFIED=$(jq -r '.testsVerified // false' "$AUTO_STATE_FILE" 2>/dev/null || echo "false")
|
|
54
|
-
|
|
55
|
-
# Allow if auto-mode is active AND tests are verified
|
|
56
|
-
if [[ "$AUTO_STATUS" == "active" && "$AUTO_VERIFIED" == "true" ]]; then
|
|
57
|
-
echo '{"decision":"allow"}'
|
|
58
|
-
exit 0
|
|
59
|
-
fi
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
# Check if called from /sw:done command (look for marker file)
|
|
63
|
-
DONE_MARKER="$_ROOT/.specweave/state/.sw-done-in-progress"
|
|
64
|
-
if [[ -f "$DONE_MARKER" ]]; then
|
|
65
|
-
echo '{"decision":"allow"}'
|
|
66
|
-
exit 0
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
# Extract increment ID for the message
|
|
70
|
-
INCREMENT_ID=$(echo "$FILE_PATH" | grep -oE '[0-9]{4}[E]?-[^/]+' || echo "unknown")
|
|
71
|
-
|
|
72
|
-
# Block the direct status change
|
|
73
|
-
cat << EOF
|
|
74
|
-
{
|
|
75
|
-
"decision": "block",
|
|
76
|
-
"reason": "Direct status change to 'completed' is blocked",
|
|
77
|
-
"systemMessage": "⛔ **STATUS PROTECTION ACTIVE**\\n\\n❌ Cannot directly edit metadata.json to set status='completed'\\n\\n**Why?** Completion requires validation:\\n- All tasks marked complete\\n- Acceptance criteria satisfied\\n- Tests passing\\n- Documentation updated\\n\\n**Correct approach:**\\n\`\`\`\\n/sw:done ${INCREMENT_ID}\\n\`\`\`\\n\\nOr in auto-mode:\\n\`\`\`\\n/sw:auto ${INCREMENT_ID}\\n\`\`\`\\n(auto-closes when all tests pass)"
|
|
78
|
-
}
|
|
79
|
-
EOF
|
|
80
|
-
exit 0
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
echo '{"decision":"allow"}'
|
|
84
|
-
exit 0
|