mandrel 2.64.0 → 2.66.0
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/.agents/agents/acceptance-critic.md +8 -7
- package/.agents/agents/auditor.md +20 -20
- package/.agents/agents/plan-critic.md +8 -7
- package/.agents/agents/story-worker.md +7 -7
- package/.agents/audit-checklists/quality.md +3 -0
- package/.agents/docs/agentrc-reference.json +1 -9
- package/.agents/docs/configuration.md +8 -7
- package/.agents/docs/execution-reference.md +27 -5
- package/.agents/instructions.md +10 -12
- package/.agents/rules/ci-remediation.md +3 -3
- package/.agents/rules/gherkin-standards.md +3 -2
- package/.agents/rules/git-conventions-reference.md +12 -3
- package/.agents/rules/git-conventions.md +9 -7
- package/.agents/rules/testing-standards.md +8 -7
- package/.agents/runtime-deps.json +1 -1
- package/.agents/schemas/agentrc.schema.json +6 -13
- package/.agents/schemas/audit-rules.schema.json +1 -1
- package/.agents/schemas/story-deliver-terminal.schema.json +5 -0
- package/.agents/scripts/bootstrap.js +102 -91
- package/.agents/scripts/check-context-budget.js +1 -1
- package/.agents/scripts/lib/ITicketingProvider.js +1 -3
- package/.agents/scripts/lib/audit-suite/findings.js +1 -17
- package/.agents/scripts/lib/audit-suite/frontmatter.js +0 -28
- package/.agents/scripts/lib/audit-suite/index.js +0 -6
- package/.agents/scripts/lib/audit-suite/selector.js +0 -31
- package/.agents/scripts/lib/baselines/duplication-scanner.js +17 -7
- package/.agents/scripts/lib/bootstrap/agents-md-fold.js +156 -0
- package/.agents/scripts/lib/bootstrap/commit-push.js +1 -1
- package/.agents/scripts/lib/bootstrap/manifest.js +2 -2
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +91 -107
- package/.agents/scripts/lib/cli/standard-args.js +60 -76
- package/.agents/scripts/lib/cli-args.js +26 -0
- package/.agents/scripts/lib/config/gates/shared.js +3 -3
- package/.agents/scripts/lib/config/review-chain-default.js +13 -0
- package/.agents/scripts/lib/config-settings-schema-delivery.js +2 -2
- package/.agents/scripts/lib/config-settings-schema-quality.js +11 -13
- package/.agents/scripts/lib/doc-tiers.js +25 -6
- package/.agents/scripts/lib/feedback-loop/graduate-steps.js +205 -0
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +47 -782
- package/.agents/scripts/lib/feedback-loop/graduator-gh.js +449 -0
- package/.agents/scripts/lib/generated/agentrc-validator.js +1 -1
- package/.agents/scripts/lib/observability/close-telemetry.js +330 -0
- package/.agents/scripts/lib/observability/metrics-ledger.js +0 -72
- package/.agents/scripts/lib/observability/runtime-friction.js +2 -0
- package/.agents/scripts/lib/observability/signal-validator.js +17 -5
- package/.agents/scripts/lib/orchestration/code-review.js +33 -6
- package/.agents/scripts/lib/orchestration/epic-rollup.js +29 -12
- package/.agents/scripts/lib/orchestration/merge-block-class.js +20 -4
- package/.agents/scripts/lib/orchestration/merge-poll.js +41 -22
- package/.agents/scripts/lib/orchestration/plan-metrics.js +76 -63
- package/.agents/scripts/lib/orchestration/required-checks.js +147 -0
- package/.agents/scripts/lib/orchestration/review-providers/code-review.js +203 -0
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +29 -4
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +3 -2
- package/.agents/scripts/lib/orchestration/run-epilogue.js +6 -0
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +1 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +2 -12
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +370 -268
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +21 -7
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +112 -82
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +4 -0
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +393 -313
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +12 -87
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +3 -0
- package/.agents/scripts/lib/orchestration/ticket-validator.js +19 -36
- package/.agents/scripts/lib/signals/detectors/common.js +63 -51
- package/.agents/scripts/lib/templates/decomposer-prompts.js +5 -24
- package/.agents/scripts/lib/transpile.js +28 -3
- package/.agents/scripts/providers/github/issues.js +14 -23
- package/.agents/scripts/single-story-close.js +10 -2
- package/.agents/scripts/single-story-confirm-merge.js +267 -238
- package/.agents/scripts/sync-claude-agents.js +1 -1
- package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -2
- package/.agents/workflows/audit-architecture.md +5 -4
- package/.agents/workflows/audit-documentation.md +5 -5
- package/.agents/workflows/audit-performance.md +10 -10
- package/.agents/workflows/audit-quality.md +42 -7
- package/.agents/workflows/helpers/acceptance-self-eval.md +9 -9
- package/.agents/workflows/helpers/audit-lens-core.md +30 -57
- package/.agents/workflows/helpers/code-review.md +15 -38
- package/.agents/workflows/helpers/deliver-digest.md +2 -2
- package/.agents/workflows/helpers/deliver-reference.md +7 -3
- package/.agents/workflows/helpers/deliver-story.md +9 -1
- package/.agents/workflows/helpers/parallel-tooling.md +16 -18
- package/.agents/workflows/helpers/plan-reference.md +9 -8
- package/.agents/workflows/mandrel-deliver.md +3 -2
- package/.agents/workflows/mandrel-plan.md +11 -7
- package/.agents/workflows/mandrel-update.md +5 -3
- package/docs/CHANGELOG.md +57 -0
- package/lib/cli/claude-code-version.js +73 -0
- package/lib/cli/doctor.js +2 -2
- package/lib/cli/guarded-sync.js +87 -0
- package/lib/cli/registry.js +9 -0
- package/lib/cli/sync-agents.js +9 -92
- package/lib/cli/sync-commands.js +9 -101
- package/lib/cli/uninstall.js +37 -9
- package/lib/migrations/index.js +2 -0
- package/lib/migrations/steps/2.65.0-fold-claude-md-into-agents-md.js +38 -0
- package/package.json +3 -2
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +0 -99
- package/.agents/scripts/lib/audit-suite/runner.js +0 -205
- package/.agents/scripts/lib/audit-suite/substitutions.js +0 -96
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +0 -37
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +0 -234
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* @typedef {import('./types.js').ProviderChain} ProviderChain
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { DEFAULT_REVIEW_PROVIDERS } from '../../config/review-chain-default.js';
|
|
18
|
+
import { createCodeReviewProviderForRegistry } from './code-review.js';
|
|
17
19
|
import { createCodexProviderForRegistry } from './codex.js';
|
|
18
20
|
import { mergeChainDegradations } from './degraded-gates.js';
|
|
19
21
|
import { createNativeProviderForRegistry } from './native.js';
|
|
@@ -22,6 +24,7 @@ import { createUltrareviewProviderForRegistry } from './ultrareview.js';
|
|
|
22
24
|
|
|
23
25
|
/** @type {Readonly<Record<string, () => ReviewProvider>>} */
|
|
24
26
|
const INLINE_PROVIDERS = Object.freeze({
|
|
27
|
+
'code-review': createCodeReviewProviderForRegistry,
|
|
25
28
|
codex: createCodexProviderForRegistry,
|
|
26
29
|
native: createNativeProviderForRegistry,
|
|
27
30
|
'security-review': createSecurityReviewProviderForRegistry,
|
|
@@ -36,8 +39,6 @@ const PROMPT_PROVIDERS = Object.freeze({
|
|
|
36
39
|
ultrareview: createUltrareviewProviderForRegistry,
|
|
37
40
|
});
|
|
38
41
|
|
|
39
|
-
export const DEFAULT_PROVIDER_NAME = 'native';
|
|
40
|
-
|
|
41
42
|
/**
|
|
42
43
|
* Gate predicate from a `when` clause (`label` / `labelAny`); absent → always true.
|
|
43
44
|
*
|
|
@@ -79,7 +80,8 @@ export function isScopeApplicable(declaredScopes, currentScope) {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
/**
|
|
82
|
-
* Takes the `codeReview` sub-object; unset/empty `providers`
|
|
83
|
+
* Takes the `codeReview` sub-object; unset/empty `providers` falls back to
|
|
84
|
+
* `DEFAULT_REVIEW_PROVIDERS`.
|
|
83
85
|
*
|
|
84
86
|
* @param {{
|
|
85
87
|
* providers?: Array<object>,
|
|
@@ -105,7 +107,7 @@ export function createReviewProvider(codeReviewConfig, opts = {}) {
|
|
|
105
107
|
Array.isArray(codeReviewConfig.providers) &&
|
|
106
108
|
codeReviewConfig.providers.length > 0
|
|
107
109
|
? codeReviewConfig.providers
|
|
108
|
-
:
|
|
110
|
+
: DEFAULT_REVIEW_PROVIDERS;
|
|
109
111
|
|
|
110
112
|
const chain = buildProviderChain(entries, {
|
|
111
113
|
inlineRegistry,
|
|
@@ -193,6 +195,16 @@ export function buildProviderChain(entries, ctx) {
|
|
|
193
195
|
return { inline, prompts };
|
|
194
196
|
}
|
|
195
197
|
|
|
198
|
+
/**
|
|
199
|
+
* @param {Record<string, number>} tally
|
|
200
|
+
* @param {string} name
|
|
201
|
+
* @param {Finding[]} findings
|
|
202
|
+
*/
|
|
203
|
+
function recordCritical(tally, name, findings) {
|
|
204
|
+
const critical = findings.filter((f) => f?.severity === 'critical').length;
|
|
205
|
+
if (critical > 0) tally[name] = critical;
|
|
206
|
+
}
|
|
207
|
+
|
|
196
208
|
/**
|
|
197
209
|
* Inline findings merge in declaration order; prompt entries render via
|
|
198
210
|
* `getPromptMessages`.
|
|
@@ -201,11 +213,14 @@ export function buildProviderChain(entries, ctx) {
|
|
|
201
213
|
* @param {{ logger?: { info?: Function, warn?: Function } }} [opts]
|
|
202
214
|
* @returns {ReviewProvider & {
|
|
203
215
|
* getPromptMessages: (input: ReviewInput) => Promise<string[]>,
|
|
216
|
+
* getCriticalByProvider: () => Record<string, number>,
|
|
204
217
|
* chain: ProviderChain,
|
|
205
218
|
* }}
|
|
206
219
|
*/
|
|
207
220
|
export function createChainProvider(chain, opts = {}) {
|
|
208
221
|
const logger = opts.logger;
|
|
222
|
+
/** Critical findings per entry from the last `runReview`, for attribution. */
|
|
223
|
+
let criticalByProvider = {};
|
|
209
224
|
|
|
210
225
|
return {
|
|
211
226
|
chain,
|
|
@@ -216,6 +231,7 @@ export function createChainProvider(chain, opts = {}) {
|
|
|
216
231
|
async runReview(input) {
|
|
217
232
|
/** @type {Finding[]} */
|
|
218
233
|
const merged = [];
|
|
234
|
+
criticalByProvider = {};
|
|
219
235
|
const ctx = {
|
|
220
236
|
scope: input?.scope,
|
|
221
237
|
labels: /** @type {ReadonlyArray<string>} */ (
|
|
@@ -236,9 +252,18 @@ export function createChainProvider(chain, opts = {}) {
|
|
|
236
252
|
);
|
|
237
253
|
}
|
|
238
254
|
for (const f of findings) merged.push(f);
|
|
255
|
+
recordCritical(criticalByProvider, entry.name, findings);
|
|
239
256
|
}
|
|
240
257
|
return merged;
|
|
241
258
|
},
|
|
259
|
+
/**
|
|
260
|
+
* Which entries raised the last run's critical findings, and how many.
|
|
261
|
+
*
|
|
262
|
+
* @returns {Record<string, number>}
|
|
263
|
+
*/
|
|
264
|
+
getCriticalByProvider() {
|
|
265
|
+
return { ...criticalByProvider };
|
|
266
|
+
},
|
|
242
267
|
/**
|
|
243
268
|
* Called after `runReview`.
|
|
244
269
|
*
|
|
@@ -24,11 +24,12 @@ export const SECURITY_REVIEW_REMEDIATIONS = Object.freeze({
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Synchronous so a missing CLI surfaces at construction, not mid-review.
|
|
27
|
+
* Shared by every `claude --print` provider.
|
|
27
28
|
*
|
|
28
29
|
* @param {{ spawnFn?: typeof spawnSync }} [opts]
|
|
29
30
|
* @returns {boolean}
|
|
30
31
|
*/
|
|
31
|
-
function
|
|
32
|
+
export function probeClaudeCli(opts = {}) {
|
|
32
33
|
const spawnFn = opts.spawnFn ?? spawnSync;
|
|
33
34
|
try {
|
|
34
35
|
const result = spawnFn('claude', ['--version'], {
|
|
@@ -173,7 +174,7 @@ export function buildUnparseableFallbackFinding() {
|
|
|
173
174
|
* @returns {ReviewProvider}
|
|
174
175
|
*/
|
|
175
176
|
export function createSecurityReviewProvider(deps = {}) {
|
|
176
|
-
const probeFn = deps.probeFn ??
|
|
177
|
+
const probeFn = deps.probeFn ?? probeClaudeCli;
|
|
177
178
|
if (!probeFn()) {
|
|
178
179
|
throw buildSecurityReviewUnavailableError();
|
|
179
180
|
}
|
|
@@ -10,6 +10,7 @@ import { selectAudits } from '../audit-suite/index.js';
|
|
|
10
10
|
import { graduateRetroProposals } from '../feedback-loop/retro-proposals-graduator.js';
|
|
11
11
|
import { gitSpawn } from '../git-utils.js';
|
|
12
12
|
import { Logger } from '../Logger.js';
|
|
13
|
+
import { gatherRunTelemetry } from '../observability/close-telemetry.js';
|
|
13
14
|
import { isEpicTicket } from './epic-container.js';
|
|
14
15
|
import { composeRoutedProposals } from './retro-proposals.js';
|
|
15
16
|
import {
|
|
@@ -657,6 +658,8 @@ async function executeFollowUpRollup({
|
|
|
657
658
|
graduateFn,
|
|
658
659
|
});
|
|
659
660
|
const categories = summarizeSignalCategories(signals);
|
|
661
|
+
// Step result only, never the roll-up comment: telemetry stays local.
|
|
662
|
+
const telemetry = await gatherRunTelemetry(stories, config);
|
|
660
663
|
const proposalCount = proposals.framework.length + proposals.consumer.length;
|
|
661
664
|
const outcome = assessRollupOutcome({
|
|
662
665
|
signalCount: signals.length,
|
|
@@ -687,6 +690,7 @@ async function executeFollowUpRollup({
|
|
|
687
690
|
categories,
|
|
688
691
|
outcome,
|
|
689
692
|
frictionWindow,
|
|
693
|
+
telemetry,
|
|
690
694
|
});
|
|
691
695
|
}
|
|
692
696
|
|
|
@@ -743,6 +747,7 @@ function buildRollupStepResult({
|
|
|
743
747
|
categories,
|
|
744
748
|
outcome,
|
|
745
749
|
frictionWindow,
|
|
750
|
+
telemetry = null,
|
|
746
751
|
}) {
|
|
747
752
|
return {
|
|
748
753
|
kind: 'follow-up-rollup',
|
|
@@ -766,6 +771,7 @@ function buildRollupStepResult({
|
|
|
766
771
|
fingerprint: item.fingerprint ?? null,
|
|
767
772
|
})),
|
|
768
773
|
emptyRollupSuspect: signals.length === 0 && storyCount > 1,
|
|
774
|
+
telemetry,
|
|
769
775
|
};
|
|
770
776
|
}
|
|
771
777
|
|
|
@@ -107,6 +107,7 @@ export function failedTerminalFor(err, args = {}) {
|
|
|
107
107
|
failure: { reason: String(err?.message ?? err) },
|
|
108
108
|
nextCommand: NEXT_COMMANDS.recover(storyId),
|
|
109
109
|
elapsedSeconds: 0,
|
|
110
|
+
phaseDurations: err?.closePhaseDurations ?? undefined,
|
|
110
111
|
});
|
|
111
112
|
} catch (buildErr) {
|
|
112
113
|
Logger.error(
|
|
@@ -56,8 +56,6 @@ async function invokeStoryReviewCore({
|
|
|
56
56
|
prNumber,
|
|
57
57
|
provider,
|
|
58
58
|
runCodeReviewFn,
|
|
59
|
-
runLocalLensReviewFn,
|
|
60
|
-
appendFindingsYieldFn,
|
|
61
59
|
gitSpawnFn,
|
|
62
60
|
progress,
|
|
63
61
|
}) {
|
|
@@ -71,8 +69,6 @@ async function invokeStoryReviewCore({
|
|
|
71
69
|
progressTag: 'REVIEW',
|
|
72
70
|
runCodeReviewFn,
|
|
73
71
|
gitSpawnFn,
|
|
74
|
-
...(runLocalLensReviewFn ? { runLocalLensReviewFn } : {}),
|
|
75
|
-
...(appendFindingsYieldFn ? { appendFindingsYieldFn } : {}),
|
|
76
72
|
});
|
|
77
73
|
}
|
|
78
74
|
|
|
@@ -131,8 +127,6 @@ async function postStoryReviewCrossRef({
|
|
|
131
127
|
* prNumber: number|null,
|
|
132
128
|
* provider: object,
|
|
133
129
|
* runCodeReviewFn: Function,
|
|
134
|
-
* runLocalLensReviewFn?: Function,
|
|
135
|
-
* appendFindingsYieldFn?: Function,
|
|
136
130
|
* gitSpawnFn?: Function,
|
|
137
131
|
* progress: (tag: string, msg: string) => void,
|
|
138
132
|
* }} args
|
|
@@ -140,12 +134,12 @@ async function postStoryReviewCrossRef({
|
|
|
140
134
|
* halted: boolean,
|
|
141
135
|
* skipped?: boolean,
|
|
142
136
|
* severity?: { critical: number, high: number, medium: number, suggestion: number },
|
|
137
|
+
* criticalByProvider?: Record<string, number>,
|
|
143
138
|
* posted?: boolean,
|
|
144
139
|
* postedCommentId?: number|null,
|
|
145
140
|
* degraded?: boolean,
|
|
146
141
|
* degradations?: Array<object>,
|
|
147
142
|
* crossRefPosted?: boolean,
|
|
148
|
-
* localLensReview?: object,
|
|
149
143
|
* }>}
|
|
150
144
|
*/
|
|
151
145
|
export async function runStoryScopeReview({
|
|
@@ -157,8 +151,6 @@ export async function runStoryScopeReview({
|
|
|
157
151
|
prNumber,
|
|
158
152
|
provider,
|
|
159
153
|
runCodeReviewFn,
|
|
160
|
-
runLocalLensReviewFn,
|
|
161
|
-
appendFindingsYieldFn,
|
|
162
154
|
gitSpawnFn,
|
|
163
155
|
progress,
|
|
164
156
|
}) {
|
|
@@ -192,8 +184,6 @@ export async function runStoryScopeReview({
|
|
|
192
184
|
prNumber,
|
|
193
185
|
provider,
|
|
194
186
|
runCodeReviewFn,
|
|
195
|
-
runLocalLensReviewFn,
|
|
196
|
-
appendFindingsYieldFn,
|
|
197
187
|
gitSpawnFn,
|
|
198
188
|
progress,
|
|
199
189
|
});
|
|
@@ -225,10 +215,10 @@ export async function runStoryScopeReview({
|
|
|
225
215
|
return {
|
|
226
216
|
halted: !!result.halted,
|
|
227
217
|
severity: sev,
|
|
218
|
+
criticalByProvider: result.criticalByProvider,
|
|
228
219
|
posted: result.posted,
|
|
229
220
|
postedCommentId: result.postedCommentId ?? null,
|
|
230
221
|
...degradationEnvelope(result.degradations),
|
|
231
222
|
crossRefPosted,
|
|
232
|
-
localLensReview: result.localLensReview,
|
|
233
223
|
};
|
|
234
224
|
}
|