scrumrun 3.1.0 → 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,6 +4,19 @@ 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
+
13
+ ## 3.1.1 - 2026-08-31
14
+
15
+ ### Fixed
16
+
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.
19
+
7
20
  ## 3.1.0 - 2026-08-31
8
21
 
9
22
  ### Changed
package/CORE.md CHANGED
@@ -90,6 +90,8 @@ AGENTS.md
90
90
 
91
91
  **Block only on real constraints.** An agent must stop for an explicit active Guardrail, secret/security risk, destructive action without approval, or an unmet required Acceptance Criterion. It must not manufacture a failed/blocked Run because optional E2E coverage, an optional reviewer, or a non-required environment is unavailable; record meaningful gaps in `## Follow-ups` or a risk note.
92
92
 
93
+ **Normal operation never mutates Run state through the CLI.** Do not call `plan run --fail|--block|--retry|--finalize|--complete|--validate` or `plan task --start` in daily work. Those are owner-requested strict audit tools only. When a legacy Run already has the wrong administrative outcome, preserve it as history and correct the delivery record directly in the Task's Technical Summary and Follow-ups.
94
+
93
95
  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.
94
96
 
95
97
  `state.md` and the semantic index use two-tier freshness checks. Matching path/stat watch fingerprints avoid rereading unchanged sources; any metadata drift falls back to complete content hashing. A cache schema mismatch rebuilds the disposable index once. Watch metadata is only an optimization and never authority.
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.0` · **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>"]
@@ -36,6 +36,7 @@ ${grammarLines().join("\n")}
36
36
  - Evaluate active Guardrails as \`passed\`, \`blocked\`, or \`deferred\`; cite exact \`GR-NNN\` ids and keep deferred execution gates visible.
37
37
  - Block only for an explicit Guardrail, secret/security risk, destructive action without approval, or an unmet required Acceptance Criterion. Optional unrun E2E/review coverage is a follow-up/risk, not a failed Run.
38
38
  - Use the CLI only for \`init\`, \`update --project\`, \`migrate\`, \`repair\`, \`doctor\`, reports, or release checks. Do not invoke \`npx scrumrun@latest\` during execution.
39
+ - Never invoke \`plan run --fail|--block|--retry|--finalize|--complete|--validate\` or \`plan task --start\` during normal work. These optional strict-audit commands must not decide a Task outcome.
39
40
  - Strict per-path Mutation Gateway permits and ledger finalization remain available only when the owner explicitly requests strict execution.
40
41
  - Knowledge/Decision/Insight records require evidence; AI-proposed Insights remain \`candidate\` until confirmed.
41
42
  - Never print vault values or write before approval.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrumrun",
3
- "version": "3.1.0",
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",
@@ -23,6 +23,7 @@ After approval:
23
23
  - record a `## Technical Summary` at completion so the next agent inherits what was done; record optional missing coverage in `## Follow-ups`;
24
24
  - work directly in code and Task Markdown after approval; do not call `npx scrumrun@latest` or normal `scrumrun plan/run` commands during execution;
25
25
  - use the CLI only for `init`, `update --project`, `migrate`, `repair`, `doctor`, reports, or release checks. It audits/repairs the folder; it does not own the daily workflow;
26
+ - never invoke `plan run --fail`, `--block`, `--retry`, `--finalize`, `--complete`, `--validate`, or `plan task --start` in normal work. A failed legacy Run due to administrative state remains historical; write the corrected delivery outcome directly in the Task instead;
26
27
  - learning proposes evidence-backed Knowledge, Decisions, or candidate Insights when the work reveals reusable context;
27
28
  - guardrails remain mandatory: stop only for an explicit Guardrail, security/secret risk, destructive action without approval, or an unmet required Acceptance Criterion. Status vocabulary, missing Runs, unavailable optional tests, and stale generated state are warnings to reconcile, not blockers.
28
29
 
@@ -18,3 +18,5 @@ Guardrails are mandatory, but administrative state is not: block only for an exp
18
18
  `.scrumrun/guardrails.md` is canonical policy. Never bypass it, overwrite owner work, auto-confirm AI knowledge, auto-migrate v1 state, or print vault values.
19
19
 
20
20
  Use the installed CLI only for `init`, `update --project`, `migrate`, `repair`, `doctor`, reports, and release checks. For daily product work, follow `.scrumrun/core.md` and edit the relevant Markdown directly.
21
+
22
+ Never invoke `plan run --fail`, `--block`, `--retry`, `--finalize`, `--complete`, `--validate`, or `plan task --start` during normal work. If an old Run says failed for an administrative reason, leave it as history and record the actual delivered outcome in the Task's Technical Summary and Follow-ups.
@@ -40,6 +40,8 @@ Normal hot path:
40
40
 
41
41
  **Do not block on administrative state.** A missing/invalid Run, legacy status vocabulary, stale generated view, or optional unrun test is a warning to reconcile in Markdown, not a reason to refuse productive work. Block only for an explicit Guardrail, security/secret risk, destructive action without approval, or an unmet required Acceptance Criterion. Optional E2E/integration/review coverage belongs in `## Follow-ups` or a risk note, never in a fabricated failed Run.
42
42
 
43
+ **Normal-operation command ban.** Do not invoke `scrumrun plan run --fail`, `--block`, `--retry`, `--finalize`, `--complete`, `--validate`, or `scrumrun plan task --start` during ordinary work. Those are optional strict-audit tools and cannot be used to decide whether a Task is delivered. If an old Run is already failed for an administrative reason, leave it as historical evidence, continue the Task directly, and write the corrected outcome in the Task's Technical Summary and Follow-ups.
44
+
43
45
  Lean mode is a read policy, not an incomplete store. Generated files and `.scrumrun/.cache/` are never authoritative.
44
46
 
45
47
  Generated state and semantic indexes use a metadata-watch fast path with a full content-hash fallback. Treat cache-schema mismatch as a request to rebuild the disposable projection, never as permission to rewrite canonical Markdown.
@@ -55,7 +57,7 @@ For a v1 project without canonical v2 artifacts, recommend `scrumrun migrate --t
55
57
  - Memory — what was learned and why: `K-NNN`, `DEC-NNN`, `INS-NNN`, and dossiers.
56
58
  - Review (`REV-NNN`) — evidence from a scoped quality gate.
57
59
 
58
- Never create a Sprint merely because work exists. A standalone Task is valid. A retry creates a new Run and preserves the failed/blocked prior Run.
60
+ Never create a Sprint merely because work exists. A standalone Task is valid. Strict audit retries preserve their prior Runs, but retries are never part of the normal workflow.
59
61
 
60
62
  ## Request pipeline
61
63
 
@@ -111,11 +113,11 @@ During execution:
111
113
 
112
114
  Never overwrite a prior attempt. Never mark work complete because time/token budget ended.
113
115
 
114
- When a Run completes and work remains queued, the briefing's `## Next Up` names the next backlog Task. Surface it with `scrumrun plan task --next` and start it with `scrumrun plan task --start [TASK-NNN]` starting is the explicit approval; the owner can always decline. Each agent declares its identity via `SCRUMRUN_AGENT` (or `Agent Identity` in `config.md`); it is recorded as the Task `assignee` and the Run event `actor`.
116
+ When work remains queued, the briefing may name the next backlog Task. The owner starts it through natural-language approval; do not call CLI start/retry commands to manufacture operational state. Each agent may record its identity in the Task handoff when useful.
115
117
 
116
118
  Every explicit Guardrail remains mandatory. In strict mode, the CLI final checkpoint fails closed on policy drift, protected-path changes, unsafe symlinks, unscannable content, newly introduced secret-like content, or missing Guardrail Evidence. The ignored permit cache is disposable; deleting it invalidates outstanding strict-mode permits and never creates authority.
117
119
 
118
- Run is the sole operational-history authority. Task synchronizes current status without copying Run events. Validation, learning, completion, failure, block, and resume require a reason or structured evidence; completion also requires evidenced validation and learning. Early v2 prose Runs are migrated explicitly, with deterministic chains recovered and uncertain history represented as an evidenced snapshot.
120
+ Task Markdown is the daily operational handoff authority. A structured Run is optional strict audit history only. Early v2 prose Runs may be repaired/migrated explicitly, but their state never overrides the Task's direct handoff or blocks approved work.
119
121
 
120
122
  Linked canonical writes use the ignored durable transaction journal. An interrupted prepared mutation rolls back before the next approved mutation; a committed journal is verified and finalized. Audit remains read-only and reports pending recovery. Use `doctor --recover` only when explicitly requested, and never overwrite bytes changed after interruption.
121
123