scrumrun 3.1.1 → 3.1.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/CHANGELOG.md CHANGED
@@ -4,11 +4,18 @@ All notable changes follow Semantic Versioning.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 3.1.2 - 2026-08-31
8
+
9
+ ### Fixed
10
+
11
+ - **Mechanical strict-audit gate.** The CLI now refuses Task start/retry and every Run state transition unless `--strict` is explicitly present. This prevents a normal agent loop from creating failed/blocked administrative Runs even if it ignores the Markdown-first guidance.
12
+
7
13
  ## 3.1.1 - 2026-08-31
8
14
 
9
15
  ### Fixed
10
16
 
11
17
  - **No strict-Run commands in daily work.** Generated Core and agent instructions now explicitly prohibit `plan run --fail|--block|--retry|--finalize|--complete|--validate` and `plan task --start` in normal operation. A legacy Run incorrectly failed for administrative reasons stays as history; the Task's direct Markdown handoff records the real result.
18
+ - **CLI backstop.** Task start/retry and Run state-changing commands now require an explicit `--strict`, so an agent that ignores the guidance cannot accidentally create another failed/blocked administrative Run.
12
19
 
13
20
  ## 3.1.0 - 2026-08-31
14
21
 
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:** `3.1.1` · **Method target:** `2.0.0` · **Runtime:** Node.js `>=22.13.0` · **License:** MIT
7
+ **Package:** `3.1.2` · **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
 
@@ -101,6 +101,8 @@ scrumrun review release --run
101
101
 
102
102
  `update --project` refreshes packaged `core.md` and recognized generated `AGENTS.md` with a local byte-exact backup before replacing them. The CLI can still generate/validate Task, Feature, Sprint, and Run records when desired, but it must never become a routine blocker.
103
103
 
104
+ For extra protection, CLI Task start/retry and every Run state transition require `--strict`. This prevents accidental administrative failures in the normal Markdown-first workflow.
105
+
104
106
  Each optional structured Run contains a machine-validated event ledger. It remains useful for strict audit/release work, but daily history can stay as concise, human-readable Task handoff Markdown.
105
107
 
106
108
  Linked Task/Run writes use a durable ignored transaction journal. Captured failures roll back immediately; interrupted operations are recovered byte-exactly on retry or through explicit `doctor --recover`. Read-only audit reports pending recovery and never repairs state silently.
package/bin/scrumrun.js CHANGED
@@ -1308,6 +1308,7 @@ function runTransitionOptions(args) {
1308
1308
  let summary = null;
1309
1309
  for (let index = 2; index < args.length; index++) {
1310
1310
  const token = args[index];
1311
+ if (token === "--strict") continue;
1311
1312
  const value = args[index + 1] && !args[index + 1].startsWith("--") ? args[index + 1] : null;
1312
1313
  if (token === "--note" || token === "--actor" || token === "--at" || token === "--evidence" || token === "--summary" || evidenceFlags.has(token)) {
1313
1314
  if (!value) throw new Error(`${token} requires a value.`);
@@ -1333,6 +1334,11 @@ function runTransitionOptions(args) {
1333
1334
  return { note: note || noteParts.join(" ").trim() || null, evidence, actor, occurredAt, summary };
1334
1335
  }
1335
1336
 
1337
+ function requireStrictAudit(args, action) {
1338
+ if (args.includes("--strict")) return;
1339
+ throw new Error(`${action} is disabled in Markdown-first daily work. Update the Task Markdown directly; use --strict only for an owner-requested audit.`);
1340
+ }
1341
+
1336
1342
  function removeOptionPairs(args, names) {
1337
1343
  const hidden = new Set(names);
1338
1344
  const next = [];
@@ -1470,6 +1476,7 @@ function executeRootRoute(route) {
1470
1476
  return;
1471
1477
  }
1472
1478
  if (noun === "plan" && subject === "task" && routeArgs[0] === "--retry") {
1479
+ requireStrictAudit(routeArgs, "Task retry");
1473
1480
  const result = retryTask(process.cwd(), routeArgs[1], { reassign: routeArgs.includes("--reassign") });
1474
1481
  console.log(`Created retry ${result.run.id} for ${result.task.id} (attempt ${result.run.attempt}).`);
1475
1482
  return;
@@ -1486,6 +1493,7 @@ function executeRootRoute(route) {
1486
1493
  return;
1487
1494
  }
1488
1495
  if (noun === "plan" && subject === "task" && routeArgs[0] === "--start") {
1496
+ requireStrictAudit(routeArgs, "Task start");
1489
1497
  let target = routeArgs[1];
1490
1498
  if (!target) {
1491
1499
  const repository = new ArtifactRepository(projectFile());
@@ -1610,9 +1618,10 @@ function executeRootRoute(route) {
1610
1618
  }
1611
1619
  if (noun === "plan" && subject === "run") {
1612
1620
  if (routeArgs[0] === "--finalize") {
1621
+ requireStrictAudit(routeArgs, "Run finalization");
1613
1622
  const runId = routeArgs[1];
1614
1623
  if (!runId) throw new Error("--finalize requires RUN-NNN.");
1615
- const result = finalizeRun(process.cwd(), runId, runTransitionOptions(routeArgs.slice(2)));
1624
+ const result = finalizeRun(process.cwd(), runId, runTransitionOptions(routeArgs));
1616
1625
  console.log(`${result.run.id}: completed; ${result.task.id}: completed. Final session audit verified ${result.changes} change(s).`);
1617
1626
  if (result.resolved.length) console.log(`Guardrails verified: ${result.resolved.join(", ")}.`);
1618
1627
  if (result.learning && result.learning.created.length) console.log(`Learning candidates: ${result.learning.created.join(", ")}.`);
@@ -1654,6 +1663,7 @@ function executeRootRoute(route) {
1654
1663
  "--block": "blocked"
1655
1664
  };
1656
1665
  if (transitions[routeArgs[0]]) {
1666
+ requireStrictAudit(routeArgs, `Run transition ${routeArgs[0]}`);
1657
1667
  const result = transitionRun(process.cwd(), routeArgs[1], transitions[routeArgs[0]], runTransitionOptions(routeArgs));
1658
1668
  console.log(`${result.run.id}: ${result.run.status}; ${result.task.id}: ${result.task.status}.`);
1659
1669
  if (result.learning) {
package/docs/COMMANDS.md CHANGED
@@ -13,14 +13,14 @@ Use `.scrumrun/` Markdown for normal project work. `/sc` and the installed CLI a
13
13
  ```text
14
14
  scrumrun plan intake <request>
15
15
  scrumrun plan intake --approve <token>
16
- scrumrun plan task --add|--list|--show|--run|--audit|--cancel|--retry
16
+ scrumrun plan task --add|--list|--show|--run|--audit|--cancel|--retry --strict
17
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
18
  scrumrun plan sprint --add|--list|--show|--start|--complete|--block
19
19
  scrumrun plan sprint --amend SPRINT-NNN [--title "..."] [--timebox "..."] [--exit-gate "..."] [--section "Heading=content"]
20
20
  scrumrun plan feature --add|--list|--show|--activate|--complete
21
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]
22
+ scrumrun plan run --list|--show|--validate|--learn|--complete|--resume|--fail|--block --strict [--note] [typed evidence flags]
23
+ scrumrun plan run --finalize RUN-NNN --strict [--summary "technical recap"] [--note]
24
24
  scrumrun plan run --authorize-mutation RUN-NNN --path <relative-path> [--path ...]
25
25
  scrumrun plan run --record-mutation RUN-NNN --permit MUT-id [--note] [--actor]
26
26
  scrumrun plan run --satisfy-guardrail RUN-NNN --guardrail GR-NNN [typed evidence flags]
@@ -29,6 +29,8 @@ scrumrun plan challenge <question>
29
29
 
30
30
  Normal execution is Markdown-first: after approval, work in code and the relevant Task Markdown, then record the Technical Summary and any Follow-ups directly. A Run/`--finalize` checkpoint is optional strict audit, never a prerequisite. Mutation permits are available only for explicitly requested strict mode.
31
31
 
32
+ The CLI refuses Task start/retry and all Run state changes unless `--strict` is present. This prevents an agent from accidentally manufacturing a failed/blocked retry during normal work; `--strict` is for an owner-requested audit only.
33
+
32
34
  `--amend` is an optional structured helper. The Markdown-first workflow may adjust Task/Feature/Sprint content directly, preserving a useful handoff. Use the CLI when atomic relation synchronization or machine audit is valuable; do not let status vocabulary or missing relations stop approved work.
33
35
 
34
36
  Every new Task starts with a `## Validation Scope`: only checks explicitly required by the owner, Acceptance Criteria, or an active Guardrail block completion. Missing optional E2E, integration, or review coverage belongs in a follow-up/risk note; it must not be used to mark the Run failed.
@@ -6,7 +6,7 @@ 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]", "--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]"],
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] --strict", "--next", "--start [TASK-NNN] --strict"],
10
10
  sprint: ["--add", "--amend <SPRINT-NNN> [--title] [--timebox] [--exit-gate] [--section \"Heading=content\"]", "--list", "--show", "--start", "--complete", "--block"],
11
11
  feature: ["--add", "--amend <FEAT-NNN> [--title] [--purpose] [--exit-criteria] [--section \"Heading=content\"]", "--list", "--show", "--activate", "--complete"],
12
12
  run: [
@@ -15,16 +15,16 @@ const nouns = Object.freeze({
15
15
  "--render <RUN-NNN>",
16
16
  "--stats [--task <TASK-NNN>] [--feature <FEAT-NNN>] [--sprint <SPRINT-NNN>] [--json]",
17
17
  "--normalize-legacy [--dry-run]",
18
- "--finalize <RUN-NNN> [--summary \"technical recap\"] [--note]",
18
+ "--finalize <RUN-NNN> --strict [--summary \"technical recap\"] [--note]",
19
19
  "--authorize-mutation <RUN-NNN> --path <relative-path>",
20
20
  "--record-mutation <RUN-NNN> --permit <MUT-id> [--note] [--actor]",
21
21
  "--satisfy-guardrail <RUN-NNN> --guardrail <GR-NNN> [--note] [--evidence] [--review] [--migration] [--actor]",
22
- "--validate [--note] [--evidence] [--command] [--test] [--file] [--review] [--actor] [--at]",
23
- "--learn [--note] [--evidence] [--decision] [--insight] [--file] [--actor] [--at]",
24
- "--complete [--note] [--evidence] [--review] [--test] [--file] [--actor] [--at] [--summary \"technical recap for future tasks\"]",
25
- "--resume [--note] [--evidence] [--risk] [--actor] [--at]",
26
- "--fail [--note] [--evidence] [--risk] [--test] [--actor] [--at]",
27
- "--block [--note] [--evidence] [--risk] [--actor] [--at]"
22
+ "--validate --strict [--note] [--evidence] [--command] [--test] [--file] [--review] [--actor] [--at]",
23
+ "--learn --strict [--note] [--evidence] [--decision] [--insight] [--file] [--actor] [--at]",
24
+ "--complete --strict [--note] [--evidence] [--review] [--test] [--file] [--actor] [--at] [--summary \"technical recap for future tasks\"]",
25
+ "--resume --strict [--note] [--evidence] [--risk] [--actor] [--at]",
26
+ "--fail --strict [--note] [--evidence] [--risk] [--test] [--actor] [--at]",
27
+ "--block --strict [--note] [--evidence] [--risk] [--actor] [--at]"
28
28
  ],
29
29
  intake: ["<request>", "--request", "--approve", "--plain", "--json", "--type <fix|task|feature|docs|discovery>", "--preview \"technical summary\""],
30
30
  challenge: ["<question>"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrumrun",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "description": "Evidence-driven Agile runtime and semantic project memory for AI coding agents.",
5
5
  "bin": {
6
6
  "scrumrun": "bin/scrumrun.js",