scrumrun 3.0.0 → 3.0.2

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/docs/COMMANDS.md CHANGED
@@ -3,40 +3,56 @@
3
3
  The canonical grammar is:
4
4
 
5
5
  ```text
6
- /sc <noun> <subject> <action> [args]
6
+ scrumrun <noun> <subject> <action> [args]
7
7
  ```
8
8
 
9
- Use `/sc` inside a supported AI client. The equivalent CLI form is `scrumrun sc ...`. Use `npx scrumrun@latest` only for one-off installation or recovery, never inside an agent's normal execution loop.
9
+ Use the installed `scrumrun` command for all normal project work. `/sc` is an optional AI-client shortcut and `scrumrun sc ...` remains a compatibility alias. Do not use `npx scrumrun@latest` inside an agent's execution loop.
10
10
 
11
11
  ## Plan
12
12
 
13
13
  ```text
14
- /sc plan intake <request>
15
- /sc plan intake --approve <token>
16
- /sc plan task --add|--list|--show|--run|--audit|--cancel|--retry
17
- /sc plan sprint --add|--list|--show|--start|--complete|--block
18
- /sc plan feature --add|--list|--show|--activate|--complete
19
- /sc plan run --list|--show|--validate|--learn|--complete|--resume|--fail|--block [--note] [typed evidence flags]
20
- /sc plan run --finalize RUN-NNN [--summary "technical recap"] [--note]
21
- /sc plan run --authorize-mutation RUN-NNN --path <relative-path> [--path ...]
22
- /sc plan run --record-mutation RUN-NNN --permit MUT-id [--note] [--actor]
23
- /sc plan run --satisfy-guardrail RUN-NNN --guardrail GR-NNN [typed evidence flags]
24
- /sc plan challenge <question>
14
+ scrumrun plan intake <request>
15
+ scrumrun plan intake --approve <token>
16
+ scrumrun plan task --add|--list|--show|--run|--audit|--cancel|--retry
17
+ scrumrun plan task --amend TASK-NNN [--title "..."] [--request "..."] [--acceptance "..."] [--section "Heading=content"] [--type fix|task|feature|docs|discovery] [--feature FEAT-NNN|null] [--sprint SPRINT-NNN|null]
18
+ scrumrun plan sprint --add|--list|--show|--start|--complete|--block
19
+ scrumrun plan sprint --amend SPRINT-NNN [--title "..."] [--timebox "..."] [--exit-gate "..."] [--section "Heading=content"]
20
+ scrumrun plan feature --add|--list|--show|--activate|--complete
21
+ scrumrun plan feature --amend FEAT-NNN [--title "..."] [--purpose "..."] [--exit-criteria "..."] [--section "Heading=content"]
22
+ scrumrun plan run --list|--show|--validate|--learn|--complete|--resume|--fail|--block [--note] [typed evidence flags]
23
+ scrumrun plan run --finalize RUN-NNN [--summary "technical recap"] [--note]
24
+ scrumrun plan run --authorize-mutation RUN-NNN --path <relative-path> [--path ...]
25
+ scrumrun plan run --record-mutation RUN-NNN --permit MUT-id [--note] [--actor]
26
+ scrumrun plan run --satisfy-guardrail RUN-NNN --guardrail GR-NNN [typed evidence flags]
27
+ scrumrun plan challenge <question>
25
28
  ```
26
29
 
27
30
  Normal execution is Markdown-first: after approval, work in code and the linked Task, then use one `--finalize` checkpoint. It verifies every workspace change and all Guardrail evidence before writing the Run transitions. A retry requires a failed, blocked, or partial Task and creates a new Run. Mutation permits are available only for explicitly requested strict mode.
28
31
 
32
+ `--amend` is the canonical way to adjust planning truth before execution — never edit an artifact Markdown file directly. Every named `--section "Heading=content"` replaces or adds one `## Heading` section, so new planning context does not need a new CLI release. Repeated `--acceptance`, `--exit-criteria`, and `--exit-gate` values become checklist items. Updating a Task's `--feature` or `--sprint` synchronizes the linked Feature/Sprint projection atomically. A Task is amendable only while `backlog` or `proposed`; after it starts, scope is historical/approved truth and follow-up work needs a new Task.
33
+
34
+ ## What can be changed
35
+
36
+ | Artifact | Canonical operation | Why |
37
+ | --- | --- | --- |
38
+ | Task, Feature, Sprint | `--add`, `--amend`, lifecycle commands | Planning truth can be refined before execution. |
39
+ | Run | transitions, `--finalize`, `--retry` | Execution history is append-only; it is never amended. |
40
+ | Review | `--run` / `--record` | A verdict is evidence, not editable prose. Record another review if it changes. |
41
+ | Knowledge, Decision, Insight, Dossier | create + lifecycle commands | Preserve evidence lineage; supersede/deprecate rather than rewrite confirmed truth. |
42
+ | Guardrail | `--add` / `--retire` | Policy history must remain auditable. |
43
+ | `state.md`, `map.md`, cache | rebuild commands | Derived projections, never manually edited. |
44
+
29
45
  ## Knowledge
30
46
 
31
47
  ```text
32
- /sc knowledge fact --add|--list|--show|--approve|--reject|--deprecate|--invalidate
33
- /sc knowledge decision --add|--list|--show|--resolve|--deprecate|--invalidate
34
- /sc knowledge insight --propose|--list|--show|--confirm|--stale|--reject|--deprecate|--invalidate
35
- /sc knowledge dossier --add|--list|--show|--refresh|--stale|--deprecate|--archive
36
- /sc knowledge context --build|--update|--show|--clear
37
- /sc knowledge map --build|--show
38
- /sc knowledge study <focus>
39
- /sc knowledge vault --add|--list|--show|--remove|--path
48
+ scrumrun knowledge fact --add|--list|--show|--approve|--reject|--deprecate|--invalidate
49
+ scrumrun knowledge decision --add|--list|--show|--resolve|--deprecate|--invalidate
50
+ scrumrun knowledge insight --propose|--list|--show|--confirm|--stale|--reject|--deprecate|--invalidate
51
+ scrumrun knowledge dossier --add|--list|--show|--refresh|--stale|--deprecate|--archive
52
+ scrumrun knowledge context --build|--update|--show|--clear
53
+ scrumrun knowledge map --build|--show
54
+ scrumrun knowledge study <focus>
55
+ scrumrun knowledge vault --add|--list|--show|--remove|--path
40
56
  ```
41
57
 
42
58
  Creation options include `--title`, `--content`, repeated `--evidence`, repeated `--relation "used_by: Target"`, `--subject type:id`, `--source`, `--source-id`, `--confidence`, `--valid-from`, `--valid-until`, and `--review-trigger`. Promotion options accept repeated `--evidence` and `--note`.
@@ -46,13 +62,13 @@ Creation options include `--title`, `--content`, repeated `--evidence`, repeated
46
62
  ## Rules and review
47
63
 
48
64
  ```text
49
- /sc rules guardrail --add|--list|--show|--retire
50
- /sc rules reviewer --add|--list|--show|--run
51
- /sc review code --run
52
- /sc review artifact --run
53
- /sc review artifact --record --task TASK-NNN [--run RUN-NNN] [--title "..."] [--evidence "..."]
54
- /sc review migration --run
55
- /sc review release --run
65
+ scrumrun rules guardrail --add|--list|--show|--retire
66
+ scrumrun rules reviewer --add|--list|--show|--run
67
+ scrumrun review code --run
68
+ scrumrun review artifact --run
69
+ scrumrun review artifact --record --task TASK-NNN [--run RUN-NNN] [--title "..."] [--evidence "..."]
70
+ scrumrun review migration --run
71
+ scrumrun review release --run
56
72
  ```
57
73
 
58
74
  `review artifact --run` is read-only and returns a machine-readable 21-invariant project audit. `--record` reruns that audit and persists its exact pass/fail result as a canonical `REV-NNN`; supplied evidence is additive and cannot turn a failed audit into a pass. Other review routes require repository reasoning and remain read-only unless fixes receive separate approval.
@@ -60,13 +76,13 @@ Creation options include `--title`, `--content`, repeated `--evidence`, repeated
60
76
  ## Config and lifecycle
61
77
 
62
78
  ```text
63
- /sc config project --show|--language|--interaction|--approval|--quick-tasks
64
- /sc config init --local|--shared|--lean|--no-agent-hint|--force
65
- /sc config update [all|codex|opencode|claude] [--migrate]
66
- /sc config migrate --to 2 --dry-run|--apply|--rollback
67
- /sc config doctor [all|codex|opencode|claude] [--strict] [--recover]
68
- /sc config uninstall --force
69
- /sc config help <topic>
79
+ scrumrun config project --show|--language|--interaction|--approval|--quick-tasks
80
+ scrumrun config init --local|--shared|--lean|--no-agent-hint|--force
81
+ scrumrun config update [all|codex|opencode|claude] [--migrate]
82
+ scrumrun config migrate --to 2 --dry-run|--apply|--rollback
83
+ scrumrun config doctor [all|codex|opencode|claude] [--strict] [--recover]
84
+ scrumrun config uninstall --force
85
+ scrumrun config help <topic>
70
86
  ```
71
87
 
72
88
  Top-level CLI aliases (`init`, `update`, `migrate`, `doctor`, `uninstall`, `status`) remain available for shell automation. Ordinary update runs only a read-only migration preflight; `--migrate` is explicit application consent.
package/docs/DEMO.md CHANGED
@@ -28,13 +28,13 @@ Inside the recording, run these commands slowly (about 5 seconds of
28
28
  reading between each), typing them yourself so viewers see the cadence:
29
29
 
30
30
  ```bash
31
- npx scrumrun@latest install --client claude
32
- npx scrumrun@latest init
33
- npx scrumrun@latest sc plan intake "Fix duplicate charges after refresh"
31
+ scrumrun install --client claude
32
+ scrumrun init
33
+ scrumrun plan intake "Fix duplicate charges after refresh"
34
34
  # copy the approval token printed above
35
- npx scrumrun@latest sc plan intake --approve <token>
36
- npx scrumrun@latest sc plan run --render RUN-001
37
- npx scrumrun@latest sc plan run --stats
35
+ scrumrun plan intake --approve <token>
36
+ scrumrun plan run --render RUN-001
37
+ scrumrun plan run --stats
38
38
  ```
39
39
 
40
40
  Exit the shell (`exit`) to stop the recording.
@@ -65,8 +65,8 @@ SR-E-102 Run transition rejected: missing validation or learning evidence.
65
65
 
66
66
  | Code | Summary | Remediation |
67
67
  |---|---|---|
68
- | `SR-E-100` | Run not found. | Check the RUN-NNN id with `sc plan run --list`. |
69
- | `SR-E-101` | Run ledger contains an invalid event. | Inspect the reported event id; use `sc plan run --render` for a human view or restore from git history. |
68
+ | `SR-E-100` | Run not found. | Check the RUN-NNN id with `scrumrun plan run --list`. |
69
+ | `SR-E-101` | Run ledger contains an invalid event. | Inspect the reported event id; use `scrumrun plan run --render` for a human view or restore from git history. |
70
70
  | `SR-E-102` | Run transition rejected: missing validation or learning evidence. | Complete `--validate` and `--learn` with typed evidence before `--complete`. |
71
71
  | `SR-E-103` | Retry rejected because the previous Run is still active. | Complete, fail, or block the current Run before creating a retry. |
72
72
 
@@ -75,14 +75,14 @@ SR-E-102 Run transition rejected: missing validation or learning evidence.
75
75
  | Code | Summary | Remediation |
76
76
  |---|---|---|
77
77
  | `SR-E-150` | Guardrail check blocked the operation. | Read the reported GR-NNN, satisfy or retire it explicitly; guardrails never bypass silently. |
78
- | `SR-E-151` | Guardrail obligation is still pending. | Resolve each pending guardrail via `sc plan run --satisfy-guardrail` before completing the Run. |
78
+ | `SR-E-151` | Guardrail obligation is still pending. | Resolve each pending guardrail via `scrumrun plan run --satisfy-guardrail` before completing the Run. |
79
79
  | `SR-E-152` | Guardrail declaration is malformed. | Every active guardrail requires Status, Enforcement, Scope, and Rule fields; check `.scrumrun/guardrails.md`. |
80
80
 
81
81
  ### Edit permits (Mutation Gateway)
82
82
 
83
83
  | Code | Summary | Remediation |
84
84
  |---|---|---|
85
- | `SR-E-200` | No edit permit for this path. | Request one with `sc plan run --authorize-mutation RUN-NNN --path <path>` before editing canonical or source files. |
85
+ | `SR-E-200` | No edit permit for this path. | Request one with `scrumrun plan run --authorize-mutation RUN-NNN --path <path>` before editing canonical or source files. |
86
86
  | `SR-E-201` | Edit permit expired. | Permits last 15 minutes. Authorize a new one and record the change immediately. |
87
87
  | `SR-E-202` | Edit permit path scope mismatch. | The permit does not cover the modified path. Request a new permit that lists it. |
88
88
  | `SR-E-203` | File hash changed unexpectedly since the permit was issued. | Someone else modified the file. Re-plan the change and request a fresh permit. |
@@ -91,28 +91,28 @@ SR-E-102 Run transition rejected: missing validation or learning evidence.
91
91
 
92
92
  | Code | Summary | Remediation |
93
93
  |---|---|---|
94
- | `SR-E-250` | Pending kernel transaction cannot be recovered automatically. | Run `sc config doctor --recover --dry-run` to preview; if it shows "would overwrite owner changes", reconcile the file manually before applying. |
94
+ | `SR-E-250` | Pending kernel transaction cannot be recovered automatically. | Run `scrumrun config doctor --recover --dry-run` to preview; if it shows "would overwrite owner changes", reconcile the file manually before applying. |
95
95
  | `SR-E-251` | Journal fails integrity check. | Inspect `.scrumrun/.transactions/pending`. Do not delete; contact support or restore from backup. |
96
96
 
97
97
  ### Memory
98
98
 
99
99
  | Code | Summary | Remediation |
100
100
  |---|---|---|
101
- | `SR-E-300` | Memory candidate rejected: missing resolvable evidence. | Attach at least one `--evidence` path or `sc knowledge <subject> --propose` before `--confirm`. |
101
+ | `SR-E-300` | Memory candidate rejected: missing resolvable evidence. | Attach at least one `--evidence` path or `scrumrun knowledge <subject> --propose` before `--confirm`. |
102
102
  | `SR-E-301` | Attempt to write into vault via canonical channel. | `vault.local.md` is local-only and never indexed. Edit the file directly. |
103
103
 
104
104
  ### Semantic index and code intelligence
105
105
 
106
106
  | Code | Summary | Remediation |
107
107
  |---|---|---|
108
- | `SR-E-350` | Semantic index is stale. | Rebuild with `sc knowledge map --build`. Cache is disposable; canonical memory is unaffected. |
109
- | `SR-E-351` | Search backend advertised in the cache does not match this runtime. | Delete `.scrumrun/.cache/semantic-index.sqlite` and re-run any `sc knowledge` query to rebuild against the current runtime. |
108
+ | `SR-E-350` | Semantic index is stale. | Rebuild with `scrumrun knowledge map --build`. Cache is disposable; canonical memory is unaffected. |
109
+ | `SR-E-351` | Search backend advertised in the cache does not match this runtime. | Delete `.scrumrun/.cache/semantic-index.sqlite` and re-run any `scrumrun knowledge` query to rebuild against the current runtime. |
110
110
 
111
111
  ### Migration
112
112
 
113
113
  | Code | Summary | Remediation |
114
114
  |---|---|---|
115
- | `SR-E-400` | Migration preflight failed. | Run `npx scrumrun@latest update` (dry) to see blockers, resolve them, then apply with `--migrate`. |
115
+ | `SR-E-400` | Migration preflight failed. | Run `scrumrun update` (dry) to see blockers, resolve them, then apply with `--migrate`. |
116
116
  | `SR-E-401` | Migration rollback requested but no backup was found. | Rollback needs the ignored byte-exact backup created during `--migrate`. Restore from version control if the backup is gone. |
117
117
 
118
118
  ### Conformance and doctor
@@ -120,13 +120,13 @@ SR-E-102 Run transition rejected: missing validation or learning evidence.
120
120
  | Code | Summary | Remediation |
121
121
  |---|---|---|
122
122
  | `SR-E-450` | Conformance check failed. | The reported invariant identifies the exact violation; the message includes the file and expected shape. |
123
- | `SR-E-451` | Installed client asset is stale. | Re-run `npx scrumrun@latest update` for the specific client. `doctor --strict` shows which files diverge. |
123
+ | `SR-E-451` | Installed client asset is stale. | Re-run `scrumrun update` for the specific client. `doctor --strict` shows which files diverge. |
124
124
 
125
125
  ### Configuration and installation
126
126
 
127
127
  | Code | Summary | Remediation |
128
128
  |---|---|---|
129
- | `SR-E-500` | ScrumRun project not initialized. | Run `npx scrumrun@latest init` in the repository root. |
129
+ | `SR-E-500` | ScrumRun project not initialized. | Run `scrumrun init` in the repository root. |
130
130
  | `SR-E-501` | Unsupported Node.js runtime. | ScrumRun requires Node.js >=22.13.0 for native SQLite. Upgrade Node and retry. |
131
131
 
132
132
  ## Adding a new code
@@ -22,8 +22,8 @@ can follow it.
22
22
  You need Node.js 22.13 or newer.
23
23
 
24
24
  ```bash
25
- npx scrumrun@latest install # installs the agent integration for your client
26
- npx scrumrun@latest init # creates the .scrumrun/ tree in the current repo
25
+ scrumrun install # installs the agent integration for your client
26
+ scrumrun init # creates the .scrumrun/ tree in the current repo
27
27
  ```
28
28
 
29
29
  By default `.scrumrun/` is added to `.git/info/exclude` — the methodology
@@ -47,7 +47,7 @@ Classification: Task (fix)
47
47
  Risk: high — financial path
48
48
  Why: Payment behavior changed after completed work; corrective Task
49
49
  linked to the original Run history.
50
- Next: /sc plan intake "double charge on refresh"
50
+ Next: scrumrun plan intake "double charge on refresh"
51
51
  Awaiting owner approval.
52
52
  ```
53
53
 
@@ -55,7 +55,7 @@ Nothing has been written yet. The classification, risk, and plan are
55
55
  proposals. Approving is one command:
56
56
 
57
57
  ```bash
58
- npx scrumrun@latest sc plan intake --approve <token>
58
+ scrumrun plan intake --approve <token>
59
59
  ```
60
60
 
61
61
  In an interactive terminal, the output is rendered as a boxed intake
@@ -87,7 +87,7 @@ You can render a Run's ledger as a human timeline instead of reading the
87
87
  raw JSON:
88
88
 
89
89
  ```bash
90
- npx scrumrun@latest sc plan run --render RUN-001
90
+ scrumrun plan run --render RUN-001
91
91
  ```
92
92
 
93
93
  For aggregate signal across every Run in the project — status mix, p50
@@ -95,9 +95,9 @@ and p95 time in `VALIDATING`, retries per Task, guardrail check counts —
95
95
  use `--stats`:
96
96
 
97
97
  ```bash
98
- npx scrumrun@latest sc plan run --stats
99
- npx scrumrun@latest sc plan run --stats --task TASK-001
100
- npx scrumrun@latest sc plan run --stats --json
98
+ scrumrun plan run --stats
99
+ scrumrun plan run --stats --task TASK-001
100
+ scrumrun plan run --stats --json
101
101
  ```
102
102
 
103
103
  ## Reading the memory
@@ -113,8 +113,8 @@ Nothing becomes canonical without confirmation. AI extraction creates
113
113
  candidates; you promote them with evidence.
114
114
 
115
115
  ```bash
116
- npx scrumrun@latest sc knowledge insight --propose "..." --evidence src/foo.ts
117
- npx scrumrun@latest sc knowledge insight --confirm INS-001
116
+ scrumrun knowledge insight --propose "..." --evidence src/foo.ts
117
+ scrumrun knowledge insight --confirm INS-001
118
118
  ```
119
119
 
120
120
  Ask the agent things like *"why is calculateFinalPrice in checkout?"* or
@@ -134,10 +134,10 @@ the memory index, not by guessing.
134
134
 
135
135
  ## Common questions
136
136
 
137
- **Do I have to type `/sc` commands?** No. Natural language is the primary
138
- entry point. The `/sc` grammar exists for scripting and reproducibility.
137
+ **Do I have to type commands?** No. Natural language is the primary entry
138
+ point. For scripting and reproducibility, use `scrumrun <noun> <subject> <action>`; `/sc` is only an AI-client shortcut.
139
139
 
140
- **What if I already use v1?** Run `npx scrumrun@latest update` for a
140
+ **What if I already use v1?** Run `scrumrun update` for a
141
141
  read-only migration preflight, then `update --migrate` when you are
142
142
  satisfied with the plan.
143
143
 
@@ -158,5 +158,5 @@ for the exact remediation. If a canonical transaction was interrupted,
158
158
  preview the repair before running it:
159
159
 
160
160
  ```bash
161
- npx scrumrun@latest sc config doctor --recover --dry-run
161
+ scrumrun config doctor --recover --dry-run
162
162
  ```
@@ -26,7 +26,7 @@ Minimum local score: **9.7/10**.
26
26
  - Full suite: `npm test`.
27
27
  - Performance suite: `npm run benchmark`.
28
28
  - Contract drift: `scripts/generate-contract-docs.js --check` runs before tests.
29
- - Project conformance: `/sc review artifact --run`, twenty-one invariants, zero findings at the release checkpoint.
29
+ - Project conformance: `scrumrun review artifact --run`, twenty-one invariants, zero findings at the release checkpoint.
30
30
  - Installed integration: `doctor codex --strict`, exact prompt/skill hashes and zero project findings.
31
31
  - Package boundary: `npm pack --dry-run --json`, explicit file inventory, no repository-local `.scrumrun/`, tests, vault, backup, migration state, or cache.
32
32
  - Tarball E2E: install, v2 memory, ongoing v1 migration, rollback, doctor, and uninstall run from the packed package in the test suite.
package/docs/RELEASE.md CHANGED
@@ -11,7 +11,7 @@ npm test
11
11
  npm run benchmark
12
12
  git diff --check
13
13
  npm pack --dry-run
14
- npx scrumrun@latest sc review artifact --run # in a clean v2 fixture/current package equivalent
14
+ scrumrun review artifact --run # in a clean v2 fixture/current package equivalent
15
15
  ```
16
16
 
17
17
  Confirm package contents exclude repository-local `.scrumrun/` state, caches, migration records, backups, vaults, tests, and secrets. The `.scrumrun/` directory inside project templates is expected. Confirm package metadata, README, changelog, tarball filename, checksum, and Git tag agree on `2.1.1`; SPEC, CORE, artifact frontmatter, migration, and installed skill continue to declare method `2.0.0`.
@@ -60,9 +60,9 @@ Entering `learning` extracts `INS-NNN` candidates. Malformed extraction emits a
60
60
  ## Query and maintenance
61
61
 
62
62
  ```bash
63
- npx scrumrun@latest sc knowledge map --build
64
- npx scrumrun@latest sc knowledge study calculateFinalPrice
65
- npx scrumrun@latest sc knowledge context --clear
63
+ scrumrun knowledge map --build
64
+ scrumrun knowledge study calculateFinalPrice
65
+ scrumrun knowledge context --clear
66
66
  ```
67
67
 
68
68
  SQLite is ignored and disposable. The derived index records its search backend: FTS5/BM25 is selected when the current Node.js SQLite build supports it; otherwise ScrumRun uses deterministic parameterized token matching over the same artifact, code, and relation tables. Queries default to 10 records/40 relations and hard-cap at 100/100. Match type, truth state, warnings, relation counts, and evidence are returned so recommendations remain explainable.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## “Project must be explicitly migrated to v2”
4
4
 
5
- Run `npx scrumrun@latest update` for a read-only preflight, then review and apply with `update --migrate`. See [`MIGRATION-1-to-2.md`](../MIGRATION-1-to-2.md).
5
+ Run `scrumrun update` for a read-only preflight, then review and apply with `update --migrate`. See [`MIGRATION-1-to-2.md`](../MIGRATION-1-to-2.md).
6
6
 
7
7
  ## Migration is blocked
8
8
 
@@ -22,7 +22,7 @@ Rollback detected post-migration work that it would erase. Copy/export wanted ch
22
22
  `state.md` refreshes after runtime transitions. Rebuild the semantic map with:
23
23
 
24
24
  ```bash
25
- npx scrumrun@latest sc knowledge map --build
25
+ scrumrun knowledge map --build
26
26
  ```
27
27
 
28
28
  Fresh projections include a source fingerprint and a watch fingerprint. A matching watch avoids a full read. If file metadata changed, ScrumRun hashes canonical/source content before deciding whether the projection is actually stale. `check: "schema"` means the disposable SQLite format changed and one rebuild is required; `check: "hash"` means the safe fallback was used.
@@ -34,7 +34,7 @@ Stale generated views are warnings, not canonical corruption.
34
34
  An approved multi-file mutation was interrupted after its durable journal was prepared. Ordinary doctor/audit is read-only and leaves the evidence untouched. Either retry the same approved operation, which recovers before writing, or explicitly run:
35
35
 
36
36
  ```bash
37
- npx scrumrun@latest doctor codex --recover --strict
37
+ scrumrun doctor codex --recover --strict
38
38
  ```
39
39
 
40
40
  Prepared transactions restore their original bytes; committed transactions verify the applied bytes and finalize. Recovery refuses if a target changed to content matching neither journal side, because that would overwrite later owner work. Receipts contain hashes and outcomes, not file contents.
@@ -44,8 +44,8 @@ Prepared transactions restore their original bytes; committed transactions verif
44
44
  Delete or clear only the disposable cache:
45
45
 
46
46
  ```bash
47
- npx scrumrun@latest sc knowledge context --clear
48
- npx scrumrun@latest sc knowledge map --build
47
+ scrumrun knowledge context --clear
48
+ scrumrun knowledge map --build
49
49
  ```
50
50
 
51
51
  Canonical Markdown is unchanged. Query automatically rebuilds a missing/stale index.
@@ -61,10 +61,10 @@ Inspect its invalidation warning and code/evidence relations. For a real code mo
61
61
  ## Doctor reports missing clients
62
62
 
63
63
  ```bash
64
- npx scrumrun@latest install codex
65
- npx scrumrun@latest install claude
66
- npx scrumrun@latest install opencode
67
- npx scrumrun@latest doctor all
64
+ scrumrun install codex
65
+ scrumrun install claude
66
+ scrumrun install opencode
67
+ scrumrun doctor all
68
68
  ```
69
69
 
70
70
  Use `doctor --compat` only while validating one-cycle v1 adapters.
@@ -6,9 +6,9 @@ const nouns = Object.freeze({
6
6
  plan: {
7
7
  description: "turn intent into Features, Tasks, Sprints, and Runs",
8
8
  subjects: {
9
- task: ["--add [--type fix] [--status backlog]", "--list", "--show", "--run", "--audit", "--cancel", "--retry [--reassign]", "--next", "--start [TASK-NNN]"],
10
- sprint: ["--add", "--list", "--show", "--start", "--complete", "--block"],
11
- feature: ["--add", "--list", "--show", "--activate", "--complete"],
9
+ task: ["--add [--type fix] [--status backlog]", "--amend <TASK-NNN> [--title] [--request] [--acceptance] [--section \"Heading=content\"] [--type task|fix|feature|docs|discovery] [--feature] [--sprint]", "--list", "--show", "--run", "--audit", "--cancel", "--retry [--reassign]", "--next", "--start [TASK-NNN]"],
10
+ sprint: ["--add", "--amend <SPRINT-NNN> [--title] [--timebox] [--exit-gate] [--section \"Heading=content\"]", "--list", "--show", "--start", "--complete", "--block"],
11
+ feature: ["--add", "--amend <FEAT-NNN> [--title] [--purpose] [--exit-criteria] [--section \"Heading=content\"]", "--list", "--show", "--activate", "--complete"],
12
12
  run: [
13
13
  "--list",
14
14
  "--show",
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- // `sc plan run --normalize-legacy [--dry-run]`
3
+ // `scrumrun plan run --normalize-legacy [--dry-run]`
4
4
  //
5
5
  // Reads every Run under `.scrumrun/runs/` and validates its ledger
6
6
  // against the current schema. When a Run fails validation (invalid
@@ -244,7 +244,7 @@ function renderIntake(plan) {
244
244
  }
245
245
  }
246
246
  } else if (plan.approvalToken) {
247
- const command = "scrumrun sc plan intake --approve";
247
+ const command = "scrumrun plan intake --approve";
248
248
  const tokenWidth = Math.max(16, width - 8);
249
249
  const materialization = plan.proposal && plan.proposal.materialization ? plan.proposal.materialization.summary : "Task + Run";
250
250
  lines.push(boxLine(width, ` ${paint(FG.gray, `APPROVE · copy the command below to create ${materialization}`)}`));
@@ -274,7 +274,7 @@ function renderIntakePlain(plan) {
274
274
  lines.push(`DEFERRED: ${result.guardrail} ${result.code}: ${result.message}`);
275
275
  }
276
276
  for (const warning of plan.context.warnings) lines.push(`WARNING: ${warning}`);
277
- if (plan.approvalToken) lines.push(`Approval: scrumrun sc plan intake --approve ${plan.approvalToken}`);
277
+ if (plan.approvalToken) lines.push(`Approval: scrumrun plan intake --approve ${plan.approvalToken}`);
278
278
  return lines.join("\n");
279
279
  }
280
280
 
@@ -19,7 +19,7 @@ Execute ScrumRun with this request: $ARGUMENTS
19
19
 
20
20
  Use the installed \`scrumrun\` skill as the authoritative workflow. This prompt is the only canonical slash-command entry point.
21
21
 
22
- If \`$ARGUMENTS\` is empty, show the five nouns below and the current project status; do not guess an action. Otherwise parse exactly \`/sc <noun> <subject> <action> [args]\`.
22
+ If \`$ARGUMENTS\` is empty, show the five nouns below and the current project status; do not guess an action. Otherwise parse exactly \`<noun> <subject> <action> [args]\` and use the installed CLI as \`scrumrun <noun> <subject> <action> [args]\`. \`/sc\` is a client shortcut retained for compatibility, never a reason to use \`npx\`.
23
23
 
24
24
  ## Grammar
25
25
 
@@ -35,7 +35,7 @@ ${grammarLines().join("\n")}
35
35
  - Linked Task/Run writes use a durable recovery journal; audit reports pending recovery and never repairs without explicit authorization.
36
36
  - \`guardrails.md\` is canonical project policy; \`golden-rules.md\` is v1 compatibility only.
37
37
  - Evaluate active Guardrails as \`passed\`, \`blocked\`, or \`deferred\`; cite exact \`GR-NNN\` ids and keep deferred execution gates visible.
38
- - The normal path is one session checkpoint: after approval, work directly in code and the linked Task Markdown; finish once with \`sc plan run --finalize RUN-NNN\`. It verifies the complete workspace delta, policy, secrets, protected paths, and all Guardrail evidence together. Do not invoke \`npx scrumrun@latest\` during execution.
38
+ - The normal path is one session checkpoint: after approval, work directly in code and the linked Task Markdown; finish once with \`scrumrun plan run --finalize RUN-NNN\`. It verifies the complete workspace delta, policy, secrets, protected paths, and all Guardrail evidence together. Do not invoke \`npx scrumrun@latest\` during execution.
39
39
  - Strict per-path Mutation Gateway permits remain available only when the owner explicitly requests strict execution.
40
40
  - Knowledge/Decision/Insight records require evidence; AI-proposed Insights remain \`candidate\` until confirmed.
41
41
  - Never print vault values or write before approval.
@@ -48,7 +48,7 @@ Method: ${METHOD_VERSION}. Command grammar source: \`lib/commands/manifest.js\`.
48
48
  function renderCompatibilityPrompt(alias) {
49
49
  const spec = aliases[alias];
50
50
  if (!spec) throw new Error(`Unknown compatibility alias: ${alias}`);
51
- const target = `/sc ${spec.target.join(" ")}`;
51
+ const target = `scrumrun ${spec.target.join(" ")}`;
52
52
  return `---
53
53
  description: Deprecated ScrumRun v1 adapter — executes ${target}
54
54
  argument-hint: [action] [args]
@@ -63,11 +63,14 @@ Emit one concise deprecation note: \`/${alias}\` becomes \`${target}\` in ScrumR
63
63
  }
64
64
 
65
65
  function renderCommandHelp() {
66
- const nounLines = Object.entries(nouns).map(([noun, spec]) => ` /sc ${noun.padEnd(10)} ${spec.description}`);
67
- const aliasLines = Object.entries(aliases).map(([alias, spec]) => ` /${alias.padEnd(14)} -> /sc ${spec.target.join(" ")}`);
66
+ const nounLines = Object.entries(nouns).map(([noun, spec]) => ` scrumrun ${noun.padEnd(10)} ${spec.description}`);
67
+ const aliasLines = Object.entries(aliases).map(([alias, spec]) => ` /${alias.padEnd(14)} -> scrumrun ${spec.target.join(" ")}`);
68
68
  return `ScrumRun ${METHOD_VERSION} command grammar:
69
69
 
70
70
  Canonical root:
71
+ scrumrun <noun> <subject> <action> [args]
72
+
73
+ Client compatibility shortcut:
71
74
  /sc <noun> <subject> <action> [args]
72
75
 
73
76
  Nouns:
@@ -14,13 +14,16 @@
14
14
  // 4. run.attempt missing → 1 (documented default).
15
15
  // 5. Sprint task projections: add Task.sprint references absent from the
16
16
  // Sprint's `## Tasks` list. Extra entries remain for human review.
17
+ // 6. Orphan active Tasks: explicitly reset a Task with no associated Run to
18
+ // backlog. This never invents history; a later `task --start` creates
19
+ // the first real Run.
17
20
  //
18
21
  // Categories intentionally NOT touched (need human judgment):
19
22
  // - Secret-like content (SECRET_CANONICAL)
20
23
  // - Missing Acceptance Criteria sections
21
24
  // - Guardrail scope/enforcement (authored semantics)
22
25
  // - Task/Run status disagreements (requires domain knowledge)
23
- // - Empty Run ledgers (use `sc plan run --normalize-legacy`)
26
+ // - Empty Run ledgers (use `scrumrun plan run --normalize-legacy`)
24
27
  //
25
28
  // Every mutated file is backed up byte-exact under
26
29
  // `.scrumrun/.migration-backup/repair/<relative-path>` before being rewritten.
@@ -430,6 +433,37 @@ function planOrphanRuns(scrumDir, taskIds) {
430
433
  return orphans;
431
434
  }
432
435
 
436
+ function planOrphanTasks(scrumDir) {
437
+ const runTasks = new Set();
438
+ for (const file of listDir(path.join(scrumDir, "runs"), RUN_FILE)) {
439
+ const split = splitFrontmatter(readIf(file));
440
+ const task = split && extractField(split.header, "task");
441
+ if (TASK_REF.test(task || "")) runTasks.add(task);
442
+ }
443
+ const active = new Set(["running", "validating", "learning", "partial"]);
444
+ const orphans = [];
445
+ for (const file of listDir(path.join(scrumDir, "tasks"), TASK_FILE)) {
446
+ const original = readIf(file);
447
+ const split = splitFrontmatter(original);
448
+ if (!split) continue;
449
+ const id = extractField(split.header, "id") || path.basename(file, ".md");
450
+ const status = extractField(split.header, "status");
451
+ if (!TASK_REF.test(id) || !active.has(status) || runTasks.has(id)) continue;
452
+ const header = replaceField(split.header, "status", "backlog");
453
+ const updated = extractField(header, "updated");
454
+ const nextHeader = updated !== undefined ? replaceField(header, "updated", new Date().toISOString().slice(0, 10)) : header;
455
+ orphans.push({
456
+ id,
457
+ status,
458
+ file,
459
+ originalText: original,
460
+ nextText: `---\n${nextHeader}\n---${split.sep}${split.body}`,
461
+ reason: `${id} is ${status} but no Run references it.`
462
+ });
463
+ }
464
+ return orphans;
465
+ }
466
+
433
467
  function planFile(file, kind, ctx) {
434
468
  const original = readIf(file);
435
469
  if (original === null) return null;
@@ -657,12 +691,13 @@ function planGuardrails(scrumDir) {
657
691
  return { file, kind: "guardrails", changes, nextText: text, originalText: original };
658
692
  }
659
693
 
660
- function analyze(scrumDir) {
694
+ function analyze(scrumDir, { recoverOrphanTasks = false } = {}) {
661
695
  const featureIds = scanFeatureIds(scrumDir);
662
696
  const taskIds = scanTaskIds(scrumDir);
663
697
  const ctx = { featureIds };
664
698
  const entries = planMissingFrontmatter(scrumDir);
665
699
  const orphanRuns = planOrphanRuns(scrumDir, taskIds);
700
+ const orphanTasks = planOrphanTasks(scrumDir);
666
701
 
667
702
  const guardrailPlan = planGuardrails(scrumDir);
668
703
  if (guardrailPlan) entries.push(guardrailPlan);
@@ -704,7 +739,7 @@ function analyze(scrumDir) {
704
739
  totals.byField[change.field] = (totals.byField[change.field] || 0) + 1;
705
740
  }
706
741
  }
707
- return { entries, totals, orphanRuns };
742
+ return { entries, totals, orphanRuns, orphanTasks, recoverOrphanTasks };
708
743
  }
709
744
 
710
745
  function writeWithBackup(scrumDir, backupRoot, file, originalText, nextText) {
@@ -760,7 +795,18 @@ function apply(scrumDir, plan) {
760
795
  applied.push({ ...rec, changes: entry.changes });
761
796
  }
762
797
 
763
- // Pass 5: rebuild the disposable state.md briefing so it reflects the
798
+ // Pass 5: only after every ordinary deterministic repair has settled, reset
799
+ // explicitly requested orphan Tasks. This avoids one repair pass erasing
800
+ // another file's frontmatter update.
801
+ const recoveredTasks = [];
802
+ if (plan.recoverOrphanTasks) {
803
+ for (const orphan of planOrphanTasks(scrumDir)) {
804
+ const rec = writeWithBackup(scrumDir, backupRoot, orphan.file, orphan.originalText, orphan.nextText);
805
+ recoveredTasks.push({ ...rec, id: orphan.id, from: orphan.status, to: "backlog" });
806
+ }
807
+ }
808
+
809
+ // Pass 6: rebuild the disposable state.md briefing so it reflects the
764
810
  // repaired canonical tree (otherwise doctor keeps warning STATE_STALE).
765
811
  try {
766
812
  require("../runtime/orchestrator").refreshState(scrumDir);
@@ -769,7 +815,7 @@ function apply(scrumDir, plan) {
769
815
  // if it truly cannot be rebuilt.
770
816
  }
771
817
 
772
- return { applied, ledger: ledgerResult, quarantined };
818
+ return { applied, ledger: ledgerResult, quarantined, recoveredTasks };
773
819
  }
774
820
 
775
821
  function renderReport(plan, applied) {
@@ -778,6 +824,7 @@ function renderReport(plan, applied) {
778
824
  lines.push(`Files needing frontmatter repair: ${plan.entries.length}`);
779
825
  if (plan.ledgerMalformed) lines.push(`Run ledgers to normalize: ${plan.ledgerMalformed}`);
780
826
  if (plan.orphanRuns && plan.orphanRuns.length) lines.push(`Orphan Runs to quarantine: ${plan.orphanRuns.length}`);
827
+ if (plan.orphanTasks && plan.orphanTasks.length) lines.push(`Orphan active Tasks found: ${plan.orphanTasks.length}`);
781
828
  const byField = plan.totals.byField;
782
829
  if (Object.keys(byField).length) {
783
830
  lines.push("\nBy field:");
@@ -793,15 +840,21 @@ function renderReport(plan, applied) {
793
840
  }
794
841
  if (plan.entries.length > 30) lines.push(` … and ${plan.entries.length - 30} more`);
795
842
  }
843
+ if (plan.orphanTasks && plan.orphanTasks.length && !plan.recoverOrphanTasks) {
844
+ lines.push("\nOrphan active Tasks are not changed automatically. Review and run: scrumrun repair --recover-orphan-tasks --apply");
845
+ for (const orphan of plan.orphanTasks.slice(0, 30)) lines.push(` - ${orphan.id}: ${orphan.reason}`);
846
+ }
796
847
  if (applied) {
797
848
  lines.push("");
798
849
  const frontmatterCount = applied.applied ? applied.applied.length : 0;
799
850
  const ledgerCount = applied.ledger && applied.ledger.applied ? applied.ledger.applied.length : 0;
800
851
  const quarantinedCount = applied.quarantined ? applied.quarantined.length : 0;
801
- if (frontmatterCount || ledgerCount || quarantinedCount) {
852
+ const recoveredTaskCount = applied.recoveredTasks ? applied.recoveredTasks.length : 0;
853
+ if (frontmatterCount || ledgerCount || quarantinedCount || recoveredTaskCount) {
802
854
  if (frontmatterCount) lines.push(`Applied: ${frontmatterCount} frontmatter file(s) rewritten.`);
803
855
  if (ledgerCount) lines.push(`Normalized: ${ledgerCount} Run ledger(s) collapsed to snapshot events.`);
804
856
  if (quarantinedCount) lines.push(`Quarantined: ${quarantinedCount} orphan Run(s) moved to .scrumrun/.migration-backup/repair/orphan-runs/.`);
857
+ if (recoveredTaskCount) lines.push(`Recovered: ${recoveredTaskCount} orphan active Task(s) reset to backlog; start each explicitly to create a Run.`);
805
858
  lines.push("Backups under .scrumrun/.migration-backup/repair/ and .scrumrun/.migration-backup/runs/.");
806
859
  } else {
807
860
  lines.push("Applied: no changes.");
@@ -813,11 +866,11 @@ function renderReport(plan, applied) {
813
866
  return lines.join("\n");
814
867
  }
815
868
 
816
- function repair(scrumDir, { apply: doApply = false } = {}) {
869
+ function repair(scrumDir, { apply: doApply = false, recoverOrphanTasks = false } = {}) {
817
870
  if (!fs.existsSync(scrumDir) || !fs.lstatSync(scrumDir).isDirectory()) {
818
871
  throw new Error(".scrumrun/ not found; run this inside a ScrumRun project.");
819
872
  }
820
- const plan = analyze(scrumDir);
873
+ const plan = analyze(scrumDir, { recoverOrphanTasks });
821
874
  let ledgerPreview = null;
822
875
  try {
823
876
  ledgerPreview = normalizeLegacyRuns(scrumDir, { dryRun: true }).plan;