@lvlup-sw/exarchos 2.0.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/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +17 -0
- package/.mcp.json +17 -0
- package/AGENTS.md +59 -0
- package/CLAUDE.md.template +62 -0
- package/LICENSE +202 -0
- package/README.md +258 -0
- package/commands/autocompact.md +37 -0
- package/commands/checkpoint.md +85 -0
- package/commands/cleanup.md +99 -0
- package/commands/debug.md +145 -0
- package/commands/delegate.md +56 -0
- package/commands/ideate.md +82 -0
- package/commands/plan.md +150 -0
- package/commands/refactor.md +139 -0
- package/commands/reload.md +37 -0
- package/commands/resume.md +130 -0
- package/commands/review.md +51 -0
- package/commands/sync-schemas.md +74 -0
- package/commands/synthesize.md +122 -0
- package/commands/tdd.md +58 -0
- package/dist/exarchos-cli.js +8828 -0
- package/dist/exarchos-mcp.js +50 -0
- package/hooks/hooks.json +53 -0
- package/package.json +59 -0
- package/rules/coding-standards.md +46 -0
- package/rules/mcp-tool-guidance.md +26 -0
- package/rules/pr-descriptions.md +12 -0
- package/rules/rm-safety.md +9 -0
- package/rules/skill-path-resolution.md +10 -0
- package/rules/tdd.md +41 -0
- package/rules/telemetry-awareness.md +9 -0
- package/scripts/assess-refactor-scope.sh +239 -0
- package/scripts/check-benchmark-regression.sh +229 -0
- package/scripts/check-coderabbit.sh +288 -0
- package/scripts/check-coverage-thresholds.sh +194 -0
- package/scripts/check-polish-scope.sh +245 -0
- package/scripts/check-property-tests.sh +167 -0
- package/scripts/check-tdd-compliance.sh +265 -0
- package/scripts/coderabbit-review-gate.sh +518 -0
- package/scripts/debug-review-gate.sh +201 -0
- package/scripts/extract-fix-tasks.sh +179 -0
- package/scripts/extract-task.sh +67 -0
- package/scripts/generate-traceability.sh +209 -0
- package/scripts/investigation-timer.sh +171 -0
- package/scripts/needs-schema-sync.sh +174 -0
- package/scripts/new-project.sh +103 -0
- package/scripts/post-delegation-check.sh +317 -0
- package/scripts/pre-synthesis-check.sh +440 -0
- package/scripts/reconcile-state.sh +346 -0
- package/scripts/reconstruct-stack.sh +432 -0
- package/scripts/review-diff.sh +63 -0
- package/scripts/review-verdict.sh +169 -0
- package/scripts/security-scan.sh +248 -0
- package/scripts/select-debug-track.sh +186 -0
- package/scripts/setup-worktree.sh +323 -0
- package/scripts/spec-coverage-check.sh +230 -0
- package/scripts/static-analysis-gate.sh +236 -0
- package/scripts/sync-labels.sh +122 -0
- package/scripts/validate-companion.sh +161 -0
- package/scripts/validate-dotnet-standards.sh +267 -0
- package/scripts/validate-installation.sh +101 -0
- package/scripts/validate-plugin.sh +223 -0
- package/scripts/validate-refactor.sh +234 -0
- package/scripts/validate-rm.sh +93 -0
- package/scripts/verify-delegation-saga.sh +240 -0
- package/scripts/verify-doc-links.sh +211 -0
- package/scripts/verify-ideate-artifacts.sh +296 -0
- package/scripts/verify-plan-coverage.sh +228 -0
- package/scripts/verify-review-triage.sh +219 -0
- package/scripts/verify-worktree-baseline.sh +159 -0
- package/scripts/verify-worktree.sh +84 -0
- package/settings.json +47 -0
- package/skills/brainstorming/SKILL.md +127 -0
- package/skills/brainstorming/references/design-template.md +65 -0
- package/skills/cleanup/SKILL.md +147 -0
- package/skills/cleanup/references/merge-verification.md +40 -0
- package/skills/debug/SKILL.md +204 -0
- package/skills/debug/references/hotfix-track.md +134 -0
- package/skills/debug/references/investigation-checklist.md +217 -0
- package/skills/debug/references/rca-template.md +150 -0
- package/skills/debug/references/state-schema.md +294 -0
- package/skills/debug/references/thorough-track.md +194 -0
- package/skills/debug/references/triage-questions.md +155 -0
- package/skills/debug/references/troubleshooting.md +47 -0
- package/skills/delegation/SKILL.md +150 -0
- package/skills/delegation/references/adaptive-orchestration.md +31 -0
- package/skills/delegation/references/agent-teams-saga.md +248 -0
- package/skills/delegation/references/fix-mode.md +74 -0
- package/skills/delegation/references/fixer-prompt.md +162 -0
- package/skills/delegation/references/implementer-prompt.md +322 -0
- package/skills/delegation/references/parallel-strategy.md +124 -0
- package/skills/delegation/references/pbt-patterns.md +172 -0
- package/skills/delegation/references/pr-fixes-mode.md +154 -0
- package/skills/delegation/references/state-management.md +51 -0
- package/skills/delegation/references/testing-patterns.md +129 -0
- package/skills/delegation/references/troubleshooting.md +33 -0
- package/skills/delegation/references/workflow-steps.md +127 -0
- package/skills/delegation/references/worktree-enforcement.md +64 -0
- package/skills/dotnet-standards/SKILL.md +269 -0
- package/skills/dotnet-standards/references/csharp-standards.md +120 -0
- package/skills/dotnet-standards/templates/.editorconfig +366 -0
- package/skills/dotnet-standards/templates/Directory.Build.props +56 -0
- package/skills/dotnet-standards/templates/Directory.Packages.props +69 -0
- package/skills/dotnet-standards/templates/global.json +6 -0
- package/skills/dotnet-standards/templates/nuget.config +9 -0
- package/skills/dotnet-standards/templates/stylecop.json +37 -0
- package/skills/git-worktrees/SKILL.md +255 -0
- package/skills/implementation-planning/SKILL.md +233 -0
- package/skills/implementation-planning/references/plan-document-template.md +42 -0
- package/skills/implementation-planning/references/spec-tracing-guide.md +51 -0
- package/skills/implementation-planning/references/task-template.md +43 -0
- package/skills/implementation-planning/references/testing-strategy-guide.md +88 -0
- package/skills/quality-review/SKILL.md +278 -0
- package/skills/quality-review/references/code-quality-checklist.md +159 -0
- package/skills/quality-review/references/review-report-template.md +65 -0
- package/skills/quality-review/references/security-checklist.md +79 -0
- package/skills/quality-review/references/typescript-standards.md +24 -0
- package/skills/refactor/COMMAND.md +67 -0
- package/skills/refactor/SKILL.md +198 -0
- package/skills/refactor/phases/auto-chain.md +262 -0
- package/skills/refactor/phases/brief.md +176 -0
- package/skills/refactor/phases/explore.md +132 -0
- package/skills/refactor/phases/overhaul-delegate.md +136 -0
- package/skills/refactor/phases/overhaul-plan.md +312 -0
- package/skills/refactor/phases/overhaul-review.md +304 -0
- package/skills/refactor/phases/polish-implement.md +349 -0
- package/skills/refactor/phases/polish-validate.md +218 -0
- package/skills/refactor/phases/update-docs.md +234 -0
- package/skills/refactor/references/brief-template.md +81 -0
- package/skills/refactor/references/doc-update-checklist.md +110 -0
- package/skills/refactor/references/explore-checklist.md +73 -0
- package/skills/refactor/references/overhaul-track.md +215 -0
- package/skills/refactor/references/polish-track.md +170 -0
- package/skills/shared/prompts/context-reading.md +58 -0
- package/skills/shared/prompts/report-format.md +54 -0
- package/skills/shared/prompts/tdd-requirements.md +39 -0
- package/skills/shepherd/SKILL.md +264 -0
- package/skills/shepherd/references/assess-checklist.md +124 -0
- package/skills/shepherd/references/fix-strategies.md +191 -0
- package/skills/spec-review/SKILL.md +229 -0
- package/skills/spec-review/references/review-checklist.md +60 -0
- package/skills/sync-schemas/SKILL.md +114 -0
- package/skills/sync-schemas/references/configuration.md +73 -0
- package/skills/synthesis/SKILL.md +129 -0
- package/skills/synthesis/references/pr-descriptions.md +87 -0
- package/skills/synthesis/references/synthesis-steps.md +109 -0
- package/skills/synthesis/references/troubleshooting.md +115 -0
- package/skills/validate-all-skills.sh +57 -0
- package/skills/validate-frontmatter.sh +237 -0
- package/skills/workflow-state/SKILL.md +210 -0
- package/skills/workflow-state/references/mcp-tool-reference.md +111 -0
- package/skills/workflow-state/references/phase-transitions.md +141 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Security Scan
|
|
3
|
+
# Scans code changes for common security anti-patterns in the quality-review workflow.
|
|
4
|
+
#
|
|
5
|
+
# Usage: security-scan.sh --diff-file <path>
|
|
6
|
+
# security-scan.sh --repo-root <path> --base-branch <branch>
|
|
7
|
+
#
|
|
8
|
+
# Exit codes:
|
|
9
|
+
# 0 = no findings
|
|
10
|
+
# 1 = findings detected
|
|
11
|
+
# 2 = usage error
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
# Colors
|
|
16
|
+
RED='\033[0;31m'
|
|
17
|
+
GREEN='\033[0;32m'
|
|
18
|
+
YELLOW='\033[1;33m'
|
|
19
|
+
NC='\033[0m'
|
|
20
|
+
|
|
21
|
+
# ============================================================
|
|
22
|
+
# ARGUMENT PARSING
|
|
23
|
+
# ============================================================
|
|
24
|
+
|
|
25
|
+
DIFF_FILE=""
|
|
26
|
+
REPO_ROOT=""
|
|
27
|
+
BASE_BRANCH=""
|
|
28
|
+
|
|
29
|
+
usage() {
|
|
30
|
+
cat << 'USAGE'
|
|
31
|
+
Usage: security-scan.sh --diff-file <path>
|
|
32
|
+
security-scan.sh --repo-root <path> --base-branch <branch>
|
|
33
|
+
|
|
34
|
+
Scan code changes for common security anti-patterns.
|
|
35
|
+
|
|
36
|
+
Options:
|
|
37
|
+
--diff-file <path> Path to a unified diff file
|
|
38
|
+
--repo-root <path> Repository root (used with --base-branch)
|
|
39
|
+
--base-branch <branch> Base branch to diff against (used with --repo-root)
|
|
40
|
+
--help Show this help message
|
|
41
|
+
|
|
42
|
+
Detected patterns:
|
|
43
|
+
- Hardcoded secrets (API keys, passwords, tokens)
|
|
44
|
+
- eval() usage
|
|
45
|
+
- SQL string concatenation
|
|
46
|
+
- innerHTML assignment
|
|
47
|
+
- dangerouslySetInnerHTML
|
|
48
|
+
- child_process.exec with variable input
|
|
49
|
+
|
|
50
|
+
Exit codes:
|
|
51
|
+
0 No security findings
|
|
52
|
+
1 Security findings detected
|
|
53
|
+
2 Usage error
|
|
54
|
+
USAGE
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
while [[ $# -gt 0 ]]; do
|
|
58
|
+
case "$1" in
|
|
59
|
+
--diff-file)
|
|
60
|
+
if [[ -z "${2:-}" ]]; then
|
|
61
|
+
echo "Error: --diff-file requires a path argument" >&2
|
|
62
|
+
exit 2
|
|
63
|
+
fi
|
|
64
|
+
DIFF_FILE="$2"
|
|
65
|
+
shift 2
|
|
66
|
+
;;
|
|
67
|
+
--repo-root)
|
|
68
|
+
if [[ -z "${2:-}" ]]; then
|
|
69
|
+
echo "Error: --repo-root requires a path argument" >&2
|
|
70
|
+
exit 2
|
|
71
|
+
fi
|
|
72
|
+
REPO_ROOT="$2"
|
|
73
|
+
shift 2
|
|
74
|
+
;;
|
|
75
|
+
--base-branch)
|
|
76
|
+
if [[ -z "${2:-}" ]]; then
|
|
77
|
+
echo "Error: --base-branch requires a branch argument" >&2
|
|
78
|
+
exit 2
|
|
79
|
+
fi
|
|
80
|
+
BASE_BRANCH="$2"
|
|
81
|
+
shift 2
|
|
82
|
+
;;
|
|
83
|
+
--help)
|
|
84
|
+
usage
|
|
85
|
+
exit 0
|
|
86
|
+
;;
|
|
87
|
+
*)
|
|
88
|
+
echo "Error: Unknown argument '$1'" >&2
|
|
89
|
+
usage >&2
|
|
90
|
+
exit 2
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
93
|
+
done
|
|
94
|
+
|
|
95
|
+
# Validate inputs
|
|
96
|
+
if [[ -z "$DIFF_FILE" && ( -z "$REPO_ROOT" || -z "$BASE_BRANCH" ) ]]; then
|
|
97
|
+
echo "Error: Must provide --diff-file or both --repo-root and --base-branch" >&2
|
|
98
|
+
usage >&2
|
|
99
|
+
exit 2
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# ============================================================
|
|
103
|
+
# DIFF RESOLUTION
|
|
104
|
+
# ============================================================
|
|
105
|
+
|
|
106
|
+
DIFF_CONTENT=""
|
|
107
|
+
|
|
108
|
+
if [[ -n "$DIFF_FILE" ]]; then
|
|
109
|
+
if [[ ! -f "$DIFF_FILE" ]]; then
|
|
110
|
+
echo "Error: Diff file not found: $DIFF_FILE" >&2
|
|
111
|
+
exit 2
|
|
112
|
+
fi
|
|
113
|
+
DIFF_CONTENT="$(cat "$DIFF_FILE")"
|
|
114
|
+
else
|
|
115
|
+
DIFF_CONTENT="$(cd "$REPO_ROOT" && git diff "$BASE_BRANCH"...HEAD 2>/dev/null)" || {
|
|
116
|
+
echo "Error: Failed to generate diff from $BASE_BRANCH" >&2
|
|
117
|
+
exit 2
|
|
118
|
+
}
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# ============================================================
|
|
122
|
+
# SECURITY PATTERN SCANNING
|
|
123
|
+
# ============================================================
|
|
124
|
+
|
|
125
|
+
FINDINGS=()
|
|
126
|
+
FINDING_COUNT=0
|
|
127
|
+
CURRENT_FILE=""
|
|
128
|
+
|
|
129
|
+
# Extract only added lines from the diff (lines starting with +, excluding +++ headers)
|
|
130
|
+
# Track file names from diff headers
|
|
131
|
+
scan_diff() {
|
|
132
|
+
local diff_line_num=0
|
|
133
|
+
|
|
134
|
+
while IFS= read -r line; do
|
|
135
|
+
# Track current file from diff headers
|
|
136
|
+
if [[ "$line" =~ ^diff\ --git\ a/(.+)\ b/ ]]; then
|
|
137
|
+
CURRENT_FILE="${BASH_REMATCH[1]}"
|
|
138
|
+
diff_line_num=0
|
|
139
|
+
continue
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Track line numbers from hunk headers
|
|
143
|
+
if [[ "$line" =~ ^@@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@ ]]; then
|
|
144
|
+
diff_line_num="${BASH_REMATCH[2]}"
|
|
145
|
+
continue
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
# Skip non-addition lines
|
|
149
|
+
if [[ ! "$line" =~ ^\+ ]]; then
|
|
150
|
+
if [[ "$line" =~ ^[^-] ]]; then
|
|
151
|
+
diff_line_num=$((diff_line_num + 1))
|
|
152
|
+
fi
|
|
153
|
+
continue
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# Skip +++ header lines
|
|
157
|
+
if [[ "$line" =~ ^\+\+\+ ]]; then
|
|
158
|
+
continue
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
local added_line="${line:1}" # Strip leading +
|
|
162
|
+
|
|
163
|
+
# Pattern 1: Hardcoded secrets (API keys, passwords, tokens in string literals)
|
|
164
|
+
if echo "$added_line" | grep -qEi '(API_KEY|SECRET|PASSWORD|TOKEN|PRIVATE_KEY)\s*=\s*["\x27]'; then
|
|
165
|
+
add_finding "$CURRENT_FILE" "$diff_line_num" "Hardcoded secret/credential" "HIGH" "$added_line"
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# Pattern 2: eval() usage
|
|
169
|
+
if echo "$added_line" | grep -qE '\beval\s*\('; then
|
|
170
|
+
add_finding "$CURRENT_FILE" "$diff_line_num" "eval() usage" "HIGH" "$added_line"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Pattern 3: SQL string concatenation
|
|
174
|
+
if echo "$added_line" | grep -qEi '"SELECT\b.*"\s*\+|`SELECT\b.*\$\{'; then
|
|
175
|
+
add_finding "$CURRENT_FILE" "$diff_line_num" "SQL string concatenation" "HIGH" "$added_line"
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Pattern 4: innerHTML assignment
|
|
179
|
+
if echo "$added_line" | grep -qE '\.innerHTML\s*='; then
|
|
180
|
+
add_finding "$CURRENT_FILE" "$diff_line_num" "innerHTML assignment" "MEDIUM" "$added_line"
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Pattern 5: dangerouslySetInnerHTML
|
|
184
|
+
if echo "$added_line" | grep -qE 'dangerouslySetInnerHTML'; then
|
|
185
|
+
add_finding "$CURRENT_FILE" "$diff_line_num" "dangerouslySetInnerHTML usage" "MEDIUM" "$added_line"
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
# Pattern 6: child_process.exec with variable
|
|
189
|
+
if echo "$added_line" | grep -qE 'child_process.*exec\s*\(|exec\s*\(\s*[^"'\''`]'; then
|
|
190
|
+
add_finding "$CURRENT_FILE" "$diff_line_num" "child_process.exec with variable input" "HIGH" "$added_line"
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
diff_line_num=$((diff_line_num + 1))
|
|
194
|
+
done <<< "$DIFF_CONTENT"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
add_finding() {
|
|
198
|
+
local file="$1"
|
|
199
|
+
local line="$2"
|
|
200
|
+
local pattern="$3"
|
|
201
|
+
local severity="$4"
|
|
202
|
+
local context="$5"
|
|
203
|
+
|
|
204
|
+
# Trim context to reasonable length
|
|
205
|
+
if [[ ${#context} -gt 120 ]]; then
|
|
206
|
+
context="${context:0:117}..."
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
FINDINGS+=("- **${severity}** \`${file}:${line}\` — ${pattern}: \`${context}\`")
|
|
210
|
+
FINDING_COUNT=$((FINDING_COUNT + 1))
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# Run the scan
|
|
214
|
+
scan_diff
|
|
215
|
+
|
|
216
|
+
# ============================================================
|
|
217
|
+
# STRUCTURED OUTPUT
|
|
218
|
+
# ============================================================
|
|
219
|
+
|
|
220
|
+
echo "## Security Scan Report"
|
|
221
|
+
echo ""
|
|
222
|
+
|
|
223
|
+
if [[ -n "$DIFF_FILE" ]]; then
|
|
224
|
+
echo "**Source:** \`$DIFF_FILE\`"
|
|
225
|
+
else
|
|
226
|
+
echo "**Source:** \`$REPO_ROOT\` (diff against \`$BASE_BRANCH\`)"
|
|
227
|
+
fi
|
|
228
|
+
echo ""
|
|
229
|
+
|
|
230
|
+
if [[ $FINDING_COUNT -eq 0 ]]; then
|
|
231
|
+
echo "No security patterns detected."
|
|
232
|
+
echo ""
|
|
233
|
+
echo "---"
|
|
234
|
+
echo ""
|
|
235
|
+
echo "**Result: CLEAN** (0 findings)"
|
|
236
|
+
exit 0
|
|
237
|
+
else
|
|
238
|
+
echo "**Findings ($FINDING_COUNT):**"
|
|
239
|
+
echo ""
|
|
240
|
+
for finding in "${FINDINGS[@]}"; do
|
|
241
|
+
echo "$finding"
|
|
242
|
+
done
|
|
243
|
+
echo ""
|
|
244
|
+
echo "---"
|
|
245
|
+
echo ""
|
|
246
|
+
echo "**Result: FINDINGS** ($FINDING_COUNT security patterns detected)"
|
|
247
|
+
exit 1
|
|
248
|
+
fi
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Select Debug Track
|
|
3
|
+
# Deterministic track selection from urgency and root-cause knowledge.
|
|
4
|
+
# Replaces prose-based decision-making with a clear decision tree.
|
|
5
|
+
#
|
|
6
|
+
# Usage: select-debug-track.sh --urgency <critical|high|medium|low> --root-cause-known <yes|no>
|
|
7
|
+
# select-debug-track.sh --state-file <path>
|
|
8
|
+
#
|
|
9
|
+
# Exit codes:
|
|
10
|
+
# 0 = hotfix track selected
|
|
11
|
+
# 1 = thorough track selected
|
|
12
|
+
# 2 = usage error (missing required args, invalid input)
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
# ============================================================
|
|
17
|
+
# ARGUMENT PARSING
|
|
18
|
+
# ============================================================
|
|
19
|
+
|
|
20
|
+
URGENCY=""
|
|
21
|
+
ROOT_CAUSE_KNOWN=""
|
|
22
|
+
STATE_FILE=""
|
|
23
|
+
|
|
24
|
+
usage() {
|
|
25
|
+
cat << 'USAGE'
|
|
26
|
+
Usage: select-debug-track.sh --urgency <critical|high|medium|low> --root-cause-known <yes|no>
|
|
27
|
+
select-debug-track.sh --state-file <path>
|
|
28
|
+
|
|
29
|
+
Required (one of):
|
|
30
|
+
--urgency <level> Urgency level: critical, high, medium, low
|
|
31
|
+
--root-cause-known <yes|no> Whether the root cause is known
|
|
32
|
+
--state-file <path> Path to workflow state JSON (reads urgency.level and investigation.rootCauseKnown)
|
|
33
|
+
|
|
34
|
+
Optional:
|
|
35
|
+
--help Show this help message
|
|
36
|
+
|
|
37
|
+
Exit codes:
|
|
38
|
+
0 Hotfix track selected
|
|
39
|
+
1 Thorough track selected
|
|
40
|
+
2 Usage error (missing args, invalid input)
|
|
41
|
+
USAGE
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
while [[ $# -gt 0 ]]; do
|
|
45
|
+
case "$1" in
|
|
46
|
+
--urgency)
|
|
47
|
+
if [[ -z "${2:-}" ]]; then
|
|
48
|
+
echo "Error: --urgency requires a level argument" >&2
|
|
49
|
+
exit 2
|
|
50
|
+
fi
|
|
51
|
+
URGENCY="$2"
|
|
52
|
+
shift 2
|
|
53
|
+
;;
|
|
54
|
+
--root-cause-known)
|
|
55
|
+
if [[ -z "${2:-}" ]]; then
|
|
56
|
+
echo "Error: --root-cause-known requires yes or no" >&2
|
|
57
|
+
exit 2
|
|
58
|
+
fi
|
|
59
|
+
ROOT_CAUSE_KNOWN="$2"
|
|
60
|
+
shift 2
|
|
61
|
+
;;
|
|
62
|
+
--state-file)
|
|
63
|
+
if [[ -z "${2:-}" ]]; then
|
|
64
|
+
echo "Error: --state-file requires a path argument" >&2
|
|
65
|
+
exit 2
|
|
66
|
+
fi
|
|
67
|
+
STATE_FILE="$2"
|
|
68
|
+
shift 2
|
|
69
|
+
;;
|
|
70
|
+
--help)
|
|
71
|
+
usage
|
|
72
|
+
exit 0
|
|
73
|
+
;;
|
|
74
|
+
*)
|
|
75
|
+
echo "Error: Unknown argument '$1'" >&2
|
|
76
|
+
usage >&2
|
|
77
|
+
exit 2
|
|
78
|
+
;;
|
|
79
|
+
esac
|
|
80
|
+
done
|
|
81
|
+
|
|
82
|
+
# ============================================================
|
|
83
|
+
# RESOLVE FROM STATE FILE
|
|
84
|
+
# ============================================================
|
|
85
|
+
|
|
86
|
+
if [[ -n "$STATE_FILE" && -z "$URGENCY" ]]; then
|
|
87
|
+
if [[ ! -f "$STATE_FILE" ]]; then
|
|
88
|
+
echo "Error: State file not found: $STATE_FILE" >&2
|
|
89
|
+
exit 2
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
if ! command -v jq &>/dev/null; then
|
|
93
|
+
echo "Error: jq is required but not installed" >&2
|
|
94
|
+
exit 2
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
URGENCY="$(jq -r '.urgency.level // empty' "$STATE_FILE")"
|
|
98
|
+
ROOT_CAUSE_KNOWN="$(jq -r '.investigation.rootCauseKnown // empty' "$STATE_FILE")"
|
|
99
|
+
|
|
100
|
+
if [[ -z "$URGENCY" ]]; then
|
|
101
|
+
echo "Error: No urgency.level found in state file" >&2
|
|
102
|
+
exit 2
|
|
103
|
+
fi
|
|
104
|
+
if [[ -z "$ROOT_CAUSE_KNOWN" ]]; then
|
|
105
|
+
echo "Error: No investigation.rootCauseKnown found in state file" >&2
|
|
106
|
+
exit 2
|
|
107
|
+
fi
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# ============================================================
|
|
111
|
+
# VALIDATE INPUTS
|
|
112
|
+
# ============================================================
|
|
113
|
+
|
|
114
|
+
if [[ -z "$URGENCY" || -z "$ROOT_CAUSE_KNOWN" ]]; then
|
|
115
|
+
echo "Error: Both --urgency and --root-cause-known are required (or use --state-file)" >&2
|
|
116
|
+
usage >&2
|
|
117
|
+
exit 2
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
case "$URGENCY" in
|
|
121
|
+
critical|high|medium|low) ;;
|
|
122
|
+
*)
|
|
123
|
+
echo "Error: Invalid urgency level '$URGENCY' (expected: critical, high, medium, low)" >&2
|
|
124
|
+
exit 2
|
|
125
|
+
;;
|
|
126
|
+
esac
|
|
127
|
+
|
|
128
|
+
case "$ROOT_CAUSE_KNOWN" in
|
|
129
|
+
yes|no) ;;
|
|
130
|
+
*)
|
|
131
|
+
echo "Error: Invalid root-cause-known value '$ROOT_CAUSE_KNOWN' (expected: yes, no)" >&2
|
|
132
|
+
exit 2
|
|
133
|
+
;;
|
|
134
|
+
esac
|
|
135
|
+
|
|
136
|
+
# ============================================================
|
|
137
|
+
# DECISION TREE
|
|
138
|
+
# ============================================================
|
|
139
|
+
|
|
140
|
+
SELECTED_TRACK=""
|
|
141
|
+
REASONING=""
|
|
142
|
+
|
|
143
|
+
case "$URGENCY" in
|
|
144
|
+
critical)
|
|
145
|
+
if [[ "$ROOT_CAUSE_KNOWN" == "yes" ]]; then
|
|
146
|
+
SELECTED_TRACK="HOTFIX"
|
|
147
|
+
REASONING="Critical urgency with known root cause — hotfix is appropriate"
|
|
148
|
+
else
|
|
149
|
+
SELECTED_TRACK="THOROUGH"
|
|
150
|
+
REASONING="Critical urgency but unknown root cause — can't fix what you don't understand"
|
|
151
|
+
fi
|
|
152
|
+
;;
|
|
153
|
+
high)
|
|
154
|
+
if [[ "$ROOT_CAUSE_KNOWN" == "yes" ]]; then
|
|
155
|
+
SELECTED_TRACK="HOTFIX"
|
|
156
|
+
REASONING="High urgency with known root cause — hotfix is appropriate"
|
|
157
|
+
else
|
|
158
|
+
SELECTED_TRACK="THOROUGH"
|
|
159
|
+
REASONING="High urgency but unknown root cause — thorough investigation needed"
|
|
160
|
+
fi
|
|
161
|
+
;;
|
|
162
|
+
medium)
|
|
163
|
+
SELECTED_TRACK="THOROUGH"
|
|
164
|
+
REASONING="Medium urgency — thorough track always applies for non-critical issues"
|
|
165
|
+
;;
|
|
166
|
+
low)
|
|
167
|
+
SELECTED_TRACK="THOROUGH"
|
|
168
|
+
REASONING="Low urgency — thorough track always applies for non-critical issues"
|
|
169
|
+
;;
|
|
170
|
+
esac
|
|
171
|
+
|
|
172
|
+
# ============================================================
|
|
173
|
+
# STRUCTURED OUTPUT
|
|
174
|
+
# ============================================================
|
|
175
|
+
|
|
176
|
+
echo "## Debug Track Selection"
|
|
177
|
+
echo "- **Urgency:** $URGENCY"
|
|
178
|
+
echo "- **Root cause known:** $ROOT_CAUSE_KNOWN"
|
|
179
|
+
echo "- **Selected track:** $SELECTED_TRACK"
|
|
180
|
+
echo "- **Reasoning:** $REASONING"
|
|
181
|
+
|
|
182
|
+
if [[ "$SELECTED_TRACK" == "HOTFIX" ]]; then
|
|
183
|
+
exit 0
|
|
184
|
+
else
|
|
185
|
+
exit 1
|
|
186
|
+
fi
|