muse-crew 0.4.3 → 0.4.4
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/AGENTS.md +2 -0
- package/API.md +68 -21
- package/README.md +18 -2
- package/docs/guide.md +81 -11
- package/docs/visual-verdict.md +120 -0
- package/identities/hazel.md +22 -0
- package/lib/AGENTS.md +5 -1
- package/lib/build-registry.js +80 -0
- package/lib/compose-evidence.py +144 -0
- package/lib/crew-release.sh +9 -1
- package/lib/merge-lock.sh +18 -0
- package/lib/orphan-sweep.sh +70 -7
- package/lib/publish-npm.sh +18 -11
- package/lib/test-merge-lock.sh +69 -0
- package/lib/test-orphan-sweep.sh +74 -8
- package/lib/test-version-write.sh +97 -0
- package/lib/test-worktree-backend.sh +79 -0
- package/lib/worktree-lifecycle.sh +69 -28
- package/package.json +1 -1
- package/seed/cron-body-template.md +5 -3
- package/seed/workflows/bugfix.md +7 -2
- package/seed/workflows/chore.md +7 -3
- package/seed/workflows/standard.md +7 -2
- package/workflows/AGENTS.md +4 -4
- package/workflows/bugfix.js +961 -167
- package/workflows/chore.js +826 -140
- package/workflows/crew-dispatch.js +405 -98
- package/workflows/crew-init.js +4 -35
- package/workflows/docs.js +342 -22
- package/workflows/standard.js +965 -159
- package/workflows/tests/retry-cap.test.mjs +102 -0
- package/workflows/tests/work-agent-failure.test.mjs +122 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# test-worktree-backend.sh — regression tests for lib/worktree-lifecycle.sh
|
|
3
|
+
# (git worktree backend).
|
|
4
|
+
#
|
|
5
|
+
# Lifecycle on a scratch repo:
|
|
6
|
+
# validate → prepare (CREATED) → prepare (REUSED) → inspect → status →
|
|
7
|
+
# cleanup → cleanup (idempotent) → dirty-main preflight (exit 4)
|
|
8
|
+
set -u
|
|
9
|
+
|
|
10
|
+
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
11
|
+
LIFECYCLE="$REPO_DIR/lib/worktree-lifecycle.sh"
|
|
12
|
+
|
|
13
|
+
fail() { echo "FAIL: $1"; exit 1; }
|
|
14
|
+
|
|
15
|
+
T=/tmp/crew-git-backend-test
|
|
16
|
+
rm -rf "$T"
|
|
17
|
+
mkdir -p "$T"
|
|
18
|
+
cd "$T"
|
|
19
|
+
git init -q -b main .
|
|
20
|
+
git config user.email test@test.t
|
|
21
|
+
git config user.name test
|
|
22
|
+
echo x > f.txt
|
|
23
|
+
git add -A
|
|
24
|
+
git commit -qm init
|
|
25
|
+
|
|
26
|
+
export CREW_REPO="$T"
|
|
27
|
+
tid="backendtest1"
|
|
28
|
+
|
|
29
|
+
# validate: good id passes, bad id is rejected
|
|
30
|
+
bash "$LIFECYCLE" validate "$tid" >/dev/null || fail "validate rejected a good id"
|
|
31
|
+
bash "$LIFECYCLE" validate "bad id!" >/dev/null 2>&1 && fail "validate accepted a bad id"
|
|
32
|
+
|
|
33
|
+
# prepare: creates worktree + branch + registry entry
|
|
34
|
+
out=$(bash "$LIFECYCLE" prepare "$tid") || fail "prepare exited non-zero: $out"
|
|
35
|
+
echo "$out" | grep -q '^CREATED' || fail "prepare: expected CREATED, got: $out"
|
|
36
|
+
echo "$out" | grep -q '^BASE: ' || fail "prepare: no BASE: line"
|
|
37
|
+
[ -d "$T/.worktrees/$tid" ] || fail "prepare: .worktrees/$tid missing"
|
|
38
|
+
git -C "$T" rev-parse --verify "task/$tid" >/dev/null 2>&1 || fail "prepare: branch task/$tid missing"
|
|
39
|
+
[ -f "$T/.worktrees/.registry/$tid" ] || fail "prepare: registry entry missing"
|
|
40
|
+
grep -q '^branch=task/backendtest1$' "$T/.worktrees/.registry/$tid" || fail "prepare: registry branch wrong"
|
|
41
|
+
grep -q "^path=$T/.worktrees/$tid\$" "$T/.worktrees/.registry/$tid" || fail "prepare: registry path wrong"
|
|
42
|
+
|
|
43
|
+
# prepare again: reuses the existing worktree
|
|
44
|
+
out=$(bash "$LIFECYCLE" prepare "$tid") || fail "prepare (reuse) exited non-zero"
|
|
45
|
+
echo "$out" | grep -q '^REUSED' || fail "prepare: expected REUSED on second run: $out"
|
|
46
|
+
|
|
47
|
+
# inspect: diffs the task branch against main
|
|
48
|
+
echo change >> "$T/.worktrees/$tid/f.txt"
|
|
49
|
+
(cd "$T/.worktrees/$tid" && git commit -qam work)
|
|
50
|
+
out=$(bash "$LIFECYCLE" inspect "$tid") || fail "inspect exited non-zero"
|
|
51
|
+
echo "$out" | grep -q "=== Branch: task/$tid ===" || fail "inspect: wrong branch header"
|
|
52
|
+
echo "$out" | grep -q "change" || fail "inspect: diff missing the worktree change"
|
|
53
|
+
|
|
54
|
+
# status: reports registry, worktree, branch
|
|
55
|
+
out=$(bash "$LIFECYCLE" status "$tid") || fail "status exited non-zero"
|
|
56
|
+
echo "$out" | grep -q "=== Worktree: $tid ===" || fail "status: missing header"
|
|
57
|
+
echo "$out" | grep -q "task/$tid" || fail "status: missing branch info"
|
|
58
|
+
|
|
59
|
+
# cleanup: removes worktree + branch + registry entry
|
|
60
|
+
out=$(bash "$LIFECYCLE" cleanup "$tid") || fail "cleanup exited non-zero"
|
|
61
|
+
[ -d "$T/.worktrees/$tid" ] && fail "cleanup: worktree still exists"
|
|
62
|
+
git -C "$T" rev-parse --verify "task/$tid" >/dev/null 2>&1 && fail "cleanup: branch still exists"
|
|
63
|
+
[ -f "$T/.worktrees/.registry/$tid" ] && fail "cleanup: registry entry still exists"
|
|
64
|
+
|
|
65
|
+
# cleanup again: idempotent
|
|
66
|
+
out=$(bash "$LIFECYCLE" cleanup "$tid") || fail "cleanup (idempotent) exited non-zero"
|
|
67
|
+
echo "$out" | grep -q "already clean" || fail "cleanup: expected already-clean on second run"
|
|
68
|
+
|
|
69
|
+
# prepare fails closed when main is dirty (exit 4)
|
|
70
|
+
echo dirty >> "$T/f.txt"
|
|
71
|
+
if bash "$LIFECYCLE" prepare "backendtest2" >/dev/null 2>&1; then
|
|
72
|
+
fail "prepare succeeded with dirty main"
|
|
73
|
+
else
|
|
74
|
+
[ "$?" -eq 4 ] || fail "prepare with dirty main: expected exit 4"
|
|
75
|
+
fi
|
|
76
|
+
git -C "$T" checkout -q -- f.txt
|
|
77
|
+
|
|
78
|
+
rm -rf "$T"
|
|
79
|
+
echo "worktree-backend: OK"
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# worktree-lifecycle.sh —
|
|
2
|
+
# worktree-lifecycle.sh — worktree lifecycle manager for Muse Crew
|
|
3
|
+
#
|
|
4
|
+
# Git backend: task worktrees live in $REPO/.worktrees/<task_id>, on
|
|
5
|
+
# branches named task/<task_id>. This script is the single seam where the
|
|
6
|
+
# worktree strategy lives — workflows and agents never run raw git worktree
|
|
7
|
+
# commands; they call these lifecycle commands instead.
|
|
8
|
+
#
|
|
9
|
+
# The crew's registry ($REPO/.worktrees/.registry/<task_id>) is the source
|
|
10
|
+
# of truth for task→branch/path. Never reconstruct the mapping from git
|
|
11
|
+
# state alone.
|
|
3
12
|
#
|
|
4
13
|
# Commands:
|
|
5
14
|
# validate <task_id> — check task ID is safe for branches/paths
|
|
@@ -30,6 +39,28 @@ ORPHAN_SWEEP="$LIB_DIR/orphan-sweep.sh"
|
|
|
30
39
|
|
|
31
40
|
# --- helpers ---
|
|
32
41
|
|
|
42
|
+
# Task branch name: task/<id>. The registry wins when the task was
|
|
43
|
+
# prepared before.
|
|
44
|
+
resolve_branch() {
|
|
45
|
+
local task_id="$1" b
|
|
46
|
+
if [ -f "$REGISTRY_DIR/$task_id" ]; then
|
|
47
|
+
b=$(grep '^branch=' "$REGISTRY_DIR/$task_id" | cut -d= -f2-)
|
|
48
|
+
if [ -n "$b" ]; then printf '%s' "$b"; return 0; fi
|
|
49
|
+
fi
|
|
50
|
+
printf 'task/%s' "$task_id"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Worktree path: $REPO/.worktrees/<id>. The registry wins when the task
|
|
54
|
+
# was prepared before.
|
|
55
|
+
resolve_path() {
|
|
56
|
+
local task_id="$1" p
|
|
57
|
+
if [ -f "$REGISTRY_DIR/$task_id" ]; then
|
|
58
|
+
p=$(grep '^path=' "$REGISTRY_DIR/$task_id" | cut -d= -f2-)
|
|
59
|
+
if [ -n "$p" ]; then printf '%s' "$p"; return 0; fi
|
|
60
|
+
fi
|
|
61
|
+
printf '%s/%s' "$WORKTREE_DIR" "$task_id"
|
|
62
|
+
}
|
|
63
|
+
|
|
33
64
|
validate_task_id() {
|
|
34
65
|
local id="$1"
|
|
35
66
|
if [[ ! "$id" =~ ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]]; then
|
|
@@ -57,12 +88,12 @@ require_clean_main() {
|
|
|
57
88
|
}
|
|
58
89
|
|
|
59
90
|
register() {
|
|
60
|
-
local task_id="$1" base_commit="$2"
|
|
91
|
+
local task_id="$1" base_commit="$2" branch="$3" wt_path="$4"
|
|
61
92
|
mkdir -p "$REGISTRY_DIR"
|
|
62
93
|
cat > "$REGISTRY_DIR/$task_id" <<EOF
|
|
63
94
|
task_id=$task_id
|
|
64
|
-
branch
|
|
65
|
-
path=$
|
|
95
|
+
branch=$branch
|
|
96
|
+
path=$wt_path
|
|
66
97
|
base_commit=$base_commit
|
|
67
98
|
created=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
68
99
|
EOF
|
|
@@ -96,7 +127,7 @@ cmd_prepare() {
|
|
|
96
127
|
return 0
|
|
97
128
|
fi
|
|
98
129
|
|
|
99
|
-
# Preflight: main must be clean
|
|
130
|
+
# Preflight: main must be clean — prepare fails closed.
|
|
100
131
|
require_clean_main || exit 4
|
|
101
132
|
|
|
102
133
|
local base_commit
|
|
@@ -107,7 +138,7 @@ cmd_prepare() {
|
|
|
107
138
|
mkdir -p "$WORKTREE_DIR"
|
|
108
139
|
git worktree add "$WORKTREE_DIR/$task_id" -b "task/$task_id"
|
|
109
140
|
|
|
110
|
-
register "$task_id" "$base_commit"
|
|
141
|
+
register "$task_id" "$base_commit" "task/$task_id" "$WORKTREE_DIR/$task_id"
|
|
111
142
|
|
|
112
143
|
echo "CREATED: .worktrees/$task_id on branch task/$task_id"
|
|
113
144
|
echo "BASE: $base_commit"
|
|
@@ -117,26 +148,29 @@ cmd_inspect() {
|
|
|
117
148
|
local task_id="$1"
|
|
118
149
|
validate_task_id "$task_id"
|
|
119
150
|
|
|
151
|
+
local branch
|
|
152
|
+
branch=$(resolve_branch "$task_id")
|
|
153
|
+
|
|
120
154
|
cd "$REPO"
|
|
121
155
|
|
|
122
156
|
# Verify the branch exists
|
|
123
|
-
if ! git rev-parse --verify "
|
|
124
|
-
echo "ERROR: branch
|
|
157
|
+
if ! git rev-parse --verify "$branch" >/dev/null 2>&1; then
|
|
158
|
+
echo "ERROR: branch $branch does not exist"
|
|
125
159
|
return 1
|
|
126
160
|
fi
|
|
127
161
|
|
|
128
|
-
echo "=== Branch:
|
|
162
|
+
echo "=== Branch: $branch ==="
|
|
129
163
|
local tip
|
|
130
|
-
tip=$(git rev-parse "
|
|
164
|
+
tip=$(git rev-parse "$branch")
|
|
131
165
|
echo "TIP: $tip"
|
|
132
166
|
echo ""
|
|
133
167
|
echo "=== Commits ahead of main ==="
|
|
134
|
-
git log --oneline "main
|
|
168
|
+
git log --oneline "main..$branch"
|
|
135
169
|
echo ""
|
|
136
|
-
echo "=== Diff: main
|
|
137
|
-
git diff --stat "main
|
|
170
|
+
echo "=== Diff: main...$branch ==="
|
|
171
|
+
git diff --stat "main...$branch"
|
|
138
172
|
echo ""
|
|
139
|
-
git diff "main
|
|
173
|
+
git diff "main...$branch"
|
|
140
174
|
}
|
|
141
175
|
|
|
142
176
|
cmd_integrate() {
|
|
@@ -144,24 +178,27 @@ cmd_integrate() {
|
|
|
144
178
|
local commit_msg="${2:-merge: $task_id}"
|
|
145
179
|
validate_task_id "$task_id"
|
|
146
180
|
|
|
181
|
+
local branch
|
|
182
|
+
branch=$(resolve_branch "$task_id")
|
|
183
|
+
|
|
147
184
|
cd "$REPO"
|
|
148
185
|
|
|
149
186
|
# Preflight: main must be clean
|
|
150
187
|
require_clean_main || exit 4
|
|
151
188
|
|
|
152
189
|
# Verify task branch exists and has commits ahead of main
|
|
153
|
-
if ! git rev-parse --verify "
|
|
154
|
-
echo "ERROR: branch
|
|
190
|
+
if ! git rev-parse --verify "$branch" >/dev/null 2>&1; then
|
|
191
|
+
echo "ERROR: branch $branch does not exist"
|
|
155
192
|
return 1
|
|
156
193
|
fi
|
|
157
194
|
|
|
158
195
|
local ahead
|
|
159
|
-
ahead=$(git rev-list --count "main
|
|
196
|
+
ahead=$(git rev-list --count "main..$branch")
|
|
160
197
|
if [ "$ahead" -eq 0 ]; then
|
|
161
198
|
# Approved empty diff: the deliverable was runtime state (cron,
|
|
162
199
|
# scheduler, dashboard config), not a repo change. Nothing to merge,
|
|
163
200
|
# nothing to serialize — the merge lock is intentionally not taken.
|
|
164
|
-
echo "MERGED_EMPTY:
|
|
201
|
+
echo "MERGED_EMPTY: $branch has no commits ahead of main — runtime-state deliverable, nothing to merge"
|
|
165
202
|
return 0
|
|
166
203
|
fi
|
|
167
204
|
|
|
@@ -174,7 +211,7 @@ cmd_integrate() {
|
|
|
174
211
|
echo "$lock_result"
|
|
175
212
|
|
|
176
213
|
# Merge
|
|
177
|
-
if ! git merge --no-ff "
|
|
214
|
+
if ! git merge --no-ff "$branch" -m "$commit_msg" 2>&1; then
|
|
178
215
|
echo "CONFLICT: merge failed — aborting"
|
|
179
216
|
git merge --abort 2>/dev/null || true
|
|
180
217
|
exit 3
|
|
@@ -248,6 +285,10 @@ cmd_status() {
|
|
|
248
285
|
local task_id="$1"
|
|
249
286
|
validate_task_id "$task_id"
|
|
250
287
|
|
|
288
|
+
local branch wt_path
|
|
289
|
+
branch=$(resolve_branch "$task_id")
|
|
290
|
+
wt_path=$(resolve_path "$task_id")
|
|
291
|
+
|
|
251
292
|
cd "$REPO"
|
|
252
293
|
|
|
253
294
|
echo "=== Worktree: $task_id ==="
|
|
@@ -261,11 +302,11 @@ cmd_status() {
|
|
|
261
302
|
fi
|
|
262
303
|
|
|
263
304
|
# Worktree existence
|
|
264
|
-
if [ -d "$
|
|
265
|
-
echo "Worktree: exists at
|
|
305
|
+
if [ -n "$wt_path" ] && [ -d "$wt_path" ]; then
|
|
306
|
+
echo "Worktree: exists at $wt_path"
|
|
266
307
|
local head dirty
|
|
267
|
-
head=$(cd "$
|
|
268
|
-
dirty=$(cd "$
|
|
308
|
+
head=$(cd "$wt_path" && git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
309
|
+
dirty=$(cd "$wt_path" && git status --porcelain 2>/dev/null | wc -l)
|
|
269
310
|
echo "HEAD: $head"
|
|
270
311
|
[ "$dirty" -gt 0 ] && echo "Dirty: $dirty uncommitted changes" || echo "Dirty: clean"
|
|
271
312
|
else
|
|
@@ -273,13 +314,13 @@ cmd_status() {
|
|
|
273
314
|
fi
|
|
274
315
|
|
|
275
316
|
# Branch existence and merge status
|
|
276
|
-
if git rev-parse --verify "
|
|
317
|
+
if git rev-parse --verify "$branch" >/dev/null 2>&1; then
|
|
277
318
|
local ahead behind
|
|
278
|
-
ahead=$(git rev-list --count "main
|
|
279
|
-
behind=$(git rev-list --count "
|
|
280
|
-
echo "Branch:
|
|
319
|
+
ahead=$(git rev-list --count "main..$branch" 2>/dev/null || echo "?")
|
|
320
|
+
behind=$(git rev-list --count "$branch..main" 2>/dev/null || echo "?")
|
|
321
|
+
echo "Branch: $branch (${ahead} ahead, ${behind} behind main)"
|
|
281
322
|
local merged
|
|
282
|
-
merged=$(git branch --merged main 2>/dev/null | sed 's/^[* +]*//' | grep -Fx "
|
|
323
|
+
merged=$(git branch --merged main 2>/dev/null | sed 's/^[* +]*//' | grep -Fx "$branch" || true)
|
|
283
324
|
[ -n "$merged" ] && echo "Merged: yes" || echo "Merged: no"
|
|
284
325
|
else
|
|
285
326
|
echo "Branch: not found"
|
package/package.json
CHANGED
|
@@ -6,15 +6,17 @@ You are the dispatch trigger for Muse Crew. Run the authoritative dispatcher wor
|
|
|
6
6
|
|
|
7
7
|
1. **Load tools:** Call tool_search_load_tool_namespace with paths ["workflow_launch"].
|
|
8
8
|
|
|
9
|
-
2. **
|
|
9
|
+
2. **Load the workflow registry:** Read the file "{crewHome}/workflows/registry.json" with the read tool and parse it as JSON. If the file does not exist (the live release predates the registry), proceed without it — omit the `registry` arg and the dispatcher will load the registry the slow way and log a warning.
|
|
10
|
+
|
|
11
|
+
3. **Run the dispatcher:** Call workflow_launch with scriptPath "{crewHome}/workflows/crew-dispatch.js" and args {"dashboardSlug": "{dashboardSlug}", "crewHome": "{crewHome}", "registry": <parsed registry JSON, or omit the key when the file was missing>}.
|
|
10
12
|
|
|
11
13
|
Wait for it to complete. It reads the board, determines eligibility, claims tasks, acknowledges the poll, and returns structured results.
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
4. **Report claims:** Extract the `claims` array from the dispatcher result. For each claim, emit one line:
|
|
14
16
|
LAUNCH: script={claim.scriptPath} args={JSON.stringify(claim.args)}
|
|
15
17
|
|
|
16
18
|
If the dispatcher returned no claims or the claims array is empty, report: NO_DISPATCH
|
|
17
19
|
|
|
18
20
|
Do NOT call workflow_launch_async for any task workflow. The main chat agent does that.
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
5. Exit silently.
|
package/seed/workflows/bugfix.md
CHANGED
|
@@ -6,7 +6,11 @@ The full software engineering workflow. Use for bug reports where reproduction m
|
|
|
6
6
|
|
|
7
7
|
### Triage
|
|
8
8
|
**Identity:** Sage
|
|
9
|
-
Validate, prioritize, connect dependencies, assign this workflow. If the task needs decomposition, break it into subtasks first.
|
|
9
|
+
Validate, prioritize, connect dependencies, assign this workflow. If the task needs decomposition, break it into subtasks first. Flags the task experiential when it changes anything rendered and visible in the artifact.
|
|
10
|
+
|
|
11
|
+
### Capture
|
|
12
|
+
**Identity:** Hazel
|
|
13
|
+
Baseline evidence for experiential tasks only — skipped otherwise. The capture itself is parent-driven; the workflow records a baseline request and parks for the parent protocol (`docs/visual-verdict.md`). After two requests the task continues with `baseline: none`.
|
|
10
14
|
|
|
11
15
|
### Reproduce
|
|
12
16
|
**Identity:** Hazel
|
|
@@ -15,7 +19,7 @@ Validate, prioritize, connect dependencies, assign this workflow. If the task ne
|
|
|
15
19
|
|
|
16
20
|
### Map
|
|
17
21
|
**Identity:** Mara
|
|
18
|
-
Update the task with a solution-oriented spec. Research options, pick the shortest path, write it clearly enough that the builder doesn't need to ask questions.
|
|
22
|
+
Update the task with a solution-oriented spec. Research options, pick the shortest path, write it clearly enough that the builder doesn't need to ask questions. For experiential tasks, the spec cannot be written without baseline evidence (or an explicit `baseline: none`) — without it Map bounces back to Capture.
|
|
19
23
|
|
|
20
24
|
### Build
|
|
21
25
|
**Identity:** Wren
|
|
@@ -40,3 +44,4 @@ Optional. Ships the merged code to the project's publish target (`deploy_type` o
|
|
|
40
44
|
**Personas:** Yes — Hazel wears a persona costume to test from that perspective.
|
|
41
45
|
**Constraint:** No code context. Same tools and process as reproduction. Pass or fail. File follow-up tasks for related issues found during testing.
|
|
42
46
|
Fail if public-affecting changes lack public docs. Public docs are not code — Hazel reads them as a user would.
|
|
47
|
+
**Visual verdict:** for experiential artifact tasks, the QA agent covers the mechanical checks only — the visual verdict is owned by the parent after the rendered post-change inspection results arrive (`docs/visual-verdict.md`). No experiential task completes without a recorded visual PASS.
|
package/seed/workflows/chore.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# Chore
|
|
2
2
|
|
|
3
|
-
For routine maintenance and simple tasks. Like Standard but without QA — the change is low-risk enough to ship after review.
|
|
3
|
+
For routine maintenance and simple tasks. Like Standard but without QA — the change is low-risk enough to ship after review. Capture keeps its baseline pass for experiential tasks, but there is no visual verdict and no QA gate here.
|
|
4
4
|
|
|
5
5
|
## Steps
|
|
6
6
|
|
|
7
7
|
### Triage
|
|
8
8
|
**Identity:** Sage
|
|
9
|
-
Validate, prioritize, connect dependencies, assign this workflow.
|
|
9
|
+
Validate, prioritize, connect dependencies, assign this workflow. Flags the task experiential when it changes anything rendered and visible in the artifact.
|
|
10
|
+
|
|
11
|
+
### Capture
|
|
12
|
+
**Identity:** Hazel
|
|
13
|
+
Baseline evidence for experiential tasks only — skipped otherwise. The capture itself is parent-driven; the workflow records a baseline request and parks for the parent protocol (`docs/visual-verdict.md`). After two requests the task continues with `baseline: none`.
|
|
10
14
|
|
|
11
15
|
### Map
|
|
12
16
|
**Identity:** Mara
|
|
13
|
-
Research options, pick the path, write the spec.
|
|
17
|
+
Research options, pick the path, write the spec. For experiential tasks, the spec cannot be written without baseline evidence (or an explicit `baseline: none`) — without it Map bounces back to Capture.
|
|
14
18
|
|
|
15
19
|
### Build
|
|
16
20
|
**Identity:** Wren
|
|
@@ -6,11 +6,15 @@ The default workflow for feature work and improvements. Like Bugfix but without
|
|
|
6
6
|
|
|
7
7
|
### Triage
|
|
8
8
|
**Identity:** Sage
|
|
9
|
-
Validate, prioritize, connect dependencies, assign this workflow.
|
|
9
|
+
Validate, prioritize, connect dependencies, assign this workflow. Flags the task experiential when it changes anything rendered and visible in the artifact.
|
|
10
|
+
|
|
11
|
+
### Capture
|
|
12
|
+
**Identity:** Hazel
|
|
13
|
+
Baseline evidence for experiential tasks only — skipped otherwise. The capture itself is parent-driven; the workflow records a baseline request and parks for the parent protocol (`docs/visual-verdict.md`). After two requests the task continues with `baseline: none` and final QA judges on the rubric alone.
|
|
10
14
|
|
|
11
15
|
### Map
|
|
12
16
|
**Identity:** Mara
|
|
13
|
-
Research options, pick the path, write the spec.
|
|
17
|
+
Research options, pick the path, write the spec. For experiential tasks, the spec cannot be written without baseline evidence (or an explicit `baseline: none`) — without it Map bounces back to Capture.
|
|
14
18
|
|
|
15
19
|
### Build
|
|
16
20
|
**Identity:** Wren
|
|
@@ -35,3 +39,4 @@ Optional. Ships the merged code to the project's publish target (`deploy_type` o
|
|
|
35
39
|
**Personas:** Yes — Hazel wears a persona costume to test from that perspective.
|
|
36
40
|
**Constraint:** No code context. Pass or fail. File follow-up tasks for related issues found during testing.
|
|
37
41
|
Fail if public-affecting changes lack public docs. Public docs are not code — Hazel reads them as a user would.
|
|
42
|
+
**Visual verdict:** for experiential artifact tasks, the QA agent covers the mechanical checks only — the visual verdict is owned by the parent after the rendered post-change inspection results arrive (`docs/visual-verdict.md`). No experiential task completes without a recorded visual PASS.
|
package/workflows/AGENTS.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Executable Muse workflow scripts (JavaScript). These are what the workflow runtime actually runs.
|
|
4
4
|
|
|
5
|
-
- `crew-dispatch.js` — reads the board,
|
|
5
|
+
- `crew-dispatch.js` — reads the board, recommends eligible tasks, returns structured launch records (the launched workflow self-claims; the dispatcher never writes claims)
|
|
6
6
|
- `crew-init.js` — sets up a new crew instance: orchestration folders, dashboard, cron, sample project
|
|
7
|
-
- `standard.js` — default task workflow: Triage → Map → Build → Review → Integrate → Publish → QA
|
|
8
|
-
- `bugfix.js` — adds
|
|
9
|
-
- `chore.js` — drops QA (low-risk)
|
|
7
|
+
- `standard.js` — default task workflow: Triage → Capture → Map → Build → Review → Integrate → Publish → QA
|
|
8
|
+
- `bugfix.js` — adds Capture after Triage, then Reproduce
|
|
9
|
+
- `chore.js` — adds Capture after Triage, drops QA (low-risk)
|
|
10
10
|
- `docs.js` — Tate writes, Cass reviews
|
|
11
11
|
|
|
12
12
|
The `.js` scripts here are distinct from the `.md` definitions in `seed/workflows/` and `.orchestration/workflows/`. The `.md` files describe phases and prompts; these `.js` files execute them.
|