scrumrun 3.1.1 → 4.0.0

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,32 @@ All notable changes follow Semantic Versioning.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 4.0.0 - 2026-08-31
8
+
9
+ ### Changed
10
+
11
+ - **Simple Markdown model.** Core, Guardrails, Knowledge, Feature, Sprint, Task, Run, and Backlog are one local Markdown graph connected by stable IDs and relative links. Derived cache/index data is optional and never required for normal work.
12
+ - **Execution-first.** An approved Task continues through discover → implement → verify → fix → verify. Intermediate inventories, progress reports, and discovered in-scope gaps are internal work, never a valid stopping point or Follow-up.
13
+ - **Flexible Task bodies.** Tasks preserve arbitrary owner frontmatter and sections. `## Done when` and `## Completion` are the packaged minimal convention; project Guardrails may require extra sections only for affected Tasks.
14
+ - **Human status vocabulary.** `in_progress` is accepted as a Task status. A Markdown-first Task neither needs a Run nor must agree with historical Run state.
15
+ - **Runs are optional.** A Run may record a Task or a Sprint execution, but no Run, ledger, permit, or CLI state transition can block daily delivery.
16
+
17
+ ### Safety
18
+
19
+ - **Sealed Markdown policy.** Fresh and refreshed projects pin Core and Guardrail fingerprints. Agents do not edit policy during product work; owner-reviewed policy changes use `scrumrun update --project --seal-policy`. Strict doctor/release audits detect policy drift at the edge, not during every edit.
20
+
21
+ ## 3.1.2 - 2026-08-31
22
+
23
+ ### Fixed
24
+
25
+ - **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.
26
+
7
27
  ## 3.1.1 - 2026-08-31
8
28
 
9
29
  ### Fixed
10
30
 
11
31
  - **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.
32
+ - **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
33
 
13
34
  ## 3.1.0 - 2026-08-31
14
35
 
package/CORE.md CHANGED
@@ -84,13 +84,21 @@ 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
- **Markdown is the normal runtime.** After explicit approval, work directly in source files and relevant `.scrumrun/` Markdown. A Task is free to be created, refined, started, completed, and handed off in Markdown; a Run is optional audit context, never a state machine that can prevent daily work. Update the Task's scope, Acceptance Criteria, Technical Summary, and Follow-ups directly. Do not use `npx scrumrun@latest` or normal `scrumrun plan/run` commands during execution.
87
+ **Markdown is the normal runtime.** After explicit approval, work directly in source files and relevant `.scrumrun/` Markdown. A Task is free to be created, refined, started, completed, and handed off in Markdown; a Run is optional audit context, never a state machine that can prevent daily work. Update the Task's scope, Done when, Completion, and Follow-ups directly. Do not use `npx scrumrun@latest` or normal `scrumrun plan/run` commands during execution.
88
+
89
+ **Execution is continuous.** Once the owner approves a Task, implement it through its delivery contract before replying. Keep using tools and editing files through the full loop: discover → implement → verify → fix → verify. A progress report is allowed only when the owner asks for status, and it must be followed immediately by more execution in the same workflow; it is never an endpoint. Do not stop to give an inventory, a progress report, a decomposition, or a remaining-work list: those are internal steps, not a deliverable. A discovery of missing code, literals, tests, migrations, or configuration inside the approved contract is required work to implement now — it cannot become a report, a partial checker, a “next step”, or a Follow-up. Stop only for an owner decision, external access, an explicit Guardrail, a secret/security risk, destructive work without approval, or an unmet required delivery criterion. A Task's `## Done when` is short and observable; `## Follow-ups` contains only work outside that contract. Never move unfinished contract work to Follow-ups without explicit owner approval.
90
+
91
+ **Verification must cover the claim.** Never claim that a Task condition is verified merely because a narrower check passes. If the request is “no visible hardcoded literals”, a locale-key parity checker alone is insufficient: scan the relevant views for literals, replace every result in scope, then re-run both the scan and the build. The same rule applies to every delivery claim.
88
92
 
89
93
  **The CLI is maintenance, not a work gate.** Use it for `init`, `update --project`, `migrate`, `repair`, `doctor`, reports, and release checks. Strict per-edit permits and ledger finalization remain available only when the owner asks for that audit level. Missing/invalid Runs, old status vocabulary, stale projections, and optional tests are warnings to reconcile in Markdown — never an automatic blocker.
90
94
 
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.
95
+ **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 Done when item. 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.
96
+
97
+ **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 Completion and Follow-ups.
98
+
99
+ **Policy is sealed at the edge.** `core.md` is the universal execution contract and `guardrails.md` is project policy. Never edit either while delivering product work. A policy change requires an explicit owner request; after review, `scrumrun update --project --seal-policy` records fresh fingerprints. Daily work stays Markdown-only; `doctor --strict` and release audit policy fingerprints, canonical guardrails, and code checks at the boundary.
92
100
 
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.
101
+ **Markdown relations are the graph.** Every artifact has a stable ID. Use small frontmatter links such as `sprint: SPRINT-012`, `feature: FEAT-003`, and `depends_on: [TASK-151, DEC-008]`, plus a human-readable `## Related` section with relative links. Preserve all unknown frontmatter and all owner-defined sections. A Guardrail may require a Task section such as `## Migration Plan`, `## Rollback`, or `## Guardrail Evidence`; add it only to the affected Task and keep it until the rule is satisfied.
94
102
 
95
103
  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.
96
104
 
@@ -176,7 +184,7 @@ understand → approve → work → validate required criteria → hand off
176
184
 
177
185
  Rules:
178
186
 
179
- - a Task carries the intended scope, `## Acceptance Criteria`, `## Technical Summary`, and relevant `## Follow-ups`;
187
+ - a Task carries intended scope, a short `## Done when` contract, `## Completion`, and relevant `## Follow-ups`;
180
188
  - validation matches risk and acceptance criteria; tests, reviews, and environments are gates only when explicitly required by the owner, the Task, or an active Guardrail;
181
189
  - direct Markdown workflow never blocks on Run linkage, status syntax, stale generated views, or missing optional coverage. If an optional check matters, record it as a follow-up/risk instead of fabricating failure;
182
190
  - configured reviews run only when a Guardrail requires one;
@@ -184,7 +192,7 @@ Rules:
184
192
  - strict permits, workspace-drift checks, and append-only Guardrail obligations apply only to that optional strict audit path;
185
193
  - learning proposes memory candidates when work reveals reusable context and never auto-confirms AI inference;
186
194
  - complete a Sprint only when its included Tasks meet its real exit gate;
187
- - do not mark work complete merely because time or token budget ended.
195
+ - do not mark work complete merely because time or token budget ended, and do not stop an approved Task merely to report intermediate progress.
188
196
 
189
197
  Canonical mutations are schema-validated, lossless, and atomic. Preserve unknown fields, prose, and unrelated owner edits. A failed mutation must leave canonical state unchanged or recoverable.
190
198
 
package/README.md CHANGED
@@ -4,30 +4,33 @@
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:** `4.0.0` · **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
 
11
11
  ## The model
12
12
 
13
13
  ```text
14
- Feature = why the initiative matters
15
- Task = what atomic work must be done
16
- Sprint = when Tasks are grouped as a timebox/batch
17
- Run = how one concrete attempt happened
18
- Memory = what the project learned and why
14
+ Core = how the agent works
15
+ Guardrails = rules that cannot be broken
16
+ Knowledge = what the project knows and why
17
+ Backlog = provisioned Tasks not yet started
18
+ Feature = why a larger initiative exists
19
+ Sprint = a feature, fix, or maintenance delivery grouping Tasks
20
+ Task = concrete work, independent or in a Sprint
21
+ Run = optional record of what happened while executing a Task/Sprint
19
22
  ```
20
23
 
21
24
  ```text
22
- FEAT-003
25
+ SPRINT-012 (type: fix)
23
26
  └── TASK-018
24
- ├── executed_byRUN-044
25
- ├── included_inSPRINT-012
26
- ├── constrained_byDEC-018
27
- └── generatedINS-041
27
+ ├── featureFEAT-003
28
+ ├── depends_onTASK-014, DEC-018
29
+ ├── guardrailsGR-004
30
+ └── runRUN-044 (optional)
28
31
  ```
29
32
 
30
- A Task does not need a Sprint. A retry creates a new Run. A fix is a Task with `type: fix`; backlog is a view of backlog Tasks.
33
+ A Task does not need a Sprint. A Sprint may be `feature`, `fix`, or `maintenance`. A Run is optional and may document a Task or Sprint. Backlog is simply Tasks with `status: backlog`.
31
34
 
32
35
  See [`docs/SCHEMA.md`](docs/SCHEMA.md) for the generated executable contract and [`docs/ENTITY-MODEL.md`](docs/ENTITY-MODEL.md) for the conceptual guide.
33
36
 
@@ -79,15 +82,15 @@ RECEIVED → CONTEXTUALIZING → POLICY → RISK → CLASSIFICATION
79
82
 
80
83
  The agent may assert the classification (`--type fix|task|feature|docs|discovery`) and attach a short technical preview (`--preview "…"`), rendered with color in the terminal before any Task exists. Nothing canonical is persisted before approval.
81
84
 
82
- Explicit approval authorizes work. In 3.1, the daily runtime is the `.scrumrun/` folder: the agent creates or refines the relevant Task Markdown, works in code, and leaves a short handoff. Feature, Sprint, and Run are optional context, not prerequisites. A structured CLI audit path remains available when a team wants it.
85
+ Explicit approval authorizes work. In 4.0, the daily runtime is the `.scrumrun/` folder: the agent creates or refines the relevant Task Markdown, works in code, and leaves a short handoff. Feature, Sprint, and Run are optional context, not prerequisites. A structured CLI audit path remains available only at maintenance/release edges.
83
86
 
84
87
  ```text
85
88
  EXECUTING → VALIDATING → LEARNING → COMPLETED | FAILED | BLOCKED
86
89
  ```
87
90
 
88
- Every Task carries `## Acceptance Criteria` so "done" is defined before work begins. After approval, the agent works directly in code and Task Markdown, updating `## Technical Summary` and `## Follow-ups`. The normal close is simply the documented Task handoff no CLI transition is required.
91
+ Every Task carries a short `## Done when` delivery contract. After approval, the agent works directly in code and Task Markdown until that contract is delivered: it keeps the full discover → implement → verify → fix → verify loop running. A report is allowed only when you ask for it and never ends execution. The normal close is a concise `## Completion`; `## Follow-ups` may only contain work outside the agreed contract. No CLI transition is required.
89
92
 
90
- Guardrails still apply. An agent stops only for an explicit active Guardrail, a secret/security risk, destructive work without approval, or an unmet required Acceptance Criterion. Tests, reviews, and environments are gates only when the owner, Acceptance Criteria, or a Guardrail explicitly requires them. Optional missing E2E coverage is a follow-up/risk, not a failed Task.
93
+ Guardrails still apply. An agent stops only for an explicit active Guardrail, a secret/security risk, destructive work without approval, or an unmet required delivery criterion. Tests, reviews, and environments are gates only when the owner, `Done when`, or a Guardrail explicitly requires them. Optional missing E2E coverage is a follow-up/risk, not a failed Task.
91
94
 
92
95
  Use the CLI at the edges, where its safety is valuable:
93
96
 
@@ -99,8 +102,14 @@ scrumrun repair --recover-orphan-tasks --apply
99
102
  scrumrun review release --run
100
103
  ```
101
104
 
105
+ `core.md` and `guardrails.md` are sealed Markdown policy. Agents never edit them during normal product work. An owner-requested policy change is reviewed and then sealed explicitly with `scrumrun update --project --seal-policy`; `doctor --strict` and release checks detect later policy drift.
106
+
107
+ Relations are plain, offline Markdown: stable IDs in frontmatter (`sprint: SPRINT-012`, `depends_on: [TASK-014, DEC-018]`) and relative links in `## Related`. Task Markdown is intentionally extensible: a Guardrail can require `## Migration Plan`, `## Rollback`, or `## Guardrail Evidence` only where relevant, and ScrumRun preserves every unknown section.
108
+
102
109
  `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
110
 
111
+ 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.
112
+
104
113
  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
114
 
106
115
  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.
@@ -159,12 +168,18 @@ It is progressive disclosure: the briefing is enough for most work; the agent fo
159
168
 
160
169
  ## Migrating an ongoing v1 project
161
170
 
162
- Update the client integrations. For an existing project, refresh the Markdown-first guidance explicitly:
171
+ Update the client integrations. For an existing project, refresh the execution-first guidance explicitly:
163
172
 
164
173
  ```bash
165
174
  scrumrun update --project
166
175
  ```
167
176
 
177
+ If you intentionally changed project Guardrails after owner review, seal the reviewed Markdown policy once:
178
+
179
+ ```bash
180
+ scrumrun update --project --seal-policy
181
+ ```
182
+
168
183
  This shows the source inventory, proposed mappings, and blockers without changing project data. Apply only the verified plan with:
169
184
 
170
185
  ```bash
package/SPEC.md CHANGED
@@ -83,6 +83,8 @@ method: 2.0.0
83
83
 
84
84
  IDs, filenames, kind, status, real ISO dates, and method version must agree. Unknown fields and authored prose are preserved. Duplicate fields, malformed frontmatter, unsafe paths, and symlinked canonical paths are invalid.
85
85
 
86
+ Relationship lists are valid local frontmatter, for example `depends_on: [TASK-014, DEC-018]` and `guardrails: [GR-004]`. Human-readable `## Related` links use relative Markdown paths. These local IDs and links are the canonical graph; generated indexes only accelerate retrieval.
87
+
86
88
  A Task may carry an optional `assignee` scalar recording the agent identity (`SCRUMRUN_AGENT` or `config.md` `Agent Identity`) that owns the work. It is descriptive metadata, never a competing authority: it does not change status transitions or block conformance.
87
89
 
88
90
  ### 3.2 Stable identifiers
@@ -200,13 +202,15 @@ RECEIVED
200
202
 
201
203
  Everything through `AWAITING_APPROVAL` is read-only. It may exist in process memory or ignored cache only. A valid approval token binds the normalized request, policy result, classification, risk, issuance time, canonical context fingerprint, and complete workspace fingerprint. Canonical or source drift after planning invalidates approval.
202
204
 
203
- Approval authorizes work after the read-only planning pass. In Markdown-first mode, a Task and optional Run may be created or updated directly; their absence or imperfect administrative metadata never prevents approved work. The CLI's atomic Task/Run creation remains an optional strict/audit path. Tests, reviews, and environments are completion gates only when explicitly required by the owner, the Task's Acceptance Criteria, or an active Guardrail; missing optional coverage is a documented follow-up/risk, not a failure by itself.
205
+ Approval authorizes work after the read-only planning pass. In Markdown-first mode, a Task and optional Run may be created or updated directly; their absence or imperfect administrative metadata never prevents approved work. The CLI's atomic Task/Run creation remains an optional strict/audit path. Tests, reviews, and environments are completion gates only when explicitly required by the owner, the Task's `## Done when` contract, or an active Guardrail; missing optional coverage is a documented follow-up/risk, not a failure by itself.
206
+
207
+ An approved Task executes continuously to its delivery contract. An agent must not end a work turn merely to provide inventory, decomposition, progress, or a list of remaining implementation work. Those are internal execution steps. It may stop only for an owner decision, external access, an active Guardrail, secret/security risk, destructive work without approval, or an unmet required contract item. `## Follow-ups` may contain only work outside `## Done when`; moving required work there requires explicit owner approval.
204
208
 
205
209
  When a structured Run is explicitly chosen, it binds the exact Guardrail-policy fingerprint and workspace baseline. Strict audit then verifies the complete delta: policy freshness, read-only boundaries, symlink safety, scannability, newly introduced secret-like content, and evidence for every Guardrail. Strict teams may opt into short-lived, path-scoped permits and per-edit recording. This audit path is never a prerequisite for ordinary Markdown-first execution.
206
210
 
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.
211
+ 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 normally declares a concise `## Done when` contract before execution, but owner-defined Markdown sections remain valid; completion is measured against the agreed delivery contract, never against elapsed time or token budget.
208
212
 
209
- When a structured Run is used, CLI transitions synchronously update the linked Task and append one event to its ledger. This is an optional audit path, not daily operational authority. Markdown-first completion records the Acceptance Criteria, Technical Summary, validation evidence, and Follow-ups directly on the Task. Multi-file CLI mutations use a durable local transaction journal; `doctor --recover` and `repair` remain explicit maintenance operations. Entering learning may extract candidates, but no administrative artifact failure blocks approved work.
213
+ When a structured Run is used, CLI transitions synchronously update the linked Task and append one event to its ledger. This is an optional audit path, not daily operational authority. Markdown-first completion records the Done when contract, Completion, validation evidence, and Follow-ups directly on the Task. Multi-file CLI mutations use a durable local transaction journal; `doctor --recover` and `repair` remain explicit maintenance operations. Entering learning may extract candidates, but no administrative artifact failure blocks approved work.
210
214
 
211
215
  Backlog is a queue view of intentionally parked Tasks, ordered oldest-first by id. CLI `--next`/`--start` helpers may create a structured Run when wanted, but an explicit owner approval is the only daily-work start gate.
212
216
 
package/bin/scrumrun.js CHANGED
@@ -39,6 +39,7 @@ const { indexPath, indexStatus, mapStatus, queryIndex, rebuildIndex, writeMap }
39
39
  const { auditProject } = require(path.join(root, "lib", "v2", "conformance"));
40
40
  const { recoverPendingTransactions, previewPendingRecovery } = require(path.join(root, "lib", "v2", "transaction"));
41
41
  const { containsSecret } = require(path.join(root, "lib", "security", "secrets"));
42
+ const { sealPolicyIntegrity } = require(path.join(root, "lib", "runtime", "policy-integrity"));
42
43
 
43
44
  const COMMANDS = ["sc"];
44
45
  const COMPATIBILITY_COMMANDS = Object.keys(COMMAND_ALIASES);
@@ -58,7 +59,7 @@ Usage:
58
59
  scrumrun <noun> <subject> <action> [args]
59
60
  scrumrun sc <noun> <subject> <action> [args] # compatibility alias
60
61
  scrumrun install [all|codex|opencode|claude] [--force]
61
- scrumrun update [all|codex|opencode|claude] [--project] [--migrate] [--verbose]
62
+ scrumrun update [all|codex|opencode|claude] [--project] [--seal-policy] [--migrate] [--verbose]
62
63
  scrumrun init [--local|--shared] [--lean] [--no-agent-hint] [--force]
63
64
  scrumrun status
64
65
  scrumrun core [--path|--prompt]
@@ -380,10 +381,13 @@ function refreshProjectGuidance(cwd = process.cwd()) {
380
381
  } else {
381
382
  results.push({ status: "skipped", dest: `${agentsFile} (not recognized as ScrumRun-generated)` });
382
383
  }
384
+ const marker = path.join(cwd, ".scrumrun", "method.json");
385
+ const sealed = writeFile(marker, sealPolicyIntegrity(path.join(cwd, ".scrumrun")), { backup: true });
386
+ results.push({ status: sealed.changed ? "updated" : "skipped", dest: marker, backup: sealed.backup });
383
387
  return results;
384
388
  }
385
389
 
386
- function updateInstallation(target, { migrate = false, project = false, verbose = false } = {}) {
390
+ function updateInstallation(target, { migrate = false, project = false, sealPolicy = false, verbose = false } = {}) {
387
391
  installVerbose = verbose;
388
392
  installSummary.cleaned = 0;
389
393
  installSummary.written = 0;
@@ -391,7 +395,14 @@ function updateInstallation(target, { migrate = false, project = false, verbose
391
395
  installSummary.targets.length = 0;
392
396
  const migration = migrate ? migrationPreflightOnUpdate({ apply: true }) : { status: "skipped" };
393
397
  install(target, true, { compatibility: true });
398
+ if (sealPolicy && !project) throw new Error("`--seal-policy` requires `--project` so the owner-reviewed project policy is explicit.");
394
399
  const projectResults = project ? refreshProjectGuidance() : [];
400
+ if (sealPolicy && project) {
401
+ const scrumDir = path.join(process.cwd(), ".scrumrun");
402
+ const marker = path.join(scrumDir, "method.json");
403
+ const sealed = writeFile(marker, sealPolicyIntegrity(scrumDir, { includeGuardrails: true }), { backup: true });
404
+ projectResults.push({ status: sealed.changed ? "updated" : "skipped", dest: marker, backup: sealed.backup });
405
+ }
395
406
  if (migrate && v2Project()) {
396
407
  try {
397
408
  refreshState(path.join(process.cwd(), ".scrumrun"));
@@ -1308,6 +1319,7 @@ function runTransitionOptions(args) {
1308
1319
  let summary = null;
1309
1320
  for (let index = 2; index < args.length; index++) {
1310
1321
  const token = args[index];
1322
+ if (token === "--strict") continue;
1311
1323
  const value = args[index + 1] && !args[index + 1].startsWith("--") ? args[index + 1] : null;
1312
1324
  if (token === "--note" || token === "--actor" || token === "--at" || token === "--evidence" || token === "--summary" || evidenceFlags.has(token)) {
1313
1325
  if (!value) throw new Error(`${token} requires a value.`);
@@ -1333,6 +1345,11 @@ function runTransitionOptions(args) {
1333
1345
  return { note: note || noteParts.join(" ").trim() || null, evidence, actor, occurredAt, summary };
1334
1346
  }
1335
1347
 
1348
+ function requireStrictAudit(args, action) {
1349
+ if (args.includes("--strict")) return;
1350
+ throw new Error(`${action} is disabled in Markdown-first daily work. Update the Task Markdown directly; use --strict only for an owner-requested audit.`);
1351
+ }
1352
+
1336
1353
  function removeOptionPairs(args, names) {
1337
1354
  const hidden = new Set(names);
1338
1355
  const next = [];
@@ -1470,6 +1487,7 @@ function executeRootRoute(route) {
1470
1487
  return;
1471
1488
  }
1472
1489
  if (noun === "plan" && subject === "task" && routeArgs[0] === "--retry") {
1490
+ requireStrictAudit(routeArgs, "Task retry");
1473
1491
  const result = retryTask(process.cwd(), routeArgs[1], { reassign: routeArgs.includes("--reassign") });
1474
1492
  console.log(`Created retry ${result.run.id} for ${result.task.id} (attempt ${result.run.attempt}).`);
1475
1493
  return;
@@ -1486,6 +1504,7 @@ function executeRootRoute(route) {
1486
1504
  return;
1487
1505
  }
1488
1506
  if (noun === "plan" && subject === "task" && routeArgs[0] === "--start") {
1507
+ requireStrictAudit(routeArgs, "Task start");
1489
1508
  let target = routeArgs[1];
1490
1509
  if (!target) {
1491
1510
  const repository = new ArtifactRepository(projectFile());
@@ -1610,9 +1629,10 @@ function executeRootRoute(route) {
1610
1629
  }
1611
1630
  if (noun === "plan" && subject === "run") {
1612
1631
  if (routeArgs[0] === "--finalize") {
1632
+ requireStrictAudit(routeArgs, "Run finalization");
1613
1633
  const runId = routeArgs[1];
1614
1634
  if (!runId) throw new Error("--finalize requires RUN-NNN.");
1615
- const result = finalizeRun(process.cwd(), runId, runTransitionOptions(routeArgs.slice(2)));
1635
+ const result = finalizeRun(process.cwd(), runId, runTransitionOptions(routeArgs));
1616
1636
  console.log(`${result.run.id}: completed; ${result.task.id}: completed. Final session audit verified ${result.changes} change(s).`);
1617
1637
  if (result.resolved.length) console.log(`Guardrails verified: ${result.resolved.join(", ")}.`);
1618
1638
  if (result.learning && result.learning.created.length) console.log(`Learning candidates: ${result.learning.created.join(", ")}.`);
@@ -1654,6 +1674,7 @@ function executeRootRoute(route) {
1654
1674
  "--block": "blocked"
1655
1675
  };
1656
1676
  if (transitions[routeArgs[0]]) {
1677
+ requireStrictAudit(routeArgs, `Run transition ${routeArgs[0]}`);
1657
1678
  const result = transitionRun(process.cwd(), routeArgs[1], transitions[routeArgs[0]], runTransitionOptions(routeArgs));
1658
1679
  console.log(`${result.run.id}: ${result.run.status}; ${result.task.id}: ${result.task.status}.`);
1659
1680
  if (result.learning) {
@@ -1696,7 +1717,12 @@ function executeRootRoute(route) {
1696
1717
  }
1697
1718
  if (noun === "config" && subject === "update") {
1698
1719
  const target = ["all", "codex", "opencode", "claude"].includes(routeArgs[0]) ? routeArgs[0] : "all";
1699
- return updateInstallation(target, { migrate: !routeArgs.includes("--no-migrate"), verbose: routeArgs.includes("--verbose") });
1720
+ return updateInstallation(target, {
1721
+ migrate: routeArgs.includes("--migrate"),
1722
+ project: routeArgs.includes("--project"),
1723
+ sealPolicy: routeArgs.includes("--seal-policy"),
1724
+ verbose: routeArgs.includes("--verbose")
1725
+ });
1700
1726
  }
1701
1727
  if (noun === "config" && subject === "init") {
1702
1728
  const localMode = routeArgs.includes("--local");
@@ -2312,6 +2338,8 @@ function promptCommand(parts) {
2312
2338
 
2313
2339
  function initProject({ force, mode, agentHint, lean }) {
2314
2340
  const cwd = process.cwd();
2341
+ const marker = path.join(cwd, ".scrumrun", "method.json");
2342
+ const markerExisted = fs.existsSync(marker);
2315
2343
  const vars = {
2316
2344
  PROJECT_NAME: path.basename(cwd),
2317
2345
  DATE: new Date().toISOString().slice(0, 10)
@@ -2322,6 +2350,10 @@ function initProject({ force, mode, agentHint, lean }) {
2322
2350
 
2323
2351
  results.push(...copyDir(path.join(projectTemplate, ".scrumrun"), path.join(cwd, ".scrumrun"), { force, vars }));
2324
2352
  results.push(copyFile(path.join(root, "CORE.md"), path.join(cwd, ".scrumrun", "core.md"), { force, vars }));
2353
+ if (force || !markerExisted) {
2354
+ const sealed = writeFile(marker, sealPolicyIntegrity(path.join(cwd, ".scrumrun"), { includeGuardrails: true }), { backup: false });
2355
+ results.push({ status: sealed.changed ? "written" : "skipped", dest: marker, backup: sealed.backup });
2356
+ }
2325
2357
  results.push(ensureProjectIgnore(cwd));
2326
2358
 
2327
2359
  if (mode === "shared" || agentHint) {
@@ -2601,8 +2633,9 @@ function doctor(target = "all", { compatibility = false, strict = false, recover
2601
2633
  console.log(`miss ScrumRun project audit: ${scrumDir}`);
2602
2634
  } else {
2603
2635
  const audit = auditProject(process.cwd());
2604
- ok = ok && audit.passed && audit.findings.length === 0;
2605
- console.log(`${audit.passed && audit.findings.length === 0 ? "ok " : "fail"} ScrumRun project audit: ${audit.findings.length} finding(s)`);
2636
+ const blocking = audit.findings.filter((item) => ["critical", "high"].includes(item.severity));
2637
+ ok = ok && audit.passed && blocking.length === 0;
2638
+ console.log(`${audit.passed && blocking.length === 0 ? "ok " : "fail"} ScrumRun project audit: ${audit.findings.length} finding(s)`);
2606
2639
  for (const item of audit.findings) console.log(` ${item.severity} ${item.code}: ${item.message}`);
2607
2640
  }
2608
2641
  }
@@ -2623,7 +2656,7 @@ if (!command || command === "--help" || command === "-h") {
2623
2656
  console.log(`ScrumRun ${version}`);
2624
2657
  } else if (command === "install" || command === "update") {
2625
2658
  const target = ["all", "codex", "opencode", "claude"].includes(args[1]) ? args[1] : "all";
2626
- if (command === "update") updateInstallation(target, { migrate: args.includes("--migrate"), project: args.includes("--project"), verbose: args.includes("--verbose") });
2659
+ if (command === "update") updateInstallation(target, { migrate: args.includes("--migrate"), project: args.includes("--project"), sealPolicy: args.includes("--seal-policy"), verbose: args.includes("--verbose") });
2627
2660
  else install(target, true, { compatibility: false });
2628
2661
  } else if (command === "sc") {
2629
2662
  runRoot(args.slice(1));
package/docs/COMMANDS.md CHANGED
@@ -1,4 +1,4 @@
1
- # ScrumRun 3.1 Command Reference
1
+ # ScrumRun 4.0 Command Reference
2
2
 
3
3
  The canonical grammar is:
4
4
 
@@ -13,25 +13,27 @@ 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]
27
27
  scrumrun plan challenge <question>
28
28
  ```
29
29
 
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.
30
+ Normal execution is Markdown-first: after approval, work in code and the relevant Task Markdown through discover → implement → verify → fix → verify, then record `## Completion` and any genuinely out-of-scope 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
+
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.
31
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
- 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.
36
+ Every new Task starts with `## Done when` and `## Validation Scope`: only checks explicitly required by the owner, Done when contract, or an active Guardrail block completion. A discovered in-scope gap remains work to implement, not a status report or Follow-up. Missing optional E2E, integration, or review coverage belongs in a follow-up/risk note; it must not be used to mark the Run failed.
35
37
 
36
38
  ## What can be changed
37
39
 
@@ -80,14 +82,14 @@ scrumrun review release --run
80
82
  ```text
81
83
  scrumrun config project --show|--language|--interaction|--approval|--quick-tasks
82
84
  scrumrun config init --local|--shared|--lean|--no-agent-hint|--force
83
- scrumrun config update [all|codex|opencode|claude] [--project] [--migrate]
85
+ scrumrun config update [all|codex|opencode|claude] [--project] [--seal-policy] [--migrate]
84
86
  scrumrun config migrate --to 2 --dry-run|--apply|--rollback
85
87
  scrumrun config doctor [all|codex|opencode|claude] [--strict] [--recover]
86
88
  scrumrun config uninstall --force
87
89
  scrumrun config help <topic>
88
90
  ```
89
91
 
90
- Top-level CLI aliases (`init`, `update`, `migrate`, `doctor`, `uninstall`, `status`) remain available for shell automation. `update --project` refreshes the packaged Markdown-first Core and recognized generated agent instructions with local backup; ordinary update does not inspect migrations, while `--migrate` explicitly does so and applies the verified plan.
92
+ Top-level CLI aliases (`init`, `update`, `migrate`, `doctor`, `uninstall`, `status`) remain available for shell automation. `update --project` refreshes the packaged execution-first Core and recognized generated agent instructions with local backup. `update --project --seal-policy` is the owner-reviewed maintenance action that pins fresh Core/Guardrail fingerprints. Ordinary update does not inspect migrations, while `--migrate` explicitly does so and applies the verified plan.
91
93
 
92
94
  Run transitions accept typed evidence through `--command`, `--test`, `--file`, `--review`, `--decision`, `--insight`, `--risk`, or generic `--evidence kind:value`. `doctor --recover` is an explicit write that resolves only safe pending kernel transactions; doctor without it remains read-only.
93
95
 
@@ -1,4 +1,4 @@
1
- # ScrumRun 2.0 Entity Model
1
+ # ScrumRun 4.0 Markdown Model
2
2
 
3
3
  This document explains the model. Exact ids, directories, initial states, transitions, structural cardinalities, truth ownership, and authority boundaries are generated from `lib/v2/schema.js` into [`SCHEMA.md`](SCHEMA.md). Do not maintain another hand-written schema table here.
4
4
 
@@ -6,32 +6,35 @@ This document explains the model. Exact ids, directories, initial states, transi
6
6
 
7
7
  | Entity | Question | Lifetime |
8
8
  |---|---|---|
9
+ | Core | How must the agent work? | Stable, sealed policy |
10
+ | Guardrails | What may never be broken here? | Stable, sealed project policy |
11
+ | Knowledge | What do we know, and why? | Reviewed until stale/deprecated/invalidated |
12
+ | Backlog | What is provisioned but not started? | Tasks with `status: backlog` |
9
13
  | Feature | Why does this initiative matter? | Long-lived |
10
- | Task | What atomic outcome is approved? | Until outcome/closure |
11
- | Sprint | When are related Tasks grouped? | Timebox/batch |
12
- | Run | How did one execution attempt happen? | Immutable attempt history |
13
- | Memory | What do we know, and why? | Reviewed until stale/deprecated/invalidated |
14
+ | Sprint | Which Tasks ship together? | Feature, fix, or maintenance batch |
15
+ | Task | What concrete outcome must be delivered? | Until outcome/closure |
16
+ | Run | What happened while executing a Task or Sprint? | Optional audit/handoff record |
14
17
 
15
18
  ```text
16
- FEAT-003
19
+ SPRINT-012 (type: fix)
17
20
  └── TASK-018
18
- ├── executed_byRUN-044
19
- ├── included_inSPRINT-012
20
- ├── constrained_byDEC-018
21
- └── generatedINS-041
21
+ ├── featureFEAT-003
22
+ ├── depends_onTASK-014, DEC-018
23
+ ├── guardrailsGR-004
24
+ └── runRUN-044 (optional)
22
25
  ```
23
26
 
24
- Task is always the executable unit. A Task may be independent of a Sprint. Sprint never substitutes for Task. A retry creates another Run for the same Task.
27
+ Task is the executable unit. A Task may be independent of a Sprint. A Sprint groups Tasks and may be `feature`, `fix`, or `maintenance`. Runs are optional and never substitute for a Task's direct Markdown handoff.
25
28
 
26
29
  ## Canonical artifacts
27
30
 
28
- All artifacts carry `id`, `kind`, `status`, `created`, `updated`, and `method`. Relations live in frontmatter for structural ownership and in `## Relations` for extensible graph edges. The generated [`SCHEMA.md`](SCHEMA.md) is the authoritative inventory.
31
+ All artifacts carry `id`, `kind`, `status`, `created`, `updated`, and `method`. Relations use simple frontmatter and relative links: `sprint: SPRINT-012`, `feature: FEAT-003`, `depends_on: [TASK-014, DEC-018]`, and `## Related`. Unknown fields and sections are preserved. The generated [`SCHEMA.md`](SCHEMA.md) is the authoritative inventory.
29
32
 
30
33
  ## Operational flow
31
34
 
32
- Approval creates one Task and one Run. The Run progresses `executing validating learning completed|failed|blocked`, while the Task mirrors `runningvalidatinglearningcompleted|failed|blocked`. Pair mutations are recoverable.
35
+ Approval creates or refines a Task. An optional Run can record strict audit or handoff history, but no Run, ledger, permit, or status synchronization blocks normal Markdown work. An approved Task continues through discover implementverifyfix verify until its `## Done when` contract is delivered.
33
36
 
34
- Feature and Sprint provide context/grouping and do not own execution history. Review attaches evidence. Memory explains decisions and constraints across all of them.
37
+ Feature and Sprint provide context/grouping and do not own execution history. Review attaches evidence. Knowledge, Decisions, and Insights explain constraints across all of them. Core and Guardrails are sealed Markdown policy: only explicit owner-reviewed maintenance may change them.
35
38
 
36
39
  ## Generated projections
37
40
 
@@ -1,18 +1,19 @@
1
1
  # Quickstart
2
2
 
3
- Get from "never heard of it" to your first approved Run in under 10 minutes.
3
+ Get from "never heard of it" to your first delivered Task in under 10 minutes.
4
4
  No `SPEC.md` reading required.
5
5
 
6
6
  ## The three-minute mental model
7
7
 
8
8
  ScrumRun gives an AI coding agent a small vocabulary and a project memory.
9
9
 
10
- - **Task** — one atomic piece of work.
11
- - **Sprint** — a batch of Tasks grouped by time or theme. Optional.
12
- - **Run** — one attempt at executing a Task. Retries create new Runs; the
13
- previous one is never overwritten.
14
- - **Feature** — a bigger initiative that groups Tasks and its own decisions.
15
- - **Memory** — what the project learned: facts, decisions, insights, dossiers.
10
+ - **Core** — how the agent works; read first and never edited during product work.
11
+ - **Guardrails** — rules that cannot be broken.
12
+ - **Knowledge** — facts, decisions, insights, and dossiers about the project.
13
+ - **Task** — one concrete delivery, independent or inside a Sprint.
14
+ - **Sprint** — a feature, fix, or maintenance batch of Tasks. Optional.
15
+ - **Feature** — a bigger initiative that groups delivery context.
16
+ - **Run** — optional audit/handoff Markdown for a Task or Sprint.
16
17
 
17
18
  Everything lives as Markdown under `.scrumrun/`. Any Markdown-capable agent
18
19
  can follow it.
@@ -64,24 +65,25 @@ command (`| less`, `> intake.txt`) or set `NO_COLOR=1` to get the plain
64
65
  Markdown summary instead; add `--json` for a fully structured payload
65
66
  you can feed to CI or a downstream tool.
66
67
 
67
- Only then does a Task and a Run get created.
68
+ Only then does the Task become approved. The agent executes it directly in code and Markdown; a Run is optional.
68
69
 
69
- ## Watching the Run
70
+ ## Delivering the Task
70
71
 
71
- The agent executes inside the approved scope. Every step lands in an
72
- append-only ledger under `.scrumrun/runs/RUN-NNN.md` with a stable event
73
- id, timestamp, actor, reason, and typed evidence.
72
+ The agent executes inside the approved scope until `## Done when` is true.
73
+ It does not stop after an inventory, partial fix, or progress report. Any
74
+ missing implementation discovered in scope is work to do now, not a follow-up.
74
75
 
75
76
  ```
76
- RUN-001-EVT-001 planned by owner reason: "checkout double-charge fix"
77
- RUN-001-EVT-002 executed command: npm test → 132 passed
78
- RUN-001-EVT-003 validated (REV-001) guardrail checks: passed
79
- RUN-001-EVT-004 learned (INS-001) "refresh triggers duplicate submit"
80
- RUN-001-EVT-005 completed
77
+ TASK-001
78
+ inspect the duplicate-submit path
79
+ implement the fix
80
+ run the relevant checks
81
+ → correct failures
82
+ → write ## Completion and status: completed
81
83
  ```
82
84
 
83
- A retry does not overwrite `RUN-001`. It creates `RUN-002` beside it. The
84
- old attempt stays as evidence.
85
+ A Run may be added when a strict audit or detailed handoff is useful. It never
86
+ needs to exist for normal work to start or finish.
85
87
 
86
88
  You can render a Run's ledger as a human timeline instead of reading the
87
89
  raw JSON: