mandrel 2.63.0 → 2.65.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 +3 -2
- package/.agents/agents/auditor.md +3 -2
- package/.agents/agents/plan-critic.md +3 -2
- package/.agents/agents/story-worker.md +2 -2
- 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/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 +8 -2
- 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/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 +13 -29
- 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/generated/agentrc-validator.js +1 -1
- package/.agents/scripts/lib/observability/metrics-ledger.js +0 -72
- package/.agents/scripts/lib/orchestration/ci-red-handling.js +73 -0
- package/.agents/scripts/lib/orchestration/code-review.js +11 -6
- package/.agents/scripts/lib/orchestration/deliver-recover.js +56 -11
- 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/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 +6 -4
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +3 -2
- 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 +0 -12
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +135 -20
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +112 -82
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +72 -5
- 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/templates/decomposer-prompts.js +5 -24
- package/.agents/scripts/pr-watch-with-update.js +13 -19
- package/.agents/scripts/providers/github/issues.js +14 -23
- package/.agents/scripts/sync-claude-agents.js +1 -1
- package/.agents/workflows/audit-quality.md +42 -7
- package/.agents/workflows/helpers/acceptance-self-eval.md +1 -1
- package/.agents/workflows/helpers/code-review.md +15 -38
- package/.agents/workflows/helpers/deliver-reference.md +4 -2
- package/.agents/workflows/helpers/deliver-story.md +3 -0
- package/.agents/workflows/helpers/plan-reference.md +9 -8
- package/.agents/workflows/mandrel-deliver.md +2 -1
- package/.agents/workflows/mandrel-plan.md +10 -7
- package/.agents/workflows/mandrel-update.md +5 -3
- package/docs/CHANGELOG.md +38 -0
- package/lib/cli/claude-code-version.js +73 -0
- package/lib/cli/doctor.js +2 -2
- package/lib/cli/registry.js +9 -0
- 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 +2 -1
- 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
|
@@ -11,6 +11,12 @@ import path from 'node:path';
|
|
|
11
11
|
import { pathToFileURL } from 'node:url';
|
|
12
12
|
import { isCommandExcluded } from '../command-header.js';
|
|
13
13
|
import { detectPackageManager as detectPm } from '../detect-package-manager.js';
|
|
14
|
+
import {
|
|
15
|
+
SYSTEM_PROMPT_BLOCK,
|
|
16
|
+
SYSTEM_PROMPT_ENTRY_DOC,
|
|
17
|
+
SYSTEM_PROMPT_IMPORT,
|
|
18
|
+
wireEntryDoc,
|
|
19
|
+
} from './agents-md-fold.js';
|
|
14
20
|
import { LEDGER_RELATIVE_PATH } from './install-ledger.js';
|
|
15
21
|
import { ensureIssueForms } from './issue-forms-template.js';
|
|
16
22
|
import { PHASE_GROUPS } from './manifest.js';
|
|
@@ -23,17 +29,10 @@ export const SYNC_AGENTS_COMMAND = 'node .agents/scripts/sync-claude-agents.js';
|
|
|
23
29
|
|
|
24
30
|
export const BOOTSTRAP_COMMAND = 'node .agents/scripts/bootstrap.js';
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
export const SYSTEM_PROMPT_IMPORT = '@.agents/instructions.md';
|
|
32
|
+
export { SYSTEM_PROMPT_BLOCK, SYSTEM_PROMPT_IMPORT };
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
${SYSTEM_PROMPT_IMPORT}
|
|
32
|
-
`;
|
|
33
|
-
|
|
34
|
-
export const SYSTEM_PROMPT_CLAUDE_MD = `# Agent Protocols
|
|
35
|
-
|
|
36
|
-
${SYSTEM_PROMPT_BLOCK}`;
|
|
34
|
+
/** Install template for a fresh AGENTS.md (also the legacy CLAUDE.md one). */
|
|
35
|
+
export const SYSTEM_PROMPT_AGENTS_MD = SYSTEM_PROMPT_ENTRY_DOC;
|
|
37
36
|
|
|
38
37
|
export const GITIGNORE_BLOCKS = Object.freeze({
|
|
39
38
|
commands: {
|
|
@@ -420,30 +419,15 @@ export function checkParity(ctx) {
|
|
|
420
419
|
}
|
|
421
420
|
|
|
422
421
|
/**
|
|
423
|
-
* Ensure `
|
|
424
|
-
* never loads on cold start.
|
|
422
|
+
* Ensure `AGENTS.md` imports the system prompt — without it the framework
|
|
423
|
+
* never loads on cold start. A pre-existing `CLAUDE.md` is folded in first
|
|
424
|
+
* (the host would otherwise read it instead). Creates, appends, or no-ops.
|
|
425
425
|
*
|
|
426
426
|
* @param {object} ctx
|
|
427
427
|
* @param {typeof fs} [ctx.fsImpl]
|
|
428
428
|
*/
|
|
429
429
|
export function ensureSystemPromptWiring(ctx) {
|
|
430
|
-
|
|
431
|
-
const target = path.join(ctx.projectRoot, 'CLAUDE.md');
|
|
432
|
-
if (!fsImpl.existsSync(target)) {
|
|
433
|
-
fsImpl.writeFileSync(target, SYSTEM_PROMPT_CLAUDE_MD, 'utf8');
|
|
434
|
-
return { action: 'created', path: target };
|
|
435
|
-
}
|
|
436
|
-
const existing = fsImpl.readFileSync(target, 'utf8');
|
|
437
|
-
if (existing.includes(SYSTEM_PROMPT_IMPORT)) {
|
|
438
|
-
return { action: 'already-present', path: target };
|
|
439
|
-
}
|
|
440
|
-
const separator = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
|
|
441
|
-
fsImpl.writeFileSync(
|
|
442
|
-
target,
|
|
443
|
-
`${existing}${separator}\n${SYSTEM_PROMPT_BLOCK}`,
|
|
444
|
-
'utf8',
|
|
445
|
-
);
|
|
446
|
-
return { action: 'appended', path: target };
|
|
430
|
+
return wireEntryDoc(ctx.projectRoot, ctx.fsImpl);
|
|
447
431
|
}
|
|
448
432
|
|
|
449
433
|
/**
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one default review chain: the factory's unset/empty fallback and the
|
|
3
|
+
* runtime schema's declared default. `code-review` is `optional` so hosts
|
|
4
|
+
* without the `claude` CLI close on `native` alone.
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_REVIEW_PROVIDERS = Object.freeze([
|
|
7
|
+
Object.freeze({ name: 'native' }),
|
|
8
|
+
Object.freeze({
|
|
9
|
+
name: 'code-review',
|
|
10
|
+
scopes: Object.freeze(['story']),
|
|
11
|
+
optional: true,
|
|
12
|
+
}),
|
|
13
|
+
]);
|
|
@@ -140,7 +140,7 @@ const WORKTREE_ISOLATION_SCHEMA = {
|
|
|
140
140
|
const MERGE_WATCH_SCHEMA = {
|
|
141
141
|
type: 'object',
|
|
142
142
|
description:
|
|
143
|
-
"Knobs consumed by the close-and-land merge wait (Story #4543). `mode` (Story #4698) selects the close-time merge posture. `maxWaitSeconds` bounds ONE invocation of the merge wait and its expiry returns a resumable `pending` terminal with no label mutation; `maxBudgetSeconds` bounds the CUMULATIVE wait across resumes (anchored at the PR's createdAt, so a resume does not restart the clock) and exhausting it is the genuine give-up that classifies and blocks. The
|
|
143
|
+
"Knobs consumed by the close-and-land merge wait (Story #4543). `mode` (Story #4698) selects the close-time merge posture. `maxWaitSeconds` bounds ONE invocation of the merge wait and its expiry returns a resumable `pending` terminal with no label mutation; `maxBudgetSeconds` bounds the CUMULATIVE wait across resumes (anchored at the PR's createdAt, so a resume does not restart the clock) and exhausting it is the genuine give-up that classifies and blocks. The poll cadence is internal (at most 30s while checks run, at most 10s once they are green and the PR is unmerged); it and the cap of 3 behind-the-base updates are not configurable.",
|
|
144
144
|
properties: {
|
|
145
145
|
mode: {
|
|
146
146
|
type: 'string',
|
|
@@ -173,7 +173,7 @@ const ROUTING_SCHEMA = {
|
|
|
173
173
|
roleScopedAgents: {
|
|
174
174
|
type: 'boolean',
|
|
175
175
|
description:
|
|
176
|
-
'Epic #4478 (M7-B). Kill-switch for the role-scoped boot contexts. When true (default), a converted delivery spawn (`story-worker`, `acceptance-critic`) boots on its own `.claude/agents/<role>.md` system prompt instead of re-paying the full CLAUDE.md @-import closure. When false, every converted spawn falls back to `subagent_type: general-purpose` — the instant, code-rollback-free per-consumer revert, and the universal escape for hosts that ignore `.claude/agents/`. The fallback is the full-closure agent that ran before M7-B, so flipping it off never drops a gate.',
|
|
176
|
+
'Epic #4478 (M7-B). Kill-switch for the role-scoped boot contexts. When true (default), a converted delivery spawn (`story-worker`, `acceptance-critic`) boots on its own `.claude/agents/<role>.md` system prompt instead of re-paying the full entry-doc (AGENTS.md or CLAUDE.md) @-import closure. When false, every converted spawn falls back to `subagent_type: general-purpose` — the instant, code-rollback-free per-consumer revert, and the universal escape for hosts that ignore `.claude/agents/`. The fallback is the full-closure agent that ran before M7-B, so flipping it off never drops a gate.',
|
|
177
177
|
default: DELIVERY_ROUTING_DEFAULTS.roleScopedAgents,
|
|
178
178
|
},
|
|
179
179
|
ceremonyProfile: {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// live in `config/gates/`.
|
|
5
5
|
|
|
6
6
|
import { GATES_SCHEMA } from './config/gates/index.js';
|
|
7
|
+
import { DEFAULT_REVIEW_PROVIDERS } from './config/review-chain-default.js';
|
|
7
8
|
import { DEFAULT_CODE_REVIEW } from './config/runners.js';
|
|
8
9
|
|
|
9
10
|
const AUTO_REFRESH_SCHEMA = {
|
|
@@ -80,9 +81,15 @@ export const CODE_REVIEW_SCHEMA = {
|
|
|
80
81
|
properties: {
|
|
81
82
|
name: {
|
|
82
83
|
type: 'string',
|
|
83
|
-
enum: [
|
|
84
|
+
enum: [
|
|
85
|
+
'native',
|
|
86
|
+
'code-review',
|
|
87
|
+
'codex',
|
|
88
|
+
'security-review',
|
|
89
|
+
'ultrareview',
|
|
90
|
+
],
|
|
84
91
|
description:
|
|
85
|
-
'Registered provider key. Inline: native, codex, security-review. Manual-prompt: ultrareview.',
|
|
92
|
+
'Registered provider key. Inline: native, code-review, codex, security-review. Manual-prompt: ultrareview.',
|
|
86
93
|
},
|
|
87
94
|
scopes: {
|
|
88
95
|
type: 'array',
|
|
@@ -125,17 +132,8 @@ export const CODE_REVIEW_SCHEMA = {
|
|
|
125
132
|
additionalProperties: false,
|
|
126
133
|
},
|
|
127
134
|
description:
|
|
128
|
-
|
|
129
|
-
default:
|
|
130
|
-
{ name: 'native' },
|
|
131
|
-
{ name: 'security-review', scopes: ['story'], optional: true },
|
|
132
|
-
{
|
|
133
|
-
name: 'ultrareview',
|
|
134
|
-
scopes: ['story'],
|
|
135
|
-
manualPrompt: true,
|
|
136
|
-
when: { label: 'risk::high' },
|
|
137
|
-
},
|
|
138
|
-
],
|
|
135
|
+
"Review-provider chain (Story #2871). When unset or empty, falls back to this default: `native` (scoped lint + MI) then an optional story-scoped `code-review` — a low-effort `claude --print` bug review whose every finding is critical and halts close before auto-merge; hosts without the `claude` CLI skip it. `security-review` and `ultrareview` are opt-in. The orchestrator iterates inline entries in declaration order and merges their Finding[] before posting one structured comment; manual-prompt entries (e.g. ultrareview) contribute a trailing 'Manual review suggestions' section. Selecting an adapter whose probe fails hard-fails at factory construction unless declared `optional: true` in the chain.",
|
|
136
|
+
default: DEFAULT_REVIEW_PROVIDERS,
|
|
139
137
|
},
|
|
140
138
|
autoFixSeverity: {
|
|
141
139
|
type: 'string',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Doc-tier resolver: partition the repo's docs into read-tiers with byte
|
|
3
|
-
* sizes for the context-budget ratchet (`alwaysLoaded` =
|
|
4
|
-
* `@`-import closure; `agentBoot` and `workflowOnDemand` are recorded, not
|
|
3
|
+
* sizes for the context-budget ratchet (`alwaysLoaded` = the host entry
|
|
4
|
+
* doc's `@`-import closure; `agentBoot` and `workflowOnDemand` are recorded, not
|
|
5
5
|
* gated). A path lives only in its highest tier. Emits paths and byte
|
|
6
6
|
* counts, never file contents.
|
|
7
7
|
*/
|
|
@@ -11,9 +11,27 @@ import path from 'node:path';
|
|
|
11
11
|
import { resolveWorkflowClosures } from './workflow-closure.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Claude Code's project-root entry precedence: it reads `CLAUDE.md` when
|
|
15
|
+
* present and falls back to `AGENTS.md` only when `CLAUDE.md` is absent.
|
|
16
|
+
*
|
|
17
|
+
* @type {string[]}
|
|
18
|
+
*/
|
|
19
|
+
const ENTRY_DOC_PRECEDENCE = ['CLAUDE.md', 'AGENTS.md'];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The root entry doc the host loads, or null when neither exists.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} root
|
|
25
|
+
* @param {{ fs?: FsLike }} [opts]
|
|
26
|
+
* @returns {string | null}
|
|
15
27
|
*/
|
|
16
|
-
|
|
28
|
+
function resolveEntryDoc(root, { fs = nodeFs } = {}) {
|
|
29
|
+
return (
|
|
30
|
+
ENTRY_DOC_PRECEDENCE.find((name) =>
|
|
31
|
+
fs.existsSync(path.resolve(root, name)),
|
|
32
|
+
) ?? null
|
|
33
|
+
);
|
|
34
|
+
}
|
|
17
35
|
|
|
18
36
|
/**
|
|
19
37
|
* @type {string[]}
|
|
@@ -89,8 +107,9 @@ function fileEntry(root, rel, fs) {
|
|
|
89
107
|
* @returns {Array<{ path: string, bytes: number }>}
|
|
90
108
|
*/
|
|
91
109
|
export function resolveAlwaysLoadedClosure(root, { fs = nodeFs } = {}) {
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
110
|
+
const entry = resolveEntryDoc(root, { fs });
|
|
111
|
+
if (entry === null) return [];
|
|
112
|
+
const entryAbs = path.resolve(root, entry);
|
|
94
113
|
|
|
95
114
|
const visited = new Set();
|
|
96
115
|
const entries = new Map();
|