@planu/cli 5.3.9 → 5.3.11
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 +23 -0
- package/dist/engine/next-spec-resolver/conflict-filter.d.ts +3 -21
- package/dist/engine/next-spec-resolver/conflict-filter.js +38 -56
- package/dist/engine/next-spec-resolver/index.d.ts +2 -2
- package/dist/engine/next-spec-resolver/index.js +5 -5
- package/dist/engine/next-spec-resolver/orchestration-planner.js +11 -3
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +4 -4
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +4 -4
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +4 -4
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +4 -4
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +4 -4
- package/dist/tools/update-status/dod-gates.d.ts +0 -2
- package/dist/tools/update-status/dod-gates.js +19 -21
- package/dist/tools/update-status/index.js +1 -9
- package/package.json +9 -9
- package/planu-native.json +1 -1
- package/planu-plugin.json +1 -1
- package/dist/engine/validator/spec-review-writer.d.ts +0 -14
- package/dist/engine/validator/spec-review-writer.js +0 -49
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## [5.3.11] - 2026-08-09
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
- fix(update-status): stop fabricating spec reviewer evidence on review transition
|
|
5
|
+
|
|
6
|
+
### Chores
|
|
7
|
+
- chore(spec-1464): mark done with validation and dual-review evidence
|
|
8
|
+
- chore(planu): SPEC-1464 approved after 3-round dual review; move to implementing
|
|
9
|
+
- chore(planu): session checkpoint after v5.3.10 release
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## [5.3.10] - 2026-08-09
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
- fix(orchestration): derive file-conflict ownership from persisted spec bodies (SPEC-1461)
|
|
16
|
+
|
|
17
|
+
### Chores
|
|
18
|
+
- chore(spec-1461): mark done after validate 100/100 and dual review
|
|
19
|
+
- chore(spec-1461): sync spec v1.3.1 into branch and strip narrative comments
|
|
20
|
+
- chore(planu): SPEC-1461 lifecycle after dual review; file SPEC-1463/SPEC-1464
|
|
21
|
+
- chore(planu): file SPEC-1462 (transient smoke CLI failure) and record v5.3.9 release state
|
|
22
|
+
|
|
23
|
+
|
|
1
24
|
## [5.3.9] - 2026-08-09
|
|
2
25
|
|
|
3
26
|
### Bug Fixes
|
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
import type { Spec } from '../../types/spec/core.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* A conflict exists when candidate.technicalFiles ∩ activeSpec.technicalFiles is non-empty.
|
|
6
|
-
* technicalFiles extracted from spec.technical?.filesToModify + spec.technical?.filesToCreate.
|
|
7
|
-
*
|
|
8
|
-
* Specs with no file info (draft/rough specs) are treated as conflict-free and included.
|
|
9
|
-
*
|
|
10
|
-
* @param candidates - specs to evaluate (approved, not blocked by deps)
|
|
11
|
-
* @param activeSpecs - all specs currently with status === 'implementing'
|
|
12
|
-
*/
|
|
13
|
-
export declare function filterConflicting(candidates: Spec[], activeSpecs: Spec[]): Spec[];
|
|
14
|
-
/**
|
|
15
|
-
* Extract all file paths from a spec's technical section.
|
|
16
|
-
* Reads filesToModify and filesToCreate from spec.technical.
|
|
17
|
-
*/
|
|
18
|
-
export declare function extractFiles(spec: Spec): string[];
|
|
19
|
-
/**
|
|
20
|
-
* Check if two specs share any files (used by orchestration planner).
|
|
21
|
-
*/
|
|
22
|
-
export declare function hasFileConflict(specA: Spec, specB: Spec): boolean;
|
|
2
|
+
export declare function filterConflicting(candidates: Spec[], activeSpecs: Spec[], projectPath: string, cache?: Map<string, string[]>): Promise<Spec[]>;
|
|
3
|
+
export declare function extractFiles(spec: Spec, projectPath: string): Promise<string[]>;
|
|
4
|
+
export declare function hasFileConflict(specA: Spec, specB: Spec, projectPath: string, cache?: Map<string, string[]>): Promise<boolean>;
|
|
23
5
|
//# sourceMappingURL=conflict-filter.d.ts.map
|
|
@@ -1,80 +1,62 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* A conflict exists when candidate.technicalFiles ∩ activeSpec.technicalFiles is non-empty.
|
|
8
|
-
* technicalFiles extracted from spec.technical?.filesToModify + spec.technical?.filesToCreate.
|
|
9
|
-
*
|
|
10
|
-
* Specs with no file info (draft/rough specs) are treated as conflict-free and included.
|
|
11
|
-
*
|
|
12
|
-
* @param candidates - specs to evaluate (approved, not blocked by deps)
|
|
13
|
-
* @param activeSpecs - all specs currently with status === 'implementing'
|
|
14
|
-
*/
|
|
15
|
-
export function filterConflicting(candidates, activeSpecs) {
|
|
1
|
+
// engine/next-spec-resolver/conflict-filter.ts — SPEC-1461: derive file ownership from persisted spec bodies
|
|
2
|
+
import { isAbsolute, join } from 'node:path';
|
|
3
|
+
import { readSpecContent } from '../spec-reader.js';
|
|
4
|
+
import { extractFilesFromSpecBody } from '../spec-format/technical-md-populator.js';
|
|
5
|
+
export async function filterConflicting(candidates, activeSpecs, projectPath, cache = new Map()) {
|
|
16
6
|
if (activeSpecs.length === 0) {
|
|
17
7
|
return candidates;
|
|
18
8
|
}
|
|
19
|
-
const activeFiles = buildFileSet(activeSpecs);
|
|
9
|
+
const activeFiles = await buildFileSet(activeSpecs, projectPath, cache);
|
|
20
10
|
if (activeFiles.size === 0) {
|
|
21
11
|
return candidates;
|
|
22
12
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (specFiles.length === 0) {
|
|
27
|
-
|
|
13
|
+
const result = [];
|
|
14
|
+
for (const spec of candidates) {
|
|
15
|
+
const specFiles = await extractFilesMemoized(spec, projectPath, cache);
|
|
16
|
+
if (specFiles.length === 0 || !specFiles.some((f) => activeFiles.has(f))) {
|
|
17
|
+
result.push(spec);
|
|
28
18
|
}
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
31
21
|
}
|
|
32
|
-
|
|
33
|
-
* Build a set of all files owned by the active (implementing) specs.
|
|
34
|
-
*/
|
|
35
|
-
function buildFileSet(specs) {
|
|
22
|
+
async function buildFileSet(specs, projectPath, cache) {
|
|
36
23
|
const files = new Set();
|
|
37
24
|
for (const spec of specs) {
|
|
38
|
-
for (const f of
|
|
25
|
+
for (const f of await extractFilesMemoized(spec, projectPath, cache)) {
|
|
39
26
|
files.add(f);
|
|
40
27
|
}
|
|
41
28
|
}
|
|
42
29
|
return files;
|
|
43
30
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
* Reads filesToModify and filesToCreate from spec.technical.
|
|
47
|
-
*/
|
|
48
|
-
export function extractFiles(spec) {
|
|
49
|
-
const technical = spec.technical;
|
|
50
|
-
if (!technical) {
|
|
31
|
+
export async function extractFiles(spec, projectPath) {
|
|
32
|
+
if (!spec.specPath) {
|
|
51
33
|
return [];
|
|
52
34
|
}
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
if (typeof f === 'string' && f.trim()) {
|
|
58
|
-
files.push(f.trim());
|
|
59
|
-
}
|
|
60
|
-
}
|
|
35
|
+
const specPath = isAbsolute(spec.specPath) ? spec.specPath : join(projectPath, spec.specPath);
|
|
36
|
+
const body = await readSpecContent(specPath);
|
|
37
|
+
if (body === null) {
|
|
38
|
+
return [];
|
|
61
39
|
}
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
40
|
+
const ownership = await extractFilesFromSpecBody(body, projectPath);
|
|
41
|
+
if (ownership === null) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
return [
|
|
45
|
+
...new Set([...ownership.create, ...ownership.modify, ...ownership.test].map((e) => e.path)),
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
async function extractFilesMemoized(spec, projectPath, cache) {
|
|
49
|
+
const cached = cache.get(spec.id);
|
|
50
|
+
if (cached !== undefined) {
|
|
51
|
+
return cached;
|
|
69
52
|
}
|
|
53
|
+
const files = await extractFiles(spec, projectPath);
|
|
54
|
+
cache.set(spec.id, files);
|
|
70
55
|
return files;
|
|
71
56
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
export function hasFileConflict(specA, specB) {
|
|
76
|
-
const filesA = extractFiles(specA);
|
|
77
|
-
const filesB = new Set(extractFiles(specB));
|
|
57
|
+
export async function hasFileConflict(specA, specB, projectPath, cache = new Map()) {
|
|
58
|
+
const filesA = await extractFilesMemoized(specA, projectPath, cache);
|
|
59
|
+
const filesB = new Set(await extractFilesMemoized(specB, projectPath, cache));
|
|
78
60
|
return filesA.some((f) => filesB.has(f));
|
|
79
61
|
}
|
|
80
62
|
//# sourceMappingURL=conflict-filter.js.map
|
|
@@ -11,8 +11,8 @@ export type { NextSpecResult } from '../../types/next-spec.js';
|
|
|
11
11
|
* 4. Sort by scoreSpec() DESC, then by id ASC (tie-break)
|
|
12
12
|
* 5. Return top-1 as NextSpecResult
|
|
13
13
|
*
|
|
14
|
-
* @param
|
|
14
|
+
* @param projectPath - absolute path to project root, used to resolve spec.md paths for conflict detection
|
|
15
15
|
* @param allSpecs - full list of all specs in the project
|
|
16
16
|
*/
|
|
17
|
-
export declare function resolveNextSpec(
|
|
17
|
+
export declare function resolveNextSpec(projectPath: string, allSpecs: Spec[]): Promise<NextSpecResult>;
|
|
18
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -14,13 +14,13 @@ import { scoreSpec } from './scorer.js';
|
|
|
14
14
|
* 4. Sort by scoreSpec() DESC, then by id ASC (tie-break)
|
|
15
15
|
* 5. Return top-1 as NextSpecResult
|
|
16
16
|
*
|
|
17
|
-
* @param
|
|
17
|
+
* @param projectPath - absolute path to project root, used to resolve spec.md paths for conflict detection
|
|
18
18
|
* @param allSpecs - full list of all specs in the project
|
|
19
19
|
*/
|
|
20
|
-
export function resolveNextSpec(
|
|
21
|
-
return
|
|
20
|
+
export function resolveNextSpec(projectPath, allSpecs) {
|
|
21
|
+
return computeNextSpec(projectPath, allSpecs);
|
|
22
22
|
}
|
|
23
|
-
function computeNextSpec(allSpecs) {
|
|
23
|
+
async function computeNextSpec(projectPath, allSpecs) {
|
|
24
24
|
// Scenario 8: empty spec list
|
|
25
25
|
if (allSpecs.length === 0) {
|
|
26
26
|
return { spec: null, reason: 'No specs in project yet' };
|
|
@@ -55,7 +55,7 @@ function computeNextSpec(allSpecs) {
|
|
|
55
55
|
}
|
|
56
56
|
// Step 3: Filter conflicting with implementing specs
|
|
57
57
|
const activeSpecs = allSpecs.filter((s) => s.status === 'implementing');
|
|
58
|
-
const candidates = filterConflicting(unblocked, activeSpecs);
|
|
58
|
+
const candidates = await filterConflicting(unblocked, activeSpecs, projectPath);
|
|
59
59
|
if (candidates.length === 0) {
|
|
60
60
|
return {
|
|
61
61
|
spec: null,
|
|
@@ -33,11 +33,12 @@ export async function resolveOrchestrationPlan(projectPath, allSpecs) {
|
|
|
33
33
|
const levels = buildTopologicalLevels(unblocked, inDegree, dependents);
|
|
34
34
|
const waves = [];
|
|
35
35
|
const resolvedIds = new Set();
|
|
36
|
+
const conflictCache = new Map();
|
|
36
37
|
for (const level of levels) {
|
|
37
38
|
if (waves.length >= MAX_WAVES) {
|
|
38
39
|
break;
|
|
39
40
|
}
|
|
40
|
-
const waveGroups = groupByConflict(level);
|
|
41
|
+
const waveGroups = await groupByConflict(level, projectPath, conflictCache);
|
|
41
42
|
for (const group of waveGroups) {
|
|
42
43
|
if (waves.length >= MAX_WAVES) {
|
|
43
44
|
break;
|
|
@@ -121,7 +122,7 @@ function buildWaveEntry(spec, group, resolvedIds) {
|
|
|
121
122
|
dependsOn: (Array.isArray(spec.dependencies) ? spec.dependencies : []).filter((d) => resolvedIds.has(d)),
|
|
122
123
|
};
|
|
123
124
|
}
|
|
124
|
-
function groupByConflict(specs) {
|
|
125
|
+
async function groupByConflict(specs, projectPath, cache) {
|
|
125
126
|
const groups = [];
|
|
126
127
|
const assigned = new Set();
|
|
127
128
|
for (const spec of specs) {
|
|
@@ -133,7 +134,14 @@ function groupByConflict(specs) {
|
|
|
133
134
|
if (group.length >= MAX_PARALLEL_PER_WAVE) {
|
|
134
135
|
continue;
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
+
let conflicts = false;
|
|
138
|
+
for (const other of group) {
|
|
139
|
+
if (await hasFileConflict(spec, other, projectPath, cache)) {
|
|
140
|
+
conflicts = true;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!conflicts) {
|
|
137
145
|
group.push(spec);
|
|
138
146
|
assigned.add(spec.id);
|
|
139
147
|
placed = true;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"cliVersion": "5.3.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
20
|
+
"artifactSha256": "a637894db9f271f49dbe9f9f0fc33d83a9b70ae1c7b2e71cad71d8ad558f4818",
|
|
21
21
|
"sbom": {
|
|
22
22
|
"format": "CycloneDX-1.5",
|
|
23
23
|
"path": "planu-core.darwin-arm64.node.sbom.json",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "eb61e29335b5a55fb357861bce4f38423d94248c1ee3b7b8dc0181e9118f4b6b"
|
|
25
25
|
},
|
|
26
26
|
"provenance": {
|
|
27
27
|
"builder": "scripts/build-rust-local.sh",
|
|
28
|
-
"sourceCommit": "
|
|
28
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
37
|
+
"value": "Pzuaa525uj5kVwR5LlqMFJKZCVmI7DKNw73xo4Zo129Zw3zIx5EapKPlFYaBAUUpa4dkuRa00EWSxNKK7zahDA=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "a637894db9f271f49dbe9f9f0fc33d83a9b70ae1c7b2e71cad71d8ad558f4818"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
20
|
+
"artifactSha256": "6be96ffd429bd0215674a9d7c7ec722d77515ef59c39573c928d7ed862c54ab4",
|
|
21
21
|
"sbom": {
|
|
22
22
|
"format": "CycloneDX-1.5",
|
|
23
23
|
"path": "planu-core.darwin-x64.node.sbom.json",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "628cc248c3ac7e5b13b000c93d7f630ea0ae1ae768f61da08ec370f3e3440794"
|
|
25
25
|
},
|
|
26
26
|
"provenance": {
|
|
27
27
|
"builder": "scripts/build-rust-local.sh",
|
|
28
|
-
"sourceCommit": "
|
|
28
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
37
|
+
"value": "mMbL9QMwOpMVPnAff8FC82N1UEyKLDsOczRq2Be65nqQl8gdh/SNh5TRMIpDv6rpoILKptm63YZUcUyowl54Dw=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "6be96ffd429bd0215674a9d7c7ec722d77515ef59c39573c928d7ed862c54ab4"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
19
|
+
"artifactSha256": "32d0b5347c2df4309a5694198808ef98e2c7bb02c4fcc13ad177f9e9883d6785",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-arm64-gnu.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "0a247e82910188488212dc4675f194712cf6fc76f3c1f3a671ff45440ede99bb"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
36
|
+
"value": "2cIeBFLwk2akHCgoFLGanCjGjQOzZvZOMTcOadPY4uSmybBItWfHnsG4uE2k7nu07AtMD9j8B8il3K445IpfBw=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "32d0b5347c2df4309a5694198808ef98e2c7bb02c4fcc13ad177f9e9883d6785"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
19
|
+
"artifactSha256": "855c446e904b1349f0b3a7d2e918f45895d2f7bcdc42fd7bcfe96b4231d34d76",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-arm64-musl.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "e8bbf7b06bb48c63b11654815814360d37f31c325d75c73d3cde284af9b388d2"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
36
|
+
"value": "gO9HbCl6ucziBx+OOWweX6jal0Qj42+AaAd4OTtO+Ttw52kc0qb7GZP2FDYJ6QuRvQxXAPXNnLEiDRV48EI3AQ=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "855c446e904b1349f0b3a7d2e918f45895d2f7bcdc42fd7bcfe96b4231d34d76"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
19
|
+
"artifactSha256": "02070a07203d610a026ee812ee150049007d305f3490f4ff76ac7b419f3bd303",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-x64-gnu.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "959488b70f6e76440ab77ae9a0d11ac14c7075054784bbeb56c9deffc28fe959"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
36
|
+
"value": "f2kOoFQHV3utAi8Dx/yNB55OCOSlrFps74CGtW5i55zhZUyt0fB3qlmPqkddIzV43O69osgSlrHrz61eNdhgBg=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "02070a07203d610a026ee812ee150049007d305f3490f4ff76ac7b419f3bd303"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
19
|
+
"artifactSha256": "d5ae1b0820532dd3751cd4daa7f6f149d8050ec6bf50acdeaea855a38773429a",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.linux-x64-musl.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "3f1547e8d5222ef6899ef2fc5321620564f58536296ba88e456f10a1f8f5d0e7"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
36
|
+
"value": "ZdsY0oytJlhoRrA4bzsz11fym6C8ePazWDLY67cDCzxNOxRtnRk3PxL89+jIdNp0INzzV0q3YPDpIS4ej8TXDA=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "d5ae1b0820532dd3751cd4daa7f6f149d8050ec6bf50acdeaea855a38773429a"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
19
|
+
"artifactSha256": "963014df7150b01a848918000c2ebca5b5387c6662cda30cb409b6b5d040ac3d",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.win32-arm64-msvc.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "d7ef9db6e58944ce6c53d087a57783d8bb1c5a4f6b37d8e82f8015e9cba8baf6"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
36
|
+
"value": "CmFxZ49SNux1uUeH55UOCds+idCDgzI+I1+NXsZM33iLJmNQ8qeYqaaJhhQrhWyqdouUuaWgsz9p8Lv22j8sCA=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "963014df7150b01a848918000c2ebca5b5387c6662cda30cb409b6b5d040ac3d"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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.
|
|
4
|
-
"engineVersion": "5.3.
|
|
5
|
-
"buildId": "1-5.3.
|
|
3
|
+
"cliVersion": "5.3.11",
|
|
4
|
+
"engineVersion": "5.3.11",
|
|
5
|
+
"buildId": "1-5.3.11-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": "
|
|
19
|
+
"artifactSha256": "c933ef9b1c8dd2948de8ff3ffc3271b7bd0fe1f06051afb972139e1543510545",
|
|
20
20
|
"sbom": {
|
|
21
21
|
"format": "CycloneDX-1.5",
|
|
22
22
|
"path": "planu-core.win32-x64-msvc.node.sbom.json",
|
|
23
|
-
"sha256": "
|
|
23
|
+
"sha256": "bc5485fdfd62fc6c9d74392245c5c41f2c26d06956e78cb0037423e5e6bac372"
|
|
24
24
|
},
|
|
25
25
|
"provenance": {
|
|
26
26
|
"builder": "scripts/build-rust-local.sh",
|
|
27
|
-
"sourceCommit": "
|
|
27
|
+
"sourceCommit": "28cab3e2226ba00916d27f735a53cb262861a186",
|
|
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": "
|
|
36
|
+
"value": "VPmZbTb40RTOsMSYvVJpBMO/ukXg/mNclxqt9NWwuYBVfV8vcaC0QiH/UyQrGBV00wanp8fdu+A3mgRSXBkIDw=="
|
|
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.
|
|
7
|
+
"bom-ref": "pkg:cargo/planu-core@5.3.11",
|
|
8
8
|
"type": "library",
|
|
9
9
|
"name": "planu-core",
|
|
10
|
-
"version": "5.3.
|
|
10
|
+
"version": "5.3.11",
|
|
11
11
|
"hashes": [
|
|
12
12
|
{
|
|
13
13
|
"alg": "SHA-256",
|
|
14
|
-
"content": "
|
|
14
|
+
"content": "c933ef9b1c8dd2948de8ff3ffc3271b7bd0fe1f06051afb972139e1543510545"
|
|
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.
|
|
1109
|
+
"ref": "pkg:cargo/planu-core@5.3.11",
|
|
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
|
-
|
|
555
|
-
|
|
556
|
-
|
|
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.
|
|
580
|
-
: 'Spec review feedback is malformed or uses an obsolete schema.
|
|
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
|
-
? '
|
|
584
|
-
: '
|
|
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
|
|
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: '
|
|
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: '
|
|
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,
|
|
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.
|
|
3
|
+
"version": "5.3.11",
|
|
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.
|
|
39
|
-
"@planu/core-darwin-x64": "5.3.
|
|
40
|
-
"@planu/core-linux-arm64-gnu": "5.3.
|
|
41
|
-
"@planu/core-linux-arm64-musl": "5.3.
|
|
42
|
-
"@planu/core-linux-x64-gnu": "5.3.
|
|
43
|
-
"@planu/core-linux-x64-musl": "5.3.
|
|
44
|
-
"@planu/core-win32-arm64-msvc": "5.3.
|
|
45
|
-
"@planu/core-win32-x64-msvc": "5.3.
|
|
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"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=24.0.0"
|
package/planu-native.json
CHANGED
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.
|
|
5
|
+
"version": "5.3.11",
|
|
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
|