scrumrun 2.7.11 → 3.0.1

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/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ All notable changes follow Semantic Versioning.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 3.0.1 - 2026-08-31
8
+
9
+ ### Fixed
10
+
11
+ - **Orphan Task recovery.** `doctor --strict` now reports `TASK_ORPHANED` when an active Task has no canonical Run. `scrumrun repair --recover-orphan-tasks` previews the affected Tasks; only `scrumrun repair --recover-orphan-tasks --apply` resets them to `backlog`, preserves a byte-exact backup, and never fabricates a Run or execution history.
12
+ - **Direct CLI grammar.** `scrumrun plan task --start TASK-NNN` is now the canonical command form. `scrumrun sc ...` and `/sc` remain compatibility shortcuts, but generated instructions, approval output, recovery guidance, and documentation use the direct installed CLI, avoiding accidental `npx` execution loops.
13
+
14
+ ## 3.0.0 - 2026-08-31
15
+
16
+ ### Changed
17
+
18
+ - **Lightweight execution is now the default.** After approval, agents work directly in application files and the linked Task Markdown, then close the Run with one `scrumrun sc plan run --finalize RUN-NNN` checkpoint.
19
+ - **Finalization is fail-closed.** It audits the complete workspace delta, policy fingerprint, protected paths, symlink safety, scannability, secret boundary, Run ledger, and every Guardrail before completing the Task.
20
+ - **Guardrail proof is co-located with work.** Non-automatic rules use a compact `## Guardrail Evidence` section in the Task and are validated together at finalization; missing evidence blocks completion.
21
+ - **No network command loop.** Generated agent instructions prohibit repeated `npx scrumrun@latest` calls during execution. `npx` remains for one-off installation, migration, and recovery.
22
+ - **Strict mode remains available.** Path-scoped Mutation Gateway permits and individual Run transitions are retained for owners who explicitly request per-edit control.
23
+
7
24
  ## 2.7.7 - 2026-08-24
8
25
 
9
26
  ### Added
package/CORE.md CHANGED
@@ -9,7 +9,7 @@ Method version: `2.0.0`
9
9
  The canonical command is:
10
10
 
11
11
  ```text
12
- /sc <noun> <subject> <action> [args]
12
+ scrumrun <noun> <subject> <action> [args]
13
13
  ```
14
14
 
15
15
  The five nouns are:
@@ -22,7 +22,7 @@ The five nouns are:
22
22
 
23
23
  Incomplete syntax lists only valid next tokens. Unknown syntax never guesses or mutates.
24
24
 
25
- The command manifest at `lib/commands/manifest.js` generates client prompts, compatibility adapters, help, and grammar tests. Fresh v2 integrations install only `/sc`. A v1 upgrade may install generated compatibility adapters for one release cycle.
25
+ The command manifest at `lib/commands/manifest.js` generates client prompts, compatibility adapters, help, and grammar tests. The installed CLI is canonical; `/sc` is a client shortcut. A v1 upgrade may install generated compatibility adapters for one release cycle.
26
26
 
27
27
  ## Entity model
28
28
 
@@ -84,7 +84,7 @@ AGENTS.md
84
84
 
85
85
  **Before querying project state, read `.scrumrun/method.json`.** Its `paths` block is the authoritative index of every canonical location in this project. Navigate by that index; if a path is not declared there, it is not canonical truth. Directory listing and grep are fallbacks — never the first step. A ScrumRun-aware agent must never search for `goals/`, `backlog.md`, `sprint.md`, or any legacy layout: those are absent by design once migration completes and are surfaced only through `.scrumrun/.migration-backup/`.
86
86
 
87
- **Never write Run events by hand.** Runs are only mutated through the CLI: `sc plan run --validate | --learn | --complete | --resume | --fail | --block | --satisfy-guardrail | --authorize-mutation | --record-mutation`. Editing `runs/RUN-NNN.md` directly bypasses schema validation, produces invalid ledger events (invalid `type`, unknown evidence `kind`, missing snapshot, wrong `from`), and breaks conformance for the entire project. If the CLI does not expose the shape you need, propose a spec change through an ADR do not invent event vocabulary. Existing hand-written Runs can be recovered with `sc plan run --normalize-legacy` (byte-exact original preserved in `.scrumrun/.migration-backup/runs/`).
87
+ **Never write Run events by hand.** After approval, work directly in code and in the linked Task Markdown. Finish the normal session once with `scrumrun plan run --finalize RUN-NNN`; the CLI then audits the complete workspace delta, verifies Guardrails and evidence, and writes the validated Run event chain. Do not use `npx scrumrun@latest` during execution. The older `--validate | --learn | --complete | --satisfy-guardrail | --authorize-mutation | --record-mutation` operations remain available only for an owner-requested strict path. Existing hand-written Runs can be recovered with `scrumrun plan run --normalize-legacy` (byte-exact original preserved in `.scrumrun/.migration-backup/runs/`).
88
88
 
89
89
  Canonical truth is Markdown. SQLite/cache data stores only rebuildable indexes, symbol projections, relations, and bounded context packages. Deleting `.cache/` must never delete authored truth.
90
90
 
@@ -112,7 +112,7 @@ Normal read path:
112
112
  4. only the canonical ids and evidence relevant to current work;
113
113
  5. `.scrumrun/core.md` when method details or exceptional transitions are needed.
114
114
 
115
- The briefing is a progressive-disclosure index, not full context. Read it first and follow its pointers to specific artifacts (`## Where to look`, `sc knowledge study "<topic>"`). Go deeper — a Task body, a Run ledger, a Decision — only when the briefing lacks what you need. Never treat the briefing as a substitute for the canonical artifact it points to.
115
+ The briefing is a progressive-disclosure index, not full context. Read it first and follow its pointers to specific artifacts (`## Where to look`, `scrumrun knowledge study "<topic>"`). Go deeper — a Task body, a Run ledger, a Decision — only when the briefing lacks what you need. Never treat the briefing as a substitute for the canonical artifact it points to.
116
116
 
117
117
  Lean mode is this bounded read policy; it is not permission to omit canonical truth.
118
118
 
@@ -156,7 +156,7 @@ Intake must:
156
156
 
157
157
  Policy evaluation is structured per active `GR-NNN`: `passed`, `blocked`, or `deferred`. A block must cite the exact Guardrail id and reason code. Deferred checks must be visible in the plan and re-evaluated at their named execution boundary; they are never silently counted as passed. Invalid/duplicate Guardrails or configuration that weakens approval block conformance and intake.
158
158
 
159
- The agent may assert the classification explicitly with `sc plan intake "…" --type fix|task|feature|docs|discovery`, overriding keyword inference (validated, with a stable reason). It may also attach a short technical explanation with `--preview "…"`, rendered in the pretty terminal layout, bound into the approval token, and stored as `## Preview` on the Task.
159
+ The agent may assert the classification explicitly with `scrumrun plan intake "…" --type fix|task|feature|docs|discovery`, overriding keyword inference (validated, with a stable reason). It may also attach a short technical explanation with `--preview "…"`, rendered in the pretty terminal layout, bound into the approval token, and stored as `## Preview` on the Task.
160
160
 
161
161
  Before approval, do not create canonical files, update status, edit application code, or retain request content outside ignored disposable context cache. The approval token binds both canonical context and the workspace fingerprint; drift in either requires a new intake. Ambiguous acknowledgement is not approval.
162
162
 
@@ -187,7 +187,7 @@ Rules:
187
187
  - before changing application/source files, issue a short-lived path-scoped mutation permit and record the verified before/after hashes in the Run;
188
188
  - unrecorded workspace drift, policy drift, out-of-scope paths, unsafe symlinks, new secret-like content, or unresolved obligations block validation/completion;
189
189
  - learning proposes memory candidates after validation and never auto-confirms AI inference;
190
- - record a `## Technical Summary` at completion with `sc plan run --complete --summary "…"` so the next agent inherits what was actually done;
190
+ - record a `## Technical Summary` at completion with `scrumrun plan run --complete --summary "…"` so the next agent inherits what was actually done;
191
191
  - complete a Sprint only when all its included Tasks meet the Sprint exit gate;
192
192
  - do not mark work complete merely because time or token budget ended.
193
193
 
@@ -197,7 +197,7 @@ Task/Run pair mutations use an ignored durable journal under `.scrumrun/.backup/
197
197
 
198
198
  ### Backlog and sequencing
199
199
 
200
- Backlog is the queue of Tasks with `status: backlog`, ordered oldest-first by id. When a Run completes, the briefing's `## Next Up` names the next backlog Task. `sc plan task --next` shows it; `sc plan task --start [TASK-NNN]` promotes it to `running`, creates its first Run, re-evaluates policy, and records the agent identity. Starting is itself the explicit approval (I-01): no work executes silently, and the owner can always say "not now".
200
+ Backlog is the queue of Tasks with `status: backlog`, ordered oldest-first by id. When a Run completes, the briefing's `## Next Up` names the next backlog Task. `scrumrun plan task --next` shows it; `scrumrun plan task --start [TASK-NNN]` promotes it to `running`, creates its first Run, re-evaluates policy, and records the agent identity. Starting is itself the explicit approval (I-01): no work executes silently, and the owner can always say "not now".
201
201
 
202
202
  ### Agent identity and assignment
203
203
 
@@ -264,7 +264,7 @@ Legacy sprint plan entries normally become Tasks. History attempts become Runs w
264
264
 
265
265
  ## Command reference
266
266
 
267
- ### `/sc plan`
267
+ ### `scrumrun plan`
268
268
 
269
269
  - `task --add|--list|--show|--run|--audit|--cancel|--retry|--next|--start [TASK-NNN]`
270
270
  - `sprint --add|--list|--show|--start|--complete|--block`
@@ -273,7 +273,7 @@ Legacy sprint plan entries normally become Tasks. History attempts become Runs w
273
273
  - `intake <request> [--type fix|task|feature|docs|discovery] [--preview "…"]`
274
274
  - `challenge <question>`
275
275
 
276
- ### `/sc knowledge`
276
+ ### `scrumrun knowledge`
277
277
 
278
278
  - `fact --add|--list|--show|--approve|--reject|--deprecate|--invalidate`
279
279
  - `decision --add|--list|--show|--resolve|--deprecate|--invalidate`
@@ -284,12 +284,12 @@ Legacy sprint plan entries normally become Tasks. History attempts become Runs w
284
284
  - `study <focus>`
285
285
  - `vault --add|--list|--show|--remove|--path`
286
286
 
287
- ### `/sc rules`
287
+ ### `scrumrun rules`
288
288
 
289
289
  - `guardrail --add|--list|--show|--retire`
290
290
  - `reviewer --add|--list|--show|--run`
291
291
 
292
- ### `/sc review`
292
+ ### `scrumrun review`
293
293
 
294
294
  - `code --run`
295
295
  - `artifact --run`
@@ -298,7 +298,7 @@ Legacy sprint plan entries normally become Tasks. History attempts become Runs w
298
298
 
299
299
  Review is read-only unless fixes are separately authorized. Report findings by severity with evidence.
300
300
 
301
- ### `/sc config`
301
+ ### `scrumrun config`
302
302
 
303
303
  - `project --show|--language|--interaction|--approval|--quick-tasks`
304
304
  - `init --local|--shared|--force`
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ScrumRun gives an agent a small command surface and a precise project memory: what should be done, how each attempt happened, which decisions constrain the code, and why the architecture exists in its current form.
6
6
 
7
- **Package:** `2.7.11` · **Method target:** `2.0.0` · **Runtime:** Node.js `>=22.13.0` · **License:** MIT
7
+ **Package:** `3.0.1` · **Method target:** `2.0.0` · **Runtime:** Node.js `>=22.13.0` · **License:** MIT
8
8
 
9
9
  **New here?** Read the [Quickstart](docs/QUICKSTART.md) — first Run in under 10 minutes, no `SPEC.md` reading required. Full docs map in [`docs/INDEX.md`](docs/INDEX.md).
10
10
 
@@ -48,17 +48,17 @@ npm i -g scrumrun@latest
48
48
  scrumrun update
49
49
  ```
50
50
 
51
- `npx scrumrun@latest <command>` also works if you prefer not to install globally, but pin the version explicitly (`@latest` or `@2.6.1`) `npx scrumrun` alone will happily reuse a stale cached version.
51
+ Use the installed `scrumrun` command for project work. `npx` is appropriate for one-off installation, migration, or recovery only; agents must never invoke `npx scrumrun@latest` repeatedly while executing a Task, because that adds network dependency and latency to the work loop.
52
52
 
53
53
  `install` adds the client integration; `init` creates the project tree. Initialization is local by default: `.scrumrun/` and the generated agent hint are added to `.git/info/exclude`. Use `--shared` when the team wants to commit the project memory.
54
54
 
55
- ScrumRun installs one canonical agent command:
55
+ ScrumRun's canonical CLI is:
56
56
 
57
57
  ```text
58
- /sc <noun> <subject> <action> [args]
58
+ scrumrun <noun> <subject> <action> [args]
59
59
  ```
60
60
 
61
- The five nouns are `plan`, `knowledge`, `rules`, `review`, and `config`.
61
+ The five nouns are `plan`, `knowledge`, `rules`, `review`, and `config`. `/sc` is an optional AI-client shortcut; `scrumrun sc ...` remains a compatibility alias for existing integrations.
62
62
 
63
63
  ## Daily flow
64
64
 
@@ -85,7 +85,13 @@ Explicit approval atomically materializes the required plan artifacts and always
85
85
  EXECUTING → VALIDATING → LEARNING → COMPLETED | FAILED | BLOCKED
86
86
  ```
87
87
 
88
- Every approved Task carries an `## Acceptance Criteria` section so "done" is defined before work begins; `--complete --summary "…"` stores a `## Technical Summary` on the Run so the next agent inherits what was actually done. Failed retries remain available as separate Runs.
88
+ Every approved Task carries an `## Acceptance Criteria` section so "done" is defined before work begins. After approval, the agent works directly in code and the Task Markdown. It adds `## Technical Summary` and, when a non-automatic rule needs proof, a compact `## Guardrail Evidence` section. One final checkpoint closes the work:
89
+
90
+ ```bash
91
+ scrumrun plan run --finalize RUN-001
92
+ ```
93
+
94
+ The checkpoint validates the complete delta, policy, protected paths, secret boundary, acceptance evidence, and every Guardrail before writing the Run ledger and synchronizing the Task. Failed retries remain available as separate Runs.
89
95
 
90
96
  Each Run contains a machine-validated event ledger. Events have stable ids such as `RUN-044-EVT-003`, RFC3339 timestamps, actors, reasons, and typed evidence for commands, tests, files, reviews, decisions, insights, and risks. Run is the only operational history; Task keeps its approved scope and synchronized current status without duplicating those events. Completion is rejected when validation or learning evidence is missing.
91
97
 
@@ -148,21 +154,21 @@ It is progressive disclosure: the briefing is enough for most work; the agent fo
148
154
  Update the client integrations and automatically run a read-only migration preflight:
149
155
 
150
156
  ```bash
151
- npx scrumrun@latest update
157
+ scrumrun update
152
158
  ```
153
159
 
154
160
  This shows the source inventory, proposed mappings, and blockers without changing project data. Apply only the verified plan with:
155
161
 
156
162
  ```bash
157
- npx scrumrun@latest update --migrate
163
+ scrumrun update --migrate
158
164
  ```
159
165
 
160
166
  The standalone workflow remains available:
161
167
 
162
168
  ```bash
163
- npx scrumrun@latest migrate --to 2 --dry-run
164
- npx scrumrun@latest migrate --to 2 --apply
165
- npx scrumrun@latest migrate --to 2 --rollback
169
+ scrumrun migrate --to 2 --dry-run
170
+ scrumrun migrate --to 2 --apply
171
+ scrumrun migrate --to 2 --rollback
166
172
  ```
167
173
 
168
174
  Migration uses content hashes, a byte-exact ignored backup, staging validation, an atomic directory switch, a source-to-destination report, idempotent replay, and rollback protection. It also recognizes incomplete hybrid v1/v2 trees, reuses already-linked canonical work, and normalizes only deterministic schema aliases. Early v2 Run prose is preflighted and upgraded to the structured ledger by the same explicit `update --migrate` gate; ambiguous paths become evidenced snapshots instead of invented transitions. Legacy-only files leave the active tree but remain byte-exact in the ignored backup; vault contents remain local. Ambiguous history remains an explicit warning, and the migrator never invents a Sprint or Run.
@@ -170,16 +176,26 @@ Migration uses content hashes, a byte-exact ignored backup, staging validation,
170
176
  For projects that already have v2 directories but contain pre-v2 Markdown records without YAML frontmatter, use the explicit repair gate:
171
177
 
172
178
  ```bash
173
- npx scrumrun@latest repair
174
- npx scrumrun@latest repair --apply
179
+ scrumrun repair
180
+ scrumrun repair --apply
175
181
  ```
176
182
 
177
183
  Repair converts deterministic `## Metadata` fields into v2 frontmatter, preserves the authored body, recovers IDs from canonical filenames, and stores byte-exact backups under `.scrumrun/.migration-backup/repair/`. It does not guess ambiguous relationships; validate afterward with `doctor --strict`.
178
184
 
185
+ If `doctor --strict` reports `TASK_ORPHANED`, first inspect the exact recovery plan, then explicitly reset only those active Tasks to backlog and start the intended one normally:
186
+
187
+ ```bash
188
+ scrumrun repair --recover-orphan-tasks
189
+ scrumrun repair --recover-orphan-tasks --apply
190
+ scrumrun plan task --start TASK-144
191
+ ```
192
+
193
+ Recovery never invents a Run or historical events; it creates a byte-exact backup before changing the Task. The final `--start` is the intentional action that creates its first Run.
194
+
179
195
  After migration or an integration update, verify both installed assets and project state:
180
196
 
181
197
  ```bash
182
- npx scrumrun@latest doctor codex --strict
198
+ scrumrun doctor codex --strict
183
199
  ```
184
200
 
185
201
  `doctor` compares managed prompt/skill contents with the package, so an obsolete installation is reported as `stale` rather than `ok` merely because the file exists.
@@ -211,7 +227,7 @@ npx scrumrun@latest doctor codex --strict
211
227
 
212
228
  `guardrails.md` is canonical project policy. Active `GR-NNN` rules are evaluated into explicit `passed`, `blocked`, or `deferred` results; blocks identify the exact Guardrail and deferred checks stay visible for their execution-time gate. `config.md` contains preferences and cannot weaken policy. Duplicate/unknown Guardrails, disabled approval, and unsafe read-only paths fail conformance. `state.md`, `map.md`, context packages, and SQLite are generated navigation aids, never authority. `state.md` carries the same source fingerprint used by intake, an RFC3339 generation time, and a watch fingerprint for fast verified staleness checks.
213
229
 
214
- Approved Runs persist every deferred result as an append-only obligation and bind the exact policy plus workspace baseline. Material source edits use a 15-minute, path-scoped Mutation Gateway permit. Recording verifies before/after hashes, owner/read-only scope, symlinks, new secret-like content, and workspace drift. Validation and completion fail closed when edits bypass that chain or obligations remain unresolved.
230
+ Approved Runs persist every deferred result as an append-only obligation and bind the exact policy plus workspace baseline. The normal final checkpoint verifies all workspace changes at once: owner/read-only scope, symlinks, new secret-like content, policy drift, and required Guardrail evidence. Completion fails closed when any verification is missing or fails. The 15-minute path-scoped Mutation Gateway remains available for teams that explicitly choose strict per-edit control.
215
231
 
216
232
  ### Owner-controlled allowlist for descriptive files
217
233
 
@@ -243,46 +259,45 @@ Rules:
243
259
 
244
260
  ```bash
245
261
  # inspect the grammar
246
- npx scrumrun@latest commands
262
+ scrumrun commands
247
263
 
248
264
  # plan without writes, then approve the emitted token
249
- npx scrumrun@latest sc plan intake "Fix pricing rounding" --type fix --preview "Rounding moved after tax calc"
250
- npx scrumrun@latest sc plan intake --approve <token>
265
+ scrumrun plan intake "Fix pricing rounding" --type fix --preview "Rounding moved after tax calc"
266
+ scrumrun plan intake --approve <token>
251
267
 
252
268
  # record what was done at completion, so the next agent inherits it
253
- npx scrumrun@latest sc plan run --complete RUN-001 --note "Done" --evidence "npm test: passed" --summary "Moved rounding after tax calc in checkout/pricing.ts"
269
+ scrumrun plan run --finalize RUN-001 --summary "Moved rounding after tax calc in checkout/pricing.ts"
254
270
 
255
271
  # auto-sequencing: surface and start the next backlog Task
256
- npx scrumrun@latest sc plan task --next
257
- npx scrumrun@latest sc plan task --start TASK-009
272
+ scrumrun plan task --next
273
+ scrumrun plan task --start TASK-009
258
274
 
259
275
  # authorize and record a material source mutation
260
- npx scrumrun@latest sc plan run --authorize-mutation RUN-001 --path src/pricing.ts
261
- npx scrumrun@latest sc plan run --record-mutation RUN-001 --permit MUT-... --note "Pricing change recorded"
276
+ scrumrun plan run --authorize-mutation RUN-001 --path src/pricing.ts # strict mode only
277
+ scrumrun plan run --record-mutation RUN-001 --permit MUT-... --note "Pricing change recorded"
262
278
 
263
279
  # record an audit-derived Review, then resolve a persisted completion gate
264
- npx scrumrun@latest sc review artifact --run
265
- npx scrumrun@latest sc review artifact --record --task TASK-001 --run RUN-001 --evidence "npm test: passed"
266
- npx scrumrun@latest sc plan run --satisfy-guardrail RUN-001 --guardrail GR-003 --review REV-001
280
+ scrumrun review artifact --run
281
+ scrumrun review artifact --record --task TASK-001 --run RUN-001 --evidence "npm test: passed"
267
282
 
268
283
  # memory lifecycle
269
- npx scrumrun@latest sc knowledge insight --propose "Pricing stays in backend" --evidence src/pricing.ts
270
- npx scrumrun@latest sc knowledge insight --confirm INS-001
271
- npx scrumrun@latest sc knowledge study calculateFinalPrice
284
+ scrumrun knowledge insight --propose "Pricing stays in backend" --evidence src/pricing.ts
285
+ scrumrun knowledge insight --confirm INS-001
286
+ scrumrun knowledge study calculateFinalPrice
272
287
 
273
288
  # rebuild or inspect the derived graph
274
- npx scrumrun@latest sc knowledge map --build
275
- npx scrumrun@latest sc knowledge map --show
289
+ scrumrun knowledge map --build
290
+ scrumrun knowledge map --show
276
291
 
277
292
  # read a Run as a human timeline instead of raw ledger JSON
278
- npx scrumrun@latest sc plan run --render RUN-001
293
+ scrumrun plan run --render RUN-001
279
294
 
280
295
  # aggregate every Run in the project (p50/p95 durations, retries, guardrail counts)
281
- npx scrumrun@latest sc plan run --stats
282
- npx scrumrun@latest sc plan run --stats --task TASK-001 --json
296
+ scrumrun plan run --stats
297
+ scrumrun plan run --stats --task TASK-001 --json
283
298
 
284
299
  # preview a canonical-transaction recovery before touching disk
285
- npx scrumrun@latest sc config doctor --recover --dry-run
300
+ scrumrun config doctor --recover --dry-run
286
301
  ```
287
302
 
288
303
  The command manifest in `lib/commands/manifest.js` generates help and compatibility adapters, preventing client grammar drift. A recorded artifact Review cannot self-declare success: ScrumRun reruns the audit and derives the `REV-NNN` verdict from the result.
package/SPEC.md CHANGED
@@ -202,11 +202,11 @@ Everything through `AWAITING_APPROVAL` is read-only. It may exist in process mem
202
202
 
203
203
  Approval atomically creates one Task and its first Run. If either write fails, neither may remain. Project changes after planning invalidate the token. Reusing a successfully consumed token is idempotent.
204
204
 
205
- The approved Run binds the exact Guardrail-policy fingerprint and a canonical workspace baseline. Every post-approval `deferred` check becomes an append-only Guardrail obligation. A material source mutation requires a short-lived, path-scoped permit issued from that baseline; recording it verifies before/after hashes, policy freshness, path scope, read-only boundaries, symlink safety, and newly introduced secret-like content. Unrecorded workspace drift fails closed. A Run cannot complete while an obligation is unresolved or the workspace differs from its last recorded mutation.
205
+ The approved Run binds the exact Guardrail-policy fingerprint and a canonical workspace baseline. Every post-approval `deferred` check becomes an append-only Guardrail obligation. In the normal session path, agents work directly and one final checkpoint verifies the complete baseline-to-final delta: policy freshness, read-only boundaries, symlink safety, scannability, newly introduced secret-like content, and evidence for every Guardrail. Missing or unverifiable evidence fails closed. Strict teams may opt into short-lived, path-scoped permits and per-edit recording; those commands add stronger intermediate control but are not required for normal execution.
206
206
 
207
207
  The agent may assert the classification explicitly (`--type fix|task|feature|docs|discovery`), overriding keyword inference with validation and a stable reason. It may attach a short technical preview (`--preview`), rendered in the terminal, bound into the approval token, and stored as `## Preview` on the approved Task. A Task declares its `## Acceptance Criteria` before execution; completion is measured against them, never against elapsed time or token budget.
208
208
 
209
- Run transitions synchronously update the linked Task and append exactly one structured event to the Run ledger. Validation, learning, completion, failure, block, and resume transitions require a reason or typed evidence. Task status changes without receiving a duplicate narrative history. On completion, an optional `## Technical Summary` section records what was actually done, surfaced to later intake through the briefing. Multi-file mutations use a durable local transaction journal: `prepared` operations roll back byte-exactly after failure/interruption, while `committed` journals are verified and finalized. Ordinary audit is read-only and reports pending recovery; `doctor --recover` or retrying the approved mutation performs recovery explicitly. Entering `learning` may extract structured candidates from the Run, but extraction failure never blocks Run progress.
209
+ Run transitions synchronously update the linked Task and append exactly one structured event to the Run ledger. The normal `--finalize` checkpoint writes the required validating, learning, and completed transitions together after its audit; strict mode may write them individually. Task status changes without receiving a duplicate narrative history. Completion requires a `## Technical Summary` and evidenced validation/learning. Multi-file mutations use a durable local transaction journal: `prepared` operations roll back byte-exactly after failure/interruption, while `committed` journals are verified and finalized. Ordinary audit is read-only and reports pending recovery; `doctor --recover` or retrying the approved mutation performs recovery explicitly. Entering `learning` may extract structured candidates from the Run, but extraction failure never blocks Run progress.
210
210
 
211
211
  Backlog is a queue view of Tasks with `status: backlog`, ordered oldest-first by id. Starting a backlog Task (`--next` to surface, `--start` to promote) transitions `backlog → running`, creates the Task's first Run, re-evaluates policy, and records the agent identity. Starting is itself the explicit approval required by I-01.
212
212
 
@@ -274,7 +274,7 @@ scrumrun migrate --to 2 --apply
274
274
  scrumrun migrate --to 2 --rollback
275
275
  ```
276
276
 
277
- `npx scrumrun@latest update` performs the same read-only preflight when run inside a v1 project and leaves project data untouched. `update --migrate` is an explicit request to apply the verified plan; it is not implicit migration.
277
+ `scrumrun update` performs the same read-only preflight when run inside a v1 project and leaves project data untouched. `update --migrate` is an explicit request to apply the verified plan; it is not implicit migration.
278
278
 
279
279
  Inside an early v2 project, the same commands preflight and explicitly upgrade legacy Run prose to ledger schema 1. Deterministic transition chains are recovered; incomplete history becomes an evidenced snapshot. Apply keeps byte-exact ignored backups, verifies hashes, is idempotent, and supports rollback that refuses to erase later Run changes.
280
280
 
@@ -318,17 +318,17 @@ Legacy sprint entries become Tasks. History entries become Runs only with an evi
318
318
  - **I-21** Material mutations are policy-bound, path-scoped, hash-verified, append-only, and fail closed on bypass; unresolved Guardrail obligations block completion.
319
319
  - **I-22** The semantic index's declared search backend must match the runtime capabilities of the current Node.js SQLite build; conformance flags a mismatch instead of relying on lazy runtime fallback.
320
320
  - **I-23** `method.json` declares the canonical path index for every artifact family so agents navigate by declaration, not by search. Missing or drifted paths fail conformance; grep and directory scans are fallbacks, never the first step.
321
- - **I-24** Runs are only mutated through the CLI. A canonical Run whose ledger fails validation is a bypass — conformance reports `RUN_WRITE_BYPASS` with a pointer to the recovery command `sc plan run --normalize-legacy`, which collapses the bad ledger into a single `snapshot` event and preserves the byte-exact original under `.scrumrun/.migration-backup/runs/`.
321
+ - **I-24** Runs are only mutated through the CLI. A canonical Run whose ledger fails validation is a bypass — conformance reports `RUN_WRITE_BYPASS` with a pointer to the recovery command `scrumrun plan run --normalize-legacy`, which collapses the bad ledger into a single `snapshot` event and preserves the byte-exact original under `.scrumrun/.migration-backup/runs/`.
322
322
 
323
323
  ## 11. Command grammar
324
324
 
325
325
  The only canonical root is:
326
326
 
327
327
  ```text
328
- /sc <noun> <subject> <action> [args]
328
+ scrumrun <noun> <subject> <action> [args]
329
329
  ```
330
330
 
331
- Exactly five nouns exist: `plan`, `knowledge`, `rules`, `review`, and `config`. The implementation manifest is the command source of truth for help and client adapters. Fresh installs expose `/sc`; generated v1 aliases may remain for one compatibility cycle and must execute the canonical route.
331
+ Exactly five nouns exist: `plan`, `knowledge`, `rules`, `review`, and `config`. The implementation manifest is the command source of truth for help and client adapters. The installed direct CLI is canonical; `/sc` and generated v1 aliases may remain as compatibility shortcuts for one release cycle and must execute the canonical route.
332
332
 
333
333
  Unknown syntax fails deterministically and never guesses a mutation.
334
334
 
package/bin/scrumrun.js CHANGED
@@ -31,7 +31,7 @@ const { ARTIFACT_TYPES, ArtifactRepository } = require(path.join(root, "lib", "v
31
31
  const { aliases: COMMAND_ALIASES, resolveAlias, resolveRoute } = require(path.join(root, "lib", "commands", "manifest"));
32
32
  const { renderCommandHelp, renderCompatibilityPrompt, renderRootPrompt } = require(path.join(root, "lib", "commands", "render"));
33
33
  const { planRequest } = require(path.join(root, "lib", "runtime", "request-engine"));
34
- const { addPlanArtifact, approveRequest, nextBacklogTask, refreshErrors, refreshState, retryTask, startBacklogTask, transitionRun } = require(path.join(root, "lib", "runtime", "orchestrator"));
34
+ const { addPlanArtifact, approveRequest, finalizeRun, nextBacklogTask, refreshErrors, refreshState, retryTask, startBacklogTask, transitionRun } = require(path.join(root, "lib", "runtime", "orchestrator"));
35
35
  const { authorizeMutation, recordMutation, satisfyGuardrail } = require(path.join(root, "lib", "runtime", "mutation-gateway"));
36
36
  const { recordArtifactReview } = require(path.join(root, "lib", "runtime", "review-service"));
37
37
  const { createMemory, listMemory, showMemory, transitionMemory } = require(path.join(root, "lib", "memory", "service"));
@@ -55,8 +55,8 @@ function usage() {
55
55
 
56
56
  Usage:
57
57
  scrumrun --version
58
- scrumrun sc
59
- scrumrun sc <noun> <subject> <action> [args]
58
+ scrumrun <noun> <subject> <action> [args]
59
+ scrumrun sc <noun> <subject> <action> [args] # compatibility alias
60
60
  scrumrun install [all|codex|opencode|claude] [--force]
61
61
  scrumrun update [all|codex|opencode|claude] [--no-migrate] [--verbose]
62
62
  scrumrun init [--local|--shared] [--lean] [--no-agent-hint] [--force]
@@ -67,18 +67,18 @@ Usage:
67
67
  scrumrun migrate --to 2 --apply
68
68
  scrumrun migrate --to 2 --rollback
69
69
  scrumrun doctor [all|codex|opencode|claude] [--strict] [--recover]
70
- scrumrun repair [--apply]
70
+ scrumrun repair [--recover-orphan-tasks] [--apply]
71
71
  scrumrun uninstall [--force]
72
72
 
73
73
  Install:
74
74
  npm i -g scrumrun@latest # recommended
75
- npx scrumrun@latest <command> # also works; pin @latest to avoid stale npx cache
75
+ npx scrumrun@latest <command> # one-off recovery only; never use in an agent loop
76
76
 
77
77
  Examples:
78
78
  scrumrun install
79
79
  scrumrun init
80
80
  scrumrun status
81
- scrumrun sc knowledge decision --list
81
+ scrumrun knowledge decision --list
82
82
  scrumrun migrate --to 2 --dry-run
83
83
  `);
84
84
  }
@@ -318,14 +318,14 @@ function migrationPreflightOnUpdate({ apply = false } = {}) {
318
318
  return { status: "blocked" };
319
319
  }
320
320
  if (!apply) {
321
- console.log("\nThe project remains unchanged. Re-run update to apply the verified plan, or keep opt-out with: npx scrumrun@latest update --no-migrate");
321
+ console.log("\nThe project remains unchanged. Re-run update to apply the verified plan, or keep opt-out with: scrumrun update --no-migrate");
322
322
  return { status: "ready" };
323
323
  }
324
324
  const result = applyRunLedgerMigration(process.cwd());
325
325
  refreshState(path.join(process.cwd(), ".scrumrun"));
326
326
  console.log("\nApplied the verified ScrumRun Run ledger schema migration.");
327
327
  console.log(`Source fingerprint: ${result.plan.fingerprint}`);
328
- console.log("Rollback remains available with: npx scrumrun@latest migrate --to 2 --rollback");
328
+ console.log("Rollback remains available with: scrumrun migrate --to 2 --rollback");
329
329
  return { status: result.status, result };
330
330
  }
331
331
  } catch {
@@ -344,13 +344,13 @@ function migrationPreflightOnUpdate({ apply = false } = {}) {
344
344
  return { status: "blocked" };
345
345
  }
346
346
  if (!apply) {
347
- console.log("\nThe project remains unchanged. Re-run update to apply the verified plan, or keep opt-out with: npx scrumrun@latest update --no-migrate");
347
+ console.log("\nThe project remains unchanged. Re-run update to apply the verified plan, or keep opt-out with: scrumrun update --no-migrate");
348
348
  return { status: "ready" };
349
349
  }
350
350
  const result = applyMigration(process.cwd(), { plan: preview.plan });
351
351
  console.log("\nApplied the verified ScrumRun v1 → v2 project migration.");
352
352
  console.log(`Source fingerprint: ${result.manifest.sourceInventory.rootSha256}`);
353
- console.log("Rollback remains available with: npx scrumrun@latest migrate --to 2 --rollback");
353
+ console.log("Rollback remains available with: scrumrun migrate --to 2 --rollback");
354
354
  return { status: "applied", result };
355
355
  } catch (error) {
356
356
  console.error(`Project migration preflight failed: ${error.message}`);
@@ -1157,7 +1157,7 @@ function commandList() {
1157
1157
  CLI helpers:
1158
1158
  scrumrun status
1159
1159
  scrumrun commands
1160
- scrumrun sc knowledge decision --list
1160
+ scrumrun knowledge decision --list
1161
1161
  scrumrun vault add "NAME" "local-dev-value"
1162
1162
  scrumrun context show
1163
1163
  scrumrun backlog add "Sprint 01"
@@ -1392,7 +1392,7 @@ function runSemanticContext(subject, args) {
1392
1392
  }
1393
1393
  const mapFile = path.join(process.cwd(), ".scrumrun", "map.md");
1394
1394
  const status = mapStatus(process.cwd());
1395
- if (status.stale) throw new Error(`Generated map.md is stale (${status.reason || status.error || "unknown reason"}); run /sc knowledge map --build.`);
1395
+ if (status.stale) throw new Error(`Generated map.md is stale (${status.reason || status.error || "unknown reason"}); run scrumrun knowledge map --build.`);
1396
1396
  console.log(fs.readFileSync(mapFile, "utf8"));
1397
1397
  return;
1398
1398
  }
@@ -1456,7 +1456,7 @@ function executeRootRoute(route) {
1456
1456
  return;
1457
1457
  }
1458
1458
  console.log(`Next backlog Task: ${next.id} — ${next.title || next.id}`);
1459
- console.log(`Start it with: scrumrun sc plan task --start ${next.id}`);
1459
+ console.log(`Start it with: scrumrun plan task --start ${next.id}`);
1460
1460
  return;
1461
1461
  }
1462
1462
  if (noun === "plan" && subject === "task" && routeArgs[0] === "--start") {
@@ -1562,6 +1562,15 @@ function executeRootRoute(route) {
1562
1562
  return;
1563
1563
  }
1564
1564
  if (noun === "plan" && subject === "run") {
1565
+ if (routeArgs[0] === "--finalize") {
1566
+ const runId = routeArgs[1];
1567
+ if (!runId) throw new Error("--finalize requires RUN-NNN.");
1568
+ const result = finalizeRun(process.cwd(), runId, runTransitionOptions(routeArgs.slice(2)));
1569
+ console.log(`${result.run.id}: completed; ${result.task.id}: completed. Final session audit verified ${result.changes} change(s).`);
1570
+ if (result.resolved.length) console.log(`Guardrails verified: ${result.resolved.join(", ")}.`);
1571
+ if (result.learning && result.learning.created.length) console.log(`Learning candidates: ${result.learning.created.join(", ")}.`);
1572
+ return;
1573
+ }
1565
1574
  if (routeArgs[0] === "--authorize-mutation") {
1566
1575
  const paths = optionValues(routeArgs.slice(2), "--path");
1567
1576
  const result = authorizeMutation(process.cwd(), routeArgs[1], paths);
@@ -1680,7 +1689,7 @@ function runRoot(parts) {
1680
1689
 
1681
1690
  function runCompatibilityAlias(alias, parts) {
1682
1691
  const route = resolveAlias(alias, parts);
1683
- console.warn(`Deprecated: ${alias} now executes /sc ${route.noun} ${route.subject}.`);
1692
+ console.warn(`Deprecated: ${alias} now executes scrumrun ${route.noun} ${route.subject}.`);
1684
1693
  if (route.note) console.warn(route.note);
1685
1694
  if (alias === "sc-backlog") return runBacklog(parts);
1686
1695
  if (alias !== "sc-init") chdirToProjectRoot();
@@ -1696,7 +1705,7 @@ function printCore({ pathOnly = false, promptOnly = false } = {}) {
1696
1705
  if (promptOnly) {
1697
1706
  console.log(`Read AGENTS.md, .scrumrun/guardrails.md, and .scrumrun/state.md first.
1698
1707
  Follow ScrumRun 2.0 and load only the canonical ids/evidence relevant to the request.
1699
- If /sc is unavailable, execute the equivalent /sc <noun> <subject> <action> workflow from .scrumrun/core.md manually.
1708
+ Use the installed CLI as scrumrun <noun> <subject> <action>; /sc is only a client shortcut.
1700
1709
  Keep intake read-only; do not create a Task or Run until explicit approval.`);
1701
1710
  return;
1702
1711
  }
@@ -2171,7 +2180,7 @@ function statusProject() {
2171
2180
  }
2172
2181
  console.log("");
2173
2182
  console.log(`Migration record: ${fs.existsSync(path.join(scrumDir, ".migration", "v1-to-v2", "manifest.json")) ? "v1-to-v2 applied" : "not applicable / native v2"}`);
2174
- console.log(`Canonical command: /sc`);
2183
+ console.log(`Canonical command: scrumrun <noun> <subject> <action>`);
2175
2184
  return;
2176
2185
  }
2177
2186
  const required = [
@@ -2227,24 +2236,24 @@ function promptCommand(parts) {
2227
2236
  const kind = parts[0];
2228
2237
  const text = joinText(parts.slice(1));
2229
2238
  const prompts = {
2230
- intake: `/sc plan intake ${text}`.trim(),
2231
- study: `/sc knowledge study${text ? ` ${text}` : ""}`,
2232
- challenge: `/sc plan challenge ${text}`.trim(),
2233
- know: `/sc knowledge fact --add ${text}`.trim(),
2234
- "context-build": `/sc knowledge context --build${text ? ` ${text}` : ""}`,
2235
- "context-update": `/sc knowledge context --update${text ? ` ${text}` : ""}`,
2236
- "context-show": `/sc knowledge context --show${text ? ` ${text}` : ""}`,
2237
- context: `/sc knowledge context ${text}`.trim(),
2238
- vault: `/sc knowledge vault ${text}`.trim(),
2239
- "goal-set": `/sc plan feature --add ${text}`.trim(),
2240
- "goal-new": `/sc plan feature --add ${text}`.trim(),
2241
- goal: `/sc plan feature --add ${text}`.trim(),
2242
- "sprint-add": `/sc plan sprint --add ${text}`.trim(),
2243
- "sprint-new": `/sc plan sprint --add ${text}`.trim(),
2244
- "sprint-run": `/sc plan task --run ${text}`.trim(),
2245
- "backlog-add": `/sc plan task --add ${text} --status backlog`.trim(),
2246
- backlog: `/sc plan task --add ${text} --status backlog`.trim(),
2247
- status: `/sc plan sprint --show${text ? ` ${text}` : ""}`
2239
+ intake: `scrumrun plan intake ${text}`.trim(),
2240
+ study: `scrumrun knowledge study${text ? ` ${text}` : ""}`,
2241
+ challenge: `scrumrun plan challenge ${text}`.trim(),
2242
+ know: `scrumrun knowledge fact --add ${text}`.trim(),
2243
+ "context-build": `scrumrun knowledge context --build${text ? ` ${text}` : ""}`,
2244
+ "context-update": `scrumrun knowledge context --update${text ? ` ${text}` : ""}`,
2245
+ "context-show": `scrumrun knowledge context --show${text ? ` ${text}` : ""}`,
2246
+ context: `scrumrun knowledge context ${text}`.trim(),
2247
+ vault: `scrumrun knowledge vault ${text}`.trim(),
2248
+ "goal-set": `scrumrun plan feature --add ${text}`.trim(),
2249
+ "goal-new": `scrumrun plan feature --add ${text}`.trim(),
2250
+ goal: `scrumrun plan feature --add ${text}`.trim(),
2251
+ "sprint-add": `scrumrun plan sprint --add ${text}`.trim(),
2252
+ "sprint-new": `scrumrun plan sprint --add ${text}`.trim(),
2253
+ "sprint-run": `scrumrun plan task --run ${text}`.trim(),
2254
+ "backlog-add": `scrumrun plan task --add ${text} --status backlog`.trim(),
2255
+ backlog: `scrumrun plan task --add ${text} --status backlog`.trim(),
2256
+ status: `scrumrun plan sprint --show${text ? ` ${text}` : ""}`
2248
2257
  };
2249
2258
  if (!kind || !prompts[kind]) {
2250
2259
  console.error("Usage: scrumrun prompt <intake|study|challenge|know|context-build|context-update|vault|goal-set|sprint-add|sprint-run|backlog-add|status> [text]");
@@ -2571,6 +2580,8 @@ if (!command || command === "--help" || command === "-h") {
2571
2580
  else install(target, true, { compatibility: false });
2572
2581
  } else if (command === "sc") {
2573
2582
  runRoot(args.slice(1));
2583
+ } else if (["plan", "knowledge", "rules", "review", "config"].includes(command)) {
2584
+ runRoot(args);
2574
2585
  } else if (COMMAND_ALIASES[command]) {
2575
2586
  runCompatibilityAlias(command, args.slice(1));
2576
2587
  } else if (command === "init") {
@@ -2585,7 +2596,8 @@ if (!command || command === "--help" || command === "-h") {
2585
2596
  try {
2586
2597
  const { repair } = require(path.join(root, "lib", "commands", "repair"));
2587
2598
  const doApply = args.includes("--apply");
2588
- const result = repair(scrumDir, { apply: doApply });
2599
+ const recoverOrphanTasks = args.includes("--recover-orphan-tasks");
2600
+ const result = repair(scrumDir, { apply: doApply, recoverOrphanTasks });
2589
2601
  console.log(result.report);
2590
2602
  if (!doApply && result.plan.entries.length) process.exitCode = 0;
2591
2603
  } catch (error) {