@planu/cli 5.3.3 → 5.3.5
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 +35 -0
- package/dist/engine/autopilot/action-registry.js +20 -2
- package/dist/engine/constitution/sdd-rules-registry.js +8 -4
- package/dist/engine/drift/violation-resolver.js +30 -8
- package/dist/engine/evidence-gates/evidence-skeletons.js +9 -4
- package/dist/engine/execution/validate-job-executor.js +25 -10
- package/dist/engine/handoff-packager.js +10 -3
- package/dist/engine/implementation-contract/common.d.ts +13 -1
- package/dist/engine/implementation-contract/common.js +19 -3
- package/dist/engine/implementation-contract/evaluator.js +116 -35
- package/dist/engine/implementation-contract/renderer.js +62 -31
- 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/engine/reconcile/apply-changes.d.ts +0 -12
- package/dist/engine/reconcile/apply-changes.js +11 -33
- package/dist/engine/reconcile/verify-write.js +2 -3
- package/dist/engine/rules-reconciler.js +21 -2
- package/dist/engine/spec-format/acceptance-criteria.js +7 -1
- package/dist/engine/spec-format/unified-spec-builder.js +32 -8
- package/dist/engine/spec-generator/fallback-generator.js +5 -3
- package/dist/engine/spec-quality/generic-output-gate.d.ts +7 -1
- package/dist/engine/spec-quality/generic-output-gate.js +199 -8
- package/dist/engine/spec-quality-scorer.js +9 -5
- package/dist/engine/universal-rules/catalog.js +6 -0
- package/dist/engine/universal-rules/rules/agent-teams.js +0 -2
- package/dist/engine/universal-rules/rules/planu-approval-gates.js +0 -1
- package/dist/engine/universal-rules/rules/planu-bdd-criteria.js +0 -1
- package/dist/engine/universal-rules/rules/planu-clean-code-no-comments.d.ts +3 -0
- package/dist/engine/universal-rules/rules/planu-clean-code-no-comments.js +30 -0
- package/dist/engine/universal-rules/rules/planu-debate-review.d.ts +3 -0
- package/dist/engine/universal-rules/rules/planu-debate-review.js +38 -0
- package/dist/engine/universal-rules/rules/planu-dogfood-bugs.js +0 -2
- package/dist/engine/universal-rules/rules/planu-english-specs.js +0 -1
- package/dist/engine/universal-rules/rules/planu-minimal-change.js +0 -2
- package/dist/engine/universal-rules/rules/planu-modes.js +0 -2
- package/dist/engine/universal-rules/rules/planu-release-policy.js +0 -1
- package/dist/engine/universal-rules/rules/planu-revert-proof-tests.d.ts +3 -0
- package/dist/engine/universal-rules/rules/planu-revert-proof-tests.js +34 -0
- package/dist/engine/universal-rules/rules/planu-sdd-model-routing.js +0 -1
- package/dist/engine/universal-rules/rules/planu-workflow.js +0 -2
- package/dist/engine/validator/validation-report-writer.js +1 -1
- package/dist/engine/workers/handlers/auto-drift.js +22 -8
- package/dist/tools/create-spec.js +5 -0
- package/dist/tools/reconcile-spec.d.ts +1 -1
- package/dist/tools/reconcile-spec.js +303 -178
- package/dist/tools/update-status/dod-gates.js +3 -3
- package/dist/tools/update-status/evidence-gate.js +10 -17
- package/dist/tools/update-status/transition-guard.js +26 -14
- package/dist/types/reconcile.d.ts +5 -17
- package/dist/types/reconcile.js +1 -7
- package/dist/types/spec-quality.d.ts +6 -1
- package/package.json +9 -9
- package/planu-native.json +1 -1
- package/planu-plugin.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function buildBody() {
|
|
2
|
+
return `# Planu Debate Review
|
|
3
|
+
|
|
4
|
+
Auto-generated by \`init_project\`. Do not edit manually.
|
|
5
|
+
|
|
6
|
+
This rule assumes \`planu-approval-gates\` (reviewer independence, self-approval prohibitions) and \`planu-sdd-model-routing\` (arbitration) and restates neither.
|
|
7
|
+
|
|
8
|
+
## Reviewer Plurality And Provider Diversity
|
|
9
|
+
|
|
10
|
+
Every spec and every implementation is reviewed by two independent reviewers from DIFFERENT providers, in ONE parallel round.
|
|
11
|
+
|
|
12
|
+
Prohibited: running a single reviewer, or running two reviewers from the same provider, and calling the result a debate round.
|
|
13
|
+
|
|
14
|
+
Replacement action: launch both reviewers in the same message so they run concurrently, and pick two different providers (for example one Claude-family model and one external model).
|
|
15
|
+
|
|
16
|
+
## One Parallel Round, No Serial Confirmation Loops
|
|
17
|
+
|
|
18
|
+
Prohibited: re-launching a reviewer for pass 2, pass 3, or a "confirm the fix" loop after the first round already produced verdicts.
|
|
19
|
+
|
|
20
|
+
Replacement action: cross the two verdicts once — coincident findings apply directly, divergent findings are arbitrated against the source code — then close the round. Re-open a reviewer only for a specific disagreement the arbiter cannot resolve by reading the code directly.
|
|
21
|
+
|
|
22
|
+
## Degradation Ladder
|
|
23
|
+
|
|
24
|
+
Prohibited: silently reviewing with only one provider when a second is unavailable and presenting it as a debate round.
|
|
25
|
+
|
|
26
|
+
Replacement action: when only one provider is available, run two isolated sessions of the same model instead of one, so two independent verdicts still exist before arbitration.
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
export const planuDebateReviewRule = {
|
|
30
|
+
id: 'planu-debate-review',
|
|
31
|
+
name: 'Planu Debate Review',
|
|
32
|
+
description: 'Requires two-provider parallel review rounds with no serial confirmation loops and a single-provider degradation ladder.',
|
|
33
|
+
category: 'quality',
|
|
34
|
+
applicableHosts: ['all'],
|
|
35
|
+
defaultEnabled: true,
|
|
36
|
+
buildContent: (_host) => buildBody(),
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=planu-debate-review.js.map
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// engine/universal-rules/rules/planu-dogfood-bugs.ts — SPEC-779
|
|
2
|
-
// Universal rule: Planu Dogfood Bugs (mandatory for all Planu-using projects)
|
|
3
1
|
/** Shared markdown body (same for all hosts). */
|
|
4
2
|
function buildBody() {
|
|
5
3
|
return `# Planu Dogfood Bugs (MANDATORY — STRICT)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function buildBody() {
|
|
2
|
+
return `# Planu Revert-Proof Tests
|
|
3
|
+
|
|
4
|
+
Auto-generated by \`init_project\`. Do not edit manually.
|
|
5
|
+
|
|
6
|
+
A new test that never fails against the unfixed source proves nothing.
|
|
7
|
+
|
|
8
|
+
## The Rule
|
|
9
|
+
|
|
10
|
+
Prohibited: reporting a new test as passing evidence without ever having watched it fail. This includes an assertion that compares a value to itself, a mock that echoes back what it was given, and a negative assertion that holds vacuously regardless of the source under test.
|
|
11
|
+
|
|
12
|
+
Replacement action: before reporting the test as evidence, revert only the source change it covers — invert the specific guard line in place, or run the test against the pre-change body read with \`git show <ref>:<path>\` — run the test, and observe it fail. Then restore the source and confirm the test passes again. Report the observed failure output, not just the final green run.
|
|
13
|
+
|
|
14
|
+
Prohibited: using \`git stash\`, \`git checkout\` or \`git restore\` on a shared checkout to stage the revert. Stashes are a process-wide LIFO stack, so a concurrent agent can pop work that is not its own.
|
|
15
|
+
|
|
16
|
+
A guard's regression test must fail against the unguarded variant specifically, not merely against an unrelated point in history such as HEAD.
|
|
17
|
+
|
|
18
|
+
## Hard Blocks
|
|
19
|
+
|
|
20
|
+
- Do not accept a test whose only run is against already-fixed source.
|
|
21
|
+
- Do not accept an assertion that compares a value to itself.
|
|
22
|
+
- Do not accept an assertion that cannot fail for any input.
|
|
23
|
+
`;
|
|
24
|
+
}
|
|
25
|
+
export const planuRevertProofTestsRule = {
|
|
26
|
+
id: 'planu-revert-proof-tests',
|
|
27
|
+
name: 'Planu Revert-Proof Tests',
|
|
28
|
+
description: 'Requires new tests to be proven to fail against the unfixed source before being reported as evidence.',
|
|
29
|
+
category: 'quality',
|
|
30
|
+
applicableHosts: ['all'],
|
|
31
|
+
defaultEnabled: true,
|
|
32
|
+
buildContent: (_host) => buildBody(),
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=planu-revert-proof-tests.js.map
|
|
@@ -154,14 +154,6 @@ async function buildDriftFindings(projectDir, effectiveChanged, activeSpecs, pro
|
|
|
154
154
|
driftedFiles,
|
|
155
155
|
cachedAt: new Date().toISOString(),
|
|
156
156
|
});
|
|
157
|
-
// Wire drift:detected event so autopilot trigger-rules can react
|
|
158
|
-
emitAutopilotEvent({
|
|
159
|
-
name: 'drift:detected',
|
|
160
|
-
projectPath: projectDir,
|
|
161
|
-
projectId,
|
|
162
|
-
specId: spec.id,
|
|
163
|
-
payload: { driftScore, driftLevel: driftScore >= 0.7 ? 'high' : 'warning' },
|
|
164
|
-
});
|
|
165
157
|
findings.push({
|
|
166
158
|
severity: driftScore >= 0.7 ? 'high' : 'warning',
|
|
167
159
|
file: '',
|
|
@@ -171,6 +163,28 @@ async function buildDriftFindings(projectDir, effectiveChanged, activeSpecs, pro
|
|
|
171
163
|
});
|
|
172
164
|
}
|
|
173
165
|
}
|
|
166
|
+
if (driftScore >= threshold) {
|
|
167
|
+
// Wire drift:detected event so autopilot trigger-rules can react.
|
|
168
|
+
// Emitted once per project run — driftScore is project-wide, not per-spec,
|
|
169
|
+
// so emitting inside the loop would fire N identical events for N specs.
|
|
170
|
+
//
|
|
171
|
+
// MUST run after the cache-persistence loop above: emitAutopilotEvent
|
|
172
|
+
// dispatches handlers in a microtask (event-bus.ts), and the enabled
|
|
173
|
+
// rule drift-detected:resolve_drift_violations calls resolveDriftViolations,
|
|
174
|
+
// which loads the drift cache as its first action. Emitting before the
|
|
175
|
+
// cache entries are persisted lets that microtask race ahead and read an
|
|
176
|
+
// empty cache, silently resolving nothing.
|
|
177
|
+
emitAutopilotEvent({
|
|
178
|
+
name: 'drift:detected',
|
|
179
|
+
projectPath: projectDir,
|
|
180
|
+
projectId,
|
|
181
|
+
payload: {
|
|
182
|
+
driftScore,
|
|
183
|
+
driftLevel: driftScore >= 0.7 ? 'high' : 'warning',
|
|
184
|
+
specIds: activeSpecs.map((s) => s.id),
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
}
|
|
174
188
|
return findings;
|
|
175
189
|
}
|
|
176
190
|
// ---------------------------------------------------------------------------
|
|
@@ -1030,6 +1030,11 @@ async function prepareCreateSpecCandidate(initialParams, server) {
|
|
|
1030
1030
|
},
|
|
1031
1031
|
}));
|
|
1032
1032
|
spec.generation = generatedSpec.generation;
|
|
1033
|
+
// SPEC-1406 (DEFECT 4, round 2): FallbackGenerator no longer emits an unconditional
|
|
1034
|
+
// warning, so qualityWarnings only needs the non-empty guard now — the redundant
|
|
1035
|
+
// constant-string filter was removed from create-spec.ts, fallback-generator.ts and
|
|
1036
|
+
// opus-generator.ts (dead code, reverted) so the literal doesn't have to stay
|
|
1037
|
+
// byte-identical across three files.
|
|
1033
1038
|
spec.qualityWarnings =
|
|
1034
1039
|
generatedSpec.qualityWarnings.length > 0 ? generatedSpec.qualityWarnings : undefined;
|
|
1035
1040
|
const baseCriteria = extractCriteria(generatedSpec.specBody).map((criterion) => criterion.text);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type ReconcileSpecInput, type ToolResult } from '../types/index.js';
|
|
3
3
|
export declare function handleReconcileSpec(params: ReconcileSpecInput, server?: McpServer): Promise<ToolResult>;
|
|
4
4
|
//# sourceMappingURL=reconcile-spec.d.ts.map
|