scrumrun 4.1.1 → 4.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,12 @@ All notable changes follow Semantic Versioning.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 4.1.2 - 2026-09-22
8
+
9
+ ### Fixed
10
+
11
+ - **`doctor --strict` now honors `allow_secrets_in`.** The audit pipeline was calling `containsSecret()` directly, ignoring the allowlist declared in `.scrumrun/config.md` frontmatter. Result: files listed under `allow_secrets_in` still triggered `SECRET_CANONICAL`. The audit now loads the allowlist once per run and calls `containsSecretWithAllowlist(text, relativePath, allowlist)` — a straight wiring bug from 4.0. Common false-positive triggers (`password: null`, `password:string`, `password` inside documentation) are now silenceable by whitelisting the specific file(s).
12
+
7
13
  ## 4.1.1 - 2026-09-22
8
14
 
9
15
  ### Added
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:** `4.1.1` · **Method target:** `2.0.0` · **Runtime:** Node.js `>=22.13.0` · **License:** MIT
7
+ **Package:** `4.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
 
@@ -132,6 +132,7 @@ function auditProject(projectRoot, options = {}) {
132
132
  const counts = {};
133
133
  const ids = new Set();
134
134
  const records = {};
135
+ const secretAllowlist = loadSecretAllowlist(scrumDir);
135
136
  for (const kind of Object.keys(ARTIFACT_TYPES)) {
136
137
  try {
137
138
  const artifacts = repository.list(kind);
@@ -140,7 +141,9 @@ function auditProject(projectRoot, options = {}) {
140
141
  for (const artifact of artifacts) {
141
142
  for (const error of artifact.errors) findings.push(finding("high", "ARTIFACT_INVALID", `${path.basename(artifact.file)}: ${error}`, artifact.file));
142
143
  const relativeArtifact = path.relative(scrumDir, artifact.file);
143
- if (containsSecret(fs.readFileSync(artifact.file, "utf8"))) findings.push(finding("critical", "SECRET_CANONICAL", `Secret-like content detected in ${relativeArtifact}.`, artifact.file));
144
+ if (containsSecretWithAllowlist(fs.readFileSync(artifact.file, "utf8"), relativeArtifact, secretAllowlist)) {
145
+ findings.push(finding("critical", "SECRET_CANONICAL", `Secret-like content detected in ${relativeArtifact}.`, artifact.file));
146
+ }
144
147
  if (artifact.record && ids.has(artifact.record.id)) findings.push(finding("critical", "ID_DUPLICATE", `Duplicate artifact id: ${artifact.record.id}`));
145
148
  if (artifact.record) ids.add(artifact.record.id);
146
149
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrumrun",
3
- "version": "4.1.1",
3
+ "version": "4.1.2",
4
4
  "description": "Markdown-first Agile memory and guardrails for AI coding agents.",
5
5
  "bin": {
6
6
  "scrumrun": "bin/scrumrun.js",