@planu/cli 5.3.11 → 5.3.13

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.
Files changed (26) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/engine/evidence-index/index-builder.js +28 -3
  3. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
  4. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +4 -4
  5. package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
  6. package/dist/engine/planu-core.darwin-x64.node.sbom.json +4 -4
  7. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
  8. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +4 -4
  9. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
  10. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +4 -4
  11. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
  12. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +4 -4
  13. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
  14. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +4 -4
  15. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
  16. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +4 -4
  17. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
  18. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +4 -4
  19. package/dist/engine/spec-quality/generic-output-gate.js +18 -2
  20. package/dist/engine/validation/validation-source-policy.js +1 -0
  21. package/dist/tools/create-spec.js +16 -4
  22. package/dist/tools/update-status/evidence-gate.js +6 -2
  23. package/dist/types/spec-quality.d.ts +3 -0
  24. package/package.json +10 -11
  25. package/planu-native.json +1 -1
  26. package/planu-plugin.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## [5.3.13] - 2026-08-10
2
+
3
+ ### Bug Fixes
4
+ - fix(spec-1468): word-boundary guard on evidence marker truncation
5
+ - fix(lifecycle): evidence-only rebind + planu digest exclusion (SPEC-1468)
6
+ - fix(spec-1469): close path-echo exemption bypass found in implementation review
7
+ - fix(spec-quality): path-token guard in restatement check + actionable gate rejection (SPEC-1469)
8
+
9
+ ### Chores
10
+ - chore(spec-1468): record done transition lifecycle state
11
+ - chore(spec-1469): record done transition lifecycle state
12
+ - chore(planu): capture auto-generated session context
13
+ - chore(specs): move SPEC-1468/1469 to implementing
14
+ - chore(specs): approve SPEC-1468/1469 after round-2 dual review + arbitration
15
+
16
+
17
+ ## [5.3.12] - 2026-08-10
18
+
19
+ ### Bug Fixes
20
+ - fix(release): cap smoke retries at 3 attempts regardless of delay overrides
21
+ - fix(release): retry transient CLI smoke failures with backoff and per-attempt diagnostics
22
+
23
+ ### Chores
24
+ - chore(spec-1462): record done transition and release bookkeeping
25
+
26
+
1
27
  ## [5.3.11] - 2026-08-09
2
28
 
3
29
  ### Bug Fixes
@@ -4,13 +4,38 @@ import { createCriterionIdentity, criterionIdentitiesMatch } from '../criterion-
4
4
  export function criterionKey(criterion) {
5
5
  return createCriterionIdentity(criterion).stableKey;
6
6
  }
7
+ const EVIDENCE_MARKER = /\b(?:FILES|FUNCTIONS|TEST):/;
8
+ function truncateAtEvidenceMarker(value) {
9
+ const markerIndex = value.search(EVIDENCE_MARKER);
10
+ return markerIndex === -1 ? value : value.slice(0, markerIndex);
11
+ }
7
12
  export async function buildSpecEvidenceIndex(args) {
8
13
  const diagnostics = [...args.artifacts.invalidArtifacts];
9
14
  const matrixRows = args.artifacts.traceabilityMatrix?.rows ?? [];
10
15
  const contractValidations = args.artifacts.contractValidations;
11
- const entries = await Promise.all(args.criteria.map(async (criterion, criterionIndex) => {
12
- const identity = createCriterionIdentity(criterion, { index: criterionIndex });
13
- const rows = matrixRows.filter((row, rowIndex) => criterionIdentitiesMatch(createCriterionIdentity(row.acceptanceCriterion, { index: rowIndex }), identity));
16
+ const criterionEntries = args.criteria.map((criterion, index) => ({
17
+ criterion,
18
+ identity: createCriterionIdentity(criterion, { index }),
19
+ truncatedIdentity: createCriterionIdentity(truncateAtEvidenceMarker(criterion), { index }),
20
+ }));
21
+ const rowCriterionIndexes = matrixRows.map((row, rowIndex) => {
22
+ const rowIdentity = createCriterionIdentity(row.acceptanceCriterion, { index: rowIndex });
23
+ const exactMatches = criterionEntries
24
+ .map((entry, criterionIndex) => criterionIdentitiesMatch(rowIdentity, entry.identity) ? criterionIndex : -1)
25
+ .filter((criterionIndex) => criterionIndex !== -1);
26
+ if (exactMatches.length > 0) {
27
+ return exactMatches;
28
+ }
29
+ const truncatedRowIdentity = createCriterionIdentity(truncateAtEvidenceMarker(row.acceptanceCriterion), { index: rowIndex });
30
+ const truncatedMatches = criterionEntries
31
+ .map((entry, criterionIndex) => criterionIdentitiesMatch(truncatedRowIdentity, entry.truncatedIdentity)
32
+ ? criterionIndex
33
+ : -1)
34
+ .filter((criterionIndex) => criterionIndex !== -1);
35
+ return truncatedMatches.length === 1 ? truncatedMatches : [];
36
+ });
37
+ const entries = await Promise.all(criterionEntries.map(async ({ criterion, identity }, criterionIndex) => {
38
+ const rows = matrixRows.filter((_, rowIndex) => (rowCriterionIndexes[rowIndex] ?? []).includes(criterionIndex));
14
39
  const evidence = await collectEvidence({
15
40
  rows,
16
41
  contractValidations,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-aarch64-apple-darwin",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-aarch64-apple-darwin",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -17,15 +17,15 @@
17
17
  "platform": "darwin",
18
18
  "arch": "arm64",
19
19
  "libc": null,
20
- "artifactSha256": "a637894db9f271f49dbe9f9f0fc33d83a9b70ae1c7b2e71cad71d8ad558f4818",
20
+ "artifactSha256": "63b4e21bd8fd8154d97f9f1a471fd7a731c6bc0514dec2ef9a2a5d9f1a98eb32",
21
21
  "sbom": {
22
22
  "format": "CycloneDX-1.5",
23
23
  "path": "planu-core.darwin-arm64.node.sbom.json",
24
- "sha256": "eb61e29335b5a55fb357861bce4f38423d94248c1ee3b7b8dc0181e9118f4b6b"
24
+ "sha256": "b25f5ddbd51db18f2bebb1e86e7cd31f174e3613e187ec00c7ebc66132a66d0c"
25
25
  },
26
26
  "provenance": {
27
27
  "builder": "scripts/build-rust-local.sh",
28
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
28
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
29
29
  "sourceTreeDirty": false,
30
30
  "sourceDateEpoch": 1,
31
31
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -34,6 +34,6 @@
34
34
  "signature": {
35
35
  "algorithm": "Ed25519",
36
36
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
37
- "value": "Pzuaa525uj5kVwR5LlqMFJKZCVmI7DKNw73xo4Zo129Zw3zIx5EapKPlFYaBAUUpa4dkuRa00EWSxNKK7zahDA=="
37
+ "value": "8h2IO454Azg9cLFFiaQj1bEZ8np+FAUG+F7hZqLueM1Cu8k3lWakVBIB4h10CNEYk59TFsi02SfqUBXiUhr1DQ=="
38
38
  }
39
39
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "a637894db9f271f49dbe9f9f0fc33d83a9b70ae1c7b2e71cad71d8ad558f4818"
14
+ "content": "63b4e21bd8fd8154d97f9f1a471fd7a731c6bc0514dec2ef9a2a5d9f1a98eb32"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-x86_64-apple-darwin",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-x86_64-apple-darwin",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -17,15 +17,15 @@
17
17
  "platform": "darwin",
18
18
  "arch": "x64",
19
19
  "libc": null,
20
- "artifactSha256": "6be96ffd429bd0215674a9d7c7ec722d77515ef59c39573c928d7ed862c54ab4",
20
+ "artifactSha256": "6af7f8df49b56c0e440dbb5088a957943d0b1e8bd6d243392d00e224205dab63",
21
21
  "sbom": {
22
22
  "format": "CycloneDX-1.5",
23
23
  "path": "planu-core.darwin-x64.node.sbom.json",
24
- "sha256": "628cc248c3ac7e5b13b000c93d7f630ea0ae1ae768f61da08ec370f3e3440794"
24
+ "sha256": "7fccd089cc1a35511497238f84f697bcee2d0c00534f6fefe3ddfbe770d3d617"
25
25
  },
26
26
  "provenance": {
27
27
  "builder": "scripts/build-rust-local.sh",
28
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
28
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
29
29
  "sourceTreeDirty": false,
30
30
  "sourceDateEpoch": 1,
31
31
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -34,6 +34,6 @@
34
34
  "signature": {
35
35
  "algorithm": "Ed25519",
36
36
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
37
- "value": "mMbL9QMwOpMVPnAff8FC82N1UEyKLDsOczRq2Be65nqQl8gdh/SNh5TRMIpDv6rpoILKptm63YZUcUyowl54Dw=="
37
+ "value": "tnN9tivctc9090o+HeQTDhLowV/Z+Kp4mUQcxpxj7CKiLWrClaGzwlcEABXsF8YJcSLHSrxiUnB+397bAOaQDw=="
38
38
  }
39
39
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "6be96ffd429bd0215674a9d7c7ec722d77515ef59c39573c928d7ed862c54ab4"
14
+ "content": "6af7f8df49b56c0e440dbb5088a957943d0b1e8bd6d243392d00e224205dab63"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-aarch64-unknown-linux-gnu",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-aarch64-unknown-linux-gnu",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -16,15 +16,15 @@
16
16
  "platform": "linux",
17
17
  "arch": "arm64",
18
18
  "libc": "glibc",
19
- "artifactSha256": "32d0b5347c2df4309a5694198808ef98e2c7bb02c4fcc13ad177f9e9883d6785",
19
+ "artifactSha256": "6dc15d18af613ad34ab23bc8d36387596c6d4e56a32130500d87581637afc5c6",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-arm64-gnu.node.sbom.json",
23
- "sha256": "0a247e82910188488212dc4675f194712cf6fc76f3c1f3a671ff45440ede99bb"
23
+ "sha256": "5284d0de91c78b38db90e45d503bdfc1663bdd347d02afa2d4ee077973a558c5"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
27
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
28
28
  "sourceTreeDirty": false,
29
29
  "sourceDateEpoch": 1,
30
30
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -33,6 +33,6 @@
33
33
  "signature": {
34
34
  "algorithm": "Ed25519",
35
35
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
36
- "value": "2cIeBFLwk2akHCgoFLGanCjGjQOzZvZOMTcOadPY4uSmybBItWfHnsG4uE2k7nu07AtMD9j8B8il3K445IpfBw=="
36
+ "value": "QBwJ3Bv0Cu43hS/zvTdSyOE9ua2CpkENsXB8xP6XmxGGXvGiJSQkkK2Un6PQ/7EZKt88wuJd95a6bZKfCSzdDw=="
37
37
  }
38
38
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "32d0b5347c2df4309a5694198808ef98e2c7bb02c4fcc13ad177f9e9883d6785"
14
+ "content": "6dc15d18af613ad34ab23bc8d36387596c6d4e56a32130500d87581637afc5c6"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-aarch64-unknown-linux-musl",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-aarch64-unknown-linux-musl",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -16,15 +16,15 @@
16
16
  "platform": "linux",
17
17
  "arch": "arm64",
18
18
  "libc": "musl",
19
- "artifactSha256": "855c446e904b1349f0b3a7d2e918f45895d2f7bcdc42fd7bcfe96b4231d34d76",
19
+ "artifactSha256": "b47bdce610685474cc5ffbe8efbe504bf22c547d87aca9f6971a5a645e63cdca",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-arm64-musl.node.sbom.json",
23
- "sha256": "e8bbf7b06bb48c63b11654815814360d37f31c325d75c73d3cde284af9b388d2"
23
+ "sha256": "0d6797a7c84e1699db01fbeb55299d9ad870e888cbd6b9a6f694e5bf7146630d"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
27
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
28
28
  "sourceTreeDirty": false,
29
29
  "sourceDateEpoch": 1,
30
30
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -33,6 +33,6 @@
33
33
  "signature": {
34
34
  "algorithm": "Ed25519",
35
35
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
36
- "value": "gO9HbCl6ucziBx+OOWweX6jal0Qj42+AaAd4OTtO+Ttw52kc0qb7GZP2FDYJ6QuRvQxXAPXNnLEiDRV48EI3AQ=="
36
+ "value": "CdnJ0CdQkjvrwcF8st5Tp/4WFb+5WZhBOQAJJOCb2tbb9jiRzC0BNuzg3O6kNlcUYDjltRSTYDo/3mamDJ2CDQ=="
37
37
  }
38
38
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "855c446e904b1349f0b3a7d2e918f45895d2f7bcdc42fd7bcfe96b4231d34d76"
14
+ "content": "b47bdce610685474cc5ffbe8efbe504bf22c547d87aca9f6971a5a645e63cdca"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-x86_64-unknown-linux-gnu",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-x86_64-unknown-linux-gnu",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -16,15 +16,15 @@
16
16
  "platform": "linux",
17
17
  "arch": "x64",
18
18
  "libc": "glibc",
19
- "artifactSha256": "02070a07203d610a026ee812ee150049007d305f3490f4ff76ac7b419f3bd303",
19
+ "artifactSha256": "e23b8e1541a7d2d9887dfe4c2baa0669a6b6f7b40d8f7537174c68ea9eab3ea2",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-x64-gnu.node.sbom.json",
23
- "sha256": "959488b70f6e76440ab77ae9a0d11ac14c7075054784bbeb56c9deffc28fe959"
23
+ "sha256": "d0395e69523bda89502adf30f3f0c5bc9b7a03050cdf959fc918b462ae652406"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
27
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
28
28
  "sourceTreeDirty": false,
29
29
  "sourceDateEpoch": 1,
30
30
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -33,6 +33,6 @@
33
33
  "signature": {
34
34
  "algorithm": "Ed25519",
35
35
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
36
- "value": "f2kOoFQHV3utAi8Dx/yNB55OCOSlrFps74CGtW5i55zhZUyt0fB3qlmPqkddIzV43O69osgSlrHrz61eNdhgBg=="
36
+ "value": "bLbpq7CqGP2XT5gEjs+A9x0HU5ltLdGJxXqCKI9WKa0GOjrNFvJZSi+G/TSMeSE6oQnh2xTFtn4uTH5oYl5QBA=="
37
37
  }
38
38
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "02070a07203d610a026ee812ee150049007d305f3490f4ff76ac7b419f3bd303"
14
+ "content": "e23b8e1541a7d2d9887dfe4c2baa0669a6b6f7b40d8f7537174c68ea9eab3ea2"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-x86_64-unknown-linux-musl",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-x86_64-unknown-linux-musl",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -16,15 +16,15 @@
16
16
  "platform": "linux",
17
17
  "arch": "x64",
18
18
  "libc": "musl",
19
- "artifactSha256": "d5ae1b0820532dd3751cd4daa7f6f149d8050ec6bf50acdeaea855a38773429a",
19
+ "artifactSha256": "ad695974ac459aab230a6d08dab91747078bc5619906be58d0667ea2a6a07521",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-x64-musl.node.sbom.json",
23
- "sha256": "3f1547e8d5222ef6899ef2fc5321620564f58536296ba88e456f10a1f8f5d0e7"
23
+ "sha256": "8c57317b906d44a1076fd15349dad0518d743d902a9ae48e0205ca3af2fd3da8"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
27
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
28
28
  "sourceTreeDirty": false,
29
29
  "sourceDateEpoch": 1,
30
30
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -33,6 +33,6 @@
33
33
  "signature": {
34
34
  "algorithm": "Ed25519",
35
35
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
36
- "value": "ZdsY0oytJlhoRrA4bzsz11fym6C8ePazWDLY67cDCzxNOxRtnRk3PxL89+jIdNp0INzzV0q3YPDpIS4ej8TXDA=="
36
+ "value": "5hurMVndDnUmbfntnmEPNN2WFsbeujSqDm5GyON1f8K5j9CfXF3P5ChNpxwHHHr8Da7SfiIwBmflAeyTU/nHCA=="
37
37
  }
38
38
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "d5ae1b0820532dd3751cd4daa7f6f149d8050ec6bf50acdeaea855a38773429a"
14
+ "content": "ad695974ac459aab230a6d08dab91747078bc5619906be58d0667ea2a6a07521"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-aarch64-pc-windows-msvc",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-aarch64-pc-windows-msvc",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -16,15 +16,15 @@
16
16
  "platform": "win32",
17
17
  "arch": "arm64",
18
18
  "libc": null,
19
- "artifactSha256": "963014df7150b01a848918000c2ebca5b5387c6662cda30cb409b6b5d040ac3d",
19
+ "artifactSha256": "509c952dde3408081c65f343258ca79f553fe72a3e3ae73c8ab1c6775bad6ac1",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.win32-arm64-msvc.node.sbom.json",
23
- "sha256": "d7ef9db6e58944ce6c53d087a57783d8bb1c5a4f6b37d8e82f8015e9cba8baf6"
23
+ "sha256": "eac44b50bc2422b46b61e251dd9e85dc504e8c69229ae40b80794d18471da7b6"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
27
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
28
28
  "sourceTreeDirty": false,
29
29
  "sourceDateEpoch": 1,
30
30
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -33,6 +33,6 @@
33
33
  "signature": {
34
34
  "algorithm": "Ed25519",
35
35
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
36
- "value": "CmFxZ49SNux1uUeH55UOCds+idCDgzI+I1+NXsZM33iLJmNQ8qeYqaaJhhQrhWyqdouUuaWgsz9p8Lv22j8sCA=="
36
+ "value": "fUPD7OvB98bmo61bccKDAY3fzL8aT96h7u07WBPo+FSm3jyyM+NSKLX6Jeyoz6yJKKxV9V+7ldHZ2YkgY/aNDQ=="
37
37
  }
38
38
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "963014df7150b01a848918000c2ebca5b5387c6662cda30cb409b6b5d040ac3d"
14
+ "content": "509c952dde3408081c65f343258ca79f553fe72a3e3ae73c8ab1c6775bad6ac1"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.11",
4
- "engineVersion": "5.3.11",
5
- "buildId": "1-5.3.11-x86_64-pc-windows-msvc",
3
+ "cliVersion": "5.3.13",
4
+ "engineVersion": "5.3.13",
5
+ "buildId": "1-5.3.13-x86_64-pc-windows-msvc",
6
6
  "protocolAbi": 1,
7
7
  "capabilityAbi": 2,
8
8
  "nodeApiAbi": 4,
@@ -16,15 +16,15 @@
16
16
  "platform": "win32",
17
17
  "arch": "x64",
18
18
  "libc": null,
19
- "artifactSha256": "c933ef9b1c8dd2948de8ff3ffc3271b7bd0fe1f06051afb972139e1543510545",
19
+ "artifactSha256": "be0545ccb62c32ac1f690fc8f916d2bbb926df8f394a73c4294959bbddc12ed3",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.win32-x64-msvc.node.sbom.json",
23
- "sha256": "bc5485fdfd62fc6c9d74392245c5c41f2c26d06956e78cb0037423e5e6bac372"
23
+ "sha256": "c859ada03fa2df805d9c64b5e4d742bd2a0f45d73f6749b187b1458fca90ae6c"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
27
+ "sourceCommit": "4c29cf026dcfa833b89a328afa3546aecbc02d22",
28
28
  "sourceTreeDirty": false,
29
29
  "sourceDateEpoch": 1,
30
30
  "rustToolchain": "rustc 1.95.0 (59807616e 2026-04-14)",
@@ -33,6 +33,6 @@
33
33
  "signature": {
34
34
  "algorithm": "Ed25519",
35
35
  "keyId": "e2ee765cb5ad9fbdc433ece332bce26d746d5e350b3acde0721a4c8c6337ff7b",
36
- "value": "VPmZbTb40RTOsMSYvVJpBMO/ukXg/mNclxqt9NWwuYBVfV8vcaC0QiH/UyQrGBV00wanp8fdu+A3mgRSXBkIDw=="
36
+ "value": "Uui7dVZf7K+hIaahkXrmkoHi9ySHm1WR3+9bldHk8btGB9vFbqq29ThLuVIBX1RSNDxzI80dMJxNIRqkPIt3Bg=="
37
37
  }
38
38
  }
@@ -4,14 +4,14 @@
4
4
  "version": 1,
5
5
  "metadata": {
6
6
  "component": {
7
- "bom-ref": "pkg:cargo/planu-core@5.3.11",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.13",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.11",
10
+ "version": "5.3.13",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "c933ef9b1c8dd2948de8ff3ffc3271b7bd0fe1f06051afb972139e1543510545"
14
+ "content": "be0545ccb62c32ac1f690fc8f916d2bbb926df8f394a73c4294959bbddc12ed3"
15
15
  }
16
16
  ]
17
17
  }
@@ -1106,7 +1106,7 @@
1106
1106
  "dependsOn": []
1107
1107
  },
1108
1108
  {
1109
- "ref": "pkg:cargo/planu-core@5.3.11",
1109
+ "ref": "pkg:cargo/planu-core@5.3.13",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -119,10 +119,13 @@ function checkInterpolatedSections(content, criteria) {
119
119
  }
120
120
  const start = heading.index + heading[0].length;
121
121
  const end = headingMatches[i + 1]?.index ?? content.length;
122
- const bullets = content
122
+ const bulletLines = content
123
123
  .slice(start, end)
124
124
  .split('\n')
125
- .map((line) => BULLET_LINE_RE.exec(line.trim())?.[1])
125
+ .map((line) => line.trim())
126
+ .filter((line) => BULLET_LINE_RE.test(line));
127
+ const bullets = bulletLines
128
+ .map((line) => BULLET_LINE_RE.exec(line)?.[1])
126
129
  .filter((line) => Boolean(line));
127
130
  if (isFileListSection(bullets)) {
128
131
  continue;
@@ -132,6 +135,7 @@ function checkInterpolatedSections(content, criteria) {
132
135
  kind: STRUCTURAL_INTERPOLATION_KIND,
133
136
  phrase: heading[1],
134
137
  reason: `subsection "${heading[1]}" restates each criterion into the same template with no new information`,
138
+ evidence: bulletLines[0],
135
139
  });
136
140
  }
137
141
  }
@@ -192,10 +196,22 @@ function restatesCriterion(variable, criteria) {
192
196
  if (normalizedCriterion.length < CRITERION_RESTATEMENT_MIN_LENGTH) {
193
197
  return false;
194
198
  }
199
+ if (isCriterionPathTokenEcho(normalizedVariable, criterion)) {
200
+ return false;
201
+ }
195
202
  return (normalizedVariable.includes(normalizedCriterion) ||
196
203
  normalizedCriterion.includes(normalizedVariable));
197
204
  });
198
205
  }
206
+ function isCriterionPathTokenEcho(normalizedVariable, criterion) {
207
+ return criterionPathTokens(criterion).some((token) => normalizeForRestatementMatch(token).includes(normalizedVariable));
208
+ }
209
+ function criterionPathTokens(criterion) {
210
+ return criterion
211
+ .split(/\s+/)
212
+ .map((word) => word.replace(/^[`'"]+|[`'".,;:]+$/g, ''))
213
+ .filter((word) => PATH_TOKEN_RE.test(word));
214
+ }
199
215
  function normalizeForRestatementMatch(value) {
200
216
  return value
201
217
  .replace(/[`*_"]/g, '')
@@ -7,6 +7,7 @@ export const SOURCE_IGNORED_ROOTS = new Set([
7
7
  'coverage',
8
8
  'dist',
9
9
  'node_modules',
10
+ 'planu',
10
11
  ]);
11
12
  export function isValidationSourcePath(path) {
12
13
  const normalized = path.replaceAll('\\', '/').normalize('NFC');
@@ -927,6 +927,21 @@ function applyEnglishOnlyGate(gate) {
927
927
  function quotePosixShellArgument(value) {
928
928
  return `'${value.replaceAll("'", `'"'"'`)}'`;
929
929
  }
930
+ /**
931
+ * SPEC-1469: the quality gate finding alone (`phrase` + `reason`) forced callers into
932
+ * trial-and-error rewording because it dropped the offending rendered line and the rule
933
+ * needed to pass. Quoting `evidence` verbatim and naming the generator-owned FILES:/TEST:
934
+ * marker exemption gives a what-failed + what-to-do-next message on the first read.
935
+ */
936
+ function formatGenericOutputIssue(issue) {
937
+ const base = `${issue.phrase}: ${issue.reason}`;
938
+ if (!issue.evidence) {
939
+ return base;
940
+ }
941
+ return (`${base}. Offending row: "${issue.evidence}". ` +
942
+ "A row that only echoes a criterion's own mandatory FILES:/TEST: marker path is generator-owned " +
943
+ "and already exempt; rewrite the row's remaining content so it adds information beyond the fixed template.");
944
+ }
930
945
  function earlyPreparation(result, clarificationProjectId) {
931
946
  return {
932
947
  kind: 'early',
@@ -1144,10 +1159,7 @@ async function prepareCreateSpecCandidate(initialParams, server) {
1144
1159
  {
1145
1160
  type: 'text',
1146
1161
  text: 'Spec quality gate blocked generic output before persistence. ' +
1147
- genericOutputGate.issues
1148
- .slice(0, 3)
1149
- .map((issue) => `${issue.phrase}: ${issue.reason}`)
1150
- .join('; '),
1162
+ genericOutputGate.issues.slice(0, 3).map(formatGenericOutputIssue).join('; '),
1151
1163
  },
1152
1164
  ],
1153
1165
  isError: true,
@@ -67,6 +67,7 @@ import { reportClassifiedDegradation } from '../../errors/classified-degradation
67
67
  import { captureValidationFreshnessLease } from '../../engine/validation/validation-freshness.js';
68
68
  import { computeDurableValidationBindings, toValidationReceiptBindings, } from '../../engine/validation/durable-validation.js';
69
69
  import { checkReconciliationFreshness } from '../../engine/evidence-gates/reconciliation-freshness.js';
70
+ import { doneReceiptBindingsDifferOnlyInEvidence } from './done-receipt-verifier.js';
70
71
  import { extractCanonicalFileOwnership } from '../../engine/handoff-packager.js';
71
72
  import { generateTaskPlanSkeleton, writeEvidenceSkeleton, } from '../../engine/evidence-gates/evidence-skeletons.js';
72
73
  import { extractSection } from '../../engine/spec-format/markdown-sections.js';
@@ -285,8 +286,11 @@ async function currentBindingsAreFresh(identity, currentBindings) {
285
286
  projectPath: identity.projectPath,
286
287
  specPath,
287
288
  });
288
- return (JSON.stringify(toValidationReceiptBindings(observed.bindings, observed.artifactDigests)) ===
289
- JSON.stringify(currentBindings));
289
+ const observedBindings = toValidationReceiptBindings(observed.bindings, observed.artifactDigests);
290
+ if (JSON.stringify(observedBindings) === JSON.stringify(currentBindings)) {
291
+ return true;
292
+ }
293
+ return doneReceiptBindingsDifferOnlyInEvidence(observedBindings, currentBindings);
290
294
  }
291
295
  catch (error) {
292
296
  reportClassifiedDegradation('VALIDATION_RECEIPT_RECOMPUTE_FAILED', error);
@@ -45,6 +45,9 @@ export interface GenericSpecOutputIssue {
45
45
  kind: GenericSpecOutputIssueKind;
46
46
  phrase: string;
47
47
  reason: string;
48
+ /** SPEC-1469: the first offending bullet verbatim, so the tool boundary can quote the exact
49
+ * rendered line instead of forcing the caller to guess which row collided. */
50
+ evidence?: string;
48
51
  }
49
52
  export interface GenericSpecOutputGateResult {
50
53
  passed: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "5.3.11",
3
+ "version": "5.3.13",
4
4
  "description": "Planu — MCP Server for Spec Driven Development with native Rust acceleration for hot paths. Cross-platform (Linux/macOS/Windows, x64/arm64, glibc/musl).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,14 +35,14 @@
35
35
  "packageName": "@planu/core"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@planu/core-darwin-arm64": "5.3.11",
39
- "@planu/core-darwin-x64": "5.3.11",
40
- "@planu/core-linux-arm64-gnu": "5.3.11",
41
- "@planu/core-linux-arm64-musl": "5.3.11",
42
- "@planu/core-linux-x64-gnu": "5.3.11",
43
- "@planu/core-linux-x64-musl": "5.3.11",
44
- "@planu/core-win32-arm64-msvc": "5.3.11",
45
- "@planu/core-win32-x64-msvc": "5.3.11"
38
+ "@planu/core-darwin-arm64": "5.3.13",
39
+ "@planu/core-darwin-x64": "5.3.13",
40
+ "@planu/core-linux-arm64-gnu": "5.3.13",
41
+ "@planu/core-linux-arm64-musl": "5.3.13",
42
+ "@planu/core-linux-x64-gnu": "5.3.13",
43
+ "@planu/core-linux-x64-musl": "5.3.13",
44
+ "@planu/core-win32-arm64-msvc": "5.3.13",
45
+ "@planu/core-win32-x64-msvc": "5.3.13"
46
46
  },
47
47
  "engines": {
48
48
  "node": ">=24.0.0"
@@ -87,7 +87,7 @@
87
87
  "native:project-graph:benchmark": "node scripts/benchmark-native-performance.mjs --operation project_graph_query --samples 30 --warmups 5 --project-path . --spec-id SPEC-1119 --json",
88
88
  "benchmark:execution-kernel": "pnpm build && node scripts/benchmark-execution-kernel.mjs",
89
89
  "check": "pnpm typecheck && pnpm lint && pnpm format:check && pnpm check:release-authorities && pnpm check:commercial-surfaces && pnpm check:tool-registration && pnpm check:public-privacy && pnpm check:website-proof && pnpm check:donation-assets && pnpm check:website-public-assets",
90
- "check:strict": "pnpm check && pnpm generate:host-tool-registry -- --check && pnpm check:native-version-parity && pnpm check:environment-schema && pnpm audit:hardcodes && pnpm audit:deadcode && pnpm audit:circular && pnpm audit:types && pnpm audit:security && pnpm audit:licenses && pnpm audit:i18n",
90
+ "check:strict": "pnpm check && pnpm generate:host-tool-registry -- --check && pnpm check:native-version-parity && pnpm check:environment-schema && pnpm audit:hardcodes && pnpm audit:deadcode && pnpm audit:circular && pnpm audit:types && pnpm audit:security && pnpm audit:i18n",
91
91
  "check:reliability": "node scripts/check-reliability-policies.mjs",
92
92
  "check:environment-schema": "node scripts/check-environment-schema.mjs",
93
93
  "test:contracts": "vitest run tests/contracts tests/integration/package-consumer-hono.test.ts",
@@ -108,7 +108,6 @@
108
108
  "audit:types": "type-coverage --at-least 98 --ignore-catch --strict --ignore-files 'tests/**'",
109
109
  "audit:tokens": "bash scripts/audit-token-usage.sh 10",
110
110
  "audit:security": "bash scripts/audit-security.sh",
111
- "audit:licenses": "bash scripts/audit-licenses.sh",
112
111
  "audit:size": "bash scripts/audit-package-size.sh",
113
112
  "audit:i18n": "bash scripts/audit-i18n.sh",
114
113
  "audit:hardcodes": "node scripts/check-hardcodes.mjs",
package/planu-native.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dev.planu.native",
3
3
  "displayName": "Planu Native Lightweight Surface",
4
- "version": "5.3.11",
4
+ "version": "5.3.13",
5
5
  "packageName": "@planu/cli",
6
6
  "modes": {
7
7
  "lightweight": {
package/planu-plugin.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dev.planu.cli",
3
3
  "displayName": "Planu — Spec Driven Development",
4
4
  "description": "Manage software specs, estimations, and autonomous SDD workflows. Language-agnostic MCP server for Claude Code.",
5
- "version": "5.3.11",
5
+ "version": "5.3.13",
6
6
  "icon": "assets/plugin/icon.svg",
7
7
  "command": ["npx", "@planu/cli@latest"],
8
8
  "packageName": "@planu/cli",