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 +13 -0
- package/CORE.md +2 -0
- package/README.md +3 -1
- package/bin/scrumrun.js +11 -1
- package/docs/COMMANDS.md +5 -3
- package/lib/commands/manifest.js +8 -8
- package/lib/commands/render.js +1 -0
- package/package.json +1 -1
- package/templates/project/AGENTS.md +1 -0
- package/templates/project-lean/AGENTS.md +2 -0
- package/templates/shared/skills/scrumrun/SKILL.md +5 -3
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.
|
|
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
|
|
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.
|
package/lib/commands/manifest.js
CHANGED
|
@@ -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/lib/commands/render.js
CHANGED
|
@@ -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
|
@@ -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.
|
|
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
|
|
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
|
-
|
|
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
|
|