crewforth 3.2.1 → 3.3.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 +85 -0
- package/README.md +2 -2
- package/VERSION +1 -1
- package/adopt.sh +7 -3
- package/kit/AGENT_TEMPLATE.md +1 -0
- package/kit/CLAUDE.md +9 -8
- package/kit/agents/crew-session-manager.md +5 -3
- package/kit/eval/doctor.sh +99 -45
- package/kit/eval/golden-routing.txt +3 -0
- package/kit/eval/lib/verify-cmd.sh +72 -0
- package/kit/eval/smoke-test.sh +368 -71
- package/kit/hooks/context-usage.sh +6 -3
- package/kit/hooks/guard-agent-model.sh +29 -8
- package/kit/hooks/guard-bash.sh +127 -2
- package/kit/hooks/guard-schedule.sh +4 -1
- package/kit/hooks/pre-commit +21 -0
- package/kit/hooks/prompt-approval.sh +80 -3
- package/kit/hooks/route-hint.sh +18 -1
- package/kit/hooks/session-rehydrate.sh +6 -2
- package/kit/owned-blobs.tsv +4 -4
- package/kit/skills/commit-message/SKILL.md +5 -0
- package/kit/skills/crew-allow-verify/SKILL.md +30 -0
- package/kit/skills/crew-doctor/SKILL.md +3 -1
- package/kit/skills/handoff/SKILL.md +3 -2
- package/kit/skills/trace-scan/SKILL.md +4 -3
- package/kit/studio/server/lib/model-outcomes.js +7 -1
- package/package.json +1 -1
- package/start.sh +6 -2
|
@@ -43,8 +43,9 @@ that never landed and has to be written down explicitly this time. Missing scrip
|
|
|
43
43
|
|
|
44
44
|
## Holding a board item? The handover is not finished until the TEAM has it
|
|
45
45
|
`docs/SESSION_STATE.md` is gitignored — it survives your `/clear`, and nobody else can read it. So when a
|
|
46
|
-
`teamboard` claim is open, **the handover is not complete until it is on the board**.
|
|
47
|
-
|
|
46
|
+
`teamboard` claim is open, **the handover is not complete until it is on the board**. Whether one is open is
|
|
47
|
+
read from `bash .claude/hooks/board.sh status` (Bash tool, not PowerShell; a row marked `<- you`), not guessed;
|
|
48
|
+
no board or no such row → the handover says nothing about the board. This is not an optional extra step:
|
|
48
49
|
- Still on it → `board.sh note <id> "<where it stands, and why the rejected path was rejected>"`.
|
|
49
50
|
- Not coming back → `board.sh drop <id> "<same>"`, which puts it back in circulation with your context attached.
|
|
50
51
|
- Anything settled here that changes how OTHER items must be done → `board.sh decide "<what>" "<why + what it
|
|
@@ -31,10 +31,11 @@ git diff --cached --unified=0 | grep -E '^\+' | grep -Ev '^\+\+\+' \
|
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## Hook setup (full install only — a plugin cannot set `core.hooksPath`)
|
|
34
|
-
`start.sh` sets `
|
|
35
|
-
under `.claude` → they are in gitignore and stay local (§4.3)
|
|
34
|
+
`start.sh` sets `core.hooksPath` to the absolute path of `.claude/hooks` (if there is a git repo). The hooks live
|
|
35
|
+
under `.claude` → they are in gitignore and stay local (§4.3), so a relative path would leave a linked worktree with
|
|
36
|
+
no hook at all. To do it later for a repo, from its root:
|
|
36
37
|
```bash
|
|
37
|
-
git config core.hooksPath
|
|
38
|
+
git config core.hooksPath "$(git rev-parse --show-toplevel)/.claude/hooks"
|
|
38
39
|
chmod +x .claude/hooks/pre-commit .claude/hooks/commit-msg
|
|
39
40
|
```
|
|
40
41
|
|
|
@@ -145,8 +145,11 @@ const firstTry = (r) => r.verify === 'pass' && r.fixes === 0;
|
|
|
145
145
|
*/
|
|
146
146
|
export function floorOfRow(r, ruleFloors = [], floors = []) {
|
|
147
147
|
let f = rankOf(AGENT_FLOORS[r.agent]);
|
|
148
|
-
|
|
148
|
+
const commitAgent = r.agent === 'crew-commit-agent';
|
|
149
|
+
if (r.verify === 'none' && r.change !== 'text' && !commitAgent) f = Math.max(f, 2);
|
|
149
150
|
if (r.change === 'test-write' || r.change === 'audit') f = Math.max(f, 2);
|
|
151
|
+
// The table's sonnet row, as the gate holds it: feature, fix-known and refactor, except for the commit agent.
|
|
152
|
+
if (!commitAgent && (r.change === 'feature' || r.change === 'fix-known' || r.change === 'refactor')) f = Math.max(f, 2);
|
|
150
153
|
if (r.risk === 'critical' && r.change !== 'test-run') f = Math.max(f, 3);
|
|
151
154
|
const any = (want, v) => want === '*' || want === v;
|
|
152
155
|
for (const x of ruleFloors) if (any(x.agent, r.agent) && any(x.change, r.change) && any(x.risk, r.risk)) f = Math.max(f, rankOf(x.model));
|
|
@@ -250,6 +253,9 @@ export function suggestionsOf(rows, floors = [], loosened = [], need = LOOSEN_AF
|
|
|
250
253
|
const k = keyOf(f);
|
|
251
254
|
// Once for each raise: a floor whose lowering stands is not offered again (the same rule the gate reads it by).
|
|
252
255
|
if (loweringOf(f, loosened)) continue;
|
|
256
|
+
// Not below the class's own floor: /crew-loosen refuses that, since the gate would refuse the lowered model anyway
|
|
257
|
+
// (a feature class raised to sonnet by the record of haiku runs from before its own floor was sonnet).
|
|
258
|
+
if (rankOf(TIERS[tier - 1]) < floorOfRow({ agent: f.agent, change: f.change, risk: f.risk, verify: 'pass' })) continue;
|
|
253
259
|
const passed = passedLatest(rows, k, f.model, Date.parse(f.when ?? '') || 0, need);
|
|
254
260
|
if (!passed) continue;
|
|
255
261
|
out.push({ key: k, agent: f.agent, change: f.change, risk: f.risk, from: f.model, to: TIERS[tier - 1], passed, heldSince: f.when ?? null });
|
package/package.json
CHANGED
package/start.sh
CHANGED
|
@@ -760,10 +760,14 @@ fi
|
|
|
760
760
|
# `--show-prefix` is the question itself: empty at the work-tree root, `sub/dir/` below it, non-zero exit
|
|
761
761
|
# outside a repo — and it carries no path spelling to disagree about. Verified here at a normal root, a
|
|
762
762
|
# worktree root, a subdirectory and a non-repo.
|
|
763
|
-
|
|
763
|
+
# ABSOLUTE, from git's own answer for the toplevel. A relative value resolves against the work tree a commit runs
|
|
764
|
+
# in, and a linked worktree (one Claude Code opens included) has no .claude/ when it is gitignored: measured, the
|
|
765
|
+
# trace scan blocked a commit at the root and let the same commit through in a worktree, with no hook run at all.
|
|
766
|
+
if PFX="$(git rev-parse --show-prefix 2>/dev/null)" && [ -z "$PFX" ] && TOP="$(git rev-parse --show-toplevel 2>/dev/null)" \
|
|
767
|
+
&& [ -n "$TOP" ] && git config core.hooksPath "$TOP/.claude/hooks" 2>/dev/null; then
|
|
764
768
|
{ _mt 'trace scan: core.hooksPath -> .claude/hooks (§4.1/§4.2 commit gate active)'; echo " ${_M}"; }
|
|
765
769
|
else
|
|
766
|
-
{ _mt 'NOTE: no git repository at this level; after %s run: %s' "'git init'"
|
|
770
|
+
{ _mt 'NOTE: no git repository at this level; after %s run: %s' "'git init'" "git config core.hooksPath \"\$PWD/.claude/hooks\""; echo " ${_M}"; }
|
|
767
771
|
fi
|
|
768
772
|
rm -rf "$SRC"
|
|
769
773
|
echo
|