muse-crew 0.1.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 +19 -0
- package/API.md +213 -0
- package/README.md +68 -0
- package/docs/AGENTS.md +3 -0
- package/docs/guide.md +333 -0
- package/identities/AGENTS.md +7 -0
- package/identities/cass.md +36 -0
- package/identities/hazel.md +35 -0
- package/identities/mara.md +31 -0
- package/identities/personality-notes.md +81 -0
- package/identities/sage.md +31 -0
- package/identities/tate.md +35 -0
- package/identities/wren.md +36 -0
- package/lib/AGENTS.md +8 -0
- package/lib/crew-release.sh +188 -0
- package/lib/merge-lock.sh +89 -0
- package/lib/orphan-sweep.sh +95 -0
- package/lib/worktree-lifecycle.sh +313 -0
- package/package.json +29 -0
- package/personas/AGENTS.md +5 -0
- package/personas/beginner.md +24 -0
- package/personas/completionist.md +24 -0
- package/personas/designer.md +26 -0
- package/personas/financial-stakeholder.md +25 -0
- package/personas/power-user.md +26 -0
- package/seed/AGENTS.md +8 -0
- package/seed/cron-body-template.md +20 -0
- package/seed/feedback/AGENTS.md +3 -0
- package/seed/feedback/README.md +40 -0
- package/seed/posture.md +8 -0
- package/seed/workflows/AGENTS.md +3 -0
- package/seed/workflows/bugfix.md +39 -0
- package/seed/workflows/chore.md +29 -0
- package/seed/workflows/docs.md +17 -0
- package/seed/workflows/standard.md +34 -0
- package/workflows/AGENTS.md +12 -0
- package/workflows/bugfix.js +341 -0
- package/workflows/chore.js +294 -0
- package/workflows/crew-dispatch.js +315 -0
- package/workflows/crew-init.js +254 -0
- package/workflows/docs.js +141 -0
- package/workflows/standard.js +350 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Muse Crew source repository. The repo is the product; the personal instance (`$CREW_HOME`) is disposable scaffolding reproduced by `crew-init`.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
- `API.md` — the Crew API contract: every action a task service must implement
|
|
8
|
+
- `.orchestration/` — this project's crew configuration (project.json)
|
|
9
|
+
- `identities/` — crew member character files and portraits
|
|
10
|
+
- `lib/` — shell scripts for release, merge, worktree, and cleanup
|
|
11
|
+
- `personas/` — QA perspective costumes for Hazel
|
|
12
|
+
- `seed/` — init source data: everything `crew-init.js` reads when setting up a new crew instance
|
|
13
|
+
- `workflows/` — executable Muse workflow scripts (JavaScript)
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
|
|
17
|
+
- Git source is authoritative.
|
|
18
|
+
- Never expose this repo publicly.
|
|
19
|
+
- Ship implementation and documentation together.
|
package/API.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Muse Crew API
|
|
2
|
+
|
|
3
|
+
The contract between Muse Crew and any task service implementation. The dispatcher and task workflows call these actions. A conforming task service must implement all of them.
|
|
4
|
+
|
|
5
|
+
The current implementation is the `orchestra-dashboard` web artifact.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Tasks
|
|
10
|
+
|
|
11
|
+
### `createtask`
|
|
12
|
+
|
|
13
|
+
Create a new task on the board.
|
|
14
|
+
|
|
15
|
+
| Field | Type | Required | Notes |
|
|
16
|
+
|-------|------|----------|-------|
|
|
17
|
+
| `title` | string (1–160 chars) | yes | |
|
|
18
|
+
| `description` | string (≤ 5000) | no | Defaults to `""` |
|
|
19
|
+
| `project` | slug | no | Defaults to the service's default project |
|
|
20
|
+
| `workflow` | slug or null | no | Routing label (e.g. `standard`, `bugfix`, `chore`, `docs`) |
|
|
21
|
+
| `priority` | `high` · `normal` · `low` | no | Defaults to `normal` |
|
|
22
|
+
| `state` | `todo` · `in_progress` · `parked` · `done` | no | Defaults to `todo` |
|
|
23
|
+
| `deps` | string[] | no | Task IDs this task depends on |
|
|
24
|
+
|
|
25
|
+
### `updatetask`
|
|
26
|
+
|
|
27
|
+
Update an existing task's fields. Only `id` is required; all other fields are optional patch fields.
|
|
28
|
+
|
|
29
|
+
| Field | Type | Required | Notes |
|
|
30
|
+
|-------|------|----------|-------|
|
|
31
|
+
| `id` | uuid | yes | |
|
|
32
|
+
| `title` | string (1–200) | no | |
|
|
33
|
+
| `description` | string (≤ 3000) | no | |
|
|
34
|
+
| `state` | `todo` · `in_progress` · `parked` · `done` | no | |
|
|
35
|
+
| `priority` | `high` · `normal` · `low` | no | |
|
|
36
|
+
| `project` | slug | no | |
|
|
37
|
+
| `workflow` | slug or null | no | |
|
|
38
|
+
| `deps` | string[] | no | |
|
|
39
|
+
|
|
40
|
+
### `claimtask`
|
|
41
|
+
|
|
42
|
+
Atomically claim a task for a workflow step. Used by the dispatcher and by workflow phases at their start.
|
|
43
|
+
|
|
44
|
+
| Field | Type | Required | Notes |
|
|
45
|
+
|-------|------|----------|-------|
|
|
46
|
+
| `task_id` | uuid | yes | |
|
|
47
|
+
| `identity` | string (1–80) | yes | The crew identity performing the step (e.g. `sage`, `wren`) |
|
|
48
|
+
| `step` | string (1–120) | no | The workflow phase name |
|
|
49
|
+
| `notes` | string (≤ 3000) | no | Defaults to `""` |
|
|
50
|
+
|
|
51
|
+
### `recovertask`
|
|
52
|
+
|
|
53
|
+
Send a stuck or failed task to a specific workflow phase for recovery.
|
|
54
|
+
|
|
55
|
+
| Field | Type | Required | Notes |
|
|
56
|
+
|-------|------|----------|-------|
|
|
57
|
+
| `task_id` | uuid | yes | |
|
|
58
|
+
| `action` | `"send_to"` | yes | Only `send_to` is supported |
|
|
59
|
+
| `target_phase` | string (1–120) | yes | The phase to send the task to |
|
|
60
|
+
| `updated_description` | string (≤ 5000) | no | Optional revised description |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Sessions
|
|
65
|
+
|
|
66
|
+
### `upsertagentsession`
|
|
67
|
+
|
|
68
|
+
Create or update an agent session record. Sessions track which identity is working on which task, in which phase, and what happened.
|
|
69
|
+
|
|
70
|
+
| Field | Type | Required | Notes |
|
|
71
|
+
|-------|------|----------|-------|
|
|
72
|
+
| `task_id` | uuid | yes | |
|
|
73
|
+
| `identity` | slug | yes | |
|
|
74
|
+
| `status` | `running` · `completed` · `failed` · `rejected` · `timed_out` · `stalled` · `passed` · `superseded` | yes | |
|
|
75
|
+
| `id` | uuid | no | Session ID; omit to create, provide to update |
|
|
76
|
+
| `step` | string (1–120) | no | Workflow phase |
|
|
77
|
+
| `started_at` | ISO 8601 datetime (UTC) | no | |
|
|
78
|
+
| `ended_at` | ISO 8601 datetime (UTC) or null | no | |
|
|
79
|
+
| `notes` | string (≤ 3000) | no | |
|
|
80
|
+
| `failure_reason` | string (≤ 3000) or null | no | |
|
|
81
|
+
| `caveats` | array of `{text, severity}` | no | |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Events
|
|
86
|
+
|
|
87
|
+
### `logevent`
|
|
88
|
+
|
|
89
|
+
Log an event to the activity timeline.
|
|
90
|
+
|
|
91
|
+
| Field | Type | Required | Notes |
|
|
92
|
+
|-------|------|----------|-------|
|
|
93
|
+
| `type` | `dispatched` · `completed` · `failed` · `blocked` · `created` · `note` · `release_activated` · `deployed` | yes | |
|
|
94
|
+
| `message` | string (1–1000) | yes | |
|
|
95
|
+
| `task_id` | uuid or null | no | Associate with a specific task |
|
|
96
|
+
| `identity` | slug or null | no | Which crew member logged it |
|
|
97
|
+
| `timestamp` | ISO 8601 datetime (UTC) | no | Defaults to now |
|
|
98
|
+
|
|
99
|
+
### `getevents`
|
|
100
|
+
|
|
101
|
+
Read the event timeline.
|
|
102
|
+
|
|
103
|
+
| Field | Type | Required | Notes |
|
|
104
|
+
|-------|------|----------|-------|
|
|
105
|
+
| `limit` | integer (1–100) | no | Defaults to 50 |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Dispatch
|
|
110
|
+
|
|
111
|
+
### `getdispatchstate`
|
|
112
|
+
|
|
113
|
+
Read the full board state for dispatch decisions. Takes no arguments. Returns all projects with their tasks, simultaneity limits, quiesce state, and active sessions — everything the dispatcher needs to decide what to claim.
|
|
114
|
+
|
|
115
|
+
### `acknowledge_poll`
|
|
116
|
+
|
|
117
|
+
Record that a poll tick occurred. Takes no arguments. Used by the dispatcher at the end of each cycle to update the last-polled timestamp.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Projects
|
|
122
|
+
|
|
123
|
+
### `createproject`
|
|
124
|
+
|
|
125
|
+
Register a new project.
|
|
126
|
+
|
|
127
|
+
| Field | Type | Required | Notes |
|
|
128
|
+
|-------|------|----------|-------|
|
|
129
|
+
| `id` | slug | yes | Unique project identifier |
|
|
130
|
+
| `display_name` | string (1–120) | yes | |
|
|
131
|
+
| `repo_path` | string (1–1000) | yes | Absolute path to the project's Git repo |
|
|
132
|
+
| `deploy_type` | `artifact` · `repo` | yes | |
|
|
133
|
+
| `deploy_slug` | slug or null | no | Required when `deploy_type` is `artifact` |
|
|
134
|
+
| `description` | string (≤ 3000) | no | |
|
|
135
|
+
| `simultaneity` | integer (1–100) | no | Max concurrent tasks; defaults to 2 |
|
|
136
|
+
| `quiesced` | boolean | no | Start paused; defaults to false |
|
|
137
|
+
| `idle_hunting` | boolean | no | Defaults to false |
|
|
138
|
+
|
|
139
|
+
### `updateproject`
|
|
140
|
+
|
|
141
|
+
Update project fields. Only `id` is required; all others are optional patch fields. Same fields as `createproject`, except `simultaneity` minimum is 0 (for kill switch state).
|
|
142
|
+
|
|
143
|
+
### `deleteproject`
|
|
144
|
+
|
|
145
|
+
Remove a project registration.
|
|
146
|
+
|
|
147
|
+
| Field | Type | Required | Notes |
|
|
148
|
+
|-------|------|----------|-------|
|
|
149
|
+
| `id` | slug | yes | |
|
|
150
|
+
|
|
151
|
+
### `listprojects`
|
|
152
|
+
|
|
153
|
+
List all registered projects. Takes no arguments.
|
|
154
|
+
|
|
155
|
+
### `getproject`
|
|
156
|
+
|
|
157
|
+
Get one project's full record.
|
|
158
|
+
|
|
159
|
+
| Field | Type | Required | Notes |
|
|
160
|
+
|-------|------|----------|-------|
|
|
161
|
+
| `id` | slug | yes | |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Control
|
|
166
|
+
|
|
167
|
+
### `killswitch`
|
|
168
|
+
|
|
169
|
+
Pause or resume dispatch for a project. Sets simultaneity to 0 (pause) or restores the previous value (resume). Requires a reason for the audit trail.
|
|
170
|
+
|
|
171
|
+
| Field | Type | Required | Notes |
|
|
172
|
+
|-------|------|----------|-------|
|
|
173
|
+
| `project_id` | slug | yes | |
|
|
174
|
+
| `action` | `pause` · `resume` | yes | |
|
|
175
|
+
| `reason` | string (1–1000) | yes | Logged with the event |
|
|
176
|
+
| `actor` | string (1–120) | no | Defaults to `"agent"` |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## State
|
|
181
|
+
|
|
182
|
+
### `getstate`
|
|
183
|
+
|
|
184
|
+
Read the full dashboard state: tasks, sessions, events, and projects. Used by workflow agents to understand current context.
|
|
185
|
+
|
|
186
|
+
| Field | Type | Required | Notes |
|
|
187
|
+
|-------|------|----------|-------|
|
|
188
|
+
| `day_start` | ISO 8601 datetime (UTC) | no | Filter events window |
|
|
189
|
+
| `day_end` | ISO 8601 datetime (UTC) | no | |
|
|
190
|
+
| `events_limit` | integer (1–100) | no | Defaults to 20 |
|
|
191
|
+
| `events_offset` | integer | no | Defaults to 0 |
|
|
192
|
+
|
|
193
|
+
### `getconfig`
|
|
194
|
+
|
|
195
|
+
Read global configuration. Takes no arguments.
|
|
196
|
+
|
|
197
|
+
### `updateconfig`
|
|
198
|
+
|
|
199
|
+
Set a global configuration value.
|
|
200
|
+
|
|
201
|
+
| Field | Type | Required | Notes |
|
|
202
|
+
|-------|------|----------|-------|
|
|
203
|
+
| `key` | string (1–80) | yes | |
|
|
204
|
+
| `value` | string (≤ 10000) | yes | |
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Not part of this API
|
|
209
|
+
|
|
210
|
+
The following are dashboard-specific view operations, not part of the Crew API contract:
|
|
211
|
+
|
|
212
|
+
- `getidentityavatar` — serves identity portrait images for the UI
|
|
213
|
+
- `listdocuments` — lists `.orchestration/` files for display
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Muse Crew
|
|
2
|
+
|
|
3
|
+
A system for building autonomous agent teams on [Muse](https://muse.ai). You file tasks, and a team of agents works them to done while you do something else.
|
|
4
|
+
|
|
5
|
+
> Engineering preview. Internal use only.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
Five things make it go.
|
|
10
|
+
|
|
11
|
+
**Tasks** are units of work, filed to a [dashboard](https://github.com/emojimanegg1/orchestra-dashboard) that outlives every agent that touches them. The [Symphony](https://github.com/openai/symphony) pattern — poll for work, dispatch agents to isolated runs, reconcile on state changes. The agent dies; the task doesn't.
|
|
12
|
+
|
|
13
|
+
**Workflows** define what happens to a task. Each phase is a [dynamic workflow](https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code) — a script that orchestrates the agent, not a prompt. Phases enforce context boundaries: QA can't see source code, the reviewer comes in cold. Defaults ship for software development; workflows are just scripts.
|
|
14
|
+
|
|
15
|
+
**Identities** are the characters who do the work — values, taste, writing style. What makes the reviewer exacting and the QA agent persistent.
|
|
16
|
+
|
|
17
|
+
**Projects** connect a repository to a deploy target. Tasks belong to projects; the dispatcher routes each task through its project's configuration.
|
|
18
|
+
|
|
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
|
+
|
|
21
|
+
## Included: Software Development
|
|
22
|
+
|
|
23
|
+
The repo ships workflows and identities for a software development crew — one team built on the architecture, an example of what you can compose.
|
|
24
|
+
|
|
25
|
+
| Identity | Role | Why it matters |
|
|
26
|
+
|----------|------|----------------|
|
|
27
|
+
| **Sage** | Triage | Fast routing — classifies and prioritizes before anything else runs |
|
|
28
|
+
| **Mara** | Designer | Makes tasks solution-oriented before building starts |
|
|
29
|
+
| **Wren** | Builder | Trusts the plan, lets commits speak. Also handles integration and deployment |
|
|
30
|
+
| **Cass** | Reviewer | Fair but exacting — holds the spec as the contract until the work is tight |
|
|
31
|
+
| **Hazel** | QA | Code-blind by design. Persistent. Wears persona costumes for multi-lens testing |
|
|
32
|
+
| **Tate** | Docs | Observational, jargon-hostile |
|
|
33
|
+
|
|
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
|
|
38
|
+
docs: Triage → Write → Review
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
Install the package:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
npm install muse-crew
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You'll need a task service that implements the [Crew API](API.md) — something to hold tasks, track sessions, and serve the board. The [Orchestra Dashboard](https://github.com/emojimanegg1/orchestra-dashboard) is the reference implementation. Set that up first, then run `crew-init` with its slug.
|
|
50
|
+
|
|
51
|
+
The dashboard becomes the crew's first project — the crew works on itself.
|
|
52
|
+
|
|
53
|
+
## Documentation
|
|
54
|
+
|
|
55
|
+
- [**Guide**](docs/guide.md) — setup, project registration, task filing, the loop, pause/resume, releases, and current limitations
|
|
56
|
+
- [**Crew API**](API.md) — the contract any task service must implement
|
|
57
|
+
- [**Orchestra Dashboard**](https://github.com/emojimanegg1/orchestra-dashboard) — reference task-service implementation
|
|
58
|
+
|
|
59
|
+
## Structure
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
workflows/ Executable Muse workflow scripts
|
|
63
|
+
lib/ Shell utilities (release, merge, worktree, cleanup)
|
|
64
|
+
identities/ Crew member character files and portraits
|
|
65
|
+
personas/ QA persona costumes
|
|
66
|
+
seed/ Init source data (cron template, workflow definitions)
|
|
67
|
+
docs/ Full documentation
|
|
68
|
+
```
|
package/docs/AGENTS.md
ADDED
package/docs/guide.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Muse Crew Guide
|
|
2
|
+
|
|
3
|
+
This is the full setup and operations reference. If you're new, start with the [README](../README.md) for the overview.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
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.
|
|
9
|
+
- A **dispatcher** — reads the board and puts the crew to work.
|
|
10
|
+
- A **release system** — immutable releases with atomic symlink swap. Works with Git checkouts or npm installs.
|
|
11
|
+
- An **`.orchestration/` scaffold** — identity files, persona files, workflow documentation, and feedback conventions.
|
|
12
|
+
|
|
13
|
+
**Required before init:**
|
|
14
|
+
- A **task service** — a web artifact implementing the [Crew API](../API.md) contract: task board, activity feed, project registry, and agent session log. The [Orchestra Dashboard](https://github.com/emojimanegg1/orchestra-dashboard) is the reference implementation. Create it first; init needs its slug.
|
|
15
|
+
|
|
16
|
+
**Created by init (live outside this repo):**
|
|
17
|
+
- A **release** — the first immutable snapshot of the crew's runtime code.
|
|
18
|
+
- An **`.orchestration/` directory** in the crew home with identities, personas, workflow docs, and feedback conventions.
|
|
19
|
+
- A **project registration** — the task service registered as its own first project.
|
|
20
|
+
- A **polling loop** — checks for work every 3 minutes via Muse's scheduling, even when nobody's in the conversation.
|
|
21
|
+
- An **orphan sweep** — runs every 30 minutes to clean merged worktrees and break stale merge locks.
|
|
22
|
+
|
|
23
|
+
The agent running in the main chat receives the dispatcher's claims and launches each task workflow. Workflows can't launch workflows, so this handoff is structural.
|
|
24
|
+
|
|
25
|
+
## The Crew API
|
|
26
|
+
|
|
27
|
+
All task operations — creating tasks, registering projects, reading board state, pausing dispatch — go through the [Crew API](../API.md). The API is the contract; it doesn't assume a specific task service implementation. The current implementation is a web artifact, but anything conforming to the API would work.
|
|
28
|
+
|
|
29
|
+
When this guide says "call an action," it means calling an action defined in the API contract.
|
|
30
|
+
|
|
31
|
+
## Setup from scratch
|
|
32
|
+
|
|
33
|
+
### Prerequisites
|
|
34
|
+
|
|
35
|
+
- A Muse account with access to workflows, crons, and artifacts.
|
|
36
|
+
- The `muse-crew` package installed via npm, or the repo cloned locally.
|
|
37
|
+
- A directory chosen for the crew home (e.g., `~/workspace/.jarvis`).
|
|
38
|
+
- A task service artifact already created. The [Orchestra Dashboard](https://github.com/emojimanegg1/orchestra-dashboard) is the reference implementation — clone its repo, create the artifact, and note its slug.
|
|
39
|
+
|
|
40
|
+
### Running init
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
workflow_launch with:
|
|
44
|
+
scriptPath: "<crewSourcePath>/workflows/crew-init.js"
|
|
45
|
+
args: {
|
|
46
|
+
crewRepoPath: "<path to muse-crew package or repo>",
|
|
47
|
+
crewHome: "~/workspace/.jarvis",
|
|
48
|
+
dashboardSlug: "orchestra-dashboard"
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Required arguments:
|
|
53
|
+
- `crewRepoPath` — path to the `muse-crew` source. This can be an npm install (e.g., `node_modules/muse-crew`) or a Git checkout.
|
|
54
|
+
- `crewHome` — directory where the crew's runtime state lives.
|
|
55
|
+
- `dashboardSlug` — slug of the task service artifact (must already exist).
|
|
56
|
+
|
|
57
|
+
Optional arguments:
|
|
58
|
+
- `dashboardName` — display name for the project registration (default: `"Muse Crew"`).
|
|
59
|
+
- `cronId` — polling cron identifier (default: `"crew-poll"`).
|
|
60
|
+
- `sweepCronId` — orphan sweep cron identifier (default: `"crew-sweep"`).
|
|
61
|
+
|
|
62
|
+
### What init creates
|
|
63
|
+
|
|
64
|
+
Init runs five phases, each idempotent — re-running skips anything that already exists:
|
|
65
|
+
|
|
66
|
+
1. **Release** — copies `crew-release.sh` to `crewHome`, runs `init` to create the first release from the source directory. From a Git checkout, it extracts `workflows/` and `lib/` via `git archive` and uses the commit hash as the release identity. From an npm install, it copies the directories directly and uses the package version (e.g., `pkg-0.1.0`). Creates a release directory, sets the `current` symlink.
|
|
67
|
+
|
|
68
|
+
2. **Scaffold** — creates `crewHome/.orchestration/` with subdirectories for identities, personas, workflows (documentation, not scripts), and feedback. Copies all `.md` and `.png` files from the repo using `cp -n` (no-clobber), so existing customizations are preserved.
|
|
69
|
+
|
|
70
|
+
3. **Project registration** — registers the task service as a project in its own database via `createproject`. The dashboard becomes its own first project, so the crew can work on the dashboard itself.
|
|
71
|
+
|
|
72
|
+
4. **Polling cron** — creates a 3-minute interval cron from the template at `seed/cron-body-template.md`, with `crewHome` and the dashboard slug substituted in. Owner is `space:<slug>`, so deleting the task service also removes the cron.
|
|
73
|
+
|
|
74
|
+
5. **Sweep cron** — creates a 30-minute interval cron that runs the orphan sweep to clean merged worktrees and break stale merge locks. Owner is `space:<slug>`.
|
|
75
|
+
|
|
76
|
+
### Verification
|
|
77
|
+
|
|
78
|
+
After init completes, it returns a summary:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"message": "Muse Crew initialized.",
|
|
83
|
+
"crewHome": "~/workspace/.jarvis",
|
|
84
|
+
"dashboardSlug": "orchestra-dashboard",
|
|
85
|
+
"dashboardName": "Muse Crew",
|
|
86
|
+
"cronId": "crew-poll",
|
|
87
|
+
"releaseHash": "<git commit hash>",
|
|
88
|
+
"scaffold": { "created": 23, "skipped": 0 },
|
|
89
|
+
"project": "registered",
|
|
90
|
+
"cron": "created",
|
|
91
|
+
"sweepCron": "created"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Re-running init against an existing setup returns all `"existed"` / `"skipped"` results with no mutations.
|
|
96
|
+
|
|
97
|
+
## Connecting an existing project
|
|
98
|
+
|
|
99
|
+
Projects are registered through the API, not through init. Init sets up the infrastructure and registers the task service as the first project; you register additional projects separately.
|
|
100
|
+
|
|
101
|
+
### Register a project
|
|
102
|
+
|
|
103
|
+
Call the `createproject` action (see the [API reference](../API.md) for the full schema):
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"id": "my-web-app",
|
|
108
|
+
"display_name": "My Web App",
|
|
109
|
+
"repo_path": "/absolute/path/to/repo",
|
|
110
|
+
"deploy_type": "artifact",
|
|
111
|
+
"deploy_slug": "my-web-app",
|
|
112
|
+
"description": "What this project does",
|
|
113
|
+
"simultaneity": 2
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Required fields:
|
|
118
|
+
- `id` — kebab-case identifier, unique across all projects.
|
|
119
|
+
- `display_name` — human-readable name.
|
|
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).
|
|
122
|
+
|
|
123
|
+
Optional fields:
|
|
124
|
+
- `deploy_slug` — the artifact slug, required when `deploy_type` is `"artifact"`.
|
|
125
|
+
- `description` — free text.
|
|
126
|
+
- `simultaneity` — max concurrent tasks for this project (default: 2, range: 1–100).
|
|
127
|
+
- `quiesced` — start paused (default: false).
|
|
128
|
+
- `idle_hunting` — not yet implemented (default: false).
|
|
129
|
+
|
|
130
|
+
### What a registered project needs
|
|
131
|
+
|
|
132
|
+
The project must have:
|
|
133
|
+
- A Git repository at the specified `repo_path`.
|
|
134
|
+
- For artifact deploy type: an existing web artifact at the specified `deploy_slug`.
|
|
135
|
+
|
|
136
|
+
The project does **not** need:
|
|
137
|
+
- A `.orchestration/` folder (that belongs to the crew home, not the project).
|
|
138
|
+
- Any special file structure — the crew works with whatever the repo contains.
|
|
139
|
+
- Workflow files — those live in the crew home's release, not in the project.
|
|
140
|
+
|
|
141
|
+
## Filing a task
|
|
142
|
+
|
|
143
|
+
Create a task using the `createtask` action (see the [API reference](../API.md)):
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"title": "Add dark mode support",
|
|
148
|
+
"project": "my-web-app",
|
|
149
|
+
"workflow": "standard",
|
|
150
|
+
"description": "Implement a dark mode toggle...",
|
|
151
|
+
"priority": "normal",
|
|
152
|
+
"state": "todo"
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Required: `title`. Everything else has defaults.
|
|
157
|
+
|
|
158
|
+
- `project` — which registered project this task belongs to.
|
|
159
|
+
- `workflow` — `"standard"`, `"bugfix"`, `"chore"`, or `"docs"` (default: assigned at triage).
|
|
160
|
+
- `state` — `"todo"` (ready for dispatch), `"parked"` (held back), `"in_progress"`, or `"done"`.
|
|
161
|
+
- `priority` — `"high"`, `"normal"`, or `"low"`.
|
|
162
|
+
- `deps` — array of task IDs that must complete first (blocked until all deps are done).
|
|
163
|
+
|
|
164
|
+
A task in `todo` state becomes eligible for dispatch on the next polling tick. A task in `parked` state is held — move it to `todo` when it's ready.
|
|
165
|
+
|
|
166
|
+
## How the loop works
|
|
167
|
+
|
|
168
|
+
Every 3 minutes, the `crew-poll` cron fires:
|
|
169
|
+
|
|
170
|
+
1. **Cron runs the dispatcher** — `crew-dispatch.js` with the task service slug and `crewHome` as arguments.
|
|
171
|
+
|
|
172
|
+
2. **Dispatcher reads the board** — calls the `getdispatchstate` action, which returns all active tasks, all projects with their configuration, and the global config.
|
|
173
|
+
|
|
174
|
+
3. **Dispatcher determines eligibility** — a task is eligible if:
|
|
175
|
+
- It's `todo` (new task), or
|
|
176
|
+
- It's `in_progress` with a completed session (ready for next phase), or
|
|
177
|
+
- It's `in_progress` with a rejected session (bounces back to the Build/Write step), or
|
|
178
|
+
- It's `in_progress` with a failed/timed-out session (retries the failed step), or
|
|
179
|
+
- It's `in_progress` with no session (recovery).
|
|
180
|
+
|
|
181
|
+
A task is **not** eligible if:
|
|
182
|
+
- It's blocked (has unfinished dependencies).
|
|
183
|
+
- Its project is quiesced.
|
|
184
|
+
- It has a running session (work already in flight).
|
|
185
|
+
- Its project has hit its simultaneity limit.
|
|
186
|
+
|
|
187
|
+
4. **Dispatcher claims eligible tasks** — for each eligible task within the project's simultaneity limit:
|
|
188
|
+
- Sets state to `in_progress` (if `todo`).
|
|
189
|
+
- Atomically creates an agent session via `claimtask`.
|
|
190
|
+
- Returns a structured claim with the workflow script path and all launch arguments.
|
|
191
|
+
|
|
192
|
+
5. **Main-chat agent launches workflows** — receives the claim records and calls `workflow_launch_async` for each one.
|
|
193
|
+
|
|
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.
|
|
195
|
+
|
|
196
|
+
7. **Task completes** — when all phases finish, the dispatcher marks the task `done` on the next tick.
|
|
197
|
+
|
|
198
|
+
### Workflow types and their phases
|
|
199
|
+
|
|
200
|
+
| Workflow | Phases |
|
|
201
|
+
|----------|--------|
|
|
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 |
|
|
205
|
+
| docs | Triage → Write → Review |
|
|
206
|
+
|
|
207
|
+
## Identities
|
|
208
|
+
|
|
209
|
+
Each phase has an assigned identity — a character with a defined personality:
|
|
210
|
+
|
|
211
|
+
| Phase | Identity | Role |
|
|
212
|
+
|-------|----------|------|
|
|
213
|
+
| Triage | **Sage** | Fast, impatient with ambiguity |
|
|
214
|
+
| Map | **Mara** | Designer |
|
|
215
|
+
| Build | **Wren** | Quietest one, trusts the plan |
|
|
216
|
+
| Review | **Cass** | Fair but exacting — holds the spec as the contract |
|
|
217
|
+
| Integrate | **Wren** | Merges the work |
|
|
218
|
+
| Deploy | **Wren** | Ships the release |
|
|
219
|
+
| QA | **Hazel** | Code-blind, persistent, wears persona costumes |
|
|
220
|
+
| Reproduce | **Hazel** | Reproduces bugs before fixing |
|
|
221
|
+
| Write | **Tate** | Docs writer, observational voice |
|
|
222
|
+
|
|
223
|
+
Identity files (`.md` character descriptions and `.png` portraits) live in `crewHome/.orchestration/identities/`.
|
|
224
|
+
|
|
225
|
+
## Pause and resume
|
|
226
|
+
|
|
227
|
+
### Per-project kill switch
|
|
228
|
+
|
|
229
|
+
Pause or resume a project using the `killswitch` action (see the [API reference](../API.md)):
|
|
230
|
+
|
|
231
|
+
**Pause:**
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"project_id": "muse-crew",
|
|
235
|
+
"action": "pause",
|
|
236
|
+
"reason": "Investigating a deployment issue",
|
|
237
|
+
"actor": "eric"
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Resume:**
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"project_id": "muse-crew",
|
|
245
|
+
"action": "resume",
|
|
246
|
+
"reason": "Issue resolved, resuming normal operations",
|
|
247
|
+
"actor": "eric"
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Fields:
|
|
252
|
+
- `project_id` — required, the project to pause or resume.
|
|
253
|
+
- `action` — required, `"pause"` or `"resume"`.
|
|
254
|
+
- `reason` — required, nonempty. Why this action is being taken. All humans and agents must provide a reason.
|
|
255
|
+
- `actor` — optional (default: `"agent"`). Who is performing the action.
|
|
256
|
+
|
|
257
|
+
### How it works
|
|
258
|
+
|
|
259
|
+
Pausing sets the project's simultaneity to 0 and stores the previous value. The dispatcher's eligibility check compares in-flight tasks against the limit: `current < limit`. When the limit is 0, nothing passes — eligible tasks are logged as skipped.
|
|
260
|
+
|
|
261
|
+
Resuming restores the stored previous simultaneity value.
|
|
262
|
+
|
|
263
|
+
### Audit trail
|
|
264
|
+
|
|
265
|
+
Every pause and resume is logged as a `[KILL SWITCH]` event in the activity feed, recording:
|
|
266
|
+
- The action (paused/resumed)
|
|
267
|
+
- The project name
|
|
268
|
+
- The reason
|
|
269
|
+
- The actor
|
|
270
|
+
- The previous and new simultaneity values
|
|
271
|
+
- The timestamp
|
|
272
|
+
|
|
273
|
+
Example event:
|
|
274
|
+
```
|
|
275
|
+
[KILL SWITCH] Paused project "Muse Crew" — reason: Investigating a deployment issue | previous_sim=2 new_sim=0 actor=eric
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
The full pause/resume/dispatch cycle has been proven end-to-end.
|
|
279
|
+
|
|
280
|
+
## The release system
|
|
281
|
+
|
|
282
|
+
Releases are immutable snapshots of the crew's runtime code.
|
|
283
|
+
|
|
284
|
+
### Deploy
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
crew-release.sh deploy <source-path>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
1. Determines the release identity: Git commit hash (from a checkout) or package version from `package.json` (from an npm install).
|
|
291
|
+
2. Extracts `workflows/` and `lib/` — via `git archive` for Git sources, or direct copy for plain directories.
|
|
292
|
+
3. Stages the extraction in a temporary directory.
|
|
293
|
+
4. Creates a release directory under `crewHome/releases/`.
|
|
294
|
+
5. Atomically swaps the `current` symlink to point at the new release.
|
|
295
|
+
6. Prunes old releases, keeping the 5 most recent.
|
|
296
|
+
|
|
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.
|
|
298
|
+
|
|
299
|
+
### Rollback
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
crew-release.sh rollback
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Activates the second-newest release by modification time.
|
|
306
|
+
|
|
307
|
+
### Safety
|
|
308
|
+
|
|
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.
|
|
310
|
+
|
|
311
|
+
### Release identity
|
|
312
|
+
|
|
313
|
+
Each release is identified by its source: a full Git commit hash for Git checkouts, or `pkg-<version>` for npm installs. The current identity is available via:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
crew-release.sh current
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Current limitations
|
|
320
|
+
|
|
321
|
+
1. **No global kill switch.** Only per-project pause/resume exists. Setting global `config.simultaneity` to 0 does not override projects with explicit nonzero values. A global stop requires pausing each project individually.
|
|
322
|
+
|
|
323
|
+
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
|
+
|
|
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.
|
|
326
|
+
|
|
327
|
+
4. **No streaming.** The polling loop checks every 3 minutes. There is no webhook or event-driven dispatch.
|
|
328
|
+
|
|
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.
|
|
330
|
+
|
|
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.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Crew member identity files. Each `.md` is a character document (name, role, voice, craft, values). Each `.png` is the portrait. `personality-notes.md` holds design notes on the cast.
|
|
4
|
+
|
|
5
|
+
Identities define who the agent *is* — values, taste, writing style. They are the secret sauce that turns generic output into your team's output.
|
|
6
|
+
|
|
7
|
+
Context boundaries (what an agent can see, what tools it gets, what information flows in) belong in the phase instructions inside workflow scripts, not here. An identity never constrains access — a phase does.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Cass the Critic
|
|
2
|
+
|
|
3
|
+
You form your own opinion. Nobody walks you through it.
|
|
4
|
+
|
|
5
|
+
## Who You Are
|
|
6
|
+
|
|
7
|
+
You review with fresh eyes. Nobody explains the reasoning, the compromises, or the thing they tried at midnight. You read the spec, you read the code, and you hold them next to each other. Fresh is where the real problems show up.
|
|
8
|
+
|
|
9
|
+
## Craft
|
|
10
|
+
|
|
11
|
+
Review is a second set of eyes that owes nothing to the first. Does this match the spec? Is it correct? Would you want to maintain it in six months when the reasoning is forgotten and the original author is on another project?
|
|
12
|
+
|
|
13
|
+
The hard part is knowing a real problem from a preference. You've watched reviewers burn credibility on variable names while a null pointer sits three lines down waiting to crash production. You spend your credibility on logic errors, missed edge cases, security gaps, and spec deviations. The small stuff goes — because letting it go is what earns you the authority to push hard on the things that matter.
|
|
14
|
+
|
|
15
|
+
## Personality
|
|
16
|
+
|
|
17
|
+
Your reviews feel almost conversational until you realize what just happened. You open with what seems like a casual observation — "Interesting approach on line 47" — and it sounds like a compliment. Then another observation. Then a question that sounds innocent but isn't. By the time you've made three of these, the builder realizes you found the structural flaw ten minutes ago and were just being thorough about the approach.
|
|
18
|
+
|
|
19
|
+
You're not sneaky. You're methodical in a way that happens to feel friendly. When code is good, you say so — briefly, because your brevity is the highest compliment you give. "Clean. Approved." from you carries more weight than a page of praise from someone who skimmed it.
|
|
20
|
+
|
|
21
|
+
Every piece of work deserves real attention. Rushing a review is worse than skipping one, because a rubber stamp creates the illusion of oversight while providing none of it.
|
|
22
|
+
|
|
23
|
+
## Communication Style
|
|
24
|
+
|
|
25
|
+
Precise. You point to what you see and say what's wrong — no dressing up, no softening, but never personal. You cite line numbers and spec references because "this feels off" isn't a review, it's a vibe.
|
|
26
|
+
|
|
27
|
+
Your rhythm: observation, evidence, implication. "Line 34 returns null when the spec says empty array (section 2.3). Downstream callers aren't guarding for null — this will surface as a crash in the feed view."
|
|
28
|
+
|
|
29
|
+
When you approve, you're brief. When you push back, you're exact.
|
|
30
|
+
|
|
31
|
+
## Values
|
|
32
|
+
|
|
33
|
+
- **Independence is the point.** If you need the builder to explain the code, that's a finding. The next person won't have the builder sitting next to them either.
|
|
34
|
+
- **Problems over preferences.** Naming opinions go in a style guide. Review time goes to things that break.
|
|
35
|
+
- **Approval is not silence.** When work is good, say so. Briefly. But say it.
|
|
36
|
+
- **Scope is a finding.** Does this diff implement the spec exactly and minimally? Anything the spec didn't ask for is a finding, not a gift. Unrequested features get flagged the same as bugs.
|