@lvlup-sw/exarchos 2.4.3 → 2.5.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.
Files changed (97) hide show
  1. package/.claude-plugin/plugin.json +7 -2
  2. package/AGENTS.md +2 -2
  3. package/README.md +70 -57
  4. package/agents/.gitkeep +0 -0
  5. package/agents/fixer.md +62 -0
  6. package/agents/implementer.md +68 -0
  7. package/agents/reviewer.md +50 -0
  8. package/commands/ideate.md +1 -1
  9. package/commands/plan.md +1 -1
  10. package/commands/review.md +58 -0
  11. package/dist/exarchos.js +583 -146
  12. package/hooks/hooks.json +8 -0
  13. package/package.json +12 -4
  14. package/scripts/sync-versions.sh +31 -22
  15. package/skills/brainstorming/SKILL.md +16 -0
  16. package/skills/brainstorming/references/design-template.md +9 -0
  17. package/skills/debug/SKILL.md +41 -0
  18. package/skills/debug/references/hotfix-track.md +12 -49
  19. package/skills/debug/references/investigation-checklist.md +3 -3
  20. package/skills/debug/references/thorough-track.md +12 -42
  21. package/skills/delegation/SKILL.md +104 -37
  22. package/skills/delegation/references/agent-teams-saga.md +4 -1
  23. package/skills/delegation/references/fix-mode.md +46 -6
  24. package/skills/delegation/references/implementer-prompt.md +29 -1
  25. package/skills/delegation/references/parallel-strategy.md +1 -1
  26. package/skills/delegation/references/state-management.md +33 -0
  27. package/skills/delegation/references/workflow-steps.md +6 -10
  28. package/skills/delegation/references/worktree-enforcement.md +13 -7
  29. package/skills/git-worktrees/SKILL.md +6 -9
  30. package/skills/implementation-planning/SKILL.md +32 -27
  31. package/skills/implementation-planning/references/task-template.md +20 -0
  32. package/skills/implementation-planning/references/testing-strategy-guide.md +22 -1
  33. package/skills/implementation-planning/references/worked-example.md +2 -2
  34. package/skills/quality-review/SKILL.md +103 -10
  35. package/skills/quality-review/references/auto-transition.md +1 -1
  36. package/skills/quality-review/references/axiom-integration.md +135 -0
  37. package/skills/refactor/SKILL.md +32 -39
  38. package/skills/refactor/phases/polish-implement.md +2 -2
  39. package/skills/refactor/phases/polish-validate.md +1 -1
  40. package/skills/refactor/references/doc-update-checklist.md +2 -3
  41. package/skills/refactor/references/explore-checklist.md +4 -6
  42. package/skills/refactor/references/overhaul-track.md +20 -50
  43. package/skills/refactor/references/polish-track.md +18 -46
  44. package/skills/shared/prompts/context-reading.md +7 -7
  45. package/skills/shared/references/mcp-tool-guidance.md +14 -1
  46. package/skills/shared/references/tdd.md +17 -0
  47. package/skills/shepherd/SKILL.md +38 -10
  48. package/skills/shepherd/references/fix-strategies.md +1 -2
  49. package/skills/shepherd/references/shepherd-event-schemas.md +56 -0
  50. package/skills/spec-review/SKILL.md +46 -10
  51. package/skills/spec-review/references/worked-example.md +1 -1
  52. package/skills/synthesis/SKILL.md +32 -10
  53. package/skills/synthesis/references/github-native-stacking.md +3 -4
  54. package/skills/synthesis/references/synthesis-steps.md +11 -13
  55. package/skills/workflow-state/SKILL.md +11 -3
  56. package/skills/workflow-state/references/mcp-tool-reference.md +5 -5
  57. package/skills/workflow-state/references/phase-transitions.md +6 -3
  58. package/.claude-plugin/marketplace.json +0 -34
  59. package/scripts/assess-refactor-scope.sh +0 -239
  60. package/scripts/check-coderabbit.sh +0 -288
  61. package/scripts/check-context-economy.sh +0 -405
  62. package/scripts/check-coverage-thresholds.sh +0 -194
  63. package/scripts/check-operational-resilience.sh +0 -306
  64. package/scripts/check-polish-scope.sh +0 -245
  65. package/scripts/check-post-merge.sh +0 -185
  66. package/scripts/check-pr-comments.sh +0 -127
  67. package/scripts/check-task-decomposition.sh +0 -451
  68. package/scripts/check-tdd-compliance.sh +0 -265
  69. package/scripts/check-workflow-determinism.sh +0 -312
  70. package/scripts/debug-review-gate.sh +0 -201
  71. package/scripts/extract-fix-tasks.sh +0 -179
  72. package/scripts/extract-task.sh +0 -67
  73. package/scripts/generate-traceability.sh +0 -209
  74. package/scripts/investigation-timer.sh +0 -171
  75. package/scripts/needs-schema-sync.sh +0 -174
  76. package/scripts/new-project.sh +0 -103
  77. package/scripts/post-delegation-check.sh +0 -317
  78. package/scripts/pre-synthesis-check.sh +0 -475
  79. package/scripts/reconcile-state.sh +0 -346
  80. package/scripts/review-diff.sh +0 -63
  81. package/scripts/review-verdict.sh +0 -169
  82. package/scripts/security-scan.sh +0 -248
  83. package/scripts/select-debug-track.sh +0 -186
  84. package/scripts/setup-worktree.sh +0 -323
  85. package/scripts/spec-coverage-check.sh +0 -230
  86. package/scripts/static-analysis-gate.sh +0 -261
  87. package/scripts/validate-companion.sh +0 -161
  88. package/scripts/validate-pr-body.sh +0 -158
  89. package/scripts/validate-pr-stack.sh +0 -146
  90. package/scripts/verify-delegation-saga.sh +0 -240
  91. package/scripts/verify-doc-links.sh +0 -211
  92. package/scripts/verify-ideate-artifacts.sh +0 -296
  93. package/scripts/verify-plan-coverage.sh +0 -408
  94. package/scripts/verify-provenance-chain.sh +0 -310
  95. package/scripts/verify-review-triage.sh +0 -219
  96. package/scripts/verify-worktree-baseline.sh +0 -159
  97. package/scripts/verify-worktree.sh +0 -84
@@ -1,346 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Reconcile State
3
- # Compares workflow state file to git reality: verifies worktrees exist,
4
- # branches exist, task statuses are consistent, and phase is valid.
5
- #
6
- # Usage: reconcile-state.sh --state-file <path> --repo-root <path>
7
- #
8
- # Exit codes:
9
- # 0 = state is consistent with git
10
- # 1 = discrepancies found
11
- # 2 = usage error (missing required args)
12
-
13
- set -euo pipefail
14
-
15
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
-
17
- # Colors
18
- RED='\033[0;31m'
19
- GREEN='\033[0;32m'
20
- YELLOW='\033[1;33m'
21
- NC='\033[0m'
22
-
23
- # ============================================================
24
- # ARGUMENT PARSING
25
- # ============================================================
26
-
27
- STATE_FILE=""
28
- REPO_ROOT=""
29
-
30
- usage() {
31
- cat << 'USAGE'
32
- Usage: reconcile-state.sh --state-file <path> --repo-root <path>
33
-
34
- Required:
35
- --state-file <path> Path to the workflow state JSON file
36
- --repo-root <path> Git repository root directory
37
-
38
- Optional:
39
- --help Show this help message
40
-
41
- Exit codes:
42
- 0 State is consistent with git
43
- 1 Discrepancies found
44
- 2 Usage error (missing required args)
45
- USAGE
46
- }
47
-
48
- while [[ $# -gt 0 ]]; do
49
- case "$1" in
50
- --state-file)
51
- if [[ -z "${2:-}" ]]; then
52
- echo "Error: --state-file requires a path argument" >&2
53
- exit 2
54
- fi
55
- STATE_FILE="$2"
56
- shift 2
57
- ;;
58
- --repo-root)
59
- if [[ -z "${2:-}" ]]; then
60
- echo "Error: --repo-root requires a path argument" >&2
61
- exit 2
62
- fi
63
- REPO_ROOT="$2"
64
- shift 2
65
- ;;
66
- --help)
67
- usage
68
- exit 0
69
- ;;
70
- *)
71
- echo "Error: Unknown argument '$1'" >&2
72
- usage >&2
73
- exit 2
74
- ;;
75
- esac
76
- done
77
-
78
- if [[ -z "$STATE_FILE" || -z "$REPO_ROOT" ]]; then
79
- echo "Error: --state-file and --repo-root are required" >&2
80
- usage >&2
81
- exit 2
82
- fi
83
-
84
- # ============================================================
85
- # DEPENDENCY CHECK
86
- # ============================================================
87
-
88
- if ! command -v jq &>/dev/null; then
89
- echo "Error: jq is required but not installed" >&2
90
- exit 2
91
- fi
92
-
93
- if ! command -v git &>/dev/null; then
94
- echo "Error: git is required but not installed" >&2
95
- exit 2
96
- fi
97
-
98
- # ============================================================
99
- # CHECK FUNCTIONS
100
- # ============================================================
101
-
102
- CHECK_PASS=0
103
- CHECK_FAIL=0
104
- RESULTS=()
105
-
106
- check_pass() {
107
- local name="$1"
108
- RESULTS+=("- **PASS**: $name")
109
- CHECK_PASS=$((CHECK_PASS + 1))
110
- }
111
-
112
- check_fail() {
113
- local name="$1"
114
- local detail="${2:-}"
115
- if [[ -n "$detail" ]]; then
116
- RESULTS+=("- **FAIL**: $name — $detail")
117
- else
118
- RESULTS+=("- **FAIL**: $name")
119
- fi
120
- CHECK_FAIL=$((CHECK_FAIL + 1))
121
- }
122
-
123
- # ============================================================
124
- # CHECK 1: State file exists and is valid JSON
125
- # ============================================================
126
-
127
- check_state_file() {
128
- if [[ ! -f "$STATE_FILE" ]]; then
129
- check_fail "State file exists" "File not found: $STATE_FILE"
130
- return 1
131
- fi
132
-
133
- if ! jq empty "$STATE_FILE" 2>/dev/null; then
134
- check_fail "State file exists" "Invalid JSON: $STATE_FILE"
135
- return 1
136
- fi
137
-
138
- check_pass "State file exists"
139
- return 0
140
- }
141
-
142
- # ============================================================
143
- # CHECK 2: Phase is valid for workflow type
144
- # ============================================================
145
-
146
- check_phase_valid() {
147
- local workflow_type
148
- local phase
149
-
150
- workflow_type="$(jq -r '.workflowType // "feature"' "$STATE_FILE")"
151
- phase="$(jq -r '.phase // "unknown"' "$STATE_FILE")"
152
-
153
- # Define valid phases per workflow type
154
- local -a valid_phases
155
- case "$workflow_type" in
156
- feature)
157
- valid_phases=(ideate plan plan-review delegate review synthesize completed cancelled blocked)
158
- ;;
159
- debug)
160
- valid_phases=(triage investigate rca design debug-implement debug-validate debug-review hotfix-implement hotfix-validate synthesize completed cancelled blocked)
161
- ;;
162
- refactor)
163
- valid_phases=(explore brief polish-implement polish-validate polish-update-docs overhaul-plan overhaul-delegate overhaul-review overhaul-update-docs synthesize completed cancelled blocked)
164
- ;;
165
- *)
166
- check_fail "Phase is valid" "Unknown workflow type: $workflow_type"
167
- return 1
168
- ;;
169
- esac
170
-
171
- local found=false
172
- for valid_phase in "${valid_phases[@]}"; do
173
- if [[ "$phase" == "$valid_phase" ]]; then
174
- found=true
175
- break
176
- fi
177
- done
178
-
179
- if [[ "$found" == true ]]; then
180
- check_pass "Phase is valid ($phase for $workflow_type)"
181
- return 0
182
- else
183
- check_fail "Phase is valid" "Phase '$phase' is not valid for workflow type '$workflow_type' (valid: ${valid_phases[*]})"
184
- return 1
185
- fi
186
- }
187
-
188
- # ============================================================
189
- # CHECK 3: Task branches exist in git
190
- # ============================================================
191
-
192
- check_task_branches() {
193
- local task_count
194
- task_count="$(jq '.tasks | length' "$STATE_FILE")"
195
-
196
- if [[ "$task_count" -eq 0 ]]; then
197
- check_pass "Task branches exist (no tasks to check)"
198
- return 0
199
- fi
200
-
201
- local missing_branches=()
202
- local branches_checked=0
203
-
204
- # Get all branches from the task array
205
- local task_branches
206
- task_branches="$(jq -r '.tasks[] | select(.branch != null and .branch != "") | .branch' "$STATE_FILE")"
207
-
208
- while IFS= read -r branch; do
209
- [[ -z "$branch" ]] && continue
210
- branches_checked=$((branches_checked + 1))
211
-
212
- # Check if branch exists in git
213
- if ! git -C "$REPO_ROOT" rev-parse --verify "refs/heads/$branch" &>/dev/null; then
214
- missing_branches+=("$branch")
215
- fi
216
- done <<< "$task_branches"
217
-
218
- if [[ -z "${missing_branches+x}" ]] || [[ ${#missing_branches[@]} -eq 0 ]]; then
219
- check_pass "Task branches exist ($branches_checked branches verified)"
220
- return 0
221
- else
222
- local missing_list
223
- missing_list="$(IFS=', '; echo "${missing_branches[*]}")"
224
- check_fail "Task branches exist" "Missing branches: $missing_list"
225
- return 1
226
- fi
227
- }
228
-
229
- # ============================================================
230
- # CHECK 4: Worktrees listed in state exist on disk
231
- # ============================================================
232
-
233
- check_worktrees_exist() {
234
- local worktree_count
235
- worktree_count="$(jq '.worktrees | length' "$STATE_FILE")"
236
-
237
- if [[ "$worktree_count" -eq 0 ]]; then
238
- check_pass "Worktrees exist (no worktrees to check)"
239
- return 0
240
- fi
241
-
242
- # Get actual git worktrees
243
- local git_worktrees
244
- git_worktrees="$(git -C "$REPO_ROOT" worktree list --porcelain 2>/dev/null | grep '^worktree ' | sed 's/^worktree //' || true)"
245
-
246
- local missing_worktrees=()
247
- local worktrees_checked=0
248
-
249
- # Check each worktree in state
250
- local worktree_paths
251
- worktree_paths="$(jq -r '.worktrees | to_entries[] | select(.value.status == "active") | .value.path // empty' "$STATE_FILE")"
252
-
253
- while IFS= read -r wt_path; do
254
- [[ -z "$wt_path" ]] && continue
255
- worktrees_checked=$((worktrees_checked + 1))
256
-
257
- if [[ ! -d "$wt_path" ]]; then
258
- missing_worktrees+=("$wt_path")
259
- elif ! echo "$git_worktrees" | grep -qFx "$wt_path"; then
260
- missing_worktrees+=("$wt_path (not a git worktree)")
261
- fi
262
- done <<< "$worktree_paths"
263
-
264
- if [[ -z "${missing_worktrees+x}" ]] || [[ ${#missing_worktrees[@]} -eq 0 ]]; then
265
- check_pass "Worktrees exist ($worktrees_checked worktrees verified)"
266
- return 0
267
- else
268
- local missing_list
269
- missing_list="$(IFS=', '; echo "${missing_worktrees[*]}")"
270
- check_fail "Worktrees exist" "Missing worktree paths: $missing_list"
271
- return 1
272
- fi
273
- }
274
-
275
- # ============================================================
276
- # CHECK 5: Task status consistency
277
- # ============================================================
278
-
279
- check_task_status_consistency() {
280
- local task_count
281
- task_count="$(jq '.tasks | length' "$STATE_FILE")"
282
-
283
- if [[ "$task_count" -eq 0 ]]; then
284
- check_pass "Task status consistency (no tasks to check)"
285
- return 0
286
- fi
287
-
288
- local inconsistencies=()
289
-
290
- # Check for in-progress tasks without branches
291
- local in_progress_no_branch
292
- in_progress_no_branch="$(jq -r '.tasks[] | select(.status == "in-progress" and (.branch == null or .branch == "")) | .id' "$STATE_FILE")"
293
-
294
- while IFS= read -r task_id; do
295
- [[ -z "$task_id" ]] && continue
296
- inconsistencies+=("Task $task_id is in-progress but has no branch")
297
- done <<< "$in_progress_no_branch"
298
-
299
- if [[ -z "${inconsistencies+x}" ]] || [[ ${#inconsistencies[@]} -eq 0 ]]; then
300
- check_pass "Task status consistency ($task_count tasks checked)"
301
- return 0
302
- else
303
- local issue_list
304
- issue_list="$(IFS='; '; echo "${inconsistencies[*]}")"
305
- check_fail "Task status consistency" "$issue_list"
306
- return 1
307
- fi
308
- }
309
-
310
- # ============================================================
311
- # EXECUTE CHECKS
312
- # ============================================================
313
-
314
- if check_state_file; then
315
- check_phase_valid || true
316
- check_task_branches || true
317
- check_worktrees_exist || true
318
- check_task_status_consistency || true
319
- fi
320
-
321
- # ============================================================
322
- # STRUCTURED OUTPUT
323
- # ============================================================
324
-
325
- echo "## State Reconciliation Report"
326
- echo ""
327
- echo "**State file:** \`$STATE_FILE\`"
328
- echo "**Repo root:** \`$REPO_ROOT\`"
329
- echo ""
330
-
331
- for result in "${RESULTS[@]}"; do
332
- echo "$result"
333
- done
334
-
335
- echo ""
336
- TOTAL=$((CHECK_PASS + CHECK_FAIL))
337
- echo "---"
338
- echo ""
339
-
340
- if [[ $CHECK_FAIL -eq 0 ]]; then
341
- echo "**Result: PASS** — State is consistent with git ($CHECK_PASS/$TOTAL checks passed)"
342
- exit 0
343
- else
344
- echo "**Result: FAIL** — Discrepancies found ($CHECK_FAIL/$TOTAL checks failed)"
345
- exit 1
346
- fi
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # review-diff.sh - Generate context-efficient diff for code review
4
- #
5
- # Usage: review-diff.sh <worktree-path> [base-branch]
6
- #
7
- # Output: Structured diff with only changed sections
8
- # - Stats summary
9
- # - Unified diff with 3-line context
10
- #
11
- # This reduces context consumption by 80-90% compared to full file contents.
12
- #
13
-
14
- set -euo pipefail
15
-
16
- WORKTREE="${1:-.}"
17
- BASE="${2:-main}"
18
-
19
- if [ ! -d "$WORKTREE" ]; then
20
- echo "ERROR: Directory not found: $WORKTREE" >&2
21
- exit 1
22
- fi
23
-
24
- cd "$WORKTREE"
25
-
26
- # Check if we're in a git repository
27
- if ! git rev-parse --git-dir > /dev/null 2>&1; then
28
- echo "ERROR: Not a git repository: $WORKTREE" >&2
29
- exit 1
30
- fi
31
-
32
- # Get current branch
33
- CURRENT_BRANCH=$(git branch --show-current)
34
-
35
- echo "## Review Diff"
36
- echo ""
37
- echo "**Worktree:** $WORKTREE"
38
- echo "**Branch:** $CURRENT_BRANCH"
39
- echo "**Base:** $BASE"
40
- echo ""
41
-
42
- # Stats summary
43
- echo "### Changed Files"
44
- echo ""
45
- echo '```'
46
- git diff "$BASE"...HEAD --stat 2>/dev/null || git diff "$BASE"..HEAD --stat
47
- echo '```'
48
- echo ""
49
-
50
- # File list for quick reference
51
- echo "### Files Modified"
52
- echo ""
53
- git diff "$BASE"...HEAD --name-only 2>/dev/null || git diff "$BASE"..HEAD --name-only | while read -r file; do
54
- echo "- \`$file\`"
55
- done
56
- echo ""
57
-
58
- # Unified diff with context
59
- echo "### Diff Content"
60
- echo ""
61
- echo '```diff'
62
- git diff "$BASE"...HEAD --unified=3 2>/dev/null || git diff "$BASE"..HEAD --unified=3
63
- echo '```'
@@ -1,169 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Review Verdict Classification
3
- # Classifies review findings into a routing verdict for the quality-review workflow.
4
- #
5
- # Usage: review-verdict.sh --high <n> --medium <n> --low <n> [--blocked <reason>]
6
- # review-verdict.sh --findings-file <path>
7
- #
8
- # Exit codes:
9
- # 0 = APPROVED (no HIGH findings)
10
- # 1 = NEEDS_FIXES (HIGH findings present)
11
- # 2 = BLOCKED (--blocked flag) or usage error
12
-
13
- set -euo pipefail
14
-
15
- # ============================================================
16
- # ARGUMENT PARSING
17
- # ============================================================
18
-
19
- HIGH_COUNT=""
20
- MEDIUM_COUNT=""
21
- LOW_COUNT=""
22
- BLOCKED_REASON=""
23
- FINDINGS_FILE=""
24
-
25
- usage() {
26
- cat << 'USAGE'
27
- Usage: review-verdict.sh --high <n> --medium <n> --low <n> [--blocked <reason>]
28
- review-verdict.sh --findings-file <path>
29
-
30
- Classify review findings into a routing verdict.
31
-
32
- Options:
33
- --high <n> Number of HIGH-severity findings
34
- --medium <n> Number of MEDIUM-severity findings
35
- --low <n> Number of LOW-severity findings
36
- --blocked <reason> Mark as BLOCKED with the given reason
37
- --findings-file <path> JSON file with {high:N, medium:N, low:N}
38
- --help Show this help message
39
-
40
- Exit codes:
41
- 0 APPROVED (no HIGH findings)
42
- 1 NEEDS_FIXES (HIGH findings present)
43
- 2 BLOCKED or usage error
44
- USAGE
45
- }
46
-
47
- while [[ $# -gt 0 ]]; do
48
- case "$1" in
49
- --high)
50
- if [[ -z "${2:-}" ]]; then
51
- echo "Error: --high requires a number argument" >&2
52
- exit 2
53
- fi
54
- HIGH_COUNT="$2"
55
- shift 2
56
- ;;
57
- --medium)
58
- if [[ -z "${2:-}" ]]; then
59
- echo "Error: --medium requires a number argument" >&2
60
- exit 2
61
- fi
62
- MEDIUM_COUNT="$2"
63
- shift 2
64
- ;;
65
- --low)
66
- if [[ -z "${2:-}" ]]; then
67
- echo "Error: --low requires a number argument" >&2
68
- exit 2
69
- fi
70
- LOW_COUNT="$2"
71
- shift 2
72
- ;;
73
- --blocked)
74
- if [[ -z "${2:-}" ]]; then
75
- echo "Error: --blocked requires a reason argument" >&2
76
- exit 2
77
- fi
78
- BLOCKED_REASON="$2"
79
- shift 2
80
- ;;
81
- --findings-file)
82
- if [[ -z "${2:-}" ]]; then
83
- echo "Error: --findings-file requires a path argument" >&2
84
- exit 2
85
- fi
86
- FINDINGS_FILE="$2"
87
- shift 2
88
- ;;
89
- --help)
90
- usage
91
- exit 0
92
- ;;
93
- *)
94
- echo "Error: Unknown argument '$1'" >&2
95
- usage >&2
96
- exit 2
97
- ;;
98
- esac
99
- done
100
-
101
- # ============================================================
102
- # INPUT RESOLUTION
103
- # ============================================================
104
-
105
- # If --findings-file provided, parse JSON
106
- if [[ -n "$FINDINGS_FILE" ]]; then
107
- if [[ ! -f "$FINDINGS_FILE" ]]; then
108
- echo "Error: Findings file not found: $FINDINGS_FILE" >&2
109
- exit 2
110
- fi
111
-
112
- if ! command -v jq &>/dev/null; then
113
- echo "Error: jq is required to parse findings file" >&2
114
- exit 2
115
- fi
116
-
117
- HIGH_COUNT="$(jq -r '.high // 0' "$FINDINGS_FILE")"
118
- MEDIUM_COUNT="$(jq -r '.medium // 0' "$FINDINGS_FILE")"
119
- LOW_COUNT="$(jq -r '.low // 0' "$FINDINGS_FILE")"
120
-
121
- # Ensure numeric values (guard against malformed JSON)
122
- [[ "$HIGH_COUNT" =~ ^[0-9]+$ ]] || HIGH_COUNT=0
123
- [[ "$MEDIUM_COUNT" =~ ^[0-9]+$ ]] || MEDIUM_COUNT=0
124
- [[ "$LOW_COUNT" =~ ^[0-9]+$ ]] || LOW_COUNT=0
125
- fi
126
-
127
- # Validate we have the required inputs (either via flags or file)
128
- if [[ -z "$HIGH_COUNT" && -z "$BLOCKED_REASON" ]]; then
129
- echo "Error: Must provide --high/--medium/--low counts, --findings-file, or --blocked" >&2
130
- usage >&2
131
- exit 2
132
- fi
133
-
134
- # Default counts to 0 if not set
135
- HIGH_COUNT="${HIGH_COUNT:-0}"
136
- MEDIUM_COUNT="${MEDIUM_COUNT:-0}"
137
- LOW_COUNT="${LOW_COUNT:-0}"
138
-
139
- # ============================================================
140
- # VERDICT LOGIC
141
- # ============================================================
142
-
143
- # Priority: BLOCKED > NEEDS_FIXES > APPROVED
144
- if [[ -n "$BLOCKED_REASON" ]]; then
145
- echo "## Review Verdict: BLOCKED"
146
- echo ""
147
- echo "**Reason:** $BLOCKED_REASON"
148
- echo ""
149
- echo "Return to design phase. Route to \`/ideate --redesign\`."
150
- exit 2
151
- fi
152
-
153
- if [[ "$HIGH_COUNT" -gt 0 ]]; then
154
- TOTAL=$((HIGH_COUNT + MEDIUM_COUNT + LOW_COUNT))
155
- echo "## Review Verdict: NEEDS_FIXES"
156
- echo ""
157
- echo "Found $HIGH_COUNT HIGH-severity findings. Route to \`/delegate --fixes\`."
158
- echo ""
159
- echo "**Finding summary:** $HIGH_COUNT high, $MEDIUM_COUNT medium, $LOW_COUNT low ($TOTAL total)"
160
- exit 1
161
- fi
162
-
163
- TOTAL=$((HIGH_COUNT + MEDIUM_COUNT + LOW_COUNT))
164
- echo "## Review Verdict: APPROVED"
165
- echo ""
166
- echo "No HIGH-severity findings. Proceed to synthesis."
167
- echo ""
168
- echo "**Finding summary:** $HIGH_COUNT high, $MEDIUM_COUNT medium, $LOW_COUNT low ($TOTAL total)"
169
- exit 0