muse-crew 0.1.0 → 0.2.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/AGENTS.md CHANGED
@@ -5,7 +5,7 @@ Muse Crew source repository. The repo is the product; the personal instance (`$C
5
5
  ## Structure
6
6
 
7
7
  - `API.md` — the Crew API contract: every action a task service must implement
8
- - `.orchestration/` — this project's crew configuration (project.json)
8
+ - `.orchestration/` — crew configuration notes (deploy config lives in the dashboard's project record — the single source of truth)
9
9
  - `identities/` — crew member character files and portraits
10
10
  - `lib/` — shell scripts for release, merge, worktree, and cleanup
11
11
  - `personas/` — QA perspective costumes for Hazel
package/API.md CHANGED
@@ -48,6 +48,13 @@ Atomically claim a task for a workflow step. Used by the dispatcher and by workf
48
48
  | `step` | string (1–120) | no | The workflow phase name |
49
49
  | `notes` | string (≤ 3000) | no | Defaults to `""` |
50
50
 
51
+ Returns one of:
52
+
53
+ - `{ "ok": true, "claimed": true, "session_id": "<uuid>", "session": {...} }`
54
+ - `{ "ok": true, "claimed": false, "reason": "already_claimed", "existing_session_id": "<uuid>" }`
55
+
56
+ `claimed` is the single field callers branch on. `reason` is present only when `claimed` is false.
57
+
51
58
  ### `recovertask`
52
59
 
53
60
  Send a stuck or failed task to a specific workflow phase for recovery.
@@ -102,6 +109,7 @@ Read the event timeline.
102
109
 
103
110
  | Field | Type | Required | Notes |
104
111
  |-------|------|----------|-------|
112
+ | `task_id` | uuid | no | Return only events for this task |
105
113
  | `limit` | integer (1–100) | no | Defaults to 50 |
106
114
 
107
115
  ---
@@ -129,12 +137,11 @@ Register a new project.
129
137
  | `id` | slug | yes | Unique project identifier |
130
138
  | `display_name` | string (1–120) | yes | |
131
139
  | `repo_path` | string (1–1000) | yes | Absolute path to the project's Git repo |
132
- | `deploy_type` | `artifact` · `repo` | yes | |
140
+ | `deploy_type` | `npm` · `artifact` · `vercel` · empty string | yes | Publish target: `npm` publishes the package to the npm registry, `artifact` rebuilds the live artifact, `vercel` is not yet implemented (blocks the task), empty skips the Publish phase |
133
141
  | `deploy_slug` | slug or null | no | Required when `deploy_type` is `artifact` |
134
142
  | `description` | string (≤ 3000) | no | |
135
143
  | `simultaneity` | integer (1–100) | no | Max concurrent tasks; defaults to 2 |
136
144
  | `quiesced` | boolean | no | Start paused; defaults to false |
137
- | `idle_hunting` | boolean | no | Defaults to false |
138
145
 
139
146
  ### `updateproject`
140
147
 
@@ -203,6 +210,21 @@ Set a global configuration value.
203
210
  | `key` | string (1–80) | yes | |
204
211
  | `value` | string (≤ 10000) | yes | |
205
212
 
213
+ ### `setprovenance`
214
+
215
+ Stamp publication provenance. Called by the crew Publish phase after rebuilding the artifact.
216
+
217
+ | Field | Type | Required | Notes |
218
+ |-------|------|----------|-------|
219
+ | `source_commit` | 40-char hex | yes | Repo commit the artifact was built from |
220
+ | `crew_release` | 40-char hex | yes | Active crew release (`$CREW_HOME/current`) at publish time |
221
+ | `published_at` | ISO 8601 datetime (UTC) | yes | |
222
+ | `task_id` | string | no | Publishing task, for traceability |
223
+
224
+ ### `getprovenance`
225
+
226
+ Read the last publication provenance. Returns `{ "provenance": { "source_commit", "crew_release", "published_at" } }`, or `{ "provenance": null }` when nothing has been published yet.
227
+
206
228
  ---
207
229
 
208
230
  ## Not part of this API
package/README.md CHANGED
@@ -14,7 +14,7 @@ Five things make it go.
14
14
 
15
15
  **Identities** are the characters who do the work — values, taste, writing style. What makes the reviewer exacting and the QA agent persistent.
16
16
 
17
- **Projects** connect a repository to a deploy target. Tasks belong to projects; the dispatcher routes each task through its project's configuration.
17
+ **Projects** connect a repository to a publish target. Every task's merged work is pushed to the project's private Git repo; the optional Publish phase then ships it to the target. Tasks belong to projects; the dispatcher routes each task through its project's configuration.
18
18
 
19
19
  **Scheduling** uses [Muse's](https://muse.ai) always-on cron. The dispatcher checks the board every few minutes, claims what's ready, and puts the right agent on the right phase. Review rejects bounce back automatically. The system keeps going until the work is done or stuck.
20
20
 
@@ -26,15 +26,15 @@ The repo ships workflows and identities for a software development crew — one
26
26
  |----------|------|----------------|
27
27
  | **Sage** | Triage | Fast routing — classifies and prioritizes before anything else runs |
28
28
  | **Mara** | Designer | Makes tasks solution-oriented before building starts |
29
- | **Wren** | Builder | Trusts the plan, lets commits speak. Also handles integration and deployment |
29
+ | **Wren** | Builder | Trusts the plan, lets commits speak. Also handles integration and publishing |
30
30
  | **Cass** | Reviewer | Fair but exacting — holds the spec as the contract until the work is tight |
31
31
  | **Hazel** | QA | Code-blind by design. Persistent. Wears persona costumes for multi-lens testing |
32
32
  | **Tate** | Docs | Observational, jargon-hostile |
33
33
 
34
34
  ```
35
- standard: Triage → Map → Build → Review → Integrate → Deploy → QA
36
- bugfix: Triage → Reproduce → Map → Build → Review → Integrate → Deploy → QA
37
- chore: Triage → Map → Build → Review → Integrate → Deploy
35
+ standard: Triage → Map → Build → Review → Integrate → Publish → QA
36
+ bugfix: Triage → Reproduce → Map → Build → Review → Integrate → Publish → QA
37
+ chore: Triage → Map → Build → Review → Integrate → Publish
38
38
  docs: Triage → Write → Review
39
39
  ```
40
40
 
package/docs/guide.md CHANGED
@@ -5,7 +5,7 @@ This is the full setup and operations reference. If you're new, start with the [
5
5
  ## Components
6
6
 
7
7
  **In this repo:**
8
- - **Workflow scripts** — walk each task through its phases (Triage → Map → Build → Review → Integrate → Deploy → QA). The defaults are built for software, but you can create your own workflows for any kind of work.
8
+ - **Workflow scripts** — walk each task through its phases (Triage → Map → Build → Review → Integrate → Publish → QA). The defaults are built for software, but you can create your own workflows for any kind of work.
9
9
  - A **dispatcher** — reads the board and puts the crew to work.
10
10
  - A **release system** — immutable releases with atomic symlink swap. Works with Git checkouts or npm installs.
11
11
  - An **`.orchestration/` scaffold** — identity files, persona files, workflow documentation, and feedback conventions.
@@ -118,20 +118,19 @@ Required fields:
118
118
  - `id` — kebab-case identifier, unique across all projects.
119
119
  - `display_name` — human-readable name.
120
120
  - `repo_path` — absolute path to the project's Git repository.
121
- - `deploy_type` — `"artifact"` (deploys via artifact edit) or `"repo"` (changes stay in the repo).
121
+ - `deploy_type` — names the project's **publish target**: `"npm"` (installs the immutable release and publishes the package to the npm registry), `"artifact"` (rebuilds the live artifact from disk), `"vercel"` (not yet implemented — blocks the task), or empty (no publish target — the Publish phase is skipped, for prototyping projects). Every project pushes merged work to its private Git repo in Integrate regardless of target — never force-push; a non-fast-forward rejection blocks the task.
122
122
 
123
123
  Optional fields:
124
124
  - `deploy_slug` — the artifact slug, required when `deploy_type` is `"artifact"`.
125
125
  - `description` — free text.
126
126
  - `simultaneity` — max concurrent tasks for this project (default: 2, range: 1–100).
127
127
  - `quiesced` — start paused (default: false).
128
- - `idle_hunting` — not yet implemented (default: false).
129
128
 
130
129
  ### What a registered project needs
131
130
 
132
131
  The project must have:
133
132
  - A Git repository at the specified `repo_path`.
134
- - For artifact deploy type: an existing web artifact at the specified `deploy_slug`.
133
+ - For the `artifact` publish target: an existing web artifact at the specified `deploy_slug`.
135
134
 
136
135
  The project does **not** need:
137
136
  - A `.orchestration/` folder (that belongs to the crew home, not the project).
@@ -191,7 +190,7 @@ Every 3 minutes, the `crew-poll` cron fires:
191
190
 
192
191
  5. **Main-chat agent launches workflows** — receives the claim records and calls `workflow_launch_async` for each one.
193
192
 
194
- 6. **Workflow executes phases** — each phase dispatches an agent in character (the identity assigned to that phase), records the result, and advances the task.
193
+ 6. **Workflow executes phases** — each phase dispatches an agent in character (the identity assigned to that phase), records the result, and advances the task. At every phase boundary the workflow re-reads the task's project: if the task was moved to another project mid-run, the stale run aborts (its session is marked `failed` at the Build/Write step and its worktree is removed from the old repo) so the dispatcher re-launches it with the new project's repo and config.
195
194
 
196
195
  7. **Task completes** — when all phases finish, the dispatcher marks the task `done` on the next tick.
197
196
 
@@ -199,9 +198,9 @@ Every 3 minutes, the `crew-poll` cron fires:
199
198
 
200
199
  | Workflow | Phases |
201
200
  |----------|--------|
202
- | standard | Triage → Map → Build → Review → Integrate → Deploy → QA |
203
- | bugfix | Triage → Reproduce → Map → Build → Review → Integrate → Deploy → QA |
204
- | chore | Triage → Map → Build → Review → Integrate → Deploy |
201
+ | standard | Triage → Map → Build → Review → Integrate → Publish → QA |
202
+ | bugfix | Triage → Reproduce → Map → Build → Review → Integrate → Publish → QA |
203
+ | chore | Triage → Map → Build → Review → Integrate → Publish |
205
204
  | docs | Triage → Write → Review |
206
205
 
207
206
  ## Identities
@@ -214,8 +213,8 @@ Each phase has an assigned identity — a character with a defined personality:
214
213
  | Map | **Mara** | Designer |
215
214
  | Build | **Wren** | Quietest one, trusts the plan |
216
215
  | Review | **Cass** | Fair but exacting — holds the spec as the contract |
217
- | Integrate | **Wren** | Merges the work |
218
- | Deploy | **Wren** | Ships the release |
216
+ | Integrate | **Wren** | Merges the work, pushes `main` to the repo |
217
+ | Publish | **Wren** | Ships the merged code to the publish target (skipped when none) |
219
218
  | QA | **Hazel** | Code-blind, persistent, wears persona costumes |
220
219
  | Reproduce | **Hazel** | Reproduces bugs before fixing |
221
220
  | Write | **Tate** | Docs writer, observational voice |
@@ -281,7 +280,7 @@ The full pause/resume/dispatch cycle has been proven end-to-end.
281
280
 
282
281
  Releases are immutable snapshots of the crew's runtime code.
283
282
 
284
- ### Deploy
283
+ ### Installing a release
285
284
 
286
285
  ```bash
287
286
  crew-release.sh deploy <source-path>
@@ -294,7 +293,7 @@ crew-release.sh deploy <source-path>
294
293
  5. Atomically swaps the `current` symlink to point at the new release.
295
294
  6. Prunes old releases, keeping the 5 most recent.
296
295
 
297
- The `crew-release.sh` manager itself lives at `crewHome/crew-release.sh`, outside the managed releases, so it's never overwritten by a deploy.
296
+ The `crew-release.sh` manager itself lives at `crewHome/crew-release.sh`, outside the managed releases, so it's never overwritten by a release activation.
298
297
 
299
298
  ### Rollback
300
299
 
@@ -306,7 +305,7 @@ Activates the second-newest release by modification time.
306
305
 
307
306
  ### Safety
308
307
 
309
- Running workflows are safe from mid-deploy changes. Muse snapshots workflow JavaScript at launch time, so a deploy that swaps the symlink does not affect workflows already in flight.
308
+ Running workflows are safe from mid-publish changes. Muse snapshots workflow JavaScript at launch time, so a deploy that swaps the symlink does not affect workflows already in flight.
310
309
 
311
310
  ### Release identity
312
311
 
@@ -322,12 +321,10 @@ crew-release.sh current
322
321
 
323
322
  2. **Stuck sessions.** If a workflow dies mid-run, its session stays `running` indefinitely and the cron skips it every tick. Manual cleanup is currently required.
324
323
 
325
- 3. **No idle hunting.** The `idle_hunting` field exists in the project schema but is not implemented. No proactive QA runs when the board is empty.
324
+ 3. **No streaming.** The polling loop checks every 3 minutes. There is no webhook or event-driven dispatch.
326
325
 
327
- 4. **No streaming.** The polling loop checks every 3 minutes. There is no webhook or event-driven dispatch.
326
+ 4. **Single dispatcher.** Only one cron runs the dispatcher. Concurrent ticks are prevented by the session-claiming atomicity, but there is no explicit distributed lock.
328
327
 
329
- 5. **Single dispatcher.** Only one cron runs the dispatcher. Concurrent ticks are prevented by the session-claiming atomicity, but there is no explicit distributed lock.
328
+ 5. **No automatic retry escalation.** Failed tasks retry the same phase on the next tick. There is no backoff, retry limit, or escalation path.
330
329
 
331
- 6. **No automatic retry escalation.** Failed tasks retry the same phase on the next tick. There is no backoff, retry limit, or escalation path.
332
-
333
- 7. **QA is code-blind.** Hazel uses `artifact_inspect` for visual/functional testing. She cannot read source code — this is by design (context isolation), but it means QA catches only what's visible or inspectable through the artifact's public interface.
330
+ 6. **QA is code-blind.** Hazel uses `artifact_inspect` for visual/functional testing. She cannot read source code — this is by design (context isolation), but it means QA catches only what's visible or inspectable through the artifact's public interface.
@@ -59,6 +59,38 @@ cmd_init() {
59
59
  echo "CURRENT: $cur"
60
60
  }
61
61
 
62
+ # ── workflow syntax validation ──────────────────────────────────────
63
+ # Every workflow script must parse before a release can install.
64
+ _validate_workflows() {
65
+ # The workflow runtime accepts top-level `export`, `return`, and `await`
66
+ # (it wraps scripts in an async function), so neither `node --check` on the
67
+ # raw .js (vacuous for ESM — exits 0 even on blatant syntax errors) nor a
68
+ # .mjs check (rejects the runtime-legal top-level `return`) is correct.
69
+ # Emulate the runtime instead: strip `export`, wrap the script in an async
70
+ # function, then node --check the result. Tokenizer errors (e.g. an
71
+ # unterminated string literal) still fail under the wrap.
72
+ local dir="$1"
73
+ local f tmp base
74
+ tmp="$(mktemp -d)"
75
+ for f in "$dir"/workflows/*.js; do
76
+ [ -f "$f" ] || continue
77
+ base="$(basename "$f" .js)"
78
+ {
79
+ echo "async function __crew_workflow__(args) {"
80
+ sed 's/^export //' "$f"
81
+ echo "}"
82
+ } > "$tmp/$base.js"
83
+ if ! node --check "$tmp/$base.js" 2>"$tmp/$base.err"; then
84
+ cat "$tmp/$base.err" >&2
85
+ echo "VALIDATION FAILED: $f does not parse" >&2
86
+ rm -rf "$tmp"
87
+ return 1
88
+ fi
89
+ done
90
+ rm -rf "$tmp"
91
+ echo "VALIDATED: workflow scripts parse"
92
+ }
93
+
62
94
  # ── deploy ────────────────────────────────────────────────────────────
63
95
  # Build, validate, and atomically activate a release from repo HEAD.
64
96
  # Single command — no cross-step lock needed.
@@ -98,6 +130,11 @@ cmd_deploy() {
98
130
  [ -d workflows ] && cp -r workflows "$staging_dir/"
99
131
  [ -d lib ] && cp -r lib "$staging_dir/"
100
132
  fi
133
+ # Gate: refuse to install a release whose workflow scripts don't parse.
134
+ if ! _validate_workflows "$staging_dir"; then
135
+ rm -rf "$staging_dir"
136
+ die "release $hash rejected: workflow syntax validation failed"
137
+ fi
101
138
  # Atomic rename into place
102
139
  mv "$staging_dir" "$release_dir"
103
140
  echo "INSTALLED: $hash"
@@ -2,9 +2,10 @@
2
2
  # orphan-sweep.sh — find and clean orphaned worktrees + stale merge locks
3
3
  #
4
4
  # Usage:
5
- # orphan-sweep.sh report — list orphans and their state (read-only)
5
+ # orphan-sweep.sh report — list orphans (read-only for worktrees);
6
+ # force-releases stale locks with dead PIDs
6
7
  # orphan-sweep.sh clean — remove safe-to-clean orphans (merged branches only)
7
- # and break stale merge locks (>30 min)
8
+ # and force-release stale merge locks (>30 min)
8
9
  #
9
10
  # "Safe to clean" means the task branch is fully merged into main.
10
11
  # Dirty or unmerged worktrees are always preserved and reported.
@@ -40,13 +41,11 @@ if [ -f "$LOCK_FILE" ]; then
40
41
  else
41
42
  echo "STALE_LOCK: held ${age_min}m by $lock_holder (pid ${lock_pid:-none} dead) — threshold ${STALE_LOCK_MIN}m"
42
43
  found=1
43
- if [ "$cmd" = "clean" ]; then
44
- rm -f "$LOCK_FILE"
45
- if [ ! -f "$LOCK_FILE" ]; then
46
- echo " → broken"
47
- else
48
- echo " → ERROR: lock file still exists after rm at $LOCK_FILE"
49
- fi
44
+ rm -f "$LOCK_FILE"
45
+ if [ ! -f "$LOCK_FILE" ]; then
46
+ echo " → released (dead PID)"
47
+ else
48
+ echo " → ERROR: lock file still exists after rm at $LOCK_FILE"
50
49
  fi
51
50
  fi
52
51
  fi
@@ -125,6 +125,14 @@ cmd_inspect() {
125
125
  return 1
126
126
  fi
127
127
 
128
+ echo "=== Branch: task/$task_id ==="
129
+ local tip
130
+ tip=$(git rev-parse "task/$task_id")
131
+ echo "TIP: $tip"
132
+ echo ""
133
+ echo "=== Commits ahead of main ==="
134
+ git log --oneline "main..task/$task_id"
135
+ echo ""
128
136
  echo "=== Diff: main...task/$task_id ==="
129
137
  git diff --stat "main...task/$task_id"
130
138
  echo ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muse-crew",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Opinionated orchestration for Muse — workflows, identities, and tooling for autonomous software development.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -19,21 +19,24 @@ Update the task with a solution-oriented spec. Research options, pick the shorte
19
19
 
20
20
  ### Build
21
21
  **Identity:** Wren
22
- Execute the spec. Write the code, write the tests.
22
+ Execute the spec. Write the code, write the tests. Update public docs for public-affecting changes — docs ship with implementation.
23
23
 
24
24
  ### Review
25
25
  **Identity:** Cass
26
26
  **Constraint:** Independent context. Do not share the builder's context. Read the spec and review the changes cold.
27
+ Verify public docs are current for public-affecting changes; reject if stale.
27
28
 
28
29
  ### Integrate
29
30
  **Identity:** Wren
30
31
  Merge changes into the target branch. Create the commit with a clear message.
32
+ Then push `main` to the project's private remote. Never force-push: a non-fast-forward rejection blocks the task.
31
33
 
32
- ### Deploy
34
+ ### Publish
33
35
  **Identity:** Wren
34
- Deploy the changes.
36
+ Optional. Ships the merged code to the project's publish target (`deploy_type` on the project record): `npm` installs the immutable release and publishes the package to the registry; `artifact` rebuilds the live artifact from disk; `vercel` is not implemented and blocks the task; an empty target skips this phase. The repo push already happened in Integrate — Publish never touches git.
35
37
 
36
38
  ### QA
37
39
  **Identity:** Hazel
38
40
  **Personas:** Yes — Hazel wears a persona costume to test from that perspective.
39
41
  **Constraint:** No code context. Same tools and process as reproduction. Pass or fail. File follow-up tasks for related issues found during testing.
42
+ Fail if public-affecting changes lack public docs. Public docs are not code — Hazel reads them as a user would.
@@ -14,16 +14,18 @@ Research options, pick the path, write the spec.
14
14
 
15
15
  ### Build
16
16
  **Identity:** Wren
17
- Execute the spec.
17
+ Execute the spec. Update public docs for public-affecting changes — docs ship with implementation.
18
18
 
19
19
  ### Review
20
20
  **Identity:** Cass
21
21
  **Constraint:** Independent context. Review cold.
22
+ Verify public docs are current for public-affecting changes; reject if stale.
22
23
 
23
24
  ### Integrate
24
25
  **Identity:** Wren
25
26
  Merge changes into the target branch. Create the commit with a clear message.
27
+ Then push `main` to the project's private remote. Never force-push: a non-fast-forward rejection blocks the task.
26
28
 
27
- ### Deploy
29
+ ### Publish
28
30
  **Identity:** Wren
29
- Deploy the changes.
31
+ Optional. Ships the merged code to the project's publish target (`deploy_type` on the project record): `npm` installs the immutable release and publishes the package to the registry; `artifact` rebuilds the live artifact from disk; `vercel` is not implemented and blocks the task; an empty target skips this phase. The repo push already happened in Integrate — Publish never touches git.
@@ -14,21 +14,24 @@ Research options, pick the path, write the spec.
14
14
 
15
15
  ### Build
16
16
  **Identity:** Wren
17
- Execute the spec.
17
+ Execute the spec. Update public docs for public-affecting changes — docs ship with implementation.
18
18
 
19
19
  ### Review
20
20
  **Identity:** Cass
21
21
  **Constraint:** Independent context. Review cold.
22
+ Verify public docs are current for public-affecting changes; reject if stale.
22
23
 
23
24
  ### Integrate
24
25
  **Identity:** Wren
25
26
  Merge changes into the target branch. Create the commit with a clear message.
27
+ Then push `main` to the project's private remote. Never force-push: a non-fast-forward rejection blocks the task.
26
28
 
27
- ### Deploy
29
+ ### Publish
28
30
  **Identity:** Wren
29
- Deploy the changes.
31
+ Optional. Ships the merged code to the project's publish target (`deploy_type` on the project record): `npm` installs the immutable release and publishes the package to the registry; `artifact` rebuilds the live artifact from disk; `vercel` is not implemented and blocks the task; an empty target skips this phase. The repo push already happened in Integrate — Publish never touches git.
30
32
 
31
33
  ### QA
32
34
  **Identity:** Hazel
33
35
  **Personas:** Yes — Hazel wears a persona costume to test from that perspective.
34
36
  **Constraint:** No code context. Pass or fail. File follow-up tasks for related issues found during testing.
37
+ Fail if public-affecting changes lack public docs. Public docs are not code — Hazel reads them as a user would.
@@ -4,7 +4,7 @@ Executable Muse workflow scripts (JavaScript). These are what the workflow runti
4
4
 
5
5
  - `crew-dispatch.js` — reads the board, claims eligible tasks, returns structured launch records
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 → Deploy → QA
7
+ - `standard.js` — default task workflow: Triage → Map → Build → Review → Integrate → Publish → QA
8
8
  - `bugfix.js` — adds Reproduce after Triage
9
9
  - `chore.js` — drops QA (low-risk)
10
10
  - `docs.js` — Tate writes, Cass reviews