@planu/cli 5.3.10 → 5.3.12

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 (25) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
  3. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +4 -4
  4. package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
  5. package/dist/engine/planu-core.darwin-x64.node.sbom.json +4 -4
  6. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
  7. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +4 -4
  8. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
  9. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +4 -4
  10. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
  11. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +4 -4
  12. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
  13. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +4 -4
  14. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
  15. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +4 -4
  16. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
  17. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +4 -4
  18. package/dist/tools/update-status/dod-gates.d.ts +0 -2
  19. package/dist/tools/update-status/dod-gates.js +19 -21
  20. package/dist/tools/update-status/index.js +1 -9
  21. package/package.json +10 -11
  22. package/planu-native.json +1 -1
  23. package/planu-plugin.json +1 -1
  24. package/dist/engine/validator/spec-review-writer.d.ts +0 -14
  25. package/dist/engine/validator/spec-review-writer.js +0 -49
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [5.3.12] - 2026-08-10
2
+
3
+ ### Bug Fixes
4
+ - fix(release): cap smoke retries at 3 attempts regardless of delay overrides
5
+ - fix(release): retry transient CLI smoke failures with backoff and per-attempt diagnostics
6
+
7
+ ### Chores
8
+ - chore(spec-1462): record done transition and release bookkeeping
9
+
10
+
11
+ ## [5.3.11] - 2026-08-09
12
+
13
+ ### Bug Fixes
14
+ - fix(update-status): stop fabricating spec reviewer evidence on review transition
15
+
16
+ ### Chores
17
+ - chore(spec-1464): mark done with validation and dual-review evidence
18
+ - chore(planu): SPEC-1464 approved after 3-round dual review; move to implementing
19
+ - chore(planu): session checkpoint after v5.3.10 release
20
+
21
+
1
22
  ## [5.3.10] - 2026-08-09
2
23
 
3
24
  ### Bug Fixes
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "cliVersion": "5.3.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-aarch64-apple-darwin",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "d8beac69c20433cc67304bfe9e6975447c6d18aa744887ebe8982858a5c9b50e",
20
+ "artifactSha256": "ff523b8deecdeea84449f8fcaf402893b744a5e6a9bb11c1ddee1e194d1f50cd",
21
21
  "sbom": {
22
22
  "format": "CycloneDX-1.5",
23
23
  "path": "planu-core.darwin-arm64.node.sbom.json",
24
- "sha256": "d14e32fc056c4d533366178a95f503ea18623c9c7502a78dede88bdfe080d149"
24
+ "sha256": "1992527c0ba21e2dfb259b3a7e4601d5df1cd7a1e7004822c8a071fbdfe0ee72"
25
25
  },
26
26
  "provenance": {
27
27
  "builder": "scripts/build-rust-local.sh",
28
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
28
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "rUhhOkekI/nd5O6msXScY3LSPnVEsXjt6NeTF94SFzkwkh8kMGthFycMcVWx35HfeWbWf7gs1AUCtliXbv8DDA=="
37
+ "value": "HTUvjAMhd8bhrAiu15H3hIo2wU0GP6IfEyDNJm5kINJEuCbxWLtdVim45RF3P+ygGZo1SPLuNxnPl9mFliQ7AQ=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "d8beac69c20433cc67304bfe9e6975447c6d18aa744887ebe8982858a5c9b50e"
14
+ "content": "ff523b8deecdeea84449f8fcaf402893b744a5e6a9bb11c1ddee1e194d1f50cd"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-x86_64-apple-darwin",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "0ff4b1ebedbbae23b9e16e336f17e4eba1be291e1ef264ef39fc63dd954f4aac",
20
+ "artifactSha256": "f8c82cf85a4a23b71d48be21a68d4df8794f859ba0dc7faf606bdfc6237b87ba",
21
21
  "sbom": {
22
22
  "format": "CycloneDX-1.5",
23
23
  "path": "planu-core.darwin-x64.node.sbom.json",
24
- "sha256": "dc1aca4f7f611ade3456586ac75b3a61850fc2d23bde6ec57abf2545f128eb17"
24
+ "sha256": "60634a9dc231f9072fde1f67ff8a5bbc55e46b60d27c60cb108bedbd50411268"
25
25
  },
26
26
  "provenance": {
27
27
  "builder": "scripts/build-rust-local.sh",
28
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
28
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "R9zcCaXmBVoWPdrBiF6/GqvfVK41W3NWgJ5JgSymiSmiwx45BjOZF7HIrvGq1tr/zruCeBBzGYl05FR/JA8ADQ=="
37
+ "value": "IzK1AOM08Nj7CATQpFl9FsIJlXXxo7To0446ljsCQQ1P2ubMQrdpsFG8zGleaP+/jY19aaI8hsix+8dDWw77CA=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "0ff4b1ebedbbae23b9e16e336f17e4eba1be291e1ef264ef39fc63dd954f4aac"
14
+ "content": "f8c82cf85a4a23b71d48be21a68d4df8794f859ba0dc7faf606bdfc6237b87ba"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-aarch64-unknown-linux-gnu",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "28e9486017819da5031ba39be725f749b91e575df2f2fcb90b1529d673a82749",
19
+ "artifactSha256": "02e9b9e3299f353c6b3f7af3c19028c59ff9709d2556511a790133c9f48a9415",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-arm64-gnu.node.sbom.json",
23
- "sha256": "845dd005c78338dd6597aa8583919e4d1d545263cc6792e7929fe1dc41458377"
23
+ "sha256": "068657ff17929cbf9648464ae855e33650852295281f018ef2e1dc7d0b81b4e5"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
27
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "UTQoqkDsSuju0czEEjP2TYgDSUoWkiC31y5cUchXvSf9LmvHNiJEG+Dq6dE66NUF2vRuTb0mxqbxPq0PwlW3Dg=="
36
+ "value": "1YvI7w6WGFWlTBPRDAq6syJqw6GWE5o3MAbDYFtkbA2k7GLIM9h6DtV+bsGHOTA1FfrO5dFLKq7TEfKBIXjTAg=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "28e9486017819da5031ba39be725f749b91e575df2f2fcb90b1529d673a82749"
14
+ "content": "02e9b9e3299f353c6b3f7af3c19028c59ff9709d2556511a790133c9f48a9415"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-aarch64-unknown-linux-musl",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "cb3e41dbb3826bbe7d7df0a24c133d2492c31ffe856ad71a4c5d8bd08560b06f",
19
+ "artifactSha256": "14d49f6f3317b10ffa02399ce9e864f8674aabbe63cddaf30c8e893caa50161b",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-arm64-musl.node.sbom.json",
23
- "sha256": "e9d225953b5b2d459d11d671cb3023a3523f98ab0a8f9576bceccff155e52877"
23
+ "sha256": "2d064fe5d098c9bcb742337a5de979b9f1527ca5631a5a50fdb7bb518572d7de"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
27
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "WJljyakoVmJfKTow05wBS/zH8bDYZG7KKqbWi6BwJORPZx1Ds3Sb9Y5F8WKv9RA+5BuFSFIJp4zHyJt9Tw6GDQ=="
36
+ "value": "oSM7VB0hcVN6suleUCCNY+pHhllCu1mkw5VFAtUWvsKu4fh6JZ/Rp9I1uVmB/GWbmXW9ydMRC1tgslU9THxqDA=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "cb3e41dbb3826bbe7d7df0a24c133d2492c31ffe856ad71a4c5d8bd08560b06f"
14
+ "content": "14d49f6f3317b10ffa02399ce9e864f8674aabbe63cddaf30c8e893caa50161b"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-x86_64-unknown-linux-gnu",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "7787ae4a0980dbbb2e63a771d7570b7006c950b1ed1acf48513aef47ea74738f",
19
+ "artifactSha256": "6b92deb985196cc4fa39f303bfaeaf6a7fe91e6956c88f4703c9eb80a14907eb",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-x64-gnu.node.sbom.json",
23
- "sha256": "983b6e5dd328ba08e035996568d2dcda48419876e22ff2c54ab09479cfdb4fd0"
23
+ "sha256": "e41dbcc50ba6a9ab7e7fd28ac7575c42278789d50df00e9b8c966f3457b26573"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
27
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "QQVd67qTw4BrhqCyOmd8SBKa8IeiTwzo6zV5UKv8206KvXxT+bqcv6ZcN1EsLYkjw9/g8DzcQSbgbpbS+oo/Ag=="
36
+ "value": "+3i482SRJYkWRr9Hen7RC/+/RylV/20s7P/Aih3Ohau2MgX9WGMuhlPtrsRm2ka7nqpfAbSiHAargBAll01oCw=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "7787ae4a0980dbbb2e63a771d7570b7006c950b1ed1acf48513aef47ea74738f"
14
+ "content": "6b92deb985196cc4fa39f303bfaeaf6a7fe91e6956c88f4703c9eb80a14907eb"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-x86_64-unknown-linux-musl",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "5c73eb5c0aacfbd3bd3a658b7037962ead65cbd568b6d503e3a94a0c676f2542",
19
+ "artifactSha256": "090f69d833611e7719e0888c077dbf77753a4e04133b24d25916bd64af5aaf43",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.linux-x64-musl.node.sbom.json",
23
- "sha256": "c754c7acf3f4bbd331670f4bbbdacfaaa634198449e960faaa9b39c922f2a249"
23
+ "sha256": "26742cf05d4862d5657fb85941248a21de692ecc6ae8ff3365d9a5b868b2249c"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
27
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "7p545clM056yw/1PTMLxeR6GrjnqnleW5oUlhLtuI6oWTWSOooTm68CuTQnvmyFFSQmTCU37zwHZIQvolmQmBw=="
36
+ "value": "oahOQvontXieDU/JM+btZgDzXZVWchvAuYHjvTFS44WwkwJguIzIcokp80qaNmtRXsY6rrSb0EB3Z91WF7xlDQ=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "5c73eb5c0aacfbd3bd3a658b7037962ead65cbd568b6d503e3a94a0c676f2542"
14
+ "content": "090f69d833611e7719e0888c077dbf77753a4e04133b24d25916bd64af5aaf43"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-aarch64-pc-windows-msvc",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "5cf4072e6f2f4623ebde20134cb670a50fefcf79f849cde428a3e68aeef4dbcf",
19
+ "artifactSha256": "cf138d9e9e92b96f5b21de5a8711eff870e3075d0c5fc065b3f4f49029777c87",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.win32-arm64-msvc.node.sbom.json",
23
- "sha256": "42a88feefc24921eda52cdd7ec4208a996136bb38871891386dadd2efbff08a6"
23
+ "sha256": "cc83713433b55a3e207c0f54ca504265f8a55ea90dea70ced1ea6699b6b9f1da"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
27
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "efNuvSLjD0P2taPCPrLqhjh28lFR4xQFX2+cV85YTuMP6Rodzy+Y3w+YqkUyfWLGjTTDnji6QJrXtIYYNK8vAg=="
36
+ "value": "ofYOfjmQbbkoYzbcQ2psnXvyHHXPejpwm98gCmQHoXwDmshJlXmEh+yGQfhB2+2sj9Vew0QEfDdup7s5WpmPCw=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "5cf4072e6f2f4623ebde20134cb670a50fefcf79f849cde428a3e68aeef4dbcf"
14
+ "content": "cf138d9e9e92b96f5b21de5a8711eff870e3075d0c5fc065b3f4f49029777c87"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
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.10",
4
- "engineVersion": "5.3.10",
5
- "buildId": "1-5.3.10-x86_64-pc-windows-msvc",
3
+ "cliVersion": "5.3.12",
4
+ "engineVersion": "5.3.12",
5
+ "buildId": "1-5.3.12-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": "0f393c02b1cfe7145bfbc4485de5ad127a07f8e8955e61d5a3bce69135f717f7",
19
+ "artifactSha256": "01375537d3a4179420ccf3bb1927246b7aeaddb87b421f88cf0bbbb795211fe3",
20
20
  "sbom": {
21
21
  "format": "CycloneDX-1.5",
22
22
  "path": "planu-core.win32-x64-msvc.node.sbom.json",
23
- "sha256": "ecc00d784269220e168e90db418228c6e92f7be9fb01409b9e9abeabe8265c1f"
23
+ "sha256": "e23734f6ed9e20b3c3ea614b16cacb63748bd11953a2d482654720a5ba9dd18a"
24
24
  },
25
25
  "provenance": {
26
26
  "builder": "scripts/build-rust-local.sh",
27
- "sourceCommit": "fb419d210888ffbb972e48b7382a7d01b50a9625",
27
+ "sourceCommit": "492ab6a01d184b5778576a890418143361819d20",
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": "9Q/RF7gB8t++GQdo4RaoBNjeCdWxXKNm3NT8sXfxDmiEPgqaAR60USiR21v3D00wStMSPoZK2UcGHKkpvqmdBg=="
36
+ "value": "p0gyjSJxiKoyZlBp9bpqNrjmd4mu/AAuliEDQKGdGXVHHB6Vb0gX74WUe5MQgI6EoaE4OfLKjJzINjC3XO5qAA=="
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.10",
7
+ "bom-ref": "pkg:cargo/planu-core@5.3.12",
8
8
  "type": "library",
9
9
  "name": "planu-core",
10
- "version": "5.3.10",
10
+ "version": "5.3.12",
11
11
  "hashes": [
12
12
  {
13
13
  "alg": "SHA-256",
14
- "content": "0f393c02b1cfe7145bfbc4485de5ad127a07f8e8955e61d5a3bce69135f717f7"
14
+ "content": "01375537d3a4179420ccf3bb1927246b7aeaddb87b421f88cf0bbbb795211fe3"
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.10",
1109
+ "ref": "pkg:cargo/planu-core@5.3.12",
1110
1110
  "dependsOn": [
1111
1111
  "pkg:cargo/core-foundation@0.10.1",
1112
1112
  "pkg:cargo/hmac@0.12.1",
@@ -105,8 +105,6 @@ export declare function deriveDoneReviewDigest(specId: string, projectId: string
105
105
  */
106
106
  export declare function checkValidationReportGate(specId: string, projectId: string, force: boolean | undefined): Promise<ToolResult | null>;
107
107
  export declare function readApprovedValidationReportGate(specId: string, projectId: string, force: boolean | undefined): Promise<ValidationReportGateResult>;
108
- /** SPEC-1051: Write spec-review evidence when a spec enters review. */
109
- export declare function writeSpecReviewArtifact(spec: Spec, specId: string, projectId: string): Promise<ToolResult | null>;
110
108
  /** SPEC-1051: Approval requires a dedicated spec reviewer artifact. */
111
109
  export declare function checkSpecReviewGate(specId: string, projectId: string, _forceApprove: boolean | undefined): Promise<ToolResult | null>;
112
110
  /**
@@ -13,7 +13,6 @@ import { dispatchFeedbackEvent } from '../learn.js';
13
13
  import { auditDeps } from '../../engine/dep-auditor/index.js';
14
14
  import { withEscalation } from '../../engine/escalator/with-escalation.js';
15
15
  import { writeImplementationReviewReport } from '../../engine/validator/validation-report-writer.js';
16
- import { writeSpecReviewFeedback } from '../../engine/validator/spec-review-writer.js';
17
16
  import { formatKeyValue } from '../output-formatter.js';
18
17
  import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
19
18
  import { verifyCurrentDoneReceipt } from './done-receipt-verifier.js';
@@ -551,19 +550,9 @@ export async function readApprovedValidationReportGate(specId, projectId, force)
551
550
  };
552
551
  }
553
552
  }
554
- /** SPEC-1051: Write spec-review evidence when a spec enters review. */
555
- export async function writeSpecReviewArtifact(spec, specId, projectId) {
556
- const result = await writeSpecReviewFeedback({ projectId, specId, spec });
557
- if (result.written) {
558
- return null;
559
- }
560
- return specReviewGateError({
561
- specId,
562
- error: 'spec_review_write_failed',
563
- message: `Could not write spec review feedback: ${result.error ?? 'unknown error'}`,
564
- blockers: result.payload.blockers,
565
- fixHint: 'Fix the artifact store issue, then retry update_status(review).',
566
- });
553
+ function isLifecycleStubBody(specId, body) {
554
+ return (body === `Spec ${specId} reviewed by planu-spec-reviewer and approved for approval gates.` ||
555
+ body === `Spec ${specId} reviewed by planu-spec-reviewer with requested changes.`);
567
556
  }
568
557
  /** SPEC-1051: Approval requires a dedicated spec reviewer artifact. */
569
558
  export async function checkSpecReviewGate(specId, projectId, _forceApprove) {
@@ -576,22 +565,31 @@ export async function checkSpecReviewGate(specId, projectId, _forceApprove) {
576
565
  specId,
577
566
  error: firstErr?.code === 'ARTIFACT_NOT_FOUND' ? 'spec_review_missing' : 'spec_review_invalid',
578
567
  message: firstErr?.code === 'ARTIFACT_NOT_FOUND'
579
- ? 'No spec review feedback exists for this spec. Move it to review so planu-spec-reviewer can review it before approval.'
580
- : 'Spec review feedback is malformed or uses an obsolete schema. Re-run update_status(review).',
568
+ ? 'No spec review feedback exists for this spec. An independent planu-spec-reviewer must review the spec and write its evidence before approval.'
569
+ : 'Spec review feedback is malformed or uses an obsolete schema.',
581
570
  blockers: [],
582
571
  fixHint: firstErr?.code === 'ARTIFACT_NOT_FOUND'
583
- ? 'Run update_status(review), resolve any review blockers, then retry update_status(approved).'
584
- : 'Re-run update_status(review) to regenerate reviewer evidence, then retry approval.',
572
+ ? 'Have planu-spec-reviewer write review_feedback.md (ReviewFeedbackV1) into the handoff store, then retry update_status(approved).'
573
+ : 'Have planu-spec-reviewer rewrite review_feedback.md as valid ReviewFeedbackV1 evidence, then retry approval.',
585
574
  });
586
575
  }
587
576
  const review = result.payload;
577
+ if (isLifecycleStubBody(specId, review.body)) {
578
+ return specReviewGateError({
579
+ specId,
580
+ error: 'spec_review_stub',
581
+ message: 'Spec review feedback is a lifecycle-generated stub, not evidence from a real reviewer.',
582
+ blockers: [],
583
+ fixHint: 'Replace the stub with genuine planu-spec-reviewer evidence in the handoff store, then retry approval.',
584
+ });
585
+ }
588
586
  if (review.verdict !== 'approved' || review.reviewer.verdict !== 'approved') {
589
587
  return specReviewGateError({
590
588
  specId,
591
589
  error: 'spec_review_changes_requested',
592
590
  message: 'Spec reviewer requested changes. Approval is blocked until the review passes.',
593
591
  blockers: review.blockers,
594
- fixHint: 'Resolve the spec review blockers, rerun update_status(review), then retry approval.',
592
+ fixHint: 'Resolve the spec review blockers and have planu-spec-reviewer write updated evidence, then retry approval.',
595
593
  });
596
594
  }
597
595
  if (review.reviewer.kind !== 'spec-review-agent' ||
@@ -601,7 +599,7 @@ export async function checkSpecReviewGate(specId, projectId, _forceApprove) {
601
599
  error: 'spec_review_wrong_reviewer',
602
600
  message: 'Approval requires a dedicated spec reviewer. The implementation reviewer cannot approve the spec plan.',
603
601
  blockers: [`Reviewer was ${review.reviewer.agent}. Expected planu-spec-reviewer.`],
604
- fixHint: 'Run update_status(review) so planu-spec-reviewer writes a fresh review artifact.',
602
+ fixHint: 'Have planu-spec-reviewer (not the implementation reviewer) write the review artifact, then retry approval.',
605
603
  });
606
604
  }
607
605
  return null;
@@ -614,7 +612,7 @@ export async function checkSpecReviewGate(specId, projectId, _forceApprove) {
614
612
  error: 'spec_review_unreadable',
615
613
  message: `Could not read spec review feedback: ${err instanceof Error ? err.message : String(err)}`,
616
614
  blockers: [],
617
- fixHint: 'Re-run update_status(review), then retry update_status(approved).',
615
+ fixHint: 'Fix the artifact store issue so review_feedback.md is readable, then retry update_status(approved).',
618
616
  });
619
617
  }
620
618
  }
@@ -15,7 +15,7 @@ import { checkApprovalGate } from '../../engine/approval-workflow.js';
15
15
  import * as approvalStore from '../../storage/approval-store.js';
16
16
  import { withApprovalSpecLock } from '../../storage/approval-operation-lock.js';
17
17
  import { isLocked, getLock } from '../../storage/spec-lock-store.js';
18
- import { checkDoneGates, checkComplianceGate, checkApprovedFormatGate, checkSpecReviewGate, writeSpecReviewArtifact, deriveDoneReviewDigest, } from './dod-gates.js';
18
+ import { checkDoneGates, checkComplianceGate, checkApprovedFormatGate, checkSpecReviewGate, deriveDoneReviewDigest, } from './dod-gates.js';
19
19
  import { checkLifecycleEvidenceTransitionGate } from './evidence-gate.js';
20
20
  import { autofillTraceabilityMatrix } from '../../engine/evidence-gates/evidence-autofill.js';
21
21
  import { buildStatusResponse, buildDryRunResponse } from './response-builder.js';
@@ -1149,14 +1149,6 @@ export async function handleUpdateStatus(params, server) {
1149
1149
  blockingReasons: [],
1150
1150
  });
1151
1151
  }
1152
- // Entering review creates reviewer evidence only after every lifecycle gate has passed.
1153
- // Auto-advance to approval must consume pre-existing approved reviewer evidence.
1154
- if (newStatus === 'review') {
1155
- const specReviewWriteError = await writeSpecReviewArtifact(spec, specId, projectId);
1156
- if (specReviewWriteError) {
1157
- return specReviewWriteError;
1158
- }
1159
- }
1160
1152
  // Explicit actuals are preserved verbatim. Provider usage and cost are
1161
1153
  // never inferred — synthesizeActuals only fills gaps the caller left
1162
1154
  // unmeasured (SPEC-1356 T-A2).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "5.3.10",
3
+ "version": "5.3.12",
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.10",
39
- "@planu/core-darwin-x64": "5.3.10",
40
- "@planu/core-linux-arm64-gnu": "5.3.10",
41
- "@planu/core-linux-arm64-musl": "5.3.10",
42
- "@planu/core-linux-x64-gnu": "5.3.10",
43
- "@planu/core-linux-x64-musl": "5.3.10",
44
- "@planu/core-win32-arm64-msvc": "5.3.10",
45
- "@planu/core-win32-x64-msvc": "5.3.10"
38
+ "@planu/core-darwin-arm64": "5.3.12",
39
+ "@planu/core-darwin-x64": "5.3.12",
40
+ "@planu/core-linux-arm64-gnu": "5.3.12",
41
+ "@planu/core-linux-arm64-musl": "5.3.12",
42
+ "@planu/core-linux-x64-gnu": "5.3.12",
43
+ "@planu/core-linux-x64-musl": "5.3.12",
44
+ "@planu/core-win32-arm64-msvc": "5.3.12",
45
+ "@planu/core-win32-x64-msvc": "5.3.12"
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.10",
4
+ "version": "5.3.12",
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.10",
5
+ "version": "5.3.12",
6
6
  "icon": "assets/plugin/icon.svg",
7
7
  "command": ["npx", "@planu/cli@latest"],
8
8
  "packageName": "@planu/cli",
@@ -1,14 +0,0 @@
1
- import type { Spec } from '../../types/index.js';
2
- import type { ReviewFeedbackV1 } from '../../types/handoff-artifacts.js';
3
- export declare function writeSpecReviewFeedback(input: {
4
- projectId: string;
5
- specId: string;
6
- spec: Spec;
7
- }): Promise<{
8
- written: boolean;
9
- path?: string;
10
- sha?: string;
11
- payload: ReviewFeedbackV1;
12
- error?: string;
13
- }>;
14
- //# sourceMappingURL=spec-review-writer.d.ts.map
@@ -1,49 +0,0 @@
1
- import { appendArtifact } from '../handoff-artifacts/io.js';
2
- export async function writeSpecReviewFeedback(input) {
3
- const blockers = buildSpecReviewBlockers(input.spec);
4
- const verdict = blockers.length === 0 ? 'approved' : 'changes-requested';
5
- const payload = {
6
- schema_version: '1.0.0',
7
- specId: input.specId,
8
- verdict,
9
- reviewer: {
10
- kind: 'spec-review-agent',
11
- agent: 'planu-spec-reviewer',
12
- verdict,
13
- },
14
- blockers,
15
- suggestions: blockers.length === 0
16
- ? ['Proceed to approval gates; keep implementation reviewer separate after coding.']
17
- : [
18
- 'Resolve blockers, rerun challenge/readiness checks, then move the spec back to review.',
19
- ],
20
- body: blockers.length === 0
21
- ? `Spec ${input.specId} reviewed by planu-spec-reviewer and approved for approval gates.`
22
- : `Spec ${input.specId} reviewed by planu-spec-reviewer with requested changes.`,
23
- reviewedAt: new Date().toISOString(),
24
- };
25
- try {
26
- const artifact = await appendArtifact({
27
- projectId: input.projectId,
28
- specId: input.specId,
29
- kind: 'review_feedback',
30
- payload,
31
- });
32
- return { written: true, path: artifact.path, sha: artifact.sha, payload };
33
- }
34
- catch (err) {
35
- return {
36
- written: false,
37
- payload,
38
- error: err instanceof Error ? err.message : String(err),
39
- };
40
- }
41
- }
42
- function buildSpecReviewBlockers(spec) {
43
- const blockers = [];
44
- if (!spec.title || spec.title.trim().length === 0) {
45
- blockers.push('Spec title is missing.');
46
- }
47
- return blockers;
48
- }
49
- //# sourceMappingURL=spec-review-writer.js.map