mandrel 2.7.0 → 2.9.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/README.md +104 -330
- package/.agents/agents/auditor.md +135 -0
- package/.agents/agents/plan-critic.md +80 -0
- package/.agents/audit-checklists/dependencies.md +7 -0
- package/.agents/audit-checklists/documentation.md +1 -0
- package/.agents/docs/SDLC.md +69 -162
- package/.agents/docs/configuration.md +159 -499
- package/.agents/docs/quality-gates.md +59 -180
- package/.agents/instructions.md +170 -295
- package/.agents/rules/changelog-style.md +8 -66
- package/.agents/rules/ci-remediation.md +65 -124
- package/.agents/rules/gherkin-standards.md +10 -31
- package/.agents/rules/git-conventions-reference.md +28 -61
- package/.agents/rules/git-conventions.md +1 -1
- package/.agents/rules/orchestration-error-handling.md +5 -15
- package/.agents/rules/security-baseline.md +7 -13
- package/.agents/rules/shell-conventions.md +4 -13
- package/.agents/rules/test-seams.md +2 -2
- package/.agents/rules/testing-standards.md +7 -17
- package/.agents/schemas/agentrc.schema.json +21 -0
- package/.agents/scripts/audit-to-stories.js +51 -0
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +120 -55
- package/.agents/scripts/lib/config-settings-schema.js +32 -0
- package/.agents/scripts/lib/findings/semantic-issue-search.js +43 -5
- package/.agents/scripts/lib/observability/terse-result.js +114 -0
- package/.agents/scripts/lib/orchestration/complexity-gate.js +207 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +3 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +221 -8
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +55 -14
- package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +9 -3
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +4 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +13 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +215 -0
- package/.agents/scripts/lib/story-body/story-body.js +18 -2
- package/.agents/scripts/lib/templates/decomposer-prompts.js +16 -0
- package/.agents/scripts/providers/github/issues.js +54 -7
- package/.agents/scripts/providers/github/search-budget.js +124 -0
- package/.agents/scripts/providers/github/search-query.js +71 -0
- package/.agents/scripts/single-story-confirm-merge.js +14 -5
- package/.agents/scripts/single-story-init.js +19 -3
- package/.agents/scripts/sync-branch-from-base.js +9 -3
- package/.agents/skills/core/api-and-interface-design/SKILL.md +23 -297
- package/.agents/skills/core/api-and-interface-design/reference.md +76 -0
- package/.agents/skills/core/browser-testing-with-devtools/SKILL.md +20 -327
- package/.agents/skills/core/browser-testing-with-devtools/reference.md +74 -0
- package/.agents/skills/core/code-review-and-quality/reference.md +16 -398
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +14 -281
- package/.agents/skills/core/documentation-and-adrs/reference.md +42 -338
- package/.agents/skills/core/git-workflow-and-versioning/SKILL.md +28 -326
- package/.agents/skills/core/idea-refinement/SKILL.md +67 -193
- package/.agents/skills/core/security-and-hardening/SKILL.md +15 -31
- package/.agents/skills/core/security-and-hardening/reference.md +15 -273
- package/.agents/skills/skills.index.json +5 -5
- package/.agents/skills/stack/qa/gherkin-authoring/SKILL.md +16 -222
- package/.agents/skills/stack/qa/gherkin-authoring/reference.md +157 -0
- package/.agents/skills/stack/qa/playwright/SKILL.md +0 -29
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +19 -23
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +35 -53
- package/.agents/skills/stack/qa/vitest/SKILL.md +0 -29
- package/.agents/workflows/audit-accessibility.md +34 -108
- package/.agents/workflows/audit-architecture.md +35 -123
- package/.agents/workflows/audit-clean-code.md +19 -78
- package/.agents/workflows/audit-data-model.md +32 -100
- package/.agents/workflows/audit-dependencies.md +47 -111
- package/.agents/workflows/audit-devops.md +16 -83
- package/.agents/workflows/audit-documentation.md +46 -93
- package/.agents/workflows/audit-navigability.md +26 -80
- package/.agents/workflows/audit-performance.md +40 -106
- package/.agents/workflows/audit-privacy.md +17 -80
- package/.agents/workflows/audit-quality.md +35 -99
- package/.agents/workflows/audit-security.md +20 -78
- package/.agents/workflows/audit-seo.md +20 -98
- package/.agents/workflows/audit-sre.md +20 -88
- package/.agents/workflows/audit-to-stories.md +1 -8
- package/.agents/workflows/audit-ux-ui.md +17 -80
- package/.agents/workflows/deliver.md +54 -9
- package/.agents/workflows/git-cleanup.md +50 -275
- package/.agents/workflows/helpers/audit-lens-core.md +230 -0
- package/.agents/workflows/helpers/code-review.md +11 -23
- package/.agents/workflows/helpers/deliver-story-reference.md +114 -17
- package/.agents/workflows/helpers/deliver-story.md +36 -186
- package/.agents/workflows/helpers/qa-core.md +174 -0
- package/.agents/workflows/helpers/qa-run-scenario-reference.md +35 -0
- package/.agents/workflows/helpers/qa-run-scenario.md +11 -25
- package/.agents/workflows/helpers/worktree-lifecycle.md +6 -67
- package/.agents/workflows/mandrel-update.md +7 -13
- package/.agents/workflows/plan.md +44 -17
- package/.agents/workflows/qa-assist.md +140 -269
- package/.agents/workflows/qa-explore.md +125 -316
- package/.agents/workflows/qa-run.md +180 -380
- package/docs/CHANGELOG.md +30 -0
- package/package.json +1 -1
- package/.agents/workflows/helpers/audit-dual-path.md +0 -59
- package/.agents/workflows/helpers/audit-self-check.md +0 -70
- package/.agents/workflows/helpers/audit-severity-scale.md +0 -19
|
@@ -102,6 +102,10 @@ top-level keys are validation errors.
|
|
|
102
102
|
| `codebaseSnapshot.include` | No | `array<string>` | — | — |
|
|
103
103
|
| `codebaseSnapshot.exclude` | No | `array<string>` | — | — |
|
|
104
104
|
| `codebaseSnapshot.recentCommitWindow` | No | `integer` | — | — |
|
|
105
|
+
| `complexityGate` | No | `object` | — | Plan-time ceremony-lite complexity gate. Routes trivial single-artifact seeds onto a collapsed plan/deliver path; conservative (full on any doubt). Never relaxes the Story-ticket / PR-to-main / repo-gates / security-baseline non-negotiables. |
|
|
106
|
+
| `complexityGate.enabled` | No | `boolean` | — | Master switch. When false, every seed takes the full plan/deliver ceremony. Default true. |
|
|
107
|
+
| `complexityGate.maxSeedWords` | No | `integer` | — | Seed prose word ceiling for the lite path. A seed above this many words is not trivial and takes the full path. Default 60. |
|
|
108
|
+
| `complexityGate.maxArtifacts` | No | `integer` | — | Enumerated-artifact ceiling for the lite path. A seed enumerating more than this many candidate artifacts is multi-capability and takes the full path. Default 1. |
|
|
105
109
|
| `failOnSharedEditors` | No | `boolean` | — | When true, upgrade shared-editor conflict findings to hard errors (default false — advisory soft findings only). |
|
|
106
110
|
| `requireExplicitCrossStoryDeps` | No | `boolean` | — | When true, upgrade implicit cross-Story dependency findings to hard errors (default false — advisory soft findings only). |
|
|
107
111
|
| `failOnRegistryConflicts` | No | `boolean` | — | When true, upgrade cross-cutting registry conflict findings to hard errors (default false). |
|
|
@@ -286,429 +290,150 @@ top-level keys are validation errors.
|
|
|
286
290
|
|
|
287
291
|
<!-- END GENERATED:agentrc -->
|
|
288
292
|
|
|
289
|
-
##
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
`
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
### `
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
|
398
|
-
| `allow_auto_merge` | No | `true` | Enable auto-merge for the repository. |
|
|
399
|
-
| `delete_branch_on_merge` | No | `true` | Delete the source branch after merge. |
|
|
400
|
-
|
|
401
|
-
### `github.notifications`
|
|
402
|
-
|
|
403
|
-
| Field | Required | Default | Purpose |
|
|
404
|
-
| ----------------- | -------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
405
|
-
| `mentionOperator` | No | `false` | When `true`, friction comments @-mention `operatorHandle` for `medium`-severity dispatches (high always @mentions). |
|
|
406
|
-
| `commentEvents` | No | `["state-transition", "story-merged", "operator-message"]` | Allowlist of event names that reach the GitHub ticket comment channel. |
|
|
407
|
-
| `webhookEvents` | No | `["state-transition", "story-merged", "story-closing", "operator-message", "merge.unlanded", "merge.flip-failed", "loop.tick"]` | Allowlist of event names that reach `NOTIFICATION_WEBHOOK_URL`. The vocabulary mirrors the events the v2 runtime actually emits through `notify()`. |
|
|
408
|
-
|
|
409
|
-
Both fields' enums are pinned in the schema and rejected if extended. To
|
|
410
|
-
suppress a channel entirely, set its array to `[]`.
|
|
411
|
-
|
|
412
|
-
> **Severity assignment.** Story state transitions fire `medium`. Blockers
|
|
413
|
-
> and HITL gates fire `high` (webhook prefix `[Action Required]` when an
|
|
414
|
-
> allowlisted blocker event reaches the webhook).
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
## `planning`
|
|
419
|
-
|
|
420
|
-
`/plan` tuning. All fields optional. **Defaults are advisory**, not Story-width
|
|
421
|
-
ceilings: the retired `taskSizing.softFiles` / `hardFiles` file-count gates,
|
|
422
|
-
`planning.modelCapacity` operator knobs, and `maxTokenBudget` envelope are
|
|
423
|
-
gone. Session-mass ceilings live as absolute authored-token constants on
|
|
424
|
-
`DEFAULT_MODEL_CAPACITY` in `ticket-validator-sizing.js` (soft 30k / hard 75k).
|
|
425
|
-
Soft findings are advisory; the hard ceiling rejects only Spec novels, and
|
|
426
|
-
`wide` lifts that rejection. Cohesion / split policy / conflict advisories
|
|
427
|
-
remain the primary sizing signal.
|
|
428
|
-
|
|
429
|
-
| Field | Required | Default | Purpose |
|
|
293
|
+
## Field semantics
|
|
294
|
+
|
|
295
|
+
The generated table above — together with the exhaustive
|
|
296
|
+
[`agentrc-reference.json`](agentrc-reference.json) — is the SSOT for every
|
|
297
|
+
key's name, type, and default. This section adds only the semantics those
|
|
298
|
+
sources cannot capture: accessor gotchas, derived values, extender forms, and
|
|
299
|
+
the operational behaviour behind a handful of keys. It does **not** restate
|
|
300
|
+
names or defaults.
|
|
301
|
+
|
|
302
|
+
### `project`
|
|
303
|
+
|
|
304
|
+
- **`paths` (required).** All three roots are required — the resolver applies
|
|
305
|
+
no code-level fallback, so a missing value is a validation error with a clear
|
|
306
|
+
`instancePath`. `auditOutputDir` is **derived, not configurable**: it
|
|
307
|
+
resolves to `${tempRoot}/audits` (the destination for every `audit-*` report
|
|
308
|
+
and the audit-suite prompt artifacts). Override `tempRoot` to relocate it.
|
|
309
|
+
- **`commands`.** Each string must be non-empty and pass the shell-injection
|
|
310
|
+
guard (`safeString` — disallows `;`, `&`, `|`, backtick, `$`, `<`, `>`).
|
|
311
|
+
`typecheck` is nullable; `null` is the canonical "not applicable for this
|
|
312
|
+
repo" value. Read the block via `getCommands(config)`
|
|
313
|
+
([`config-resolver.js`](../scripts/lib/config-resolver.js)).
|
|
314
|
+
- **`docsContextFiles`.** Entries are **plain filenames, not globs** — each
|
|
315
|
+
resolves to a single file under `paths.docsRoot`. For the decisions log this
|
|
316
|
+
means the **index** `decisions.md` stays the mandatory-read while per-ADR
|
|
317
|
+
bodies under a `decisions/` directory are link-followed on demand (index-only
|
|
318
|
+
by default; there is no `decisions/*.md` glob). See
|
|
319
|
+
[`documentation-and-adrs`](../skills/core/documentation-and-adrs/SKILL.md).
|
|
320
|
+
|
|
321
|
+
### `github`
|
|
322
|
+
|
|
323
|
+
- **`operatorHandle`.** Schema-required but per-contributor: the committed
|
|
324
|
+
`.agentrc.json` carries only the `@[USERNAME]` placeholder, which
|
|
325
|
+
[`normalizeOperatorHandle`](../scripts/lib/orchestration/ticket-lease.js)
|
|
326
|
+
resolves to `null`, making the lease guards fail closed until you set your own
|
|
327
|
+
handle locally (see [Per-machine local overrides](#per-machine-local-overrides)).
|
|
328
|
+
`github.owner` / `repo` are shared and stay committed with real values.
|
|
329
|
+
- **`branchProtection.requiredChecks`.** Each `{ name, cmd[] }` entry is used
|
|
330
|
+
**both** as a required-status-check expectation on the PR and as a local
|
|
331
|
+
close-validation gate invocation.
|
|
332
|
+
- **`notifications`.** Both event allowlists filter their channel
|
|
333
|
+
independently; their enums are pinned in the schema. Set an array to `[]` to
|
|
334
|
+
suppress a channel. The severity vocabulary and shipped default allowlists
|
|
335
|
+
are documented under [`SDLC.md` § Notification system](SDLC.md#notification-system).
|
|
336
|
+
|
|
337
|
+
### `planning`
|
|
338
|
+
|
|
339
|
+
Defaults are **advisory, not Story-width ceilings**. Session-mass ceilings live
|
|
340
|
+
as absolute authored-token constants on `DEFAULT_MODEL_CAPACITY` in
|
|
341
|
+
`ticket-validator-sizing.js` (soft 30k / hard 75k); there is no `maxTokenBudget`
|
|
342
|
+
envelope, and cohesion / split policy / conflict advisories are the primary
|
|
343
|
+
sizing signal. The `codebaseSnapshot` `skinny` tier caps at 250 paths using
|
|
344
|
+
**per-top-level-directory proportional budgeting** (round-robin across matched
|
|
345
|
+
trees) so a large dot-prefixed tree like `.agents/scripts/**` cannot monopolise
|
|
346
|
+
the budget and truncate away the consumer's own source; the shipped `include`
|
|
347
|
+
scans `.agents/scripts/**`, `src/**`, `lib/**`, `app/**`, `packages/**` and
|
|
348
|
+
`exclude` drops `node_modules`, build dirs, and test files. Override `include`
|
|
349
|
+
only when the project's source layout differs.
|
|
350
|
+
|
|
351
|
+
- **`complexityGate`.** Plan-time ceremony-lite routing (Story #4683). The full
|
|
352
|
+
two-session plan/deliver ceremony buys measurable quality on capability-sized
|
|
353
|
+
work but imposes a large fixed cost premium on genuinely trivial
|
|
354
|
+
single-artifact scopes with no measured quality gain. The gate reads the
|
|
355
|
+
planning seed and emits a `complexityRoute` signal on the `/plan` context
|
|
356
|
+
envelope: `lite` collapses the plan/deliver session split and skips the
|
|
357
|
+
fresh-critic / Tech-Spec ceremony a one-artifact scope does not earn; `full`
|
|
358
|
+
keeps the whole ceremony. It is **deterministic and conservative** — `lite`
|
|
359
|
+
only when every trivial-scope signal agrees (seed ≤ `maxSeedWords` words **and**
|
|
360
|
+
≤ `maxArtifacts` enumerated items), and `full` on any doubt (empty seed, over
|
|
361
|
+
the ceiling, multi-capability enumeration, or the gate disabled). The lite path
|
|
362
|
+
**never** relaxes a non-negotiable: it still produces a Story ticket, still
|
|
363
|
+
lands via a PR to `main`, still runs every repo quality gate, and still honours
|
|
364
|
+
`rules/security-baseline.md` — those gates run in `single-story-close.js`
|
|
365
|
+
regardless of route. **Threshold + override:** `enabled` (default `true`;
|
|
366
|
+
`false` forces every seed to `full`), `maxSeedWords` (default `60`), and
|
|
367
|
+
`maxArtifacts` (default `1`). The defaults are the single source of truth on
|
|
368
|
+
`DEFAULT_COMPLEXITY_GATE` in
|
|
369
|
+
[`lib/orchestration/complexity-gate.js`](../scripts/lib/orchestration/complexity-gate.js);
|
|
370
|
+
a malformed or negative ceiling falls back to the default rather than widening
|
|
371
|
+
the lite path.
|
|
372
|
+
|
|
373
|
+
### `delivery`
|
|
374
|
+
|
|
375
|
+
- **`docsFreshness.paths`.** Files refreshed during the post-PR-merge release
|
|
376
|
+
tagging step.
|
|
377
|
+
- **`quality` accessor gotcha.** Internal callers MUST read the quality block
|
|
378
|
+
via `getQuality(config)` where `config` is the full `resolveConfig()` envelope
|
|
379
|
+
(or any object exposing `delivery.quality.*`). Passing a sub-pick like
|
|
380
|
+
`getQuality({ agentSettings })` silently resolves to framework defaults —
|
|
381
|
+
`agentSettings` is not part of the post-Epic-#2880 resolver output. The same
|
|
382
|
+
applies to `getBaselines(config)`.
|
|
383
|
+
- **`quality.gates.<tier>` common shape.** Every gate shares
|
|
384
|
+
`enabled` / `baselinePath` / `tolerance` (`{ kind, value }`) /
|
|
385
|
+
`floors` (`{ <workspace>: { <metric>: <number> } }`) /
|
|
386
|
+
`components` (`{ <component>: [<glob>] }`). The `crap` / `maintainability` /
|
|
387
|
+
`duplication` `targetDirs` default `["src"]`. The `bundle-size` gate has
|
|
388
|
+
**no** `refreshTag` — there is no scorer to regenerate its baseline, so its
|
|
389
|
+
one-shot refresh is the `BUNDLE_SIZE_REFRESH=1` env var, not a config knob
|
|
390
|
+
(see [`quality-gates.md` § Bundle-size ratchet](quality-gates.md#bundle-size-ratchet--one-shot-refreshacknowledge-story-151)).
|
|
391
|
+
Extend the list-valued gate keys with the deep-merge extender form (see
|
|
392
|
+
[How to extend](#how-to-extend)).
|
|
393
|
+
|
|
394
|
+
#### `delivery.worktreeIsolation` — node_modules strategies
|
|
395
|
+
|
|
396
|
+
When `enabled: true`, each Story runs in its own worktree under
|
|
397
|
+
`.worktrees/story-<id>/`, and `nodeModulesStrategy` picks how `node_modules` is
|
|
398
|
+
populated. This is the single home for the strategy trade-offs (README's
|
|
399
|
+
worktree section points here):
|
|
400
|
+
|
|
401
|
+
| Strategy | When to use | Cold-start cost | Notes |
|
|
430
402
|
| --- | --- | --- | --- |
|
|
431
|
-
| `
|
|
432
|
-
| `
|
|
433
|
-
| `
|
|
434
|
-
| `
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
`
|
|
445
|
-
`
|
|
446
|
-
|
|
447
|
-
`
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
| `recentCommitWindow` | No | `30` | Number of recent commits to summarise in the snapshot header. |
|
|
466
|
-
|
|
467
|
-
The shipped `include` default scans `.agents/scripts/**`, `src/**`,
|
|
468
|
-
`lib/**`, `app/**`, and `packages/**`; the shipped `exclude` default drops
|
|
469
|
-
`node_modules`, `dist`, `build`, `.next`, `.turbo`, `coverage`, and
|
|
470
|
-
`*.test.*` / `*.spec.*`. Override only when the project's source layout
|
|
471
|
-
differs.
|
|
472
|
-
|
|
473
|
-
The `skinny` tier caps its file list at 250 paths. When the include set
|
|
474
|
-
matches more than that, the cap is applied with **per-top-level-directory
|
|
475
|
-
proportional budgeting** (round-robin across the matched top-level trees)
|
|
476
|
-
rather than a flat lexicographic slice — so a large, dot-prefixed tree like
|
|
477
|
-
`.agents/scripts/**` can no longer monopolise the budget and truncate away
|
|
478
|
-
the consumer's own `src/` / `lib/` source. When `.agents/scripts/**` is the
|
|
479
|
-
only matching tree (the Mandrel-repo dogfood case), the round-robin
|
|
480
|
-
degenerates to taking the first 250 sorted paths, so that snapshot stays
|
|
481
|
-
useful. When truncation occurs, `/plan` emits an operator-visible warning
|
|
482
|
-
naming the dropped file count and suggesting `tier: "medium"` and/or a
|
|
483
|
-
narrowed `include`. Opt into the richer `medium` tier or narrow `include`
|
|
484
|
-
if the partial skinny view is insufficient.
|
|
485
|
-
|
|
486
|
-
### `planning.navigation`
|
|
487
|
-
|
|
488
|
-
Opt-in. When `routeGlobs` is absent or empty the reachability gate is a
|
|
489
|
-
silent no-op. When configured, a Story that adds a matching route path is
|
|
490
|
-
expected to also touch a `navRegistry` token.
|
|
491
|
-
|
|
492
|
-
| Field | Required | Default | Purpose |
|
|
493
|
-
| ------------- | -------- | ------- | ------- |
|
|
494
|
-
| `routeGlobs` | No | `[]` | Globs marking user-facing route paths. |
|
|
495
|
-
| `navRegistry` | No | `[]` | Tokens identifying the nav-registry SSOT. |
|
|
496
|
-
|
|
497
|
-
---
|
|
498
|
-
|
|
499
|
-
## `delivery`
|
|
500
|
-
|
|
501
|
-
`/deliver` and `/deliver` tuning. All sub-blocks are optional and
|
|
502
|
-
fall back to documented defaults (or are no-ops when omitted).
|
|
503
|
-
|
|
504
|
-
### `delivery.execution`
|
|
505
|
-
|
|
506
|
-
| Field | Required | Default | Purpose |
|
|
507
|
-
| ----------- | -------- | ---------- | ------------------------------------------------------------------ |
|
|
508
|
-
| `timeoutMs` | No | `600000` | Per-spawn timeout (ms) for child processes the framework launches. |
|
|
509
|
-
|
|
510
|
-
> Session-mass ceilings live as absolute authored-token constants on
|
|
511
|
-
> `DEFAULT_MODEL_CAPACITY` in `ticket-validator-sizing.js` (soft 30k / hard
|
|
512
|
-
> 75k). There is no `maxTokenBudget` envelope — cohesion is the primary
|
|
513
|
-
> sizing signal; the numeric backstop only catches Spec novels.
|
|
514
|
-
|
|
515
|
-
### `delivery.docsFreshness`
|
|
516
|
-
|
|
517
|
-
| Field | Required | Default | Purpose |
|
|
518
|
-
| ------- | -------- | ------- | ------------------------------------------------------------- |
|
|
519
|
-
| `paths` | No | `[]` | Files refreshed during the post-PR-merge release tagging step. |
|
|
520
|
-
|
|
521
|
-
### `delivery.deliverRunner`
|
|
522
|
-
|
|
523
|
-
| Field | Required | Default | Purpose |
|
|
524
|
-
| --------------------------- | -------- | ------- | ------------------------------------------------ |
|
|
525
|
-
| `concurrencyCap` | No | `3` | Max ready Stories dispatched by `/deliver` at once. |
|
|
526
|
-
|
|
527
|
-
### `delivery.worktreeIsolation`
|
|
528
|
-
|
|
529
|
-
Story-level worktree isolation. When `enabled: true`, `/deliver` runs
|
|
530
|
-
each Story inside `.worktrees/story-<id>/` instead of moving the main
|
|
531
|
-
checkout's HEAD.
|
|
532
|
-
|
|
533
|
-
| Field | Required | Default | Purpose |
|
|
534
|
-
| ----------------------- | --------------- | ---------------- | ----------------------------------------------------------- |
|
|
535
|
-
| `enabled` | No | `true` | Master switch. |
|
|
536
|
-
| `root` | Conditional | `.worktrees` | Required when `enabled: true`. Worktree parent directory. |
|
|
537
|
-
| `nodeModulesStrategy` | No | `clone` (darwin/linux); `per-worktree` (Windows) | One of `per-worktree`, `clone`, `symlink`, `pnpm-store`. `clone` copy-on-write (reflink/clonefile) clones the donor's `node_modules` and skips the per-tree install on a byte-exact lockfile match, falling back to `per-worktree` on any failure. |
|
|
538
|
-
| `primeFromPath` | No | `null` | Optional source path used to prime `node_modules`. |
|
|
539
|
-
| `allowSymlinkOnWindows` | No | `false` | Permit symlink strategy on Windows (requires admin/dev mode). |
|
|
540
|
-
| `reapOnSuccess` | No | `true` | Reap the worktree after a successful Story close. |
|
|
541
|
-
| `bootstrapFiles` | No | `[".env", ".mcp.json", ".agentrc.local.json", ".agents/instructions.local.md"]` | Untracked files copied into each new worktree (local overrides included). |
|
|
542
|
-
|
|
543
|
-
### `delivery.signals`
|
|
544
|
-
|
|
545
|
-
Friction-detector thresholds consumed by progress-signal listeners.
|
|
546
|
-
|
|
547
|
-
| Field | Required | Default | Purpose |
|
|
548
|
-
| ---------------------- | -------- | ------- | ------------------------------------------------------------------------ |
|
|
549
|
-
| `rework.editsPerFile` | No | (none) | Edits to the same file before a rework signal fires. |
|
|
550
|
-
| `retry.repeatCount` | No | (none) | Identical retried commands before a retry signal fires. |
|
|
551
|
-
|
|
552
|
-
### `delivery.quality`
|
|
553
|
-
|
|
554
|
-
Quality-gate configuration. Lives under `delivery.quality` and uses the
|
|
555
|
-
uniform `gates.<tier>` shape (seven gates: `lint`, `coverage`, `crap`,
|
|
556
|
-
`maintainability`, `mutation`, `lighthouse`, `bundle-size`) introduced by
|
|
557
|
-
Epic #1720 Story #1737.
|
|
558
|
-
|
|
559
|
-
#### `delivery.quality.gateScoping`
|
|
560
|
-
|
|
561
|
-
| Field | Required | Default | Purpose |
|
|
562
|
-
| --------- | -------- | -------- | ------------------------------------------------------------------------------ |
|
|
563
|
-
| `scope` | No | `'full'` | One of `'diff'` (only files changed vs `diffRef`) or `'full'` (all targetDirs). |
|
|
564
|
-
| `diffRef` | No | (none) | Ref used to compute the diff when `scope: 'diff'` (e.g. `main`). |
|
|
565
|
-
|
|
566
|
-
#### `delivery.quality.gates.<tier>` — common shape
|
|
567
|
-
|
|
568
|
-
Every gate shares the same envelope:
|
|
569
|
-
|
|
570
|
-
| Field | Required | Purpose |
|
|
571
|
-
| -------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
|
|
572
|
-
| `enabled` | No | Master switch. `false` makes all three gate sites self-skip for this tier. |
|
|
573
|
-
| `baselinePath` | No | Path to the per-tier ratchet baseline file (e.g. `baselines/crap.json`). |
|
|
574
|
-
| `tolerance` | No | `{ kind: 'absolute' \| 'percent', value: <number> }` — slack permitted when comparing scores against baseline. |
|
|
575
|
-
| `floors` | No | `{ <workspace>: { <metric>: <number> } }` — absolute floors below which the gate fails regardless of baseline. |
|
|
576
|
-
| `components` | No | `{ <component>: [<glob>, ...] }` — optional component-level grouping for breakdown reporting. |
|
|
577
|
-
|
|
578
|
-
Tier-specific knobs:
|
|
579
|
-
|
|
580
|
-
##### `gates.lint`
|
|
581
|
-
|
|
582
|
-
No tier-specific knobs beyond the common shape.
|
|
583
|
-
|
|
584
|
-
##### `gates.coverage`
|
|
585
|
-
|
|
586
|
-
| Field | Required | Default | Purpose |
|
|
587
|
-
| -------------- | -------- | -------------------------------- | -------------------------------------------------------- |
|
|
588
|
-
| `coveragePath` | No | `coverage/coverage-final.json` | Per-method coverage artifact consumed by the gate. |
|
|
589
|
-
| `timeoutMs` | No | `600000` | Wall clock (ms) for `npm run test:coverage` spawned by `coverage-capture.js`. SIGKILL → exit 124 (GNU `timeout` convention) so close-validation can branch on hang-vs-failure. |
|
|
590
|
-
|
|
591
|
-
> **Canonical accessor.** Internal callers MUST read this block via
|
|
592
|
-
> `getQuality(config)` where `config` is the full envelope returned by
|
|
593
|
-
> `resolveConfig()` (or any object that exposes `delivery.quality.*`).
|
|
594
|
-
> Passing a sub-pick such as `getQuality({ agentSettings })` silently
|
|
595
|
-
> resolves to framework defaults — `agentSettings` is not part of the
|
|
596
|
-
> post-Epic-#2880 resolver output and `getQuality` reads only
|
|
597
|
-
> `config?.delivery?.quality`. The same applies to `getBaselines(config)`.
|
|
598
|
-
|
|
599
|
-
##### `gates.crap`
|
|
600
|
-
|
|
601
|
-
| Field | Required | Default | Purpose |
|
|
602
|
-
| ------------------- | ----------- | --------------------------- | ---------------------------------------------------------------- |
|
|
603
|
-
| `targetDirs` | No | `["src"]` | Source dirs to score. Accepts list or `{ append/prepend }` form. |
|
|
604
|
-
| `newMethodCeiling` | No | `30` | Max CRAP score allowed for methods absent from the baseline. |
|
|
605
|
-
| `requireCoverage` | No | `true` | When `true`, methods without coverage are skipped (not failed). |
|
|
606
|
-
| `friction.markerKey`| No | `crap-baseline-regression` | Friction-log marker for regressions. |
|
|
607
|
-
| `refreshTag` | No | `baseline-refresh:` | Subject prefix the refresh-guardrail expects on baseline-only commits. |
|
|
608
|
-
| `refreshTimeoutMs` | No | `60000` | Bounded timeout (ms) for `npm run crap:update` in the baseline-attribution refresh path. SIGKILL → exit 124 → Story `agent::blocked`. |
|
|
609
|
-
|
|
610
|
-
##### `gates.maintainability`
|
|
611
|
-
|
|
612
|
-
| Field | Required | Default | Purpose |
|
|
613
|
-
| ------------------ | -------- | ----------- | ---------------------------------------------------------------- |
|
|
614
|
-
| `targetDirs` | No | `["src"]` | Source dirs to score. Accepts list or `{ append/prepend }` form. |
|
|
615
|
-
| `refreshTimeoutMs` | No | `60000` | Bounded timeout (ms) for `npm run maintainability:update` in the baseline-attribution refresh path. |
|
|
616
|
-
|
|
617
|
-
##### `gates.mutation`
|
|
618
|
-
|
|
619
|
-
| Field | Required | Default | Purpose |
|
|
620
|
-
| -------------------- | -------- | ------- | -------------------------------------------------------- |
|
|
621
|
-
| `strykerConfigPath` | No | `null` | Path to the Stryker config the mutation gate consumes. |
|
|
622
|
-
|
|
623
|
-
##### `gates.lighthouse`
|
|
624
|
-
|
|
625
|
-
| Field | Required | Default | Purpose |
|
|
626
|
-
| --------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
|
|
627
|
-
| `baseUrl` | No | `null` | Base URL Lighthouse audits. |
|
|
628
|
-
| `routes` | No | `[]` | Array of `{ path, formFactor? }` entries, where `formFactor` is `'mobile'` or `'desktop'`. |
|
|
629
|
-
|
|
630
|
-
##### `gates.bundle-size`
|
|
631
|
-
|
|
632
|
-
| Field | Required | Default | Purpose |
|
|
633
|
-
| --------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
|
|
634
|
-
| `bundles` | No | `[]` | Array of `{ name, path, limit }` entries (e.g. `{ "name": "app", "path": "dist/app.js", "limit": "100kB" }`). |
|
|
635
|
-
|
|
636
|
-
Unlike `crap` / `maintainability`, this gate has no `refreshTag` config
|
|
637
|
-
field — there is no scorer to regenerate the baseline from source, so the
|
|
638
|
-
one-shot refresh/acknowledge mechanism is an env var, not a config knob.
|
|
639
|
-
See [`.agents/docs/quality-gates.md` § Bundle-size ratchet](quality-gates.md#bundle-size-ratchet--one-shot-refreshacknowledge-story-151)
|
|
640
|
-
for `BUNDLE_SIZE_REFRESH=1` usage.
|
|
641
|
-
|
|
642
|
-
#### `delivery.quality.formatAutofix`
|
|
643
|
-
|
|
644
|
-
| Field | Required | Default | Purpose |
|
|
645
|
-
| ----------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
646
|
-
| `timeoutMs` | No | (none) | Bounded timeout (ms) for the close-time `npx biome format --write` spawn. SIGKILL maps to exit 124 → Story `agent::blocked`. |
|
|
647
|
-
|
|
648
|
-
#### `delivery.quality.codingGuardrails`
|
|
649
|
-
|
|
650
|
-
| Field | Required | Default | Purpose |
|
|
651
|
-
| ---------------------- | -------- | ------- | ------------------------------------------------------------------ |
|
|
652
|
-
| `cyclomaticFlag` | No | (none) | Cyclomatic-complexity value at which the engineer should refactor. |
|
|
653
|
-
| `cyclomaticMustFix` | No | (none) | Cyclomatic-complexity value that hard-fails the gate. |
|
|
654
|
-
| `requireSiblingTest` | No | (none) | When `true`, a new function requires a sibling test file. |
|
|
655
|
-
|
|
656
|
-
#### `delivery.quality.autoRefresh`
|
|
657
|
-
|
|
658
|
-
Controls Story-close auto-baseline-refresh for gated metrics.
|
|
659
|
-
|
|
660
|
-
| Field | Required | Default | Purpose |
|
|
661
|
-
| ------------- | -------- | ------- | -------------------------------------------------------- |
|
|
662
|
-
| `enabled` | No | (none) | Master switch. |
|
|
663
|
-
| `crapJumpCap` | No | (none) | Max CRAP jump the auto-refresher will absorb before failing. |
|
|
664
|
-
| `scope` | No | (none) | One of `'diff'` or `'full'`. |
|
|
665
|
-
|
|
666
|
-
#### `delivery.quality.baselineEpsilon`
|
|
667
|
-
|
|
668
|
-
Per-kind epsilon (introduced by Story #1964). Sub-epsilon row deltas resolve
|
|
669
|
-
to prior bytes so cross-environment variance does not rewrite the on-disk
|
|
670
|
-
baseline.
|
|
671
|
-
|
|
672
|
-
| Field | Required | Default | Purpose |
|
|
673
|
-
| ----------------- | -------- | ------- | -------------------------------------- |
|
|
674
|
-
| `maintainability` | No | (none) | Epsilon for maintainability rows. |
|
|
675
|
-
| `crap` | No | (none) | Epsilon for CRAP rows. |
|
|
676
|
-
| `coverage` | No | (none) | Epsilon for coverage rows. |
|
|
677
|
-
| `mutation` | No | (none) | Epsilon for mutation rows. |
|
|
678
|
-
| `lint` | No | (none) | Epsilon for lint rows. |
|
|
679
|
-
| `lighthouse` | No | (none) | Epsilon for Lighthouse rows. |
|
|
680
|
-
| `bundle-size` | No | (none) | Epsilon for bundle-size rows. |
|
|
681
|
-
|
|
682
|
-
### `delivery.codeReview`
|
|
683
|
-
|
|
684
|
-
Configuration block for the code-review pipeline that runs during Story
|
|
685
|
-
delivery (`helpers/deliver-story` / `runCodeReview()`). Select providers
|
|
686
|
-
via the `providers[]` chain (generated table above); when unset or empty,
|
|
687
|
-
the factory defaults to `[{ name: "native" }]`. See
|
|
688
|
-
[`.agents/README.md` § Code review providers](../README.md#code-review-providers-pluggable-chain)
|
|
689
|
-
for chain-entry fields (`name`, `scopes`, `optional`, `manualPrompt`, `when`).
|
|
690
|
-
|
|
691
|
-
| Field | Required | Default | Purpose |
|
|
692
|
-
| ------------------ | -------- | ------- | -------------------------------------------------------------------- |
|
|
693
|
-
| `providers` | No | `[{ name: "native" }]` | Review-provider chain. Inline adapters merge `Finding[]`; manual-prompt entries append suggestions. |
|
|
694
|
-
| `providerConfig` | No | `{}` | Optional escape hatch for adapter-specific configuration. Reserved; no documented keys yet. |
|
|
695
|
-
| `maxFixAttempts` | No | `3` | Max auto-fix retry attempts per finding. `0` disables auto-fix. |
|
|
696
|
-
| `maxFixScopeFiles` | No | `5` | Max file count a single auto-fix may modify before escalating to `agent::blocked`. |
|
|
697
|
-
| `autoFixSeverity` | No | `"medium"` | Severity threshold for on-branch remediation (`medium` or `high`). |
|
|
698
|
-
|
|
699
|
-
#### Dual-scope fix budget
|
|
700
|
-
|
|
701
|
-
`maxFixAttempts` and `maxFixScopeFiles` are enforced during the risk-routed
|
|
702
|
-
Story review ceremony using the same configured values for every Story in
|
|
703
|
-
a `/deliver` run. Setting `maxFixAttempts: 0` disables auto-fix; there is
|
|
704
|
-
no per-Story override.
|
|
705
|
-
|
|
706
|
-
### `delivery.feedbackLoop`
|
|
707
|
-
|
|
708
|
-
| Field | Required | Default | Purpose |
|
|
709
|
-
| ----------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
710
|
-
| `auditResultsAutoFile` | No | `true` | When `true`, the deliver finalize path auto-files non-blocking findings from the unified `verification-results` comment as follow-up issues routed by source classification. (The former `codeReviewAutoFile` key was retired with its graduator when Story #4411 unified the pass; a config carrying it fails validation.) |
|
|
711
|
-
| `retroProposals` | No | `true` | When `true`, auto-file the retro's actionable routed proposals as GitHub follow-up issues (Story #4418). |
|
|
403
|
+
| `clone` | **Default on darwin/linux** — copy-on-write clone of donor `node_modules`. | Near-zero on reflink FS. | Falls back to `per-worktree` on unsupported/cross-volume FS. |
|
|
404
|
+
| `per-worktree` | Default on Windows; safe fallback everywhere. | Full `npm ci` per Story. | Independent `node_modules` per worktree. |
|
|
405
|
+
| `symlink` | npm/yarn repos wanting the fast path. **Opt-in.** | Near-zero. | Junctions a donor `node_modules`; refuses on Windows unless `allowSymlinkOnWindows`. |
|
|
406
|
+
| `pnpm-store` | pnpm repos. **Opt-in.** | Fast (store-backed). | `pnpm install --frozen-lockfile` against the shared store. |
|
|
407
|
+
|
|
408
|
+
For `symlink`, also set `primeFromPath` (relative path to the donor worktree
|
|
409
|
+
whose `node_modules/` is reused — `"."` = the root checkout, which must already
|
|
410
|
+
have `node_modules/`; `single-story-init.js` pre-checks this) and, on Windows,
|
|
411
|
+
`allowSymlinkOnWindows: true` (junctions, no admin rights). `single-story-init.js`
|
|
412
|
+
then skips `npm ci` and junctions/symlinks the donor's `node_modules`.
|
|
413
|
+
|
|
414
|
+
#### `delivery.codeReview` — provider chain
|
|
415
|
+
|
|
416
|
+
`providers[]` is iterated in declaration order (unset/empty →
|
|
417
|
+
`[{ name: "native" }]`). Beyond the field list in the generated table: `scopes`
|
|
418
|
+
defaults to both `story` and `epic`; `when` is a label predicate (`when.label`
|
|
419
|
+
/ `when.labelAny`) that silently skips the entry when false; `manualPrompt`
|
|
420
|
+
entries contribute a one-line suggestion and do **not** affect severity counts
|
|
421
|
+
or the `halted` gate. **Cross-runtime contract:** manual-prompt providers emit
|
|
422
|
+
Markdown only and MUST NEVER throw under any host; inline providers that shell
|
|
423
|
+
out to a host-specific binary (e.g. `security-review` →
|
|
424
|
+
`claude --print /security-review`) SHOULD be declared `optional: true` so
|
|
425
|
+
non-Claude consumers can pin the same `.agents/` version unmodified. The fix
|
|
426
|
+
budget (`maxFixAttempts` / `maxFixScopeFiles`) uses the same values for every
|
|
427
|
+
Story in a run — there is no per-Story override.
|
|
428
|
+
|
|
429
|
+
#### `delivery.feedbackLoop` — verification-results auto-graduation
|
|
430
|
+
|
|
431
|
+
`auditResultsAutoFile` auto-graduates surviving non-blocking findings from the
|
|
432
|
+
unified `verification-results` comment into follow-up issues; the graduator
|
|
433
|
+
embeds a content-derived idempotency marker so re-runs skip findings that
|
|
434
|
+
already have an issue (re-enabling after a manual-triage window is safe). The
|
|
435
|
+
former `codeReviewAutoFile` key was retired when Story #4411 unified the pass —
|
|
436
|
+
a config carrying it fails validation; delete it.
|
|
712
437
|
|
|
713
438
|
---
|
|
714
439
|
|
|
@@ -765,18 +490,12 @@ the lint ratchet, and the CRAP/MI gates.
|
|
|
765
490
|
| `baselines/maintainability.json` | `update-maintainability-baseline.js` | `npm run maintainability:update` |
|
|
766
491
|
| `baselines/bundle-size.json` | consumer's own build/measure step | Commit the build's measured sizes; for an intentional growth, run the check with `BUNDLE_SIZE_REFRESH=1` (see [Bundle-size ratchet](quality-gates.md#bundle-size-ratchet--one-shot-refreshacknowledge-story-151)) |
|
|
767
492
|
|
|
768
|
-
These files are the contract
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
default values match the canonical layout above; override only when a
|
|
775
|
-
project genuinely stores baselines elsewhere.
|
|
776
|
-
|
|
777
|
-
The `.agents/state/` directory itself is created on demand by the progress
|
|
778
|
-
reporter; the framework does not require it to exist ahead of time and does
|
|
779
|
-
not commit its contents.
|
|
493
|
+
These files are the contract — read by every gate (Story close, push hook, CI)
|
|
494
|
+
and regenerated only via tagged `baseline-refresh:` commits with a non-empty
|
|
495
|
+
body (see [`quality-gates.md`](quality-gates.md) for the policy). Paths are
|
|
496
|
+
configured in `delivery.quality.gates.<tier>.baselinePath`, defaulting to the
|
|
497
|
+
layout above. The `.agents/state/` directory is created on demand by the
|
|
498
|
+
progress reporter and is not committed.
|
|
780
499
|
|
|
781
500
|
---
|
|
782
501
|
|
|
@@ -999,72 +718,13 @@ move and the allowlist response in the same diff.
|
|
|
999
718
|
|
|
1000
719
|
---
|
|
1001
720
|
|
|
1002
|
-
## CLI subcommand
|
|
1003
|
-
|
|
1004
|
-
`mandrel --help` prints the full subcommand list. Each subcommand that
|
|
1005
|
-
mutates state supports `--dry-run` to preview without writing. The table
|
|
1006
|
-
below covers every dispatch-visible subcommand:
|
|
1007
|
-
|
|
1008
|
-
| Subcommand | What it does | Key flags |
|
|
1009
|
-
| ---------- | ------------ | --------- |
|
|
1010
|
-
| `init` | Install and configure mandrel in the current project. | `--assume-yes`, `--skip-github`, `--dry-run` |
|
|
1011
|
-
| `sync` | Re-materialize `.agents/` from the installed package payload. | `--dry-run`, `--force` |
|
|
1012
|
-
| `sync-commands` | Rebuild `.claude/commands/` from `.agents/workflows/`. | — |
|
|
1013
|
-
| `doctor` | Run readiness checks and report remedies. | — |
|
|
1014
|
-
| `update` | Upgrade mandrel to the newest published version. | `--dry-run`, `--install-cmd` |
|
|
1015
|
-
| `migrate` | Apply version-keyed migrations for a version range. | `--from`, `--to`, `--dry-run` |
|
|
1016
|
-
| `explain` | Print resolved config values with sources. | `--json` |
|
|
1017
|
-
| `uninstall` | Reverse a recorded install using the install ledger. | `--include-github`, `--dry-run` |
|
|
1018
|
-
|
|
1019
|
-
### `mandrel explain`
|
|
1020
|
-
|
|
1021
|
-
Prints every resolved config key — its effective value, its source layer
|
|
1022
|
-
(`[agentrc]` or `[default]`), and a one-line description. Secret-shaped
|
|
1023
|
-
values are shown as `<redacted>`. Useful when debugging unexpected behavior
|
|
1024
|
-
caused by config layering.
|
|
1025
|
-
|
|
1026
|
-
```bash
|
|
1027
|
-
mandrel explain # human-readable report
|
|
1028
|
-
mandrel explain --json # JSON report for scripting
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
### `mandrel sync-commands`
|
|
1032
|
-
|
|
1033
|
-
Regenerates the flat `.claude/commands/` tree from `.agents/workflows/`. Runs
|
|
1034
|
-
automatically at install time (via `prepare`) and as part of `mandrel
|
|
1035
|
-
sync`/`update`; manual invocations are only needed when the commands/ tree is
|
|
1036
|
-
manually deleted or edited by hand. Refuses to project when the materialized
|
|
1037
|
-
`.agents/` tree doesn't match the running CLI's own version.
|
|
1038
|
-
|
|
1039
|
-
```bash
|
|
1040
|
-
mandrel sync-commands
|
|
1041
|
-
```
|
|
1042
|
-
|
|
1043
|
-
### `mandrel sync-agents`
|
|
1044
|
-
|
|
1045
|
-
Regenerates the flat `.claude/agents/` tree from `.agents/agents/` — the
|
|
1046
|
-
role-scoped boot contexts `delivery.routing.roleScopedAgents` (default
|
|
1047
|
-
`true`) dispatches spawns against. Same wiring and version-match refusal as
|
|
1048
|
-
`mandrel sync-commands` above.
|
|
1049
|
-
|
|
1050
|
-
```bash
|
|
1051
|
-
mandrel sync-agents
|
|
1052
|
-
```
|
|
721
|
+
## CLI subcommand reference
|
|
1053
722
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
is preserved; only install-created files and framework additions are removed.
|
|
1060
|
-
GitHub-side state is never acted on automatically; it is surfaced as a
|
|
1061
|
-
manual checklist.
|
|
1062
|
-
|
|
1063
|
-
```bash
|
|
1064
|
-
mandrel uninstall # reverse all local mutations
|
|
1065
|
-
mandrel uninstall --dry-run # preview without writing
|
|
1066
|
-
mandrel uninstall --include-github # acknowledge GitHub-side follow-ups
|
|
1067
|
-
```
|
|
723
|
+
The `mandrel` CLI subcommands (`init`, `sync`, `sync-commands`, `sync-agents`,
|
|
724
|
+
`doctor`, `update`, `migrate`, `explain`, `uninstall`) — what each does, its
|
|
725
|
+
key flags, and the per-subcommand notes — are documented once in
|
|
726
|
+
[`.agents/README.md` § CLI subcommand reference](../README.md#cli-subcommand-reference).
|
|
727
|
+
Run `mandrel --help` for the live list.
|
|
1068
728
|
|
|
1069
729
|
---
|
|
1070
730
|
|