@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.
Files changed (153) hide show
  1. package/.claude-plugin/marketplace.json +22 -0
  2. package/.claude-plugin/plugin.json +17 -0
  3. package/.mcp.json +17 -0
  4. package/AGENTS.md +59 -0
  5. package/CLAUDE.md.template +62 -0
  6. package/LICENSE +202 -0
  7. package/README.md +258 -0
  8. package/commands/autocompact.md +37 -0
  9. package/commands/checkpoint.md +85 -0
  10. package/commands/cleanup.md +99 -0
  11. package/commands/debug.md +145 -0
  12. package/commands/delegate.md +56 -0
  13. package/commands/ideate.md +82 -0
  14. package/commands/plan.md +150 -0
  15. package/commands/refactor.md +139 -0
  16. package/commands/reload.md +37 -0
  17. package/commands/resume.md +130 -0
  18. package/commands/review.md +51 -0
  19. package/commands/sync-schemas.md +74 -0
  20. package/commands/synthesize.md +122 -0
  21. package/commands/tdd.md +58 -0
  22. package/dist/exarchos-cli.js +8828 -0
  23. package/dist/exarchos-mcp.js +50 -0
  24. package/hooks/hooks.json +53 -0
  25. package/package.json +59 -0
  26. package/rules/coding-standards.md +46 -0
  27. package/rules/mcp-tool-guidance.md +26 -0
  28. package/rules/pr-descriptions.md +12 -0
  29. package/rules/rm-safety.md +9 -0
  30. package/rules/skill-path-resolution.md +10 -0
  31. package/rules/tdd.md +41 -0
  32. package/rules/telemetry-awareness.md +9 -0
  33. package/scripts/assess-refactor-scope.sh +239 -0
  34. package/scripts/check-benchmark-regression.sh +229 -0
  35. package/scripts/check-coderabbit.sh +288 -0
  36. package/scripts/check-coverage-thresholds.sh +194 -0
  37. package/scripts/check-polish-scope.sh +245 -0
  38. package/scripts/check-property-tests.sh +167 -0
  39. package/scripts/check-tdd-compliance.sh +265 -0
  40. package/scripts/coderabbit-review-gate.sh +518 -0
  41. package/scripts/debug-review-gate.sh +201 -0
  42. package/scripts/extract-fix-tasks.sh +179 -0
  43. package/scripts/extract-task.sh +67 -0
  44. package/scripts/generate-traceability.sh +209 -0
  45. package/scripts/investigation-timer.sh +171 -0
  46. package/scripts/needs-schema-sync.sh +174 -0
  47. package/scripts/new-project.sh +103 -0
  48. package/scripts/post-delegation-check.sh +317 -0
  49. package/scripts/pre-synthesis-check.sh +440 -0
  50. package/scripts/reconcile-state.sh +346 -0
  51. package/scripts/reconstruct-stack.sh +432 -0
  52. package/scripts/review-diff.sh +63 -0
  53. package/scripts/review-verdict.sh +169 -0
  54. package/scripts/security-scan.sh +248 -0
  55. package/scripts/select-debug-track.sh +186 -0
  56. package/scripts/setup-worktree.sh +323 -0
  57. package/scripts/spec-coverage-check.sh +230 -0
  58. package/scripts/static-analysis-gate.sh +236 -0
  59. package/scripts/sync-labels.sh +122 -0
  60. package/scripts/validate-companion.sh +161 -0
  61. package/scripts/validate-dotnet-standards.sh +267 -0
  62. package/scripts/validate-installation.sh +101 -0
  63. package/scripts/validate-plugin.sh +223 -0
  64. package/scripts/validate-refactor.sh +234 -0
  65. package/scripts/validate-rm.sh +93 -0
  66. package/scripts/verify-delegation-saga.sh +240 -0
  67. package/scripts/verify-doc-links.sh +211 -0
  68. package/scripts/verify-ideate-artifacts.sh +296 -0
  69. package/scripts/verify-plan-coverage.sh +228 -0
  70. package/scripts/verify-review-triage.sh +219 -0
  71. package/scripts/verify-worktree-baseline.sh +159 -0
  72. package/scripts/verify-worktree.sh +84 -0
  73. package/settings.json +47 -0
  74. package/skills/brainstorming/SKILL.md +127 -0
  75. package/skills/brainstorming/references/design-template.md +65 -0
  76. package/skills/cleanup/SKILL.md +147 -0
  77. package/skills/cleanup/references/merge-verification.md +40 -0
  78. package/skills/debug/SKILL.md +204 -0
  79. package/skills/debug/references/hotfix-track.md +134 -0
  80. package/skills/debug/references/investigation-checklist.md +217 -0
  81. package/skills/debug/references/rca-template.md +150 -0
  82. package/skills/debug/references/state-schema.md +294 -0
  83. package/skills/debug/references/thorough-track.md +194 -0
  84. package/skills/debug/references/triage-questions.md +155 -0
  85. package/skills/debug/references/troubleshooting.md +47 -0
  86. package/skills/delegation/SKILL.md +150 -0
  87. package/skills/delegation/references/adaptive-orchestration.md +31 -0
  88. package/skills/delegation/references/agent-teams-saga.md +248 -0
  89. package/skills/delegation/references/fix-mode.md +74 -0
  90. package/skills/delegation/references/fixer-prompt.md +162 -0
  91. package/skills/delegation/references/implementer-prompt.md +322 -0
  92. package/skills/delegation/references/parallel-strategy.md +124 -0
  93. package/skills/delegation/references/pbt-patterns.md +172 -0
  94. package/skills/delegation/references/pr-fixes-mode.md +154 -0
  95. package/skills/delegation/references/state-management.md +51 -0
  96. package/skills/delegation/references/testing-patterns.md +129 -0
  97. package/skills/delegation/references/troubleshooting.md +33 -0
  98. package/skills/delegation/references/workflow-steps.md +127 -0
  99. package/skills/delegation/references/worktree-enforcement.md +64 -0
  100. package/skills/dotnet-standards/SKILL.md +269 -0
  101. package/skills/dotnet-standards/references/csharp-standards.md +120 -0
  102. package/skills/dotnet-standards/templates/.editorconfig +366 -0
  103. package/skills/dotnet-standards/templates/Directory.Build.props +56 -0
  104. package/skills/dotnet-standards/templates/Directory.Packages.props +69 -0
  105. package/skills/dotnet-standards/templates/global.json +6 -0
  106. package/skills/dotnet-standards/templates/nuget.config +9 -0
  107. package/skills/dotnet-standards/templates/stylecop.json +37 -0
  108. package/skills/git-worktrees/SKILL.md +255 -0
  109. package/skills/implementation-planning/SKILL.md +233 -0
  110. package/skills/implementation-planning/references/plan-document-template.md +42 -0
  111. package/skills/implementation-planning/references/spec-tracing-guide.md +51 -0
  112. package/skills/implementation-planning/references/task-template.md +43 -0
  113. package/skills/implementation-planning/references/testing-strategy-guide.md +88 -0
  114. package/skills/quality-review/SKILL.md +278 -0
  115. package/skills/quality-review/references/code-quality-checklist.md +159 -0
  116. package/skills/quality-review/references/review-report-template.md +65 -0
  117. package/skills/quality-review/references/security-checklist.md +79 -0
  118. package/skills/quality-review/references/typescript-standards.md +24 -0
  119. package/skills/refactor/COMMAND.md +67 -0
  120. package/skills/refactor/SKILL.md +198 -0
  121. package/skills/refactor/phases/auto-chain.md +262 -0
  122. package/skills/refactor/phases/brief.md +176 -0
  123. package/skills/refactor/phases/explore.md +132 -0
  124. package/skills/refactor/phases/overhaul-delegate.md +136 -0
  125. package/skills/refactor/phases/overhaul-plan.md +312 -0
  126. package/skills/refactor/phases/overhaul-review.md +304 -0
  127. package/skills/refactor/phases/polish-implement.md +349 -0
  128. package/skills/refactor/phases/polish-validate.md +218 -0
  129. package/skills/refactor/phases/update-docs.md +234 -0
  130. package/skills/refactor/references/brief-template.md +81 -0
  131. package/skills/refactor/references/doc-update-checklist.md +110 -0
  132. package/skills/refactor/references/explore-checklist.md +73 -0
  133. package/skills/refactor/references/overhaul-track.md +215 -0
  134. package/skills/refactor/references/polish-track.md +170 -0
  135. package/skills/shared/prompts/context-reading.md +58 -0
  136. package/skills/shared/prompts/report-format.md +54 -0
  137. package/skills/shared/prompts/tdd-requirements.md +39 -0
  138. package/skills/shepherd/SKILL.md +264 -0
  139. package/skills/shepherd/references/assess-checklist.md +124 -0
  140. package/skills/shepherd/references/fix-strategies.md +191 -0
  141. package/skills/spec-review/SKILL.md +229 -0
  142. package/skills/spec-review/references/review-checklist.md +60 -0
  143. package/skills/sync-schemas/SKILL.md +114 -0
  144. package/skills/sync-schemas/references/configuration.md +73 -0
  145. package/skills/synthesis/SKILL.md +129 -0
  146. package/skills/synthesis/references/pr-descriptions.md +87 -0
  147. package/skills/synthesis/references/synthesis-steps.md +109 -0
  148. package/skills/synthesis/references/troubleshooting.md +115 -0
  149. package/skills/validate-all-skills.sh +57 -0
  150. package/skills/validate-frontmatter.sh +237 -0
  151. package/skills/workflow-state/SKILL.md +210 -0
  152. package/skills/workflow-state/references/mcp-tool-reference.md +111 -0
  153. package/skills/workflow-state/references/phase-transitions.md +141 -0
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env bash
2
+ # Verify Doc Links
3
+ # Checks that internal markdown links resolve to existing files.
4
+ # Replaces manual documentation link verification with deterministic validation.
5
+ #
6
+ # Usage: verify-doc-links.sh --doc-file <path> | --docs-dir <path>
7
+ #
8
+ # Exit codes:
9
+ # 0 = all links valid
10
+ # 1 = broken links 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
+ DOC_FILE=""
28
+ DOCS_DIR=""
29
+
30
+ usage() {
31
+ cat << 'USAGE'
32
+ Usage: verify-doc-links.sh --doc-file <path> | --docs-dir <path>
33
+
34
+ Required (one of):
35
+ --doc-file <path> Single markdown file to check
36
+ --docs-dir <path> Directory to check recursively (all .md files)
37
+
38
+ Optional:
39
+ --help Show this help message
40
+
41
+ Exit codes:
42
+ 0 All internal links resolve to existing files
43
+ 1 One or more broken links found
44
+ 2 Usage error (missing required args)
45
+
46
+ Notes:
47
+ - External URLs (http://, https://) are skipped
48
+ - Anchor-only links (#section) are skipped
49
+ - Links with anchors (file.md#section) check the file part only
50
+ USAGE
51
+ }
52
+
53
+ while [[ $# -gt 0 ]]; do
54
+ case "$1" in
55
+ --doc-file)
56
+ if [[ -z "${2:-}" ]]; then
57
+ echo "Error: --doc-file requires a path argument" >&2
58
+ exit 2
59
+ fi
60
+ DOC_FILE="$2"
61
+ shift 2
62
+ ;;
63
+ --docs-dir)
64
+ if [[ -z "${2:-}" ]]; then
65
+ echo "Error: --docs-dir requires a path argument" >&2
66
+ exit 2
67
+ fi
68
+ DOCS_DIR="$2"
69
+ shift 2
70
+ ;;
71
+ --help)
72
+ usage
73
+ exit 0
74
+ ;;
75
+ *)
76
+ echo "Error: Unknown argument '$1'" >&2
77
+ usage >&2
78
+ exit 2
79
+ ;;
80
+ esac
81
+ done
82
+
83
+ if [[ -z "$DOC_FILE" && -z "$DOCS_DIR" ]]; then
84
+ echo "Error: --doc-file or --docs-dir is required" >&2
85
+ usage >&2
86
+ exit 2
87
+ fi
88
+
89
+ # ============================================================
90
+ # LINK CHECKING
91
+ # ============================================================
92
+
93
+ BROKEN_COUNT=0
94
+ CHECKED_COUNT=0
95
+ SKIPPED_COUNT=0
96
+ BROKEN_LINKS=()
97
+
98
+ check_file() {
99
+ local file="$1"
100
+ local file_dir
101
+ file_dir="$(dirname "$file")"
102
+ local line_num=0
103
+
104
+ while IFS= read -r line; do
105
+ line_num=$((line_num + 1))
106
+
107
+ # Extract markdown links: [text](target)
108
+ # Use grep to find all link targets on this line
109
+ while IFS= read -r target; do
110
+ [[ -z "$target" ]] && continue
111
+
112
+ # Skip external URLs
113
+ if [[ "$target" == http://* || "$target" == https://* ]]; then
114
+ SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
115
+ continue
116
+ fi
117
+
118
+ # Skip anchor-only links
119
+ if [[ "$target" == \#* ]]; then
120
+ SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
121
+ continue
122
+ fi
123
+
124
+ # Strip anchor from target (file.md#section -> file.md)
125
+ local file_target="${target%%#*}"
126
+
127
+ # Skip if empty after stripping anchor
128
+ if [[ -z "$file_target" ]]; then
129
+ SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
130
+ continue
131
+ fi
132
+
133
+ CHECKED_COUNT=$((CHECKED_COUNT + 1))
134
+
135
+ # Resolve relative to the file's directory (or use as-is if absolute)
136
+ local resolved_path
137
+ if [[ "$file_target" == /* ]]; then
138
+ resolved_path="$file_target"
139
+ else
140
+ resolved_path="$file_dir/$file_target"
141
+ fi
142
+
143
+ if [[ ! -e "$resolved_path" ]]; then
144
+ BROKEN_COUNT=$((BROKEN_COUNT + 1))
145
+ BROKEN_LINKS+=("$file:$line_num -> $target (resolved: $resolved_path)")
146
+ fi
147
+ done < <(echo "$line" | grep -oE '\[[^]]*\]\([^)]+\)' | sed -E 's/\[[^]]*\]\(([^)]+)\)/\1/g' || true)
148
+ done < "$file"
149
+ }
150
+
151
+ # ============================================================
152
+ # COLLECT FILES TO CHECK
153
+ # ============================================================
154
+
155
+ FILES_TO_CHECK=()
156
+
157
+ if [[ -n "$DOC_FILE" ]]; then
158
+ if [[ ! -f "$DOC_FILE" ]]; then
159
+ echo "Error: File not found: $DOC_FILE" >&2
160
+ exit 2
161
+ fi
162
+ FILES_TO_CHECK+=("$DOC_FILE")
163
+ elif [[ -n "$DOCS_DIR" ]]; then
164
+ if [[ ! -d "$DOCS_DIR" ]]; then
165
+ echo "Error: Directory not found: $DOCS_DIR" >&2
166
+ exit 2
167
+ fi
168
+ while IFS= read -r f; do
169
+ FILES_TO_CHECK+=("$f")
170
+ done < <(find "$DOCS_DIR" -name "*.md" -type f 2>/dev/null | sort)
171
+ fi
172
+
173
+ # ============================================================
174
+ # EXECUTE CHECKS
175
+ # ============================================================
176
+
177
+ for f in "${FILES_TO_CHECK[@]}"; do
178
+ check_file "$f"
179
+ done
180
+
181
+ # ============================================================
182
+ # STRUCTURED OUTPUT
183
+ # ============================================================
184
+
185
+ echo "## Documentation Link Verification Report"
186
+ echo ""
187
+ echo "**Files checked:** ${#FILES_TO_CHECK[@]}"
188
+ echo "**Links checked:** $CHECKED_COUNT"
189
+ echo "**Links skipped:** $SKIPPED_COUNT (external URLs, anchors)"
190
+ echo "**Broken links:** $BROKEN_COUNT"
191
+ echo ""
192
+
193
+ if [[ $BROKEN_COUNT -gt 0 ]]; then
194
+ echo "### Broken Links"
195
+ echo ""
196
+ for link in "${BROKEN_LINKS[@]}"; do
197
+ echo "- \`$link\`"
198
+ done
199
+ echo ""
200
+ fi
201
+
202
+ echo "---"
203
+ echo ""
204
+
205
+ if [[ $BROKEN_COUNT -eq 0 ]]; then
206
+ echo "**Result: PASS** — All internal links resolve to existing files"
207
+ exit 0
208
+ else
209
+ echo "**Result: FAIL** — $BROKEN_COUNT broken link(s) found"
210
+ exit 1
211
+ fi
@@ -0,0 +1,296 @@
1
+ #!/usr/bin/env bash
2
+ # Verify Ideate Artifacts
3
+ # Checks brainstorming/ideation completion by validating design document existence,
4
+ # required sections, option evaluation, and state file consistency.
5
+ #
6
+ # Usage: verify-ideate-artifacts.sh --state-file <path> [--docs-dir <path>] [--design-file <path>]
7
+ #
8
+ # Exit codes:
9
+ # 0 = all checks pass (ideation complete)
10
+ # 1 = one or more checks failed (missing sections or artifacts)
11
+ # 2 = usage error (missing required args)
12
+
13
+ set -euo pipefail
14
+
15
+ # ============================================================
16
+ # ARGUMENT PARSING
17
+ # ============================================================
18
+
19
+ STATE_FILE=""
20
+ DOCS_DIR=""
21
+ DESIGN_FILE=""
22
+
23
+ usage() {
24
+ cat << 'USAGE'
25
+ Usage: verify-ideate-artifacts.sh --state-file <path> [--docs-dir <path>] [--design-file <path>]
26
+
27
+ Required:
28
+ --state-file <path> Path to the workflow state JSON file
29
+
30
+ Optional:
31
+ --docs-dir <path> Directory to search for design documents (e.g., docs/designs)
32
+ --design-file <path> Direct path to the design document (overrides --docs-dir)
33
+ --help Show this help message
34
+
35
+ Exit codes:
36
+ 0 All completion criteria met
37
+ 1 Missing artifacts or sections
38
+ 2 Usage error (missing required args)
39
+ USAGE
40
+ }
41
+
42
+ while [[ $# -gt 0 ]]; do
43
+ case "$1" in
44
+ --state-file)
45
+ if [[ -z "${2:-}" ]]; then
46
+ echo "Error: --state-file requires a path argument" >&2
47
+ exit 2
48
+ fi
49
+ STATE_FILE="$2"
50
+ shift 2
51
+ ;;
52
+ --docs-dir)
53
+ if [[ -z "${2:-}" ]]; then
54
+ echo "Error: --docs-dir requires a path argument" >&2
55
+ exit 2
56
+ fi
57
+ DOCS_DIR="$2"
58
+ shift 2
59
+ ;;
60
+ --design-file)
61
+ if [[ -z "${2:-}" ]]; then
62
+ echo "Error: --design-file requires a path argument" >&2
63
+ exit 2
64
+ fi
65
+ DESIGN_FILE="$2"
66
+ shift 2
67
+ ;;
68
+ --help)
69
+ usage
70
+ exit 0
71
+ ;;
72
+ *)
73
+ echo "Error: Unknown argument '$1'" >&2
74
+ usage >&2
75
+ exit 2
76
+ ;;
77
+ esac
78
+ done
79
+
80
+ if [[ -z "$STATE_FILE" ]]; then
81
+ echo "Error: --state-file is required" >&2
82
+ usage >&2
83
+ exit 2
84
+ fi
85
+
86
+ # ============================================================
87
+ # DEPENDENCY CHECK
88
+ # ============================================================
89
+
90
+ if ! command -v jq &>/dev/null; then
91
+ echo "Error: jq is required but not installed" >&2
92
+ exit 2
93
+ fi
94
+
95
+ # ============================================================
96
+ # CHECK FUNCTIONS
97
+ # ============================================================
98
+
99
+ CHECK_PASS=0
100
+ CHECK_FAIL=0
101
+ RESULTS=()
102
+
103
+ check_pass() {
104
+ local name="$1"
105
+ RESULTS+=("- **PASS**: $name")
106
+ CHECK_PASS=$((CHECK_PASS + 1))
107
+ }
108
+
109
+ check_fail() {
110
+ local name="$1"
111
+ local detail="${2:-}"
112
+ if [[ -n "$detail" ]]; then
113
+ RESULTS+=("- **FAIL**: $name — $detail")
114
+ else
115
+ RESULTS+=("- **FAIL**: $name")
116
+ fi
117
+ CHECK_FAIL=$((CHECK_FAIL + 1))
118
+ }
119
+
120
+ # ============================================================
121
+ # RESOLVE DESIGN FILE
122
+ # ============================================================
123
+
124
+ resolve_design_file() {
125
+ # If --design-file was given, use it directly
126
+ if [[ -n "$DESIGN_FILE" ]]; then
127
+ if [[ -f "$DESIGN_FILE" ]]; then
128
+ return 0
129
+ else
130
+ check_fail "Design document exists" "File not found: $DESIGN_FILE"
131
+ return 1
132
+ fi
133
+ fi
134
+
135
+ # Try to get design path from state file
136
+ if [[ -f "$STATE_FILE" ]] && jq empty "$STATE_FILE" 2>/dev/null; then
137
+ local state_design_path
138
+ state_design_path="$(jq -r '.artifacts.design // empty' "$STATE_FILE")"
139
+ if [[ -n "$state_design_path" && -f "$state_design_path" ]]; then
140
+ DESIGN_FILE="$state_design_path"
141
+ return 0
142
+ fi
143
+ if [[ -n "$state_design_path" ]] && [[ ! -f "$state_design_path" ]]; then
144
+ check_fail "Design document exists" "State references $state_design_path but file not found"
145
+ return 1
146
+ fi
147
+ fi
148
+
149
+ # Search in docs dir for YYYY-MM-DD-*.md pattern
150
+ if [[ -n "$DOCS_DIR" && -d "$DOCS_DIR" ]]; then
151
+ local found_files
152
+ found_files="$(find "$DOCS_DIR" -maxdepth 1 -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-*.md' -type f 2>/dev/null | sort -r | head -1)"
153
+ if [[ -n "$found_files" ]]; then
154
+ DESIGN_FILE="$found_files"
155
+ return 0
156
+ fi
157
+ fi
158
+
159
+ check_fail "Design document exists" "No design document found in ${DOCS_DIR:-<no docs-dir>}"
160
+ return 1
161
+ }
162
+
163
+ # ============================================================
164
+ # CHECK 1: Design document exists
165
+ # ============================================================
166
+
167
+ check_design_exists() {
168
+ if resolve_design_file; then
169
+ check_pass "Design document exists ($DESIGN_FILE)"
170
+ return 0
171
+ fi
172
+ return 1
173
+ }
174
+
175
+ # ============================================================
176
+ # CHECK 2: Required sections present
177
+ # ============================================================
178
+
179
+ REQUIRED_SECTIONS=(
180
+ "Problem Statement"
181
+ "Chosen Approach"
182
+ "Technical Design"
183
+ "Integration Points"
184
+ "Testing Strategy"
185
+ "Open Questions"
186
+ )
187
+
188
+ check_required_sections() {
189
+ local missing=()
190
+ local content
191
+ content="$(cat "$DESIGN_FILE")"
192
+
193
+ for section in "${REQUIRED_SECTIONS[@]}"; do
194
+ if ! echo "$content" | grep -qi "##.*$section"; then
195
+ missing+=("$section")
196
+ fi
197
+ done
198
+
199
+ if [[ ${#missing[@]} -eq 0 ]]; then
200
+ check_pass "Required sections present (${#REQUIRED_SECTIONS[@]}/${#REQUIRED_SECTIONS[@]})"
201
+ return 0
202
+ else
203
+ local missing_list
204
+ missing_list="$(IFS=', '; echo "${missing[*]}")"
205
+ check_fail "Required sections present" "Missing: $missing_list"
206
+ return 1
207
+ fi
208
+ }
209
+
210
+ # ============================================================
211
+ # CHECK 3: Multiple options evaluated (2-3)
212
+ # ============================================================
213
+
214
+ check_multiple_options() {
215
+ local content
216
+ content="$(cat "$DESIGN_FILE")"
217
+
218
+ # Count "Option N" or "Option [N]" patterns in headings
219
+ local option_count
220
+ option_count="$(echo "$content" | grep -ciE '#+\s*(option\s+[0-9]|option\s+\[?[0-9])' || true)"
221
+
222
+ if [[ "$option_count" -ge 2 ]]; then
223
+ check_pass "Multiple options evaluated ($option_count options found)"
224
+ return 0
225
+ else
226
+ check_fail "Multiple options evaluated" "Found $option_count option(s), expected at least 2"
227
+ return 1
228
+ fi
229
+ }
230
+
231
+ # ============================================================
232
+ # CHECK 4: State file has design path recorded
233
+ # ============================================================
234
+
235
+ check_state_design_path() {
236
+ if [[ ! -f "$STATE_FILE" ]]; then
237
+ check_fail "State file has design path" "State file not found: $STATE_FILE"
238
+ return 1
239
+ fi
240
+
241
+ if ! jq empty "$STATE_FILE" 2>/dev/null; then
242
+ check_fail "State file has design path" "Invalid JSON: $STATE_FILE"
243
+ return 1
244
+ fi
245
+
246
+ local design_path
247
+ design_path="$(jq -r '.artifacts.design // empty' "$STATE_FILE")"
248
+
249
+ if [[ -n "$design_path" ]]; then
250
+ check_pass "State file has design path ($design_path)"
251
+ return 0
252
+ else
253
+ check_fail "State file has design path" "artifacts.design is empty or missing"
254
+ return 1
255
+ fi
256
+ }
257
+
258
+ # ============================================================
259
+ # EXECUTE CHECKS
260
+ # ============================================================
261
+
262
+ if check_design_exists; then
263
+ check_required_sections || true
264
+ check_multiple_options || true
265
+ fi
266
+
267
+ check_state_design_path || true
268
+
269
+ # ============================================================
270
+ # STRUCTURED OUTPUT
271
+ # ============================================================
272
+
273
+ echo "## Ideation Artifact Verification Report"
274
+ echo ""
275
+ echo "**State file:** \`$STATE_FILE\`"
276
+ if [[ -n "$DESIGN_FILE" ]]; then
277
+ echo "**Design file:** \`$DESIGN_FILE\`"
278
+ fi
279
+ echo ""
280
+
281
+ for result in "${RESULTS[@]}"; do
282
+ echo "$result"
283
+ done
284
+
285
+ echo ""
286
+ TOTAL=$((CHECK_PASS + CHECK_FAIL))
287
+ echo "---"
288
+ echo ""
289
+
290
+ if [[ $CHECK_FAIL -eq 0 ]]; then
291
+ echo "**Result: PASS** ($CHECK_PASS/$TOTAL checks passed)"
292
+ exit 0
293
+ else
294
+ echo "**Result: FAIL** ($CHECK_FAIL/$TOTAL checks failed)"
295
+ exit 1
296
+ fi