codeharness 0.26.5 → 0.27.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.
@@ -1,129 +0,0 @@
1
- #!/usr/bin/env bash
2
- # validate_epic_docs.sh — Validate architectural docs at epic completion
3
- # Checks that ARCHITECTURE.md exists and is current when all stories in an epic are verified.
4
- #
5
- # Usage: ralph/validate_epic_docs.sh --epic NAME --project-dir DIR --progress PATH
6
-
7
- set -e
8
-
9
- EPIC_NAME=""
10
- PROJECT_DIR=""
11
- PROGRESS_FILE=""
12
-
13
- show_help() {
14
- cat << 'HELPEOF'
15
- Design-Doc Validation — validate architecture docs at epic completion
16
-
17
- Usage:
18
- ralph/validate_epic_docs.sh --epic NAME --project-dir DIR --progress PATH
19
-
20
- Checks:
21
- 1. All stories in the epic are complete
22
- 2. ARCHITECTURE.md exists
23
- 3. ARCHITECTURE.md was updated since the epic's code changes
24
-
25
- Options:
26
- --epic NAME Epic name to validate (e.g., "Epic 1: Auth")
27
- --project-dir DIR Project root directory
28
- --progress PATH Path to ralph/progress.json
29
- -h, --help Show this help message
30
- HELPEOF
31
- }
32
-
33
- while [[ $# -gt 0 ]]; do
34
- case $1 in
35
- -h|--help)
36
- show_help
37
- exit 0
38
- ;;
39
- --epic)
40
- EPIC_NAME="$2"
41
- shift 2
42
- ;;
43
- --project-dir)
44
- PROJECT_DIR="$2"
45
- shift 2
46
- ;;
47
- --progress)
48
- PROGRESS_FILE="$2"
49
- shift 2
50
- ;;
51
- *)
52
- echo "Unknown option: $1" >&2
53
- exit 1
54
- ;;
55
- esac
56
- done
57
-
58
- # ─── Validation ───────────────────────────────────────────────────────────
59
-
60
- if [[ -z "$EPIC_NAME" ]]; then
61
- echo "Error: --epic is required" >&2
62
- exit 2
63
- fi
64
-
65
- if [[ -z "$PROJECT_DIR" ]]; then
66
- echo "Error: --project-dir is required" >&2
67
- exit 2
68
- fi
69
-
70
- if [[ -z "$PROGRESS_FILE" ]]; then
71
- echo "Error: --progress is required" >&2
72
- exit 2
73
- fi
74
-
75
- if [[ ! -f "$PROGRESS_FILE" ]]; then
76
- echo "Error: progress file not found: $PROGRESS_FILE" >&2
77
- exit 2
78
- fi
79
-
80
- # ─── Check 1: All stories in epic are complete ────────────────────────────
81
-
82
- total_in_epic=$(jq --arg epic "$EPIC_NAME" \
83
- '[.tasks[] | select(.epic == $epic)] | length' \
84
- "$PROGRESS_FILE" 2>/dev/null || echo "0")
85
-
86
- if [[ "$total_in_epic" == "0" ]]; then
87
- echo "[FAIL] No stories found for epic: $EPIC_NAME" >&2
88
- exit 1
89
- fi
90
-
91
- pending_in_epic=$(jq --arg epic "$EPIC_NAME" \
92
- '[.tasks[] | select(.epic == $epic and .status != "complete")] | length' \
93
- "$PROGRESS_FILE" 2>/dev/null || echo "0")
94
-
95
- if [[ "$pending_in_epic" != "0" ]]; then
96
- echo "[FAIL] Epic \"$EPIC_NAME\" is not complete — $pending_in_epic stories still pending" >&2
97
- exit 1
98
- fi
99
-
100
- # ─── Check 2: ARCHITECTURE.md exists ─────────────────────────────────────
101
-
102
- ARCH_FILE="$PROJECT_DIR/ARCHITECTURE.md"
103
-
104
- if [[ ! -f "$ARCH_FILE" ]]; then
105
- echo "[FAIL] ARCHITECTURE.md not found — epic \"$EPIC_NAME\" cannot be marked complete"
106
- echo " → Create ARCHITECTURE.md documenting architectural decisions from this epic"
107
- exit 1
108
- fi
109
-
110
- # ─── Check 3: ARCHITECTURE.md is current ─────────────────────────────────
111
-
112
- # Get ARCHITECTURE.md last commit time
113
- arch_commit_time=$(git -C "$PROJECT_DIR" log -1 --format="%ct" -- "$ARCH_FILE" 2>/dev/null || echo "0")
114
-
115
- # Get the latest commit time across all tracked files (excluding ARCHITECTURE.md itself)
116
- latest_code_time=$(git -C "$PROJECT_DIR" log -1 --format="%ct" -- . 2>/dev/null || echo "0")
117
-
118
- # If code was committed after ARCHITECTURE.md, it may be stale
119
- if [[ $latest_code_time -gt $arch_commit_time && $arch_commit_time -gt 0 ]]; then
120
- echo "[FAIL] ARCHITECTURE.md is stale — code changed after architecture doc was last updated"
121
- echo " Epic: $EPIC_NAME ($total_in_epic stories)"
122
- echo " → Update ARCHITECTURE.md to reflect architectural decisions made during this epic"
123
- exit 1
124
- fi
125
-
126
- # ─── All checks pass ─────────────────────────────────────────────────────
127
-
128
- echo "[OK] Epic \"$EPIC_NAME\" — architecture docs validated ($total_in_epic stories verified)"
129
- exit 0
@@ -1,210 +0,0 @@
1
- #!/usr/bin/env bash
2
- # DEPRECATED: Verification gates are now handled by the /harness-run sprint execution skill.
3
- # This script is kept as a standalone diagnostic tool.
4
- #
5
- # verify_gates.sh — Verification gates for the Ralph loop
6
- # Checks that a story has: Showboat proof, tests passing, coverage met, verification run.
7
- # Previously called by ralph.sh after each iteration to decide: mark done or iterate again.
8
- #
9
- # Usage:
10
- # ralph/verify_gates.sh --story-id ID --project-dir DIR --progress PATH
11
- #
12
- # Exit codes:
13
- # 0 = all gates pass, story marked complete
14
- # 1 = gates failed, story needs more work (iteration incremented)
15
- # 2 = error (missing files, unknown story)
16
-
17
- set -e
18
-
19
- # Portable in-place sed (macOS uses -i '', Linux uses -i)
20
- sed_i() {
21
- if sed --version 2>/dev/null | grep -q GNU; then
22
- sed -i "$@"
23
- else
24
- sed -i '' "$@"
25
- fi
26
- }
27
-
28
- # ─── Arguments ────────────────────────────────────────────────────────────
29
-
30
- STORY_ID=""
31
- PROJECT_DIR=""
32
- PROGRESS_FILE=""
33
-
34
- show_help() {
35
- cat << 'HELPEOF'
36
- Verification Gates — check if a story is truly done
37
-
38
- Usage:
39
- ralph/verify_gates.sh --story-id ID --project-dir DIR --progress PATH
40
-
41
- Gates checked:
42
- 1. Showboat proof document exists for the story
43
- 2. Tests have passed (session_flags.tests_passed)
44
- 3. Coverage at 100% (session_flags.coverage_met)
45
- 4. Verification has been run (session_flags.verification_run)
46
-
47
- On pass: story marked complete in progress.json, session flags reset
48
- On fail: iteration count incremented, failures listed
49
-
50
- Options:
51
- -h, --help Show this help message
52
- HELPEOF
53
- }
54
-
55
- while [[ $# -gt 0 ]]; do
56
- case $1 in
57
- -h|--help)
58
- show_help
59
- exit 0
60
- ;;
61
- --story-id)
62
- STORY_ID="$2"
63
- shift 2
64
- ;;
65
- --project-dir)
66
- PROJECT_DIR="$2"
67
- shift 2
68
- ;;
69
- --progress)
70
- PROGRESS_FILE="$2"
71
- shift 2
72
- ;;
73
- *)
74
- echo "Unknown option: $1" >&2
75
- exit 2
76
- ;;
77
- esac
78
- done
79
-
80
- # ─── Validation ───────────────────────────────────────────────────────────
81
-
82
- if [[ -z "$STORY_ID" || -z "$PROJECT_DIR" || -z "$PROGRESS_FILE" ]]; then
83
- echo "[FAIL] Missing required arguments: --story-id, --project-dir, --progress" >&2
84
- exit 2
85
- fi
86
-
87
- STATE_FILE="$PROJECT_DIR/.claude/codeharness.local.md"
88
-
89
- if [[ ! -f "$STATE_FILE" ]]; then
90
- echo "[FAIL] Harness state file not found: $STATE_FILE — harness not initialized" >&2
91
- exit 2
92
- fi
93
-
94
- if [[ ! -f "$PROGRESS_FILE" ]]; then
95
- echo "[FAIL] Progress file not found: $PROGRESS_FILE" >&2
96
- exit 2
97
- fi
98
-
99
- # Check that the story exists in progress
100
- STORY_EXISTS=$(jq -r --arg id "$STORY_ID" '.tasks[] | select(.id == $id) | .id' "$PROGRESS_FILE" 2>/dev/null)
101
- if [[ -z "$STORY_EXISTS" || "$STORY_EXISTS" == "null" ]]; then
102
- echo "[FAIL] Story $STORY_ID not found in $PROGRESS_FILE" >&2
103
- exit 2
104
- fi
105
-
106
- # ─── Read proof path from progress ────────────────────────────────────────
107
-
108
- PROOF_PATH=$(jq -r --arg id "$STORY_ID" \
109
- '.tasks[] | select(.id == $id) | .verification.proof_path // ""' \
110
- "$PROGRESS_FILE" 2>/dev/null)
111
-
112
- if [[ -z "$PROOF_PATH" ]]; then
113
- PROOF_PATH="verification/${STORY_ID}-proof.md"
114
- fi
115
-
116
- # ─── Gate Checks ──────────────────────────────────────────────────────────
117
-
118
- FAILURES=""
119
- GATES_PASSED=0
120
- GATES_TOTAL=4
121
-
122
- # Gate 1: Showboat proof exists
123
- if [[ -f "$PROJECT_DIR/$PROOF_PATH" ]]; then
124
- GATES_PASSED=$((GATES_PASSED + 1))
125
- else
126
- FAILURES="${FAILURES}\n - Showboat proof not found: $PROOF_PATH"
127
- fi
128
-
129
- # Gate 2: Tests passed
130
- TESTS_PASSED=$(grep -o 'tests_passed: *[a-z]*' "$STATE_FILE" 2>/dev/null | head -1 | awk '{print $2}')
131
- if [[ "$TESTS_PASSED" == "true" ]]; then
132
- GATES_PASSED=$((GATES_PASSED + 1))
133
- else
134
- FAILURES="${FAILURES}\n - Tests not passed (tests_passed: ${TESTS_PASSED:-unknown})"
135
- fi
136
-
137
- # Gate 3: Coverage met
138
- COVERAGE_MET=$(grep -o 'coverage_met: *[a-z]*' "$STATE_FILE" 2>/dev/null | head -1 | awk '{print $2}')
139
- if [[ "$COVERAGE_MET" == "true" ]]; then
140
- GATES_PASSED=$((GATES_PASSED + 1))
141
- else
142
- FAILURES="${FAILURES}\n - Test coverage not at 100% (coverage_met: ${COVERAGE_MET:-unknown})"
143
- fi
144
-
145
- # Gate 4: Verification run
146
- VERIFICATION_RUN=$(grep -o 'verification_run: *[a-z]*' "$STATE_FILE" 2>/dev/null | head -1 | awk '{print $2}')
147
- if [[ "$VERIFICATION_RUN" == "true" ]]; then
148
- GATES_PASSED=$((GATES_PASSED + 1))
149
- else
150
- FAILURES="${FAILURES}\n - Verification not run (verification_run: ${VERIFICATION_RUN:-unknown})"
151
- fi
152
-
153
- # ─── Increment iteration count (always, on check) ─────────────────────────
154
-
155
- increment_iteration() {
156
- local updated
157
- updated=$(jq --arg id "$STORY_ID" \
158
- '(.tasks[] | select(.id == $id)).iterations = ((.tasks[] | select(.id == $id)).iterations // 0) + 1' \
159
- "$PROGRESS_FILE" 2>/dev/null)
160
- if [[ -n "$updated" ]]; then
161
- echo "$updated" > "$PROGRESS_FILE"
162
- fi
163
- }
164
-
165
- # ─── Decision ─────────────────────────────────────────────────────────────
166
-
167
- if [[ $GATES_PASSED -eq $GATES_TOTAL ]]; then
168
- # Log pass event
169
- # All gates pass — mark story complete
170
- local_updated=$(jq --arg id "$STORY_ID" \
171
- '(.tasks[] | select(.id == $id)).status = "complete"' \
172
- "$PROGRESS_FILE" 2>/dev/null)
173
- if [[ -n "${local_updated}" ]]; then
174
- echo "${local_updated}" > "$PROGRESS_FILE"
175
- fi
176
-
177
- # Reset session flags for the next story
178
- sed_i 's/tests_passed: true/tests_passed: false/' "$STATE_FILE"
179
- sed_i 's/coverage_met: true/coverage_met: false/' "$STATE_FILE"
180
- sed_i 's/verification_run: true/verification_run: false/' "$STATE_FILE"
181
- sed_i 's/logs_queried: true/logs_queried: false/' "$STATE_FILE"
182
-
183
- # Move exec-plan from active to completed (if exec-plans exist)
184
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
185
- exec_plans_dir="$PROJECT_DIR/docs/exec-plans"
186
- if [[ -f "$exec_plans_dir/active/$STORY_ID.md" && -f "$SCRIPT_DIR/exec_plans.sh" ]]; then
187
- "$SCRIPT_DIR/exec_plans.sh" complete \
188
- --story-id "$STORY_ID" \
189
- --output-dir "$exec_plans_dir" \
190
- --proof-path "$PROOF_PATH" 2>/dev/null || true
191
- fi
192
-
193
- echo "[PASS] Story $STORY_ID — all $GATES_TOTAL verification gates passed"
194
- echo " → Story marked complete, session flags reset for next story"
195
- exit 0
196
- else
197
- # Log fail event
198
- # Gates failed — increment iteration, report failures
199
- increment_iteration
200
-
201
- iterations=$(jq -r --arg id "$STORY_ID" \
202
- '.tasks[] | select(.id == $id) | .iterations // 0' \
203
- "$PROGRESS_FILE" 2>/dev/null)
204
-
205
- echo "[BLOCKED] Story $STORY_ID — $GATES_PASSED/$GATES_TOTAL gates passed (iteration $iterations)"
206
- echo -e " Failures:$FAILURES"
207
- echo ""
208
- echo " → Agent must fix failures and re-verify before story completion"
209
- exit 1
210
- fi