mandrel 1.90.0 → 1.92.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 +5 -5
- package/.agents/docs/SDLC.md +75 -107
- package/.agents/docs/configuration.md +1 -1
- package/.agents/docs/quality-gates.md +8 -7
- package/.agents/docs/workflows.md +4 -10
- package/.agents/instructions.md +2 -2
- package/.agents/schemas/agentrc.schema.json +1 -1
- package/.agents/schemas/lifecycle/README.md +2 -1
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/risk-verdict.schema.json +14 -1
- package/.agents/scripts/README.md +0 -46
- package/.agents/scripts/analyze-execution.js +76 -1
- package/.agents/scripts/check-doc-links.js +3 -0
- package/.agents/scripts/check-workflow-cli-lint.js +208 -0
- package/.agents/scripts/epic-audit-recheck.js +1 -1
- package/.agents/scripts/epic-deliver-preflight.js +37 -1
- package/.agents/scripts/epic-plan-clarity.js +16 -6
- package/.agents/scripts/epic-plan-decompose.js +37 -59
- package/.agents/scripts/epic-plan-healthcheck.js +39 -6
- package/.agents/scripts/epic-plan-spec.js +41 -168
- package/.agents/scripts/epic-reconcile.js +7 -1
- package/.agents/scripts/lib/Logger.js +4 -4
- package/.agents/scripts/lib/audit-suite/index.js +4 -5
- package/.agents/scripts/lib/audit-suite/runner.js +6 -4
- package/.agents/scripts/lib/audit-suite/selector.js +2 -3
- package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
- package/.agents/scripts/lib/command-header.js +20 -0
- package/.agents/scripts/lib/config/github.js +1 -3
- package/.agents/scripts/lib/config-settings-schema.js +4 -3
- package/.agents/scripts/lib/degraded-mode.js +1 -1
- package/.agents/scripts/lib/label-constants.js +18 -3
- package/.agents/scripts/lib/label-taxonomy.js +14 -3
- package/.agents/scripts/lib/mutation/baseline-snapshot.js +7 -6
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +18 -8
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +3 -4
- package/.agents/scripts/lib/orchestration/docs-digest.js +2 -2
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +4 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +22 -12
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +6 -1
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +18 -2
- package/.agents/scripts/{lifecycle-diff.js → lib/orchestration/lifecycle/ledger-diff.js} +10 -76
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +32 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +510 -0
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +177 -0
- package/.agents/scripts/lib/orchestration/plan-metrics.js +445 -0
- package/.agents/scripts/lib/orchestration/plan-persist/amend.js +359 -0
- package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +127 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +978 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +191 -0
- package/.agents/scripts/lib/orchestration/plan-reachability.js +160 -0
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +3 -3
- package/.agents/scripts/lib/orchestration/planning-risk.js +1 -1
- package/.agents/scripts/lib/orchestration/remote-verifier.js +165 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +10 -0
- package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +1 -1
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +11 -2
- package/.agents/scripts/lib/plan-phase-cleanup.js +16 -0
- package/.agents/scripts/lib/presentation/manifest-persistence.js +2 -3
- package/.agents/scripts/lib/templates/spec-author-prompts.js +74 -0
- package/.agents/scripts/plan-context.js +186 -0
- package/.agents/scripts/plan-critics.js +227 -0
- package/.agents/scripts/plan-persist.js +383 -0
- package/.agents/scripts/pr-watch-with-update.js +8 -7
- package/.agents/scripts/run-lint.js +10 -11
- package/.agents/scripts/single-story-init.js +22 -0
- package/.agents/scripts/story-plan.js +19 -7
- package/.agents/scripts/sync-claude-commands.js +10 -5
- package/.agents/skills/core/knowledge-transfer/SKILL.md +11 -7
- package/.agents/workflows/audit-documentation.md +5 -7
- package/.agents/workflows/audit-lighthouse.md +1 -0
- package/.agents/workflows/audit-security.md +1 -0
- package/.agents/workflows/audit-to-stories.md +16 -5
- package/.agents/workflows/deliver.md +8 -0
- package/.agents/workflows/git-deliver.md +76 -243
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/code-review.md +7 -6
- package/.agents/workflows/helpers/deliver-epic.md +16 -4
- package/.agents/workflows/helpers/plan-epic-reference.md +109 -96
- package/.agents/workflows/helpers/plan-epic.md +246 -999
- package/.agents/workflows/helpers/plan-story.md +14 -14
- package/.agents/workflows/helpers/scope-triage-gate.md +6 -4
- package/.agents/workflows/helpers/single-story-deliver.md +13 -4
- package/.agents/workflows/helpers/worktree-lifecycle.md +9 -7
- package/.agents/workflows/mandrel-update.md +144 -466
- package/.agents/workflows/plan.md +73 -143
- package/docs/CHANGELOG.md +20 -0
- package/lib/cli/registry.js +21 -3
- package/package.json +1 -1
- package/.agents/schemas/loop-unit.schema.json +0 -70
- package/.agents/scripts/assert-branch.js +0 -81
- package/.agents/scripts/check-loop-units.js +0 -204
- package/.agents/scripts/detect-merges.js +0 -111
- package/.agents/scripts/git-pr-quality-gate.js +0 -205
- package/.agents/scripts/git-rebase-and-resolve.js +0 -234
- package/.agents/scripts/hierarchy-gate.js +0 -192
- package/.agents/scripts/hydrate-context.js +0 -179
- package/.agents/scripts/lib/loop-units/validate-loop-unit.js +0 -197
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/cli.js +0 -167
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +0 -69
- package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +0 -86
- package/.agents/scripts/loc-delta.js +0 -205
- package/.agents/scripts/render-manifest.js +0 -143
- package/.agents/scripts/run-audit-suite.js +0 -97
- package/.agents/scripts/select-audits.js +0 -155
- package/.agents/scripts/update-mutation-baseline.js +0 -189
- package/.agents/workflows/explain.md +0 -118
- package/.agents/workflows/git-merge-pr.md +0 -377
- package/.agents/workflows/helpers/epic-plan-decompose.md +0 -22
- package/.agents/workflows/helpers/epic-plan-spec.md +0 -22
- package/.agents/workflows/loops/README.md +0 -65
- package/.agents/workflows/loops/fix-failing-tests.md +0 -74
- package/.agents/workflows/loops/nightly-audit.md +0 -81
- package/.agents/workflows/loops/watch-ci.md +0 -68
|
@@ -14,237 +14,97 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
> **Upgrade owner.** The mechanical upgrade is owned end to end by the
|
|
16
16
|
> [`mandrel update`](../../lib/cli/update.js) CLI under the npm distribution
|
|
17
|
-
> model (
|
|
18
|
-
>
|
|
17
|
+
> model (#3436/#3437). This workflow wraps that CLI: it runs
|
|
18
|
+
> `npx mandrel update`, then walks the operator through the
|
|
19
19
|
> **distribution-agnostic judgment steps** the CLI deliberately does **not**
|
|
20
20
|
> perform — config reconciliation, the Epic #1386 quality-gate installs, the
|
|
21
21
|
> permission-allowlist refresh, the consumer-side changelog reconciliation,
|
|
22
22
|
> and the stage-and-commit of the staged lockfile bump.
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- **The version only moves on explicit invocation.** `mandrel update`
|
|
35
|
-
resolves the newest published version and bumps the dependency only when
|
|
36
|
-
you run it. There is no `postinstall` hook and no background drift;
|
|
37
|
-
teammates work against the exact `mandrel` version pinned in the
|
|
38
|
-
consumer's `package-lock.json` until someone runs this workflow and commits
|
|
39
|
-
the result.
|
|
40
|
-
- **CI honours the committed lockfile.** Consumer CI runs `npm ci` against
|
|
41
|
-
the committed `package-lock.json`, so it installs exactly the version the
|
|
42
|
-
lockfile pins — never "whatever the registry's newest is today."
|
|
43
|
-
- **Majors apply like any other bump.** Mandrel ships hard cutovers
|
|
44
|
-
(`.agents/rules/git-conventions.md` § Contract Cutovers), so a major
|
|
45
|
-
crossing is applied directly — the surfaced changelog is the migration
|
|
46
|
-
guide.
|
|
47
|
-
- **The CLI never commits.** The npm bump rewrites `package.json` /
|
|
48
|
-
`package-lock.json` and leaves them **staged on disk** for operator review;
|
|
49
|
-
`mandrel update` performs no `git add` / `git commit`. Staging and
|
|
50
|
-
committing the bump (plus any consumer-side reconciliation) is Step 5 of
|
|
51
|
-
this workflow.
|
|
52
|
-
- **`.agents/workflows/` → `.claude/commands/` projection is delegated.**
|
|
53
|
-
`mandrel update`'s sync step re-materializes `.agents/`, and the only
|
|
54
|
-
authoritative writer of the generated flat command tree
|
|
55
|
-
(`.claude/commands/`) is
|
|
56
|
-
[`sync-claude-commands.js`](../scripts/sync-claude-commands.js), which
|
|
57
|
-
prepends the `<!-- AUTO-GENERATED -->` header. Nothing else copies workflow
|
|
58
|
-
files.
|
|
24
|
+
The upgrade contract, in brief: the version only moves on explicit
|
|
25
|
+
invocation (no `postinstall` drift — teammates track the committed
|
|
26
|
+
lockfile pin, and CI's `npm ci` honours it); majors apply like any other
|
|
27
|
+
bump (Mandrel ships hard cutovers — the surfaced changelog is the
|
|
28
|
+
migration guide); the CLI **never commits** (the lockfile bump is left
|
|
29
|
+
staged for operator review); and the only authoritative writer of the
|
|
30
|
+
generated `.claude/commands/` tree is
|
|
31
|
+
[`sync-claude-commands.js`](../scripts/sync-claude-commands.js), invoked by
|
|
32
|
+
the CLI's sync step.
|
|
59
33
|
|
|
60
34
|
> **Persona**: `devops-engineer` · **Skills**:
|
|
61
35
|
> `core/ci-cd-and-automation`, `core/documentation-and-adrs`
|
|
62
36
|
|
|
63
|
-
**Invocation form.** In a consumer project `mandrel` is a local
|
|
64
|
-
devDependency at `node_modules/.bin/mandrel` and is **not** on `PATH`, so a
|
|
65
|
-
bare `mandrel <subcommand>` fails with `command not found` before any of the
|
|
66
|
-
hardened CLI logic ([`lib/cli/update.js`](../../lib/cli/update.js)) runs.
|
|
67
|
-
Every **runnable** command in this workflow therefore uses the
|
|
68
|
-
`npx mandrel <subcommand>` form, matching [`README.md`](../../README.md).
|
|
69
|
-
Prose that names the CLI as a noun (e.g. "`mandrel update`'s sync step")
|
|
70
|
-
refers to the binary by name, not as a command to type — run it via the form
|
|
71
|
-
Step 0 selects. The exception is a project where `mandrel` is installed
|
|
72
|
-
**globally**: there, the bare form works and Step 0 says so.
|
|
73
|
-
|
|
74
37
|
## Step 0 — Detect the install state and pick the invocation form
|
|
75
38
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
# 1. Globally installed and on PATH?
|
|
81
|
-
command -v mandrel
|
|
82
|
-
# 2. Installed as a local devDependency?
|
|
83
|
-
ls node_modules/.bin/mandrel 2>/dev/null || npm ls mandrel
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Three real states, three routes:
|
|
87
|
-
|
|
88
|
-
| State | Detection | Invocation form |
|
|
89
|
-
| --------------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
|
90
|
-
| **Global install (on `PATH`)** | `command -v mandrel` prints a path | Bare `mandrel <subcommand>` works. |
|
|
91
|
-
| **Local devDependency (not on `PATH`)** | `command -v mandrel` is empty; `node_modules/.bin/mandrel` exists | Use `npx mandrel <subcommand>` (resolves the local bin). |
|
|
92
|
-
| **Not installed** | `command -v mandrel` empty **and** `node_modules/.bin/mandrel` absent | Run `npm install -D mandrel` first, then `npx mandrel`. |
|
|
39
|
+
In a consumer project `mandrel` is usually a local devDependency and **not**
|
|
40
|
+
on `PATH`, so the bare `mandrel <subcommand>` form fails before any CLI
|
|
41
|
+
logic runs. Detect and route:
|
|
93
42
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
43
|
+
- `command -v mandrel` prints a path → global install; the bare form works.
|
|
44
|
+
- `node_modules/.bin/mandrel` exists → local devDependency; use
|
|
45
|
+
`npx mandrel <subcommand>` (the default form the rest of this workflow
|
|
46
|
+
uses — it is harmless on a global install too).
|
|
47
|
+
- Neither → run `npm install -D mandrel` first, then `npx mandrel`.
|
|
99
48
|
|
|
100
49
|
## Step 0.5 — First-run preflight (before any bump)
|
|
101
50
|
|
|
102
|
-
Before running the updater, run the first-run preflight. It catches three
|
|
103
|
-
day-0 failure modes — **wrong project**, a **dirty git index**, and being
|
|
104
|
-
**offline** — before `npx mandrel update` bumps anything. Run from the
|
|
105
|
-
consumer repo root:
|
|
106
|
-
|
|
107
51
|
```bash
|
|
108
52
|
node .agents/scripts/mandrel-update-preflight.js
|
|
109
53
|
```
|
|
110
54
|
|
|
111
|
-
|
|
112
|
-
(`{ ok, blocked, findings[] }`)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Routing:
|
|
127
|
-
|
|
128
|
-
- **Exit 0, `ok: true`** — all checks passed; proceed to Step 1.
|
|
129
|
-
- **Exit 0 with warnings** (`blocked: false`, non-empty `findings[]`) —
|
|
130
|
-
review the warnings. For **dirty-index**, unstage unrelated changes
|
|
131
|
-
(`git restore --staged <path>`) so they are not swept into the
|
|
132
|
-
`chore: update mandrel` commit. For **offline**, restore connectivity
|
|
133
|
-
before the version probe. Then proceed.
|
|
134
|
-
- **Exit 2, `blocked: true`** — the consumer-shape check failed. Stop. You
|
|
135
|
-
are not in a Mandrel consumer project (wrong directory, the framework repo
|
|
136
|
-
itself, or a project that never ran `mandrel sync`). `cd` into the consumer
|
|
137
|
-
repo, or bootstrap one with `npm install -D mandrel && npx mandrel sync`,
|
|
138
|
-
then re-run the preflight.
|
|
139
|
-
|
|
140
|
-
> **Scope.** The preflight is a **workflow-layer** guard; it deliberately
|
|
141
|
-
> lives outside [`lib/cli/update.js`](../../lib/cli/update.js), which stays
|
|
142
|
-
> git-free and side-effect-scoped. It composes cleanly with the Step 0
|
|
143
|
-
> invocation-form detection above — Step 0 picks *how* to call the updater;
|
|
144
|
-
> Step 0.5 verifies it is *safe* to call it at all.
|
|
55
|
+
Catches three day-0 failure modes before anything bumps, printing a JSON
|
|
56
|
+
envelope (`{ ok, blocked, findings[] }`) plus a human-readable report:
|
|
57
|
+
|
|
58
|
+
- **consumer-shape** — **blocker** (exit 2): `package.json` lists `mandrel`
|
|
59
|
+
**and** `.agents/` exists. On failure, STOP — you are not in a consumer
|
|
60
|
+
project (wrong directory, the framework repo itself, or a project that
|
|
61
|
+
never ran `mandrel sync`). `cd` into the consumer repo or bootstrap one
|
|
62
|
+
(`npm install -D mandrel && npx mandrel sync`), then re-run.
|
|
63
|
+
- **dirty-index** — warn-only: pre-existing staged changes would be swept
|
|
64
|
+
into the Step 5 commit; `git restore --staged <path>` the unrelated ones.
|
|
65
|
+
- **offline** — warn-only: `npm ping` fails; restore connectivity before
|
|
66
|
+
the version probe.
|
|
67
|
+
|
|
68
|
+
The preflight is a workflow-layer guard; it deliberately lives outside
|
|
69
|
+
[`lib/cli/update.js`](../../lib/cli/update.js), which stays git-free.
|
|
145
70
|
|
|
146
71
|
## Step 1 — Run the updater
|
|
147
72
|
|
|
148
|
-
Preview first, then apply
|
|
73
|
+
Preview first, then apply, from the consumer repo root:
|
|
149
74
|
|
|
150
75
|
```bash
|
|
151
76
|
npx mandrel update --dry-run
|
|
152
77
|
npx mandrel update
|
|
153
78
|
```
|
|
154
79
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
the daily freshness cache in `temp/version-check.json`) and the currently
|
|
165
|
-
installed version.
|
|
166
|
-
2. **No-op short-circuit** — already on the newest version ⇒ prints
|
|
167
|
-
`Already up to date` and exits 0.
|
|
168
|
-
3. **Install** — bumps the dependency (default
|
|
169
|
-
`npm install mandrel@<target>`; pass
|
|
170
|
-
`--install-cmd "<pm> <args>"` for a pnpm/yarn workspace). The lockfile
|
|
171
|
-
change is left **staged** for review; the CLI never commits.
|
|
172
|
-
4. **runSync** — re-materializes `.agents/` from the freshly installed
|
|
173
|
-
payload, which also regenerates the flat `.claude/commands/` tree via
|
|
174
|
-
`sync-claude-commands.js`.
|
|
175
|
-
5. **runMigrations** — applies any version-keyed migration steps for the
|
|
176
|
-
crossed range.
|
|
177
|
-
6. **doctor** — runs the check registry to verify the resulting install.
|
|
178
|
-
7. **Surface changelog** — prints the `docs/CHANGELOG.md` section(s) covering
|
|
179
|
-
the applied range `(current, target]`. Capture this output — Step 4
|
|
180
|
-
reconciles the consumer's own instructions against it.
|
|
181
|
-
|
|
182
|
-
## Step 2 — Expected output
|
|
183
|
-
|
|
184
|
-
A successful bump ends with:
|
|
185
|
-
|
|
186
|
-
```text
|
|
187
|
-
Updating v1.44.0 → v1.46.0…
|
|
188
|
-
✅ Updated to v1.46.0. The lockfile bump is staged for review.
|
|
189
|
-
|
|
190
|
-
Changelog for v1.46.0:
|
|
191
|
-
## [1.46.0](…)
|
|
192
|
-
### Features
|
|
193
|
-
* new workflow X
|
|
194
|
-
### Bug Fixes
|
|
195
|
-
* tighten Y validation
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
A no-op run (already on the newest version) looks like:
|
|
199
|
-
|
|
200
|
-
```text
|
|
201
|
-
✅ Already up to date (v1.46.0 is the newest version).
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
A `--dry-run` preview looks like:
|
|
205
|
-
|
|
206
|
-
```text
|
|
207
|
-
mandrel update — planned upgrade v1.44.0 → v1.46.0
|
|
208
|
-
1. npm-update
|
|
209
|
-
2. runSync
|
|
210
|
-
3. runMigrations
|
|
211
|
-
4. doctor
|
|
212
|
-
5. surface changelog
|
|
213
|
-
Dry run: no files written, no dependency bumped.
|
|
214
|
-
```
|
|
80
|
+
The dry run resolves the newest published version and prints the ordered
|
|
81
|
+
step plan (`npm-update → runSync → runMigrations → doctor → surface
|
|
82
|
+
changelog`) without touching anything — read the planned target version
|
|
83
|
+
before applying. The live run drives those phases in order, leaves the
|
|
84
|
+
lockfile bump **staged** (never committed), and finishes by printing the
|
|
85
|
+
`docs/CHANGELOG.md` sections covering the applied range `(current, target]`.
|
|
86
|
+
**Capture that changelog output** — Step 4 reconciles the consumer's own
|
|
87
|
+
instructions against it. Already-newest is a clean no-op (`Already up to
|
|
88
|
+
date`, exit 0).
|
|
215
89
|
|
|
216
90
|
## Step 2.5 — Partial-upgrade recovery (**blocker — resolve before Step 5**)
|
|
217
91
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
phase
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
the post-upgrade state failed validation (doctor failed).
|
|
232
|
-
|
|
233
|
-
This is the dangerous case the whole workflow exists to guard: the operator
|
|
234
|
-
is now **one `git commit` away** (Step 5) from recording a broken
|
|
235
|
-
half-upgrade as "done". `mandrel update` prints the per-phase manual remedy
|
|
236
|
-
to **stderr**, but a line buried in stderr is easy to scroll past and commit
|
|
237
|
-
right over. **Treat any post-install phase failure as an explicit blocker:
|
|
238
|
-
do not proceed to Step 5 (commit) until the failed phase is recovered and a
|
|
239
|
-
clean re-run reports success.**
|
|
240
|
-
|
|
241
|
-
When `npx mandrel update` exits non-zero, identify which phase failed (the
|
|
242
|
-
CLI's stderr names it) and run the matching manual remedy from the consumer
|
|
243
|
-
repo root. These commands match the hint strings
|
|
92
|
+
The install phase stages the lockfile bump *before* the later phases run,
|
|
93
|
+
and by deliberate design the CLI **never rolls back the install on
|
|
94
|
+
failure**. So when a post-install phase (`sync` / `sync-commands` /
|
|
95
|
+
`migrate` / `doctor`) exits non-zero you land in a **partially-upgraded
|
|
96
|
+
state**: the bump is already staged while `.agents/` may be
|
|
97
|
+
half-materialized, the command tree out of sync, or a migration partially
|
|
98
|
+
applied — and the operator is one `git commit` away from recording a broken
|
|
99
|
+
half-upgrade as "done". **Treat any post-install phase failure as an
|
|
100
|
+
explicit blocker: do not proceed to Step 5 until the failed phase is
|
|
101
|
+
recovered and a clean re-run reports success.**
|
|
102
|
+
|
|
103
|
+
Identify the failed phase (the CLI's stderr names it) and run the matching
|
|
104
|
+
remedy. These commands match the hint strings
|
|
244
105
|
[`lib/cli/update.js`](../../lib/cli/update.js) emits verbatim — it is the
|
|
245
|
-
single source of truth, kept in lockstep with this table by
|
|
246
|
-
`mandrel-update-recovery-drift`
|
|
247
|
-
([`tests/bootstrap/mandrel-update-recovery-drift.test.js`](../../tests/bootstrap/mandrel-update-recovery-drift.test.js)):
|
|
106
|
+
single source of truth, kept in lockstep with this table by
|
|
107
|
+
[`tests/bootstrap/mandrel-update-recovery-drift.test.js`](../../tests/bootstrap/mandrel-update-recovery-drift.test.js):
|
|
248
108
|
|
|
249
109
|
| Failed phase | Manual remedy |
|
|
250
110
|
| ----------------- | ------------------------------------------------------- |
|
|
@@ -253,9 +113,7 @@ single source of truth, kept in lockstep with this table by the
|
|
|
253
113
|
| **migrate** | `npx mandrel migrate --from <cur> --to <target>` |
|
|
254
114
|
| **doctor** | `npx mandrel doctor` (then apply the per-check remedies) |
|
|
255
115
|
|
|
256
|
-
The exact stderr the CLI prints per failed phase
|
|
257
|
-
[`lib/cli/update.js`](../../lib/cli/update.js) so the table above can never
|
|
258
|
-
drift from what the operator actually sees:
|
|
116
|
+
The exact stderr the CLI prints per failed phase:
|
|
259
117
|
|
|
260
118
|
- **sync** — the .agents/ materialization may be incomplete. Run `mandrel
|
|
261
119
|
sync` manually to restore.
|
|
@@ -266,242 +124,103 @@ drift from what the operator actually sees:
|
|
|
266
124
|
- **doctor** — upgraded to v\<target\> but doctor reported failures. → Run
|
|
267
125
|
`mandrel doctor` for remedies.
|
|
268
126
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
> Substitute the real values the failing run reported.
|
|
272
|
-
|
|
273
|
-
Recovery sequence:
|
|
274
|
-
|
|
275
|
-
1. **Run the matching remedy** for the failed phase from the table above.
|
|
276
|
-
2. **Re-run `npx mandrel update`.** It is idempotent — the install already
|
|
277
|
-
landed, so a clean re-run short-circuits the bump and re-drives the
|
|
278
|
-
post-install phases. Repeat the per-phase remedy until the run reports
|
|
279
|
-
`✅ Updated to v<target>. The lockfile bump is staged for review.` (or
|
|
280
|
-
`✅ Already up to date`).
|
|
281
|
-
3. **Only then proceed** to Step 3. The staged lockfile bump is safe to
|
|
282
|
-
commit (Step 5) once — and only once — the post-install phases have all
|
|
283
|
-
gone green.
|
|
284
|
-
|
|
285
|
-
> **Why not auto-rollback / `mandrel update --resume`?** A `--resume` flag
|
|
286
|
-
> that re-enters the cycle at the failed phase was **evaluated and
|
|
287
|
-
> deferred** (Story #4172, Out of Scope). The per-phase manual remedies
|
|
288
|
-
> above fully cover recovery: each failed phase has an exact, idempotent
|
|
289
|
-
> command, and re-running `npx mandrel update` already short-circuits the
|
|
290
|
-
> completed install and re-drives the remaining phases — so a dedicated
|
|
291
|
-
> resume entrypoint would add a parallel code path without covering any
|
|
292
|
-
> recovery case the manual remedies miss. If a future change makes the
|
|
293
|
-
> phases expensive enough that re-driving completed ones is wasteful,
|
|
294
|
-
> revisit `--resume` then; today it is unnecessary.
|
|
127
|
+
(`<cur>` / `<target>` are the installed and resolved-newest version strings
|
|
128
|
+
the failing run reported.)
|
|
295
129
|
|
|
296
|
-
|
|
130
|
+
Recovery sequence: run the matching remedy, then **re-run
|
|
131
|
+
`npx mandrel update`** — it is idempotent (the install already landed, so a
|
|
132
|
+
clean re-run short-circuits the bump and re-drives the post-install
|
|
133
|
+
phases). Repeat until it reports success; only then proceed. A dedicated
|
|
134
|
+
`--resume` entrypoint was evaluated and deferred (Story #4172) — the
|
|
135
|
+
per-phase remedies plus the idempotent re-run already cover every recovery
|
|
136
|
+
case.
|
|
297
137
|
|
|
298
|
-
|
|
299
|
-
`.agents/docs/agentrc-reference.json` (and the underlying schema). Run the
|
|
300
|
-
reconciliation helper to verify the consumer's `.agentrc.json` still
|
|
301
|
-
validates against the new schema, and to surface any project values that
|
|
302
|
-
already match framework defaults (and could therefore be safely deleted):
|
|
138
|
+
## Step 3 — Reconcile `.agentrc.json` against the new defaults
|
|
303
139
|
|
|
304
140
|
```bash
|
|
305
141
|
node .agents/scripts/sync-agentrc.js
|
|
306
142
|
```
|
|
307
143
|
|
|
308
|
-
The helper (Story #1995) is
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
`.agentrc.json` only bloats the consumer's config diff without
|
|
316
|
-
changing behaviour.
|
|
317
|
-
- Project values that deep-equal the framework default are flagged as
|
|
318
|
-
`[REDUNDANT]` advisory rows — informational only; the file is never
|
|
319
|
-
modified.
|
|
320
|
-
|
|
321
|
-
Full procedure reference:
|
|
144
|
+
The helper (Story #1995) is default-aware and **read-only**: it validates
|
|
145
|
+
the consumer config against the new schema (non-zero exit → fix the
|
|
146
|
+
validation error and re-run before proceeding), never auto-fills missing
|
|
147
|
+
optional keys (the runtime layers defaults at read time), and flags
|
|
148
|
+
project values that deep-equal the framework default as `[REDUNDANT]`
|
|
149
|
+
advisory rows you may optionally delete by hand (commit alongside the bump
|
|
150
|
+
in Step 5). Full procedure:
|
|
322
151
|
[`helpers/mandrel-sync-config.md`](helpers/mandrel-sync-config.md).
|
|
323
152
|
|
|
324
|
-
If the helper prints `No changes required` with no advisories, the config
|
|
325
|
-
is already in sync — carry on. If it lists `[REDUNDANT]` rows, you may
|
|
326
|
-
optionally delete those keys from `.agentrc.json` by hand (commit
|
|
327
|
-
alongside the bump in Step 5) for a leaner config. If it exits non-zero,
|
|
328
|
-
fix the validation error and re-run before proceeding.
|
|
329
|
-
|
|
330
153
|
## Step 3.5 — Upgrade the stabilized-quality-gates surface (Epic #1386)
|
|
331
154
|
|
|
332
|
-
A framework bump that crosses the Epic #1386 boundary requires four
|
|
333
|
-
additive installs on the consumer project so the new gate behaviour is
|
|
334
|
-
actually wired into the consumer's commit / push / CI surfaces. The
|
|
335
|
-
installs share the same idempotent helpers the quality-gates phase of
|
|
336
|
-
[`bootstrap.js`](../scripts/bootstrap.js) uses,
|
|
337
|
-
so a project that already ran the bootstrap on a post-Epic #1386
|
|
338
|
-
framework version sees `no-change` everywhere here.
|
|
339
|
-
|
|
340
|
-
Run from the consumer repo root:
|
|
341
|
-
|
|
342
155
|
```bash
|
|
343
156
|
node .agents/scripts/apply-quality-bootstrap.js
|
|
344
157
|
```
|
|
345
158
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
`
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
3. **`scripts`** — backfills `quality:preview` and `quality:watch` in
|
|
370
|
-
`package.json` only when the keys are absent. Existing operator
|
|
371
|
-
values survive.
|
|
372
|
-
4. **`config`** — seeds `delivery.quality.codingGuardrails` and
|
|
373
|
-
`delivery.quality.autoRefresh` defaults in `.agentrc.json`.
|
|
374
|
-
Only missing keys are written — operator overrides survive.
|
|
375
|
-
|
|
376
|
-
The `baselines-layout-migration` step relocates per-Epic snapshots
|
|
377
|
-
into the `temp/epic/<id>/baselines/` namespace (Story #1467: ephemeral
|
|
378
|
-
scratch state, not committed, reaped on `/deliver` merge with the
|
|
379
|
-
rest of the per-Epic temp tree):
|
|
380
|
-
|
|
381
|
-
- Loose `baselines/epic-<id>-{maintainability,crap}.json` files →
|
|
382
|
-
moved under `temp/epic/<id>/baselines/`.
|
|
383
|
-
- Legacy `baselines/snapshots/<id>/{maintainability,crap}.json` trees →
|
|
384
|
-
re-keyed under `temp/epic/<id>/baselines/`.
|
|
385
|
-
- Committed `baselines/epic/<id>/{maintainability,crap}.json` snapshots
|
|
386
|
-
(the shape Story #1396 introduced) → moved out to
|
|
387
|
-
`temp/epic/<id>/baselines/` and the now-empty committed tree is staged
|
|
388
|
-
for removal via `git rm -r --quiet --ignore-unmatch baselines/epic/<id>`
|
|
389
|
-
so the next commit prunes the tracked tree.
|
|
390
|
-
- The main-tracked `baselines/{maintainability,crap}.json` files at
|
|
391
|
-
the root are **not** touched — they remain the `main`-baseline
|
|
392
|
-
contract for the framework.
|
|
393
|
-
|
|
394
|
-
A second run produces `no-change` on every install path, which is the
|
|
395
|
-
guarantee `mandrel-update`'s idempotence contract requires.
|
|
396
|
-
|
|
397
|
-
## Step 3.6 — Refresh the harness permission allowlist (`/fewer-permission-prompts`)
|
|
398
|
-
|
|
399
|
-
A framework bump frequently introduces new helper scripts and `node
|
|
400
|
-
.agents/scripts/<name>.js` invocations the consumer's
|
|
401
|
-
`.claude/settings.json` allowlist has never seen. Left alone, the next
|
|
402
|
-
`/deliver` or `/deliver` run trips a fresh wave of
|
|
403
|
-
permission prompts that operators answer by hand — and those hand-tuned
|
|
404
|
-
allowlists drift across projects.
|
|
405
|
-
|
|
406
|
-
Run the harness skill that scans recent transcripts and emits an
|
|
407
|
-
additive allowlist patch for `.claude/settings.json`:
|
|
159
|
+
Runs the same idempotent installs the quality-gates phase of
|
|
160
|
+
[`bootstrap.js`](../scripts/bootstrap.js) uses — `applyQualityBootstrap`
|
|
161
|
+
then `migrateBaselinesLayout` — and prints a `{ quality, baselines }` JSON
|
|
162
|
+
envelope. The four quality-bootstrap outcomes: **helper** (materialize
|
|
163
|
+
[`code-quality-guardrails.md`](helpers/code-quality-guardrails.md)),
|
|
164
|
+
**hook** (install the `.husky/pre-commit` diff-scoped `quality:preview`
|
|
165
|
+
invocation — a pre-existing **custom hook is never overwritten silently**;
|
|
166
|
+
the action is `custom-hook-skip` and the helper returns the snippet to
|
|
167
|
+
append by hand), **scripts** (backfill `quality:preview` /
|
|
168
|
+
`quality:watch` only when absent), **config** (seed missing
|
|
169
|
+
`delivery.quality.*` defaults — operator overrides survive). The baselines
|
|
170
|
+
step relocates per-Epic snapshots under `temp/epic/<id>/baselines/`; the
|
|
171
|
+
main-tracked root baselines are never touched. A second run reports
|
|
172
|
+
`no-change` on every path — the idempotence contract this workflow
|
|
173
|
+
requires.
|
|
174
|
+
|
|
175
|
+
## Step 3.6 — Refresh the harness permission allowlist
|
|
176
|
+
|
|
177
|
+
A framework bump frequently introduces new `node .agents/scripts/<name>.js`
|
|
178
|
+
invocations the consumer's `.claude/settings.json` allowlist has never
|
|
179
|
+
seen; left alone, the next delivery run trips a wave of hand-answered
|
|
180
|
+
permission prompts that drift across projects. From the same session that
|
|
181
|
+
ran the update, invoke the harness-supplied skill:
|
|
408
182
|
|
|
409
183
|
```text
|
|
410
184
|
/fewer-permission-prompts
|
|
411
185
|
```
|
|
412
186
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
`.claude/settings.json`) — never removes existing entries.
|
|
421
|
-
|
|
422
|
-
Treat the skill's output as a **PR-reviewable artifact**, not an
|
|
423
|
-
auto-applied change:
|
|
424
|
-
|
|
425
|
-
- Read every proposed entry. Reject anything that grants write
|
|
426
|
-
permissions, network egress, or shells out to a destructive
|
|
427
|
-
command (`rm`, `git push --force`, `gh release delete`, ...).
|
|
428
|
-
- Accept only narrowly-scoped read-only entries
|
|
429
|
-
(`Bash(node .agents/scripts/<name>.js *)`, `Bash(gh issue view *)`,
|
|
430
|
-
`mcp__github__get_*`, etc.).
|
|
431
|
-
- Apply the accepted subset by editing `.claude/settings.json` and
|
|
432
|
-
stage it alongside the version bump in Step 5.
|
|
433
|
-
|
|
434
|
-
The maintenance cadence is **once per `/mandrel-update` invocation** —
|
|
435
|
-
the same operator who just ran `mandrel update` is the one with the
|
|
436
|
-
freshest transcript context to review the proposed allowlist
|
|
437
|
-
diff. Skipping the step is fine when the bump introduces no new
|
|
438
|
-
scripts (the skill will report "no new high-frequency calls"), but the
|
|
439
|
-
step itself is non-optional: silence-by-omission is what produces the
|
|
440
|
-
hand-tuned drift this maintenance is meant to eliminate.
|
|
187
|
+
Treat its output as a **PR-reviewable artifact**, not an auto-applied
|
|
188
|
+
change: reject anything granting write permissions, network egress, or
|
|
189
|
+
destructive shell-outs; accept only narrowly-scoped read-only entries;
|
|
190
|
+
apply the accepted subset to `.claude/settings.json` and stage it alongside
|
|
191
|
+
the bump. The cadence is once per `/mandrel-update` invocation — skipping
|
|
192
|
+
is fine when the bump introduces no new scripts, but the review itself is
|
|
193
|
+
non-optional.
|
|
441
194
|
|
|
442
195
|
## Step 4 — Review the surfaced changelog and update consumer-side guidance
|
|
443
196
|
|
|
444
|
-
Framework upgrades change behaviour the consumer
|
|
445
|
-
`
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
For each changelog entry between the installed and target versions, check
|
|
462
|
-
the consumer repo for guidance that has gone stale or guidance that should
|
|
463
|
-
now exist:
|
|
464
|
-
|
|
465
|
-
1. **Consumer `AGENTS.md` / `CLAUDE.md`.** If the changelog entry
|
|
466
|
-
introduces a new contract the consumer instructions must reflect
|
|
467
|
-
(e.g., "tasks must emit a structured 4-section body", "PRs must
|
|
468
|
-
include `audit-snapshot:`"), update the consumer instructions so a
|
|
469
|
-
fresh agent reading them in isolation produces output that passes
|
|
470
|
-
the framework's new validators. Conversely, remove or rewrite
|
|
471
|
-
instructions that contradict a tightened rule.
|
|
472
|
-
2. **Project-specific runbooks.** If the consumer has its own runbooks
|
|
473
|
-
(e.g., `docs/RUNBOOK.md`, `docs/delivery-runner.md`) that paraphrase
|
|
474
|
-
framework workflows, sweep them for renamed flags / changed exit
|
|
475
|
-
codes / removed scripts.
|
|
476
|
-
|
|
477
|
-
Do not invent updates. If a changelog entry has no consumer-side
|
|
478
|
-
implication, note that explicitly in your scratch and move on — silence
|
|
479
|
-
is a valid review outcome. The goal is to leave the consumer
|
|
480
|
-
instructions and runbooks *consistent* with the new framework version,
|
|
481
|
-
not to manufacture churn.
|
|
482
|
-
|
|
483
|
-
Stage every consumer-side edit alongside the staged lockfile bump so the
|
|
484
|
-
upgrade and the reconciliation land in the same commit (Step 5). A
|
|
485
|
-
reviewer reading the bump should be able to see, in one diff, both
|
|
486
|
-
"the framework version moved" and "what we changed in our own files in
|
|
487
|
-
response."
|
|
197
|
+
Framework upgrades change behaviour the consumer's own `AGENTS.md` /
|
|
198
|
+
`CLAUDE.md` and runbooks often encode. Step 1 already printed the changelog
|
|
199
|
+
for the applied range — that output is your source of truth (re-read the
|
|
200
|
+
transcript or the GitHub Releases page if it scrolled past). For each entry
|
|
201
|
+
between the installed and target versions:
|
|
202
|
+
|
|
203
|
+
1. **Consumer `AGENTS.md` / `CLAUDE.md`.** Update instructions so a fresh
|
|
204
|
+
agent reading them in isolation produces output that passes the
|
|
205
|
+
framework's new validators; remove or rewrite instructions that
|
|
206
|
+
contradict a tightened rule.
|
|
207
|
+
2. **Project-specific runbooks.** Sweep any docs that paraphrase framework
|
|
208
|
+
workflows for renamed flags / changed exit codes / removed scripts.
|
|
209
|
+
|
|
210
|
+
Do not invent updates — silence is a valid review outcome. Stage every
|
|
211
|
+
consumer-side edit alongside the staged lockfile bump so the upgrade and
|
|
212
|
+
the reconciliation land in one reviewable commit.
|
|
488
213
|
|
|
489
214
|
## Step 5 — Commit the bump
|
|
490
215
|
|
|
491
216
|
> **Blocker check before you commit.** The staged lockfile bump is only safe
|
|
492
217
|
> to commit once every post-install phase has gone green. If `npx mandrel
|
|
493
|
-
> update` exited non-zero,
|
|
494
|
-
>
|
|
495
|
-
>
|
|
496
|
-
>
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
`mandrel update` leaves the dependency bump **staged on disk** but never
|
|
500
|
-
commits. After reviewing the surfaced changelog, any `.agentrc.json`
|
|
501
|
-
reconciliation diff from Step 3, the `.claude/settings.json` allowlist
|
|
502
|
-
patch from Step 3.6, and the consumer instruction / runbook updates from
|
|
503
|
-
Step 4, stage and commit the bump (plus the reconciliation and consumer
|
|
504
|
-
edits, if any) from the consumer repo root:
|
|
218
|
+
> update` exited non-zero, resolve it via
|
|
219
|
+
> [Step 2.5 — Partial-upgrade recovery](#step-25--partial-upgrade-recovery-blocker--resolve-before-step-5)
|
|
220
|
+
> **before** the `git commit` below. Committing over a half-upgrade records
|
|
221
|
+
> a broken state as "done".
|
|
222
|
+
|
|
223
|
+
Stage and commit the bump plus everything the wraparound touched:
|
|
505
224
|
|
|
506
225
|
```bash
|
|
507
226
|
git add package.json package-lock.json .agentrc.json .claude/settings.json AGENTS.md # plus any runbook files touched in Step 4
|
|
@@ -515,63 +234,22 @@ Upgraded v<OLD_VERSION> → v<NEW_VERSION> via mandrel update.
|
|
|
515
234
|
```
|
|
516
235
|
|
|
517
236
|
Include the version range and, optionally, the surfaced changelog
|
|
518
|
-
highlights
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
> **Note:** `mandrel update`'s sync step also re-materializes `.agents/`
|
|
525
|
-
> (and the flat command tree under `.claude/commands/`). On the npm
|
|
526
|
-
> distribution `.agents/` is a
|
|
527
|
-
> materialized directory rebuilt from the installed package — whether the
|
|
528
|
-
> consumer commits the regenerated `.agents/` tree, or treats it as a
|
|
529
|
-
> gitignored install artifact rebuilt by `npx mandrel sync`, depends on the
|
|
530
|
-
> consumer's own vendoring policy. Stage the `.agents/` / `.claude/`
|
|
531
|
-
> changes here only if the project commits its materialized tree.
|
|
532
|
-
|
|
533
|
-
## Troubleshooting
|
|
534
|
-
|
|
535
|
-
- **`doctor reported failures: …`** — the dependency bumped and `.agents/`
|
|
536
|
-
re-materialized, but a doctor check failed (and the run exited
|
|
537
|
-
non-zero). This is one shape of the **partial-upgrade** failure mode —
|
|
538
|
-
the lockfile bump is already staged, so it is a **blocker** you MUST
|
|
539
|
-
resolve before the commit step (see
|
|
540
|
-
[Step 2.5 — Partial-upgrade recovery](#step-25--partial-upgrade-recovery-blocker--resolve-before-step-5)).
|
|
541
|
-
Run `npx mandrel doctor` for the per-check remedies; fix the doctor
|
|
542
|
-
finding (often a missing bootstrap install — Step 3.5 — or a stale
|
|
543
|
-
`.agentrc.json` — Step 3), re-run `npx mandrel update` until it reports
|
|
544
|
-
success, and only then commit in Step 5.
|
|
545
|
-
|
|
546
|
-
- **A post-install phase failed (`sync` / `sync-commands` / `migrate`)** —
|
|
547
|
-
the install bumped the lockfile but a later phase exited non-zero, leaving
|
|
548
|
-
a partially-upgraded tree. Do not commit. Run the matching per-phase
|
|
549
|
-
remedy and re-run the updater per
|
|
550
|
-
[Step 2.5 — Partial-upgrade recovery](#step-25--partial-upgrade-recovery-blocker--resolve-before-step-5).
|
|
551
|
-
|
|
552
|
-
- **Install command failed / `npm install … exited <n>`** — the npm
|
|
553
|
-
install step could not bump the dependency (network hiccup, registry
|
|
554
|
-
auth gap, or a peer-dependency conflict). Resolve the underlying npm
|
|
555
|
-
error and re-run `npx mandrel update`; it is idempotent — a clean re-run
|
|
556
|
-
resumes from the resolve step and short-circuits if the install already
|
|
557
|
-
landed.
|
|
558
|
-
|
|
559
|
-
- **Wrong package manager** — the default install is `npm install`. For a
|
|
560
|
-
pnpm or yarn workspace, pass the package manager explicitly:
|
|
561
|
-
`npx mandrel update --install-cmd "pnpm add mandrel@<target>"`.
|
|
562
|
-
The registry probe always stays on `npm view` (a PM-agnostic query); only
|
|
563
|
-
the install seam honours the override.
|
|
237
|
+
highlights. Omit any path whose step was a no-op. Whether the consumer
|
|
238
|
+
commits the re-materialized `.agents/` / `.claude/commands/` trees or
|
|
239
|
+
gitignores them as install artifacts depends on the consumer's own
|
|
240
|
+
vendoring policy — stage them here only if the project commits its
|
|
241
|
+
materialized tree.
|
|
564
242
|
|
|
565
243
|
## Constraints
|
|
566
244
|
|
|
567
|
-
- **Idempotent.** A second `mandrel update`
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
disk and never runs git. The operator reviews the surfaced changelog and
|
|
572
|
-
writes the commit message (Step 5) — the CLI does not know whether the
|
|
573
|
-
bump is release-worthy for the consumer.
|
|
245
|
+
- **Idempotent.** A second `mandrel update` after a successful run hits the
|
|
246
|
+
no-op short-circuit — exit 0, nothing bumped.
|
|
247
|
+
- **No auto-commit.** The CLI leaves the lockfile bump staged and never runs
|
|
248
|
+
git; the operator writes the commit (Step 5).
|
|
574
249
|
- **No framework-side version bump.** This workflow advances the
|
|
575
|
-
*consumer's* pinned
|
|
576
|
-
|
|
577
|
-
|
|
250
|
+
*consumer's* pinned version; framework releases remain the maintainer's
|
|
251
|
+
call via release-please.
|
|
252
|
+
- **Wrong package manager?** The default install seam is `npm install`; for
|
|
253
|
+
a pnpm/yarn workspace pass
|
|
254
|
+
`--install-cmd "pnpm add mandrel@<target>"` (the registry probe stays on
|
|
255
|
+
the PM-agnostic `npm view`).
|