codeharness 0.26.4 → 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.
- package/dist/{chunk-KZQETPQS.js → chunk-JMYDBV6O.js} +127 -430
- package/dist/{docker-JEC7THRT.js → docker-5LUADX2H.js} +1 -1
- package/dist/index.js +5150 -2054
- package/package.json +5 -3
- package/patches/AGENTS.md +1 -1
- package/patches/dev/enforcement.md +16 -7
- package/patches/retro/enforcement.md +2 -2
- package/patches/review/enforcement.md +24 -3
- package/patches/verify/story-verification.md +25 -11
- package/templates/agents/analyst.yaml +10 -0
- package/templates/agents/architect.yaml +11 -0
- package/templates/agents/dev.yaml +10 -0
- package/templates/agents/evaluator.yaml +92 -0
- package/templates/agents/pm.yaml +12 -0
- package/templates/agents/qa.yaml +15 -0
- package/templates/agents/sm.yaml +10 -0
- package/templates/agents/tech-writer.yaml +11 -0
- package/templates/agents/ux-designer.yaml +13 -0
- package/templates/workflows/default.yaml +23 -0
- package/ralph/AGENTS.md +0 -48
- package/ralph/bridge.sh +0 -424
- package/ralph/db_schema_gen.sh +0 -109
- package/ralph/drivers/claude-code.sh +0 -140
- package/ralph/exec_plans.sh +0 -252
- package/ralph/harness_status.sh +0 -147
- package/ralph/lib/circuit_breaker.sh +0 -210
- package/ralph/lib/date_utils.sh +0 -60
- package/ralph/lib/timeout_utils.sh +0 -77
- package/ralph/onboard.sh +0 -83
- package/ralph/ralph.sh +0 -1402
- package/ralph/validate_epic_docs.sh +0 -129
- package/ralph/verify_gates.sh +0 -210
|
@@ -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
|
package/ralph/verify_gates.sh
DELETED
|
@@ -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
|