@mu-crew/mu 3.0.0 → 3.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.
@@ -115,7 +115,7 @@ it mu is just an agent runner.
115
115
  decides edge satisfaction: any `CLOSED` task satisfies its blockers.
116
116
  - **Substate** qualifies status and never touches edges:
117
117
  `OPEN/todo|parked`, `IN_PROGRESS/active`,
118
- `CLOSED/done|wontfix|duplicate|superseded`. Rule: **store intent,
118
+ `CLOSED/done|rejected|wontfix|duplicate|superseded`. Rule: **store intent,
119
119
  derive graph facts** — ready and blocked stay derived from edges.
120
120
  `OPEN/parked` is excluded from `ready` but stays in `goals`.
121
121
 
@@ -389,8 +389,8 @@ table/key/field is the reproduction. See
389
389
  `mu` refuses to open a pre-v11 DB (`SchemaTooOldError`, exit 4) or a DB
390
390
  newer than it understands (`SchemaTooNewError`, exit 4) and leaves the
391
391
  file alone. The retained `scripts/migrate.ts` sidecar auto-detects v7,
392
- v8, v9, or v10 and writes a fresh v11 DB. It never migrates in place.
393
- Legacy `REJECTED` tasks become `CLOSED/wontfix` and `DEFERRED` tasks
392
+ v8, v9, v10, or v11 and writes a fresh v11 DB. It never migrates in place.
393
+ Legacy `REJECTED` tasks become `CLOSED/rejected` and `DEFERRED` tasks
394
394
  become `OPEN/parked`; their original op payloads remain unchanged.
395
395
  Pre-1.0 archives restore as live workstreams under their original
396
396
  `source_workstream` names unless you pass `--drop-archives`.
@@ -1630,8 +1630,9 @@ mu task unpark polish # OPEN/parked → OPEN/todo
1630
1630
 
1631
1631
  Every task carries a **substate** next to its status, rendered as a pair.
1632
1632
  `OPEN` is `todo` or `parked`; `IN_PROGRESS` is `active`; `CLOSED` is
1633
- `done`, `wontfix`, `duplicate`, or `superseded`. `--as` picks the closed
1634
- substate. Anything but `done` requires `--why`, stored as a note in the
1633
+ `done`, `rejected`, `wontfix`, `duplicate`, or `superseded`. `--as` picks
1634
+ the closed substate: `rejected` when the proposal itself was declined,
1635
+ `wontfix` when it is valid but not worth doing. Anything but `done` requires `--why`, stored as a note in the
1635
1636
  same transaction. Any `CLOSED/*` satisfies a blocker, so a non-`done`
1636
1637
  close prints the dependents it unblocked.
1637
1638
 
@@ -2400,10 +2401,10 @@ mv "$DB" "${DB}.old-kept" && mv "${DB}.v11" "$DB"
2400
2401
  mu doctor
2401
2402
  ```
2402
2403
 
2403
- The script auto-detects v7, v8, v9, or v10, opens it read-only, compares
2404
+ The script auto-detects v7, v8, v9, v10, or v11, opens it read-only, compares
2404
2405
  its SHA-256 before and after, and never overwrites a target unless
2405
2406
  `--force` is explicit. v9/v10 history is retained unchanged; legacy
2406
- statuses map onto substates (`REJECTED` → `CLOSED/wontfix`, `DEFERRED` →
2407
+ statuses map onto substates (`REJECTED` → `CLOSED/rejected`, `DEFERRED` →
2407
2408
  `OPEN/parked`) while projecting into v11, and no migration notes are
2408
2409
  written. Where an undo or a note hid the legacy status, the script
2409
2410
  records a `migrate.substate` op; `--recover <db>` reruns that recovery
@@ -30,7 +30,7 @@ defined here, fix the doc. If you need a new term, add it here first.
30
30
  | **crew** | *Informal* collective noun for the agents in a workstream | (no API surface; prose only) |
31
31
  | **task** | A node in the DAG. Has mandatory `impact` and `effort_days`. Has a **task status** and a **substate**, shown as a pair (`OPEN/parked`, `CLOSED/wontfix`). | "issue", "ticket", "item" |
32
32
  | **task status** | The lifecycle phase, one of 3: **OPEN** = not started; **IN_PROGRESS** = claimed and active; **CLOSED** = ended. Status alone decides edge satisfaction: any `CLOSED/*` satisfies a `--blocked-by` edge. | "state" |
33
- | **substate** | What the **task status** means for this task. Never null; each status has a default. `OPEN`: `todo` (default), `parked`. `IN_PROGRESS`: `active`. `CLOSED`: `done` (default), `wontfix`, `duplicate`, `superseded`. Rendered as a pair `STATUS/substate`; a default substate renders as the bare status. Valid pairs live in the `task_substates` table. Never affects edges. Refer to a non-`done` close as a *closed substate*. | "resolution", "reason", "sub-status" |
33
+ | **substate** | What the **task status** means for this task. Never null; each status has a default. `OPEN`: `todo` (default), `parked`. `IN_PROGRESS`: `active`. `CLOSED`: `done` (default), `rejected` (the proposal was declined), `wontfix` (valid, not worth doing), `duplicate`, `superseded`. Rendered as a pair `STATUS/substate`; a default substate renders as the bare status. Valid pairs live in the `task_substates` table. Never affects edges. Refer to a non-`done` close as a *closed substate*. | "resolution", "reason", "sub-status" |
34
34
  | **park** | Verb: set an `OPEN` task to `OPEN/parked` with a required `--why` note. A parked task leaves **ready** and `next`, `claim` refuses it without `--force`, and it stays in **goals**. Its dependents stay blocked. Refuses `IN_PROGRESS` (release first) and `CLOSED` (open first). | "defer", "snooze", "shelve" |
35
35
  | **unpark** | Verb: return an `OPEN/parked` task to `OPEN/todo`. | "resume", "reactivate" |
36
36
  | **task DAG** / **graph** | The directed acyclic graph of tasks. | "task list", "todo", "tree" (it's a DAG, not a tree) |
@@ -57,7 +57,7 @@ Consequences:
57
57
  | D8 | Apply resolves the pair before writing: a status-only op, or an unknown substate from a newer peer, falls back to the status default. The original payload stays in `ops`. | The foreign key fails the whole commit. Version skew must not break sync; the foreign key is there to catch our own bugs. |
58
58
  | D9 | Non-`done` close and `park` require `--why`, stored as an ordinary note in the same transaction. | Keeps the rationale, the one good part of the notes-only convention. |
59
59
  | D10 | Start with `parked` as the only non-default `OPEN` substate. No `--until`. | YAGNI. mu has no daemon to run the automatic un-park. Adding `triage` later is one seeded row. |
60
- | D11 | One shared legacy mapping: `REJECTED → CLOSED/wontfix`, `DEFERRED → OPEN/parked`. | Replaces `normalizeTaskStatus` (currently folds both onto `OPEN`). Apply, rebuild, undo and migration all use it, so recovery happens on every path. |
60
+ | D11 | One shared legacy mapping: `REJECTED → CLOSED/rejected` (3.1.0; 3.0.0 used `wontfix`), `DEFERRED → OPEN/parked`. | Replaces `normalizeTaskStatus` (currently folds both onto `OPEN`). Apply, rebuild, undo and migration all use it, so recovery happens on every path. |
61
61
  | D12 | Migrate v10 → v11 through `scripts/migrate.ts`, not in `openDb`. | Keeps the "production never migrates in place" rule. SQLite cannot add a foreign key to an existing table, so a new target is required anyway. |
62
62
 
63
63
  ## Schema (v11)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mu-crew/mu",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "A persistent, observable crew of pi agents running in one tmux or herdr session per workstream, coordinated through a built-in task DAG.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -36,7 +36,7 @@ both. `--json` exists on every verb:
36
36
  on tmux and from herdr on herdr; `mu agent kick` is Linux-only on herdr.
37
37
  - **task** — DAG node with mandatory `impact` (1–100) and
38
38
  `effort_days`. Shown as status/substate: `OPEN/todo|parked`,
39
- `IN_PROGRESS/active`, `CLOSED/done|wontfix|duplicate|superseded`.
39
+ `IN_PROGRESS/active`, `CLOSED/done|rejected|wontfix|duplicate|superseded`.
40
40
  Any `CLOSED/*` satisfies `--blocked-by`.
41
41
  - **claim / release** — atomic take/clear of `tasks.owner`.
42
42
  - **note** — append-only task context; survives sessions.
@@ -233,7 +233,7 @@ Every turn:
233
233
  5 timeout, 6 pane died.
234
234
  - **`task close --if-ready`** no-ops until every blocker is CLOSED; bare
235
235
  `task release` reopens IN_PROGRESS.
236
- - **`task close --as wontfix --why ...`** unblocks dependents (listed in
236
+ - **`task close --as rejected|wontfix --why ...`** (declined | valid, not worth it) unblocks dependents (listed in
237
237
  the output). To keep dependents waiting, `task park --why` instead: parked
238
238
  leaves `next`, and `claim` refuses it without `--force`. Park refuses
239
239
  IN_PROGRESS — `task release` first.