@kitschpatrol/shared-config 8.10.1 → 8.12.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.
@@ -0,0 +1,686 @@
1
+ ---
2
+ name: ksc-update
3
+ description: >-
4
+ Update dependencies in kitschpatrol shared config pnpm repositories and
5
+ monorepos with compatible changes, explicitly approved breaking changes, or
6
+ breaking changes for zero-versioned projects. Use when asked to update,
7
+ upgrade, refresh, or audit repository dependencies or GitHub Actions. Applies
8
+ a 24-hour release maturity policy with exceptions for kitschpatrol's packages,
9
+ reviews fresh-install consumer compatibility, validates known consumers,
10
+ minimizes configuration overrides, and recommends a release level.
11
+ Does not commit or release.
12
+ compatibility: Requires Node.js, pnpm/pnpx, curl, jq, git, Bash, and access to npm, GitHub, and upstream release documentation.
13
+ ---
14
+
15
+ # Update dependencies
16
+
17
+ Accept dependency and GitHub Actions updates under the version policy below.
18
+ For projects at 1.0.0 or later, preserve existing contracts: public APIs, CLI
19
+ behavior, outputs, defaults, supported consumer environments, and peer
20
+ compatibility, unless the user explicitly approves a reviewed breaking change.
21
+ Make the migrations accepted updates require. Do not commit, push, tag, publish,
22
+ or release.
23
+
24
+ ## Execution mode
25
+
26
+ Determine the mode before Setup and record it with the reason. Use unattended
27
+ mode when explicitly requested, when `GITHUB_ACTIONS=true` or `CI=true`, or when
28
+ the host cannot receive user replies. Otherwise use interactive mode; a missing
29
+ TTY alone does not establish that an agent session is unattended.
30
+
31
+ In unattended mode, never ask questions, wait for answers, or invoke a command
32
+ that requires an interactive response. Existing explicit approvals still apply;
33
+ silence and CI execution do not grant new approval. This mode overrides every
34
+ instruction below to ask, confirm, or await a decision:
35
+
36
+ - **Projects at 1.0.0 or later:** apply compatible changes and any reviewed
37
+ breaks already explicitly authorized. Defer other breaking candidates and
38
+ report them for a later decision. Judge consumer impact, not dependency
39
+ version labels; a compatible dependency major remains eligible.
40
+ - **Zero-versioned projects:** retain the existing `0.x` allowance in unattended
41
+ runs. Apply reviewed breaking changes, complete their migrations, validate
42
+ the new contracts, and normally recommend a minor release. Do not defer them
43
+ merely because no person is present to approve the break. Other requirements,
44
+ including explicit approval for runtime-range restrictions and Node-types
45
+ changes, still apply.
46
+ - **Other decisions and missing prerequisites:** without prior authorization,
47
+ leave approval-dependent changes unapplied, including range restrictions and
48
+ peer-warning suppressions. Report missing consumer information, credentials,
49
+ permissions, or validation resources instead of requesting them. Continue
50
+ independent work; if a required prerequisite prevents progress, report the
51
+ affected work as blocked or incomplete without waiting or bypassing it.
52
+
53
+ Review and validation remain required in both modes. Defer candidates whose
54
+ impact cannot be established or whose migration cannot be validated. If safe
55
+ updates cannot be isolated without an unapproved change, leave those updates
56
+ unapplied and explain the blocker. Report incompatible releases already allowed
57
+ by published runtime ranges as existing consumer exposure; an older lockfile
58
+ does not resolve that exposure.
59
+
60
+ Produce changes and a report suitable for later PR automation. This skill does
61
+ not create workflows or pull requests, or split work into multiple PRs. If
62
+ nothing can be applied, produce the report without manufacturing a change.
63
+
64
+ ## Policy
65
+
66
+ - **Compatible by default at 1.0.0 or later:** assess the effect on this repository
67
+ and its consumers, not just the dependency's version label. Minor and patch
68
+ updates can break compatibility; a dependency major can still be compatible.
69
+ Present useful breaking candidates with their impact, migration, validation,
70
+ and release implications before asking for approval; apply only within the
71
+ approved scope. Existing explicit approval remains valid. Defer unapproved
72
+ breaks and updates whose impact cannot be established. This includes authored
73
+ packages, production transitives, and workflow actions.
74
+ - **Zero-versioned projects:** if the project's current release version has
75
+ major version zero (`0.x.y`), any breaking change within this update workflow
76
+ is permitted in both interactive and unattended modes, including changes to
77
+ public contracts and consumer Node.js requirements. This exception overrides
78
+ compatibility-preservation requirements below. Use the project's version, not
79
+ the dependency's version; in monorepos,
80
+ assess each affected published package or shared release version, not just a
81
+ private workspace root. Review and report breaking changes, make required
82
+ migrations, and validate the resulting behavior. All other policies still
83
+ apply.
84
+ - **Release maturity:** third-party releases must be at least 24 hours old
85
+ (`--maturity-period 1` for Taze, `--min-age 1` for Actions Up, pnpm
86
+ `minimumReleaseAge` of 1440 minutes). Never disable installation safeguards to
87
+ make an update succeed.
88
+ - **Authored packages:** packages owned by `kitschpatrol` (discovered at runtime
89
+ in Setup) are exempt from maturity and target their latest stable release,
90
+ including majors. The exemption does not bypass security or compatibility
91
+ review.
92
+ - **Consumer ranges:** review the newest published version allowed by each
93
+ runtime dependency's declared range, as well as the lockfile. A fresh consumer
94
+ install can resolve that version even when CI locks an older one. Holding
95
+ back an in-range release requires a genuinely restrictive published range
96
+ (for example, `~1.8.0` instead of `^1.8.0` to exclude `1.9.0`), not just an
97
+ older lockfile entry. Obtain explicit approval before narrowing a runtime
98
+ range to hold a release back, even for a zero-versioned project; explain the
99
+ consumer effect. Do not use local overrides as a substitute for that decision.
100
+ - **TypeScript:** select a compiler within the peer range of the accepted
101
+ `@kitschpatrol/typescript-config` version, intersected with other required
102
+ peers. Do not hard-code a compiler version. Offer the migration when an
103
+ authored major requires a newer compiler; see step 3. If that config is not
104
+ used, follow the project's compiler policy and peer requirements.
105
+ - **Node types:** preserve `@types/node` declarations, including catalogs and
106
+ overrides, unless a reviewed migration has explicit authorization to change
107
+ them. New compiler libraries do not establish runtime API availability.
108
+ - **Package manager:** only Setup manages `packageManager`. Exclude `pnpm`
109
+ from Taze discovery and writes.
110
+ - **No weakening:** do not relax tests, lint rules, type checking, or security
111
+ settings to get a pass; do not blindly accept changed snapshots or generated
112
+ output. Compatibility-preserving lint disables described in step 5 are an
113
+ exception.
114
+ - **No new noise:** every check is compared against the Setup baseline. A new
115
+ warning, deprecation, or peer issue is a finding to trace and report, not
116
+ background noise. Report compatibility-preserving lint disables from step 5;
117
+ ask before silencing other findings.
118
+
119
+ ## Environment
120
+
121
+ Shell variables do not persist between commands. Save anything later steps need
122
+ under `node_modules/.cache/ksc-update/` and pass values literally.
123
+
124
+ Plan network access for `registry.npmjs.org`, `raw.githubusercontent.com`,
125
+ `api.github.com`, and `nodejs.org`; identify any additional upstream hosts as
126
+ needed. Prefer registry metadata and raw changelog files over GitHub API calls
127
+ for package reviews. Cache responses and share them between reviewers.
128
+
129
+ Under Claude Code's sandbox:
130
+
131
+ - **pnpm store:** pnpm 12 cannot take its store lock inside the sandbox
132
+ (`ERR_PNPM_STORE_DIR_OPEN_OPERATION_LOCK`), even with writable store, cache,
133
+ and temp directories. `pnpm install`, `pnpm update`, `pnpm dedupe`,
134
+ `pnpx taze`, and `pnpx actions-up` must be listed in the user's
135
+ `sandbox.excludedCommands` and `permissions.allow`. If the Setup install fails
136
+ this way, stop the affected work and ask the user to add them in interactive
137
+ mode; in unattended mode, report the missing prerequisite. Do not route around
138
+ it. Run these commands bare (no pipes, redirects, or command substitution) so the
139
+ exclusions match. Run each as its own invocation, without `&&` or `||`.
140
+ Save captured tool output to log files in a separate operation.
141
+ - **Proxy:** Node-based tools ignore the proxy variables. If one fails with
142
+ `ENOTFOUND`, rerun it with `NODE_USE_ENV_PROXY=1`.
143
+ - **Sockets:** the `tsx` CLI cannot open its IPC socket. Run the same script
144
+ with `node --import tsx <script>` and report the substitution.
145
+ - **GitHub API:** without `GITHUB_TOKEN`, GitHub allows 60 requests per hour.
146
+ One Actions Up run plus a few release-note lookups can exhaust it. The sandbox
147
+ cannot read `gh` credentials, so budget lookups or ask for a token in
148
+ interactive mode. In unattended mode, report any review blocked by missing
149
+ credentials or exhausted API limits.
150
+ - **JSON output:** pnpm can emit `[WARN]` lines on stdout. Sync `packageManager`
151
+ before parsing pnpm JSON; if warnings remain, save them separately, remove
152
+ only lines beginning with `[WARN]`, and parse the rest strictly. Do not hide
153
+ malformed output or other diagnostics.
154
+ - **Supply-chain settings:** an unreadable global config or `~/.npmrc` can make
155
+ a sandboxed config query return `undefined`; this does not mean the policy is
156
+ disabled. Read accessible workspace settings and record pnpm's successful
157
+ `Lockfile passes supply-chain policies` message from the actual install.
158
+ That message confirms the active checks passed, not the numeric release-age
159
+ threshold. Verify the required 1440 minutes from accessible configuration or
160
+ release timestamps when the effective setting cannot be read. Do not disable
161
+ safeguards or access private config through a workaround.
162
+
163
+ ## Setup
164
+
165
+ 1. Read repository instructions. Note uncommitted changes in the working tree
166
+ and preserve them. If files change during the run that you did not touch,
167
+ leave them alone and report them.
168
+ Read the `Known consumers` section in the project's `CLAUDE.md` or `AGENTS.md`.
169
+ Maintain a short section in the existing instruction file using confirmed
170
+ consumer names, local paths, consumed packages, test commands, and CLI
171
+ fixtures. If none are documented, ask for known consumers in interactive
172
+ mode; in unattended mode, report the missing information and use available
173
+ repository evidence. Continue independent review; do not invent consumers or
174
+ treat example paths as real. Report unavailable consumer validation as a gap.
175
+ 2. Map the workspace: root, every maintained package root, catalogs, overrides,
176
+ `pnpm-workspace.yaml`, Taze config. Exclude fixtures, generated files, and
177
+ dependency directories. Run each step once per shared-lockfile workspace and
178
+ separately in any independent package root. Check Taze config for anything
179
+ that overrides mode, adds maturity exemptions, or auto-writes/installs.
180
+ Record current project and published package versions to determine where the
181
+ zero-versioned exception applies.
182
+ Create the baseline folder and preserve the starting manifests and lockfile
183
+ before the package-manager sync or any other edit.
184
+ 3. Sync `packageManager` before installs and parsed pnpm output. Read the actual
185
+ installed pnpm from an empty directory so the project's stale pin cannot
186
+ select or download another version:
187
+
188
+ ```bash
189
+ pnpm --version
190
+ ```
191
+
192
+ Run that command with a new empty directory under `${TMPDIR:-/tmp}` as its
193
+ working directory. Then edit only the workspace root's `packageManager`
194
+ directly to `pnpm@<observed-version>`, preserving all other manifest fields.
195
+ Use the editor or a structured JSON edit, not `pnpm pkg set`; use direct
196
+ edits for later specifiers and engines too. pnpm commands can trigger
197
+ version-manager downloads after the pin changes. If this crosses a pnpm
198
+ major, report it and verify the CI installer supports the selected version.
199
+
200
+ 4. Install the starting dependency declarations and record a baseline before
201
+ dependency updates. Keep the original files saved in Setup 2 even if
202
+ installation fails.
203
+
204
+ ```bash
205
+ pnpm install --frozen-lockfile
206
+ ```
207
+
208
+ On `ERR_PNPM_OUTDATED_LOCKFILE` only, run this as a separate bare command:
209
+
210
+ ```bash
211
+ pnpm install --no-frozen-lockfile
212
+ ```
213
+
214
+ Save the lockfile diff against the starting copy in the baseline folder and
215
+ report the drift. Treat checks after repair as the repaired baseline, not as
216
+ proof that the original locked tree passed. Other installation failures need
217
+ their own diagnosis; do not generalize this fallback or relax safeguards.
218
+
219
+ Save the output of each install attempt and of `pnpm build`, `pnpm test`, and
220
+ `pnpm lint` to `node_modules/.cache/ksc-update/baseline/`. If the repository
221
+ produces build output (`dist/` or similar), copy it there as well. Use the
222
+ repository's switches to disable nondeterministic build steps (encryption,
223
+ timestamps) and note the exact command and environment; later comparison
224
+ builds must match them. Baseline failures are pre-existing; record them.
225
+
226
+ Record each published package's declared `engines.node`, effective consumer
227
+ Node.js minimum and supported range, and separate development requirement.
228
+ Include published dependency trees and built artifacts, not just the root
229
+ manifest or current CI runtime. If no Node.js support policy is declared,
230
+ establish the existing requirement from the published code and dependencies;
231
+ do not assume the developer's Node.js version is the consumer minimum.
232
+ Save production-tree engine inventories and baseline consumer results using
233
+ [the verification recipes](references/verification.md). Distinguish the
234
+ starting locked tree, the newest versions a fresh consumer install can
235
+ resolve, and the published release with its old dependencies when available.
236
+
237
+ 5. Discover authored packages:
238
+
239
+ ```bash
240
+ set -euo pipefail
241
+ mkdir -p node_modules/.cache/ksc-update
242
+ curl -fsS https://registry.npmjs.org/-/user/kitschpatrol/package \
243
+ | jq -er 'keys | join(",") | select(length > 0)' \
244
+ > node_modules/.cache/ksc-update/authored-packages.txt
245
+ ```
246
+
247
+ If registry discovery fails or returns empty, stop and report. Intersect the
248
+ result with direct dependency names across the maintained manifests in this
249
+ workspace, including dev, optional, and peer dependencies and dependencies
250
+ using catalogs or npm aliases. Save the intersection separately; an empty
251
+ intersection is valid. `<authored-packages>` below means only those exact
252
+ matching names, comma-separated and passed literally, with no wildcards.
253
+ Omit `--maturity-period-exclude` if the intersection is empty. Keep the full
254
+ ownership list only for evaluating other packages encountered later.
255
+
256
+ ## 1. Workflow actions
257
+
258
+ ```bash
259
+ pnpx actions-up --yes --min-age 1 --style sha
260
+ ```
261
+
262
+ Read the whole output. Actions Up can print "All actions are up to date!" after
263
+ checks failed; any `Skipped`, `Failed`, or `Rate Limit` line means the run is
264
+ incomplete. Fix the cause and rerun.
265
+
266
+ Review the diff: major action bumps, runner, input, output, and permission
267
+ changes. Every external GitHub Action and reusable workflow must be pinned to
268
+ its full commit SHA, including `kitschpatrol/*`; retain version comments for
269
+ readability. Do not exclude first-party actions from pinning or allow their
270
+ floating refs in zizmor's `unpinned-uses` policy. Resolve skipped branch/tag
271
+ refs and unchanged versions to verified commits too; if an update is deferred,
272
+ pin the retained version. Check existing zizmor configuration for exceptions
273
+ that contradict this policy. Pin container actions by digest; local `./` actions
274
+ use the checked-out tree. Keep only reviewed changes without disturbing user
275
+ edits. Local tests say nothing about remote workflows.
276
+
277
+ ## 2. Discover all candidates (read-only)
278
+
279
+ ```bash
280
+ pnpx taze major -r --force --include-locked \
281
+ --no-github-actions --no-node-version \
282
+ --exclude '@types/node,pnpm' \
283
+ --maturity-period 1 \
284
+ --maturity-period-exclude '<authored-packages>'
285
+ ```
286
+
287
+ Major mode lists every available update, minor and major. Confirm authored
288
+ packages are offered their latest stable release, not the latest within their
289
+ current major. Do not opt into new prerelease channels. Taze's newest candidate
290
+ does not replace the separate newest-in-range runtime review in step 3.
291
+
292
+ ## 3. Evaluate candidates
293
+
294
+ ### Runtime ranges and review scope
295
+
296
+ For each runtime dependency of a published package, inspect registry metadata
297
+ for the newest stable version satisfying its current declared range, accounting
298
+ for catalogs and aliases. Record declared range, locked version, newest allowed
299
+ version, and proposed range/version. Review that newest allowed release even
300
+ if it is already in range or too young for this run to install; consumer
301
+ package managers may not enforce this repository's maturity policy. Keep the
302
+ installation safeguards and report any untested consumer exposure.
303
+
304
+ Review direct candidates and production-tree changes fully. For development-only
305
+ transitives, check advisories, deprecations, and engines; investigate release
306
+ notes only when those checks, validation failures, or output differences give
307
+ cause. A package bundled or shipped with a CLI/config package belongs to the
308
+ consumer review even if this repository also uses it as development tooling.
309
+
310
+ An in-range behavior change may already reach the published release's consumers.
311
+ Do not describe an older lockfile as protecting them or infer a new breaking
312
+ release solely from the lockfile movement. Test the published release and
313
+ updated build against actual consumer resolution, and separately preserve the
314
+ old locked baseline. To hold back an incompatible allowed release, present a
315
+ specific narrower range and obtain the policy's required approval.
316
+
317
+ ### Breaking candidates
318
+
319
+ Track breaking-candidate decisions throughout the run; report applied breaks
320
+ and deferred opportunities separately.
321
+ For each candidate, identify affected APIs, behavior, Node.js support, known
322
+ consumers, migration work, validation results or gaps, and release implications.
323
+ Prepare a concrete proposal and, where useful, validate a trial migration in an
324
+ isolated copy before seeking a decision. For stable projects in interactive
325
+ mode, ask explicitly whether to accept each reviewed break unless that exact
326
+ scope was already authorized; continue independent updates while awaiting the
327
+ answer. In unattended mode, defer unapproved stable-project breaks and include
328
+ them under `Breaking changes available` in the report without asking. General
329
+ permission to update dependencies is not approval for an unspecified break.
330
+ For `0.x` projects, both modes authorize reviewed breaking migrations without
331
+ another question, but runtime-range narrowing still needs explicit approval.
332
+ Record accepted, declined, pending, and deferred decisions separately.
333
+
334
+ ### Node.js compatibility
335
+
336
+ For every candidate, minor and patch included, distinguish consumer requirements
337
+ from development requirements:
338
+
339
+ - **Consumers:** for projects at 1.0.0 or later, keep the user-facing Node.js
340
+ minimum and supported range unchanged unless explicitly approved under
341
+ `Breaking candidates`. A higher effective consumer minimum or loss of any
342
+ supported Node.js version is a break even if `engines.node` is left unchanged.
343
+ Check direct, transitive, optional, peer, and workspace dependencies used by
344
+ published packages, plus bundled code, emitted syntax, and runtime APIs.
345
+ A tool used only for development here is still a consumer dependency if it
346
+ ships in a published CLI or configuration package. Compare
347
+ full engine ranges, not just the lowest version in each range.
348
+ For authorized breaks or zero-versioned projects, update published
349
+ `engines.node` to reflect the actual supported range and validate against it.
350
+ - **Development:** a higher Node.js requirement for development-only tools,
351
+ builds, or CI is allowed when published artifacts remain compatible. If it
352
+ exceeds the consumer requirement, add or update the Node.js entry in the
353
+ relevant `package.json`'s `devEngines.runtime` with `name: "node"` and a
354
+ `version` range covering the actual development requirement. Use the workspace
355
+ root for shared tooling and package manifests for package-specific tooling;
356
+ preserve other runtime entries and settings. This is the development Node.js
357
+ dependency notice; do not raise published `engines.node` to satisfy dev tools.
358
+ Align development version pins and build CI as needed while retaining consumer
359
+ compatibility checks at the applicable supported minimums (the original ones
360
+ unless an approved break or the zero-versioned exception changes them).
361
+
362
+ ### TypeScript migrations
363
+
364
+ Read the accepted `@kitschpatrol/typescript-config` release's TypeScript peer
365
+ range and base configuration. If it requires a new compiler major, offer that
366
+ migration with its concrete effects rather than automatically deferring the
367
+ authored update. Apply it within existing authorization; ask only for additional
368
+ breaking or Node-types changes that the policy actually requires approval for.
369
+
370
+ - Add `"node"` to `compilerOptions.types` where Node globals are needed,
371
+ preserving other required type entries and the separation from browser code.
372
+ - Fix errors exposed by newly enabled strict options; do not disable those
373
+ options just to pass.
374
+ - Check the new base `lib`, emitted syntax, declarations, and APIs used by
375
+ shipped code against the consumer Node.js floor and browser targets. A newer
376
+ `lib` can make unavailable APIs type-check; it does not polyfill them.
377
+
378
+ Run type checks, build, and consumer validation after the migration, retaining
379
+ the distinction between development and consumer Node.js requirements.
380
+
381
+ ### Compatibility review
382
+
383
+ For direct candidates and production-tree changes, read relevant upstream
384
+ release notes, migration guides, and advisories, and assess:
385
+
386
+ - **Security:** vulnerabilities fixed or introduced, ownership or publishing
387
+ anomalies, new install scripts or permissions.
388
+ - **Breaking:** APIs, types, defaults, configuration, module format, peer
389
+ ranges, runtime requirements, measured against this repository's actual use.
390
+ - **Coupling:** peer and engine requirements against the versions this update
391
+ will produce, not the current ones. A major can require a newer minor of a
392
+ sibling package (`@astrojs/mdx` 8 requires `astro` 7.2.10 or later).
393
+ - **Worth it:** fixes and performance adoptable under the version policy.
394
+ Note features exposed by the update and optional feature opportunities for the
395
+ report; do not implement new features as extra work.
396
+
397
+ When delegation is available, run independent release-note reviews in parallel,
398
+ split into authored packages, remaining runtime packages, and remaining direct
399
+ development packages. Give each reviewer its disjoint package list, a short
400
+ survey of actual usage and relevant source paths, consumer requirements, and
401
+ the version policy. Reviewers return decisions and sources without editing
402
+ dependencies; the primary agent resolves coupling and combines the results.
403
+ Share cached metadata and the GitHub API budget. Review sequentially when
404
+ delegation is unavailable.
405
+
406
+ Record current → proposed version, decision, and sources. Accept only when
407
+ compatibility is preserved, an explicit approval covers the break, or the
408
+ zero-versioned exception permits it; defer the rest with a reason. Do not
409
+ defer a migration merely because it needs a major release recommendation.
410
+
411
+ ## 4. Apply
412
+
413
+ Apply only accepted candidates, including minors and patches, by exact package
414
+ name. Major mode can apply all accepted update sizes:
415
+
416
+ ```bash
417
+ pnpx taze major -rw --force --include-locked \
418
+ --no-github-actions --no-node-version \
419
+ --include 'pkg-a,pkg-b' \
420
+ --exclude '@types/node,pnpm' \
421
+ --maturity-period 1 \
422
+ --maturity-period-exclude '<authored-packages>'
423
+ ```
424
+
425
+ Replace the example names with the accepted set; skip the command if it is
426
+ empty. If only an older compatible target was accepted, set that reviewed
427
+ version manually instead of letting Taze choose the latest. Then check the
428
+ diff: every manifest and catalog covered, only reviewed versions applied, no
429
+ excluded or deferred update slipped in, range style and `workspace:` references
430
+ intact. A package accepted in one workspace package is not automatically
431
+ accepted in every other one. Hand-edit anything Taze missed (catalogs,
432
+ overrides), and add any required development Node.js notice. Use direct edits
433
+ for reviewed compiler versions inside the required peer range and for
434
+ authorized Node-types changes; do not let Taze choose an incompatible compiler.
435
+ Verify `packageManager` remains at Setup's selected version.
436
+
437
+ ## 5. Resolve and validate
438
+
439
+ Run each command as a separate invocation:
440
+
441
+ ```bash
442
+ pnpm update -r
443
+ ```
444
+
445
+ ```bash
446
+ pnpm dedupe --check
447
+ ```
448
+
449
+ Inspect the result. If it reports available deduplication, run the following
450
+ separately; other failures need diagnosis, not an unconditional retry:
451
+
452
+ ```bash
453
+ pnpm dedupe
454
+ ```
455
+
456
+ Then run the checks, each separately:
457
+
458
+ ```bash
459
+ pnpm build
460
+ pnpm fix
461
+ pnpm build # only if fix changed source files
462
+ pnpm test
463
+ pnpm lint
464
+ ```
465
+
466
+ Always use bare `pnpm update -r` for the full refresh, without package selectors.
467
+ Named-package updates do not provide the same transitive refresh; do not use
468
+ `!pkg` selectors as a workaround for deferred candidates. It resolves within
469
+ the written ranges and rechecks release age without discarding `node_modules`.
470
+ In pnpm 12 it can also raise range floors in `package.json` and catalogs
471
+ (for example, `^1.8.0` to `^1.9.0`), so review the manifest and catalog diffs
472
+ after every update, not just the lockfile. Preserve excluded declarations and
473
+ undo unreviewed range changes by direct edits, then synchronize the lockfile.
474
+
475
+ Deduplication consolidates compatible references onto newer versions already
476
+ in the tree; it is not a way to hold back or downgrade a dependency. Review
477
+ production changes fully and development-only transitives under step 3's
478
+ narrower checks. If a deferred version is still allowed by a published runtime
479
+ range, use the explicit range/consumer decision path rather than fighting the
480
+ resolver with an older lockfile or an unapproved override.
481
+ If an authored release is blocked by `minimumReleaseAge`, add only that
482
+ package/version to `minimumReleaseAgeExclude`; never its dependencies.
483
+
484
+ Compare every result with the baseline:
485
+
486
+ - **Consumer compatibility:** recheck the resolved published dependency trees
487
+ and build artifacts against the Node.js baseline, including transitive
488
+ changes from resolution or deduplication. Validate consumer installation and
489
+ representative runtime behavior at the applicable supported minimums separately
490
+ from checks needing the newer development runtime. Review `pnpm fix` changes
491
+ to `engines.node` and `devEngines.runtime`; a passing fixer or build on newer
492
+ Node.js does not establish consumer compatibility. Diff the production-engine
493
+ inventories, test the packed build in known consumers, and run fixtures at the
494
+ exact supported Node.js floor using [the verification recipes](references/verification.md).
495
+ For stable projects, do not retain a newly introduced break outside explicit
496
+ approval; present the candidate or defer it. Do not mask it with an unapproved
497
+ `engines.node` increase. For authorized breaks and zero-versioned projects,
498
+ validate the new contracts and Node.js range and report the baseline changes.
499
+ - **Logs:** for each new warning, deprecation, or peer issue, find the package
500
+ that introduced it (`pnpm why`) and search upstream for a known issue. Report
501
+ it with the link. For a peer declaration lagging a verified compatible
502
+ version, offer a scoped `peerDependencyRules.allowedVersions` entry such as
503
+ `"parent@range>peer": "tested-range"` in `pnpm-workspace.yaml`, explaining
504
+ that it suppresses a warning rather than fixing incompatibility. Show the
505
+ exact entry and evidence, and ask before applying unless already authorized.
506
+ Do not use broad `allowAny` or disable strict peer checks. Revisit such
507
+ workarounds during step 8.
508
+ - **Build output:** if the baseline includes build output, rebuild with the
509
+ same command and environment and diff the trees with content-hashed filenames
510
+ normalized (`name.[hash].js`). Explain every remaining difference with an
511
+ upstream changelog entry, issue, or reviewed migration/configuration change;
512
+ anything unexplained needs investigation. Unless explicitly configured,
513
+ tsdown derives its build target from `engines.node`, so an engine change can
514
+ legitimately alter emitted syntax. Record the effective targets before and
515
+ after, distinguish expected output changes from regressions, and check runtime
516
+ APIs separately because syntax lowering does not provide polyfills.
517
+ - **After `pnpm fix`:** review the diff, then rebuild and diff against the
518
+ pre-fix build. Formatting changes must produce identical output. A lint
519
+ rule's suggested fix can change behavior (default parameters do not replace
520
+ `null`); in that case keep the code and add an inline disable that says why.
521
+ If the project can or is likely to run in browsers, including alongside
522
+ Node.js, disable the offending rule for the affected shipped code when its
523
+ fix would introduce regex flags or DOM APIs unsupported by the project's
524
+ browser targets. Explain the compatibility reason and keep the compatible
525
+ code instead of applying the fix; revert the fix if already applied. This
526
+ also applies to zero-versioned projects, but does not apply to Node.js-only
527
+ projects.
528
+ Resolve remaining lint errors by hand.
529
+
530
+ On failure, make the smallest change consistent with the version policy and
531
+ rerun from the failing step:
532
+
533
+ - To tell a new failure from a pre-existing one, check the baseline logs.
534
+ `git stash` does not revert `node_modules`, so rerunning a check after
535
+ stashing still uses the new dependencies.
536
+ - To isolate a breaking update: set half the accepted updates back to their
537
+ previous specifiers, `pnpm update -r`, rerun the failing check, repeat.
538
+ For an out-of-range update, defer the culprit unless an approval or the
539
+ zero-versioned exception permits it and the migration resolves the failure.
540
+ For an already allowed runtime release, follow the range decision path in
541
+ step 3; resetting a specifier or lockfile may not exclude it.
542
+
543
+ Add focused tests only where a compatibility change touches behavior not
544
+ already covered. Review `readme.md` accuracy and automation opportunities in step 7.
545
+
546
+ ## 6. Exclusion cleanup
547
+
548
+ Only if `minimumReleaseAgeExclude` is non-empty in any `pnpm-workspace.yaml`
549
+ (at the start, or after step 5). Empty the list (`[]` or remove the key),
550
+ preserving neighboring keys and comments. Repeat step 5's separate bare
551
+ `pnpm update -r` and `pnpm dedupe --check` invocations, followed by a separate
552
+ `pnpm dedupe` only when the check reports available changes. Then run each check
553
+ separately:
554
+
555
+ ```bash
556
+ pnpm build
557
+ pnpm test
558
+ pnpm lint
559
+ ```
560
+
561
+ If `pnpm-lock.yaml` comes out byte-identical and no ranges or build settings
562
+ changed, the installed tree did not change; rerun only `pnpm lint`.
563
+
564
+ If resolution is blocked: for an authored release, re-add the narrowest
565
+ package/version entry; for a third-party release, choose a mature version or
566
+ defer that upgrade. Obtain approval if that choice requires narrowing a
567
+ published runtime range. Never restore the whole previous list.
568
+
569
+ If the list was empty throughout, skip this section and continue to step 7.
570
+ If cleanup changes resolution, repeat step 5's consumer compatibility review
571
+ before reviewing documentation.
572
+
573
+ ## 7. Documentation review
574
+
575
+ Review `readme.md` against the updated project. Correct stale installation
576
+ instructions, requirements, commands, examples, configuration guidance, and
577
+ feature descriptions. If `readme.md` is generated or copied from another file,
578
+ update its maintained source and regenerate it through the existing workflow.
579
+
580
+ Review each section for content that would be more reliably maintained through
581
+ mdat, especially content duplicated from package metadata, CLI help, source
582
+ files, or other documentation. Prefer a rule bundled with mdat when it fits,
583
+ then a suitable mdat plugin, or a custom rule in `mdat.config.ts` for
584
+ project-specific needs. Check the installed rules and relevant documentation
585
+ before choosing an implementation. Replace manually maintained sections where
586
+ generation reduces duplication or prevents drift while preserving their useful
587
+ content and readability; keep explanatory prose manual when automation adds
588
+ no benefit. Any new plugin dependency must satisfy the dependency review,
589
+ release maturity, and compatibility policies above.
590
+
591
+ Run the project's mdat generation and documentation checks, inspect the
592
+ rendered content for accuracy, and confirm that a second generation produces
593
+ no further changes. Validate any new dependency under steps 5 and 6 before
594
+ continuing. Include documentation corrections and mdat conversions in the
595
+ final report.
596
+
597
+ ## 8. @kitschpatrol/shared-config override minimization
598
+
599
+ Run this as the final cleanup after all accepted updates, migrations,
600
+ validation, release-age exclusion cleanup, and documentation review, before
601
+ the release recommendation and report.
602
+
603
+ Review every shared-config-related configuration file in the project root,
604
+ including dotfiles, companion ignore files, and configuration stored in
605
+ `package.json`. Include the individual `@kitschpatrol/*-config` packages used by
606
+ the project. Inventory every local override beyond the upstream default export
607
+ or equivalent base configuration: rule settings, options, ignores, file globs,
608
+ and other customizations.
609
+ Include scoped peer-warning workarounds added during the update; remove them
610
+ when upstream peer declarations now cover the tested versions.
611
+
612
+ For each override, compare it with the defaults and effective configuration of
613
+ the exact versions installed after the updates. Check the current code it
614
+ targets and, for upstream workarounds, the relevant upstream changes or fixes.
615
+ Remove overrides that duplicate current defaults, target code or files that no
616
+ longer exist, or compensate for issues now fixed upstream. Do not infer that an
617
+ override is redundant merely because checks pass while it is still enabled.
618
+
619
+ Validate removals in small groups using the affected tools' checks without
620
+ caches, covering the affected files and any files newly included by removing
621
+ ignores. Recheck effective configuration where merge order or file matching
622
+ matters. Keep overrides that still serve a concrete project requirement,
623
+ including the behavior and browser-compatibility protections from step 5, and
624
+ record why each is needed. If necessity cannot be established, retain the
625
+ override and report the unresolved evidence instead of guessing.
626
+
627
+ After changing configuration, rerun the affected build, test, type, and lint
628
+ checks and compare results and build output as in step 5. The final report must
629
+ account for every override: removed with evidence, retained with a current
630
+ justification, or unresolved with the missing evidence identified.
631
+
632
+ ## Release recommendation
633
+
634
+ Recommend `patch`, `minor`, or `major` from the final consumer-visible changes,
635
+ following the repository's release conventions. Do not infer the recommendation
636
+ from the largest dependency version bump:
637
+
638
+ - **Patch:** compatible bug or security fixes, performance improvements, or
639
+ dependency/tooling maintenance with no new consumer-facing capability. A
640
+ development-only Node.js increase with the required notice can remain a patch.
641
+ - **Minor:** backward-compatible functionality or capabilities actually exposed
642
+ to consumers by the accepted updates. Explain what consumers gain; an upstream
643
+ minor or major alone is not a reason for a minor release. For zero-versioned
644
+ projects, also recommend a minor release for accepted consumer-facing breaking
645
+ changes unless the repository's pre-1.0 release conventions specify otherwise.
646
+ - **Major:** explicitly approved consumer-facing breaks in projects at 1.0.0
647
+ or later, including a raised consumer Node.js floor. A dependency major or
648
+ development-only requirement by itself does not justify a project major.
649
+
650
+ Give a short rationale per affected published package, or one recommendation
651
+ for a shared release version using the highest applicable level. If nothing
652
+ releasable changed, say no release is needed. An approved major release is
653
+ within scope; an unapproved breaking candidate stays pending or deferred.
654
+ For `0.x`, accepted consumer breaks normally require a minor, not a patch;
655
+ follow an explicit repository convention if it differs. Assess changes already
656
+ reachable through the old published ranges separately from newly introduced
657
+ consumer breaks. Recommend only; do not bump repository versions.
658
+
659
+ ## Report
660
+
661
+ State the execution mode and why it was selected. Include a `Breaking changes
662
+ available` section for deferred breaking candidates: current and proposed
663
+ versions, affected consumers/contracts, required migration, validation results
664
+ or gaps, recommended release level, and the decision still needed. Distinguish
665
+ these from applied breaks authorized explicitly or by the `0.x` policy. In
666
+ unattended mode, record decisions needed as follow-up items, not questions or
667
+ pending waits. Report unavailable checks and blocked work even when independent
668
+ updates succeeded.
669
+
670
+ Review the full diff for unrelated changes, excluded-package edits, and stray
671
+ exemptions first. Then summarize: applied updates; major decisions with
672
+ sources; consumer impact, approvals, declined/deferred decisions, and breaks
673
+ accepted under the zero-versioned policy;
674
+ output differences and their upstream or migration explanations;
675
+ consumer Node.js requirements before and after, development Node.js changes and
676
+ their `devEngines.runtime` notices; the release recommendation and its rationale;
677
+ baseline lockfile drift; runtime ranges, fresh-install exposure, and approved
678
+ range restrictions; TypeScript migrations; new warnings and scoped peer
679
+ workarounds; what was validated, at which exact Node.js versions, and in which
680
+ known consumers, including CLI/fixture comparisons and unavailable baselines;
681
+ remaining `minimumReleaseAgeExclude` entries with reasons; deferred upgrades,
682
+ documentation corrections and mdat conversions;
683
+ shared-config overrides removed or retained with their justifications and any
684
+ unresolved override reviews; unresolved failures, checks that could not run,
685
+ and steps run differently because of the environment. Passing checks do not
686
+ prove the absence of breaking changes. Leave everything uncommitted.