devrites 2.2.0 → 2.4.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/CHANGELOG.md +24 -0
- package/README.md +30 -17
- package/docs/architecture.md +30 -24
- package/docs/command-map.md +15 -6
- package/docs/flow.md +19 -5
- package/docs/orchestration.md +17 -7
- package/docs/skills.md +32 -8
- package/pack/.claude/agents/devrites-code-reviewer.md +6 -1
- package/pack/.claude/agents/devrites-devex-reviewer.md +94 -0
- package/pack/.claude/agents/devrites-forge-judge.md +92 -0
- package/pack/.claude/agents/devrites-frontend-reviewer.md +8 -0
- package/pack/.claude/agents/devrites-retrospector.md +91 -0
- package/pack/.claude/agents/devrites-slice-wright.md +18 -5
- package/pack/.claude/rules/README.md +5 -2
- package/pack/.claude/rules/agents.md +30 -2
- package/pack/.claude/rules/anti-patterns.md +11 -0
- package/pack/.claude/rules/code-review.md +16 -6
- package/pack/.claude/rules/core.md +13 -4
- package/pack/.claude/rules/developer-experience.md +119 -0
- package/pack/.claude/rules/principles.md +158 -0
- package/pack/.claude/rules/spec-grammar.md +106 -0
- package/pack/.claude/skills/devrites-browser-proof/SKILL.md +42 -3
- package/pack/.claude/skills/devrites-doubt/SKILL.md +1 -1
- package/pack/.claude/skills/devrites-lib/SKILL.md +9 -2
- package/pack/.claude/skills/devrites-lib/scripts/devrites.sh +8 -0
- package/pack/.claude/skills/devrites-lib/scripts/doubt-coverage.sh +39 -0
- package/pack/.claude/skills/devrites-lib/scripts/spec-validate.sh +130 -0
- package/pack/.claude/skills/rite-adopt/SKILL.md +13 -1
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +3 -1
- package/pack/.claude/skills/rite-build/SKILL.md +51 -2
- package/pack/.claude/skills/rite-build/reference/anti-patterns.md +12 -0
- package/pack/.claude/skills/rite-build/reference/forge.md +171 -0
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +2 -0
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +22 -2
- package/pack/.claude/skills/rite-define/SKILL.md +14 -1
- package/pack/.claude/skills/rite-frame/SKILL.md +7 -2
- package/pack/.claude/skills/rite-learn/SKILL.md +17 -4
- package/pack/.claude/skills/rite-polish/SKILL.md +3 -1
- package/pack/.claude/skills/rite-prove/SKILL.md +30 -1
- package/pack/.claude/skills/rite-quick/SKILL.md +9 -4
- package/pack/.claude/skills/rite-review/SKILL.md +5 -2
- package/pack/.claude/skills/rite-seal/SKILL.md +39 -4
- package/pack/.claude/skills/rite-seal/reference/anti-patterns.md +2 -0
- package/pack/.claude/skills/rite-ship/SKILL.md +21 -0
- package/pack/.claude/skills/rite-spec/SKILL.md +29 -5
- package/pack/.claude/skills/rite-spec/reference/spec-template.md +11 -1
- package/pack/.claude/skills/rite-status/SKILL.md +3 -1
- package/pack/.claude/skills/rite-vet/SKILL.md +46 -14
- package/package.json +1 -1
- package/scripts/check-cross-refs.py +4 -0
- package/scripts/run-behavioral-evals.sh +170 -0
- package/scripts/run-evals.sh +3 -0
- package/scripts/validate.sh +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/run-behavioral-evals.sh — validate the SHAPE of DevRites behavioral evals.
|
|
3
|
+
#
|
|
4
|
+
# Trigger evals (run-evals.sh) test whether the right skill *fires*. Behavioral
|
|
5
|
+
# evals test whether a gating skill's discipline *holds under pressure* — does it
|
|
6
|
+
# resist the rationalizations it documents in `rules/anti-patterns.md` (and its own
|
|
7
|
+
# `reference/anti-patterns.md`), or does the agent talk itself past the gate. Each
|
|
8
|
+
# scenario pairs a pressure prompt with the resistance a holding response shows and
|
|
9
|
+
# the capitulation markers a failed one shows.
|
|
10
|
+
#
|
|
11
|
+
# This script is the DETERMINISTIC, zero-token CI gate — the analog of run-evals.sh's
|
|
12
|
+
# schema path and spec-validate.sh: it checks that every behavioral eval is well-formed
|
|
13
|
+
# so a malformed one can't reach the live grader. It does NOT invoke a model. Executing
|
|
14
|
+
# the scenarios against a live Claude (does the skill actually resist?) is the labeled /
|
|
15
|
+
# nightly rung documented in evals/behavioral/README.md.
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
# scripts/run-behavioral-evals.sh # validate every evals/behavioral/*.json
|
|
19
|
+
# scripts/run-behavioral-evals.sh evals/behavioral/rite-prove.json # validate one file
|
|
20
|
+
#
|
|
21
|
+
# Exit: 0 all valid (or no behavioral evals present — opt-in, never a failure) ·
|
|
22
|
+
# 1 shape violation(s) · 2 missing parser
|
|
23
|
+
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
27
|
+
# Overridable so the test harness can exercise the opt-in no-op path against a
|
|
28
|
+
# scratch directory; defaults to the real behavioral-eval set.
|
|
29
|
+
BEHAVIORAL_DIR="${DEVRITES_BEHAVIORAL_DIR:-$ROOT/evals/behavioral}"
|
|
30
|
+
|
|
31
|
+
if [[ $# -gt 0 ]]; then
|
|
32
|
+
FILES=("$@")
|
|
33
|
+
else
|
|
34
|
+
if [[ ! -d "$BEHAVIORAL_DIR" ]]; then
|
|
35
|
+
echo "No evals/behavioral/ directory — behavioral evals are opt-in; nothing to validate."
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
FILES=()
|
|
39
|
+
while IFS= read -r f; do
|
|
40
|
+
[[ "$f" == */README.md ]] && continue
|
|
41
|
+
FILES+=("$f")
|
|
42
|
+
done < <(find "$BEHAVIORAL_DIR" -type f -name '*.json' | sort)
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [[ ${#FILES[@]} -eq 0 ]]; then
|
|
46
|
+
echo "No behavioral eval files — behavioral evals are opt-in; nothing to validate."
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
51
|
+
PARSER="python3"
|
|
52
|
+
elif command -v jq >/dev/null 2>&1; then
|
|
53
|
+
PARSER="jq"
|
|
54
|
+
else
|
|
55
|
+
echo "Need python3 or jq to validate JSON." >&2
|
|
56
|
+
exit 2
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
FAILED=0
|
|
60
|
+
TOTAL=0
|
|
61
|
+
SCENARIOS=0
|
|
62
|
+
|
|
63
|
+
for file in "${FILES[@]}"; do
|
|
64
|
+
TOTAL=$((TOTAL + 1))
|
|
65
|
+
printf '== %s ==\n' "$file"
|
|
66
|
+
|
|
67
|
+
if [[ "$PARSER" == "python3" ]]; then
|
|
68
|
+
if OUT=$(python3 - "$file" <<'PY'
|
|
69
|
+
import json, sys, pathlib
|
|
70
|
+
path = pathlib.Path(sys.argv[1])
|
|
71
|
+
try:
|
|
72
|
+
data = json.loads(path.read_text())
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print(f" FAIL: INVALID JSON: {e}")
|
|
75
|
+
sys.exit(1)
|
|
76
|
+
|
|
77
|
+
errors = []
|
|
78
|
+
for key in ("skill", "description", "scenarios"):
|
|
79
|
+
if key not in data:
|
|
80
|
+
errors.append(f"missing top-level key: {key}")
|
|
81
|
+
|
|
82
|
+
scenarios = data.get("scenarios", [])
|
|
83
|
+
if not isinstance(scenarios, list):
|
|
84
|
+
errors.append("scenarios is not a list")
|
|
85
|
+
scenarios = []
|
|
86
|
+
elif len(scenarios) == 0:
|
|
87
|
+
errors.append("scenarios is empty — a behavioral eval needs at least one")
|
|
88
|
+
|
|
89
|
+
seen_ids = {}
|
|
90
|
+
for i, s in enumerate(scenarios):
|
|
91
|
+
if not isinstance(s, dict):
|
|
92
|
+
errors.append(f"scenario[{i}] not an object")
|
|
93
|
+
continue
|
|
94
|
+
sid = s.get("id")
|
|
95
|
+
if not sid or not isinstance(sid, str):
|
|
96
|
+
errors.append(f"scenario[{i}] missing non-empty string id")
|
|
97
|
+
elif sid in seen_ids:
|
|
98
|
+
errors.append(f"scenario[{i}] duplicate id {sid!r} (also scenario[{seen_ids[sid]}])")
|
|
99
|
+
else:
|
|
100
|
+
seen_ids[sid] = i
|
|
101
|
+
where = sid or f"[{i}]"
|
|
102
|
+
# Non-empty string fields.
|
|
103
|
+
for k in ("rationalization", "pressure", "source"):
|
|
104
|
+
v = s.get(k)
|
|
105
|
+
if not isinstance(v, str) or not v.strip():
|
|
106
|
+
errors.append(f"scenario {where} missing non-empty {k}")
|
|
107
|
+
# Non-empty list-of-string fields.
|
|
108
|
+
for k in ("expected_resistance", "capitulation_markers"):
|
|
109
|
+
v = s.get(k)
|
|
110
|
+
if not isinstance(v, list) or len(v) == 0:
|
|
111
|
+
errors.append(f"scenario {where} missing non-empty {k} list")
|
|
112
|
+
elif not all(isinstance(x, str) and x.strip() for x in v):
|
|
113
|
+
errors.append(f"scenario {where} {k} has an empty / non-string entry")
|
|
114
|
+
|
|
115
|
+
if errors:
|
|
116
|
+
for e in errors:
|
|
117
|
+
print(f" FAIL: {e}")
|
|
118
|
+
sys.exit(1)
|
|
119
|
+
|
|
120
|
+
print(f" skill: {data['skill']}")
|
|
121
|
+
print(f" scenarios: {len(scenarios)}")
|
|
122
|
+
print(f"__COUNT__ {len(scenarios)}")
|
|
123
|
+
PY
|
|
124
|
+
); then rc=0; else rc=$?; fi
|
|
125
|
+
else
|
|
126
|
+
if OUT=$(jq -r '
|
|
127
|
+
if (.skill and .description and (.scenarios|type=="array") and (.scenarios|length > 0)) then
|
|
128
|
+
( [ .scenarios[]
|
|
129
|
+
| select(
|
|
130
|
+
((.id|type=="string") and (.id|length>0))
|
|
131
|
+
and ((.rationalization|type=="string") and (.rationalization|length>0))
|
|
132
|
+
and ((.pressure|type=="string") and (.pressure|length>0))
|
|
133
|
+
and ((.source|type=="string") and (.source|length>0))
|
|
134
|
+
and ((.expected_resistance|type=="array") and (.expected_resistance|length>0))
|
|
135
|
+
and ((.capitulation_markers|type=="array") and (.capitulation_markers|length>0))
|
|
136
|
+
) ] | length
|
|
137
|
+
) as $ok
|
|
138
|
+
| if $ok == (.scenarios|length)
|
|
139
|
+
then " skill: \(.skill)\n scenarios: \(.scenarios|length)\n__COUNT__ \(.scenarios|length)"
|
|
140
|
+
else " FAIL: \((.scenarios|length) - $ok) scenario(s) missing required fields"
|
|
141
|
+
end
|
|
142
|
+
else
|
|
143
|
+
" FAIL: missing required keys or empty scenarios"
|
|
144
|
+
end
|
|
145
|
+
' "$file"); then rc=0; else rc=$?; fi
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
COUNT=$(printf '%s\n' "$OUT" | sed -n 's/^__COUNT__ //p')
|
|
149
|
+
OUT=$(printf '%s\n' "$OUT" | grep -v '^__COUNT__' || true)
|
|
150
|
+
printf '%s\n' "$OUT"
|
|
151
|
+
|
|
152
|
+
if [[ ${rc:-0} -ne 0 ]] || [[ "$OUT" == *"FAIL"* ]]; then
|
|
153
|
+
FAILED=$((FAILED + 1))
|
|
154
|
+
else
|
|
155
|
+
SCENARIOS=$((SCENARIOS + ${COUNT:-0}))
|
|
156
|
+
fi
|
|
157
|
+
done
|
|
158
|
+
|
|
159
|
+
echo
|
|
160
|
+
printf 'Validated %d behavioral eval file(s); %d scenario(s); %d failed.\n' "$TOTAL" "$SCENARIOS" "$FAILED"
|
|
161
|
+
|
|
162
|
+
if [[ $FAILED -gt 0 ]]; then
|
|
163
|
+
exit 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
echo
|
|
167
|
+
echo "Note: this is shape validation only — it does not execute the scenarios."
|
|
168
|
+
echo "To grade whether the skills actually resist under pressure (live model):"
|
|
169
|
+
echo " see evals/behavioral/README.md — the labeled / nightly rung."
|
|
170
|
+
exit 0
|
package/scripts/run-evals.sh
CHANGED
|
@@ -26,6 +26,9 @@ else
|
|
|
26
26
|
FILES=()
|
|
27
27
|
while IFS= read -r f; do
|
|
28
28
|
[[ "$f" == */README.md ]] && continue
|
|
29
|
+
# Behavioral evals have their own schema + validator (run-behavioral-evals.sh);
|
|
30
|
+
# they are not 20-query trigger evals, so keep them out of this scan.
|
|
31
|
+
[[ "$f" == */behavioral/* ]] && continue
|
|
29
32
|
FILES+=("$f")
|
|
30
33
|
done < <(find "$EVALS_DIR" -type f -name '*.json' | sort)
|
|
31
34
|
fi
|
package/scripts/validate.sh
CHANGED
|
@@ -14,7 +14,7 @@ good() { printf 'ok: %s\n' "$*"; }
|
|
|
14
14
|
|
|
15
15
|
PUBLIC="rite rite-spec rite-adopt rite-temper rite-define rite-vet rite-plan rite-build rite-prove rite-polish rite-review rite-seal rite-ship rite-status rite-doctor rite-resolve rite-pressure-test rite-zoom-out rite-prototype rite-handoff rite-autocomplete"
|
|
16
16
|
INTERNAL="devrites-interview devrites-source-driven devrites-doubt devrites-ux-shape devrites-frontend-craft devrites-browser-proof devrites-debug-recovery devrites-api-interface devrites-audit"
|
|
17
|
-
AGENT_FILES="devrites-spec-reviewer devrites-code-reviewer devrites-test-analyst devrites-frontend-reviewer devrites-security-auditor devrites-performance-reviewer devrites-doubt-reviewer devrites-simplifier-reviewer devrites-strategy-reviewer devrites-plan-reviewer devrites-slice-wright"
|
|
17
|
+
AGENT_FILES="devrites-spec-reviewer devrites-code-reviewer devrites-test-analyst devrites-frontend-reviewer devrites-security-auditor devrites-performance-reviewer devrites-devex-reviewer devrites-doubt-reviewer devrites-simplifier-reviewer devrites-strategy-reviewer devrites-plan-reviewer devrites-retrospector devrites-slice-wright"
|
|
18
18
|
|
|
19
19
|
# ---- 1. bash -n on every shell script ------------------------------------
|
|
20
20
|
section "bash syntax (bash -n)"
|