@kitschpatrol/shared-config 8.12.0 → 8.13.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.
@@ -1,280 +1,239 @@
1
1
  ---
2
2
  name: ksc-update
3
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.
4
+ Run full dependency and repository maintenance in kitschpatrol shared config
5
+ pnpm repositories and monorepos. Use when asked to update, upgrade, refresh,
6
+ or audit dependencies or GitHub Actions. Includes compatibility review,
7
+ migrations, configuration and documentation cleanup, packed-install
8
+ validation, and a release recommendation. Does not commit or release.
9
+ license: MIT
13
10
  ---
14
11
 
15
12
  # Update dependencies
16
13
 
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.
14
+ Every invocation is a full maintenance run, including audits and requests that
15
+ mention only GitHub Actions; there is no report-only or Actions-only mode. The
16
+ caller's only decision is whether consumer-breaking changes are pre-approved for
17
+ packages at 1.0.0 or later. Make the migrations that accepted updates require.
18
+
19
+ Supporting files sit beside this file. [configuration.md](references/configuration.md)
20
+ owns every per-file rule; read it during Setup and apply it through the final
21
+ cleanup. [verification.md](references/verification.md) owns baselines,
22
+ validation procedures, and the bundled scripts.
23
+
24
+ ## Execution and authorization
25
+
26
+ Record the execution mode and its reason before Setup. Use unattended mode when
27
+ explicitly requested, when `GITHUB_ACTIONS=true` or `CI=true`, or when the host
28
+ cannot receive replies; a missing TTY alone does not establish it. Unattended
29
+ runs never ask, wait, or run a command that needs an interactive response, and
30
+ report needed decisions as follow-up items.
31
+
32
+ Judge compatibility by effect on public APIs, CLI behavior, outputs, defaults,
33
+ supported consumer environments, and peers, never by a dependency's version
34
+ label: minors and patches can break those contracts and majors can preserve
35
+ them. This applies to authored packages, production transitives, and actions
36
+ alike. A package is `0.x` by its own published version, or the shared release
37
+ version in a monorepo, never a private root's version.
38
+
39
+ | Change | Rule |
40
+ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
41
+ | Compatible update | Apply after review and validation. |
42
+ | Consumer break in a package at 1.0.0 or later | Apply only within existing explicit approval. |
43
+ | Consumer break in a `0.x` package, including Node.js support changes | Apply after review, migration, and validation. |
44
+ | Pre-authorized by the configuration policy: Homebrew pnpm alignment, LTS-only Node.js ranges, Node-types alignment, compatibility-preserving lint disables, scoped suppression of a verified-compatible peer warning | Apply and report. |
45
+ | Other restrictions and suppressions: a published runtime-range restriction to hold a release back, including in `0.x`; a build approval outside the trust list; any other warning suppression | Apply only within existing explicit approval. |
46
+
47
+ Where approval is missing, present the reviewed proposal and ask in interactive
48
+ mode; defer in unattended mode. General permission to update dependencies never
49
+ approves an unspecified break. For each approval-dependent candidate record
50
+ concrete effects, migration work, validation results or gaps, and release
51
+ implications, trialing an isolated migration when useful. Continue independent
52
+ work while a decision is pending; track accepted, declined, pending, and
53
+ deferred decisions separately. Defer candidates with unknown impact or
54
+ unvalidated migrations, and leave acceptable updates unapplied when they cannot
55
+ be separated from an unauthorized change. Report missing credentials,
56
+ permissions, and validation resources instead of bypassing them.
57
+
58
+ Produce working-tree changes and a report suitable for later PR automation even
59
+ when nothing can be applied. Do not manufacture changes, create workflows or
60
+ pull requests, split work into PRs, bump repository versions, commit, push, tag,
61
+ publish, or release.
62
+
63
+ ### Pacing
64
+
65
+ Unattended runs have a turn limit, and a run that stops early publishes nothing.
66
+ Finish Setup and steps 1 to 5 before steps 6 to 9 and the fresh-install
67
+ exposure checks, and reserve budget for the report. Delegate per-package reviews
68
+ when subagents are available. If budget runs short, skip the remaining optional
69
+ work, list it in the report as not done, and write the report.
70
+
71
+ ## Version policy
72
+
73
+ - **Third-party maturity:** a run introduces only releases at least 24 hours
74
+ old: Taze `--maturity-period 1` and Actions Up `--min-age 1` enforce it for
75
+ candidates, and pnpm's default `minimumReleaseAge` of 1440 minutes covers
76
+ resolution. Do not add or change `minimumReleaseAge` in `pnpm-workspace.yaml`,
77
+ never disable an installation safeguard, and never downgrade a previously
78
+ locked version to satisfy age.
79
+ - **Authored packages:** npm packages and GitHub Actions owned by `kitschpatrol`
80
+ always target their latest stable release, including majors, however young.
81
+ They still get security and compatibility review and required migrations, but
82
+ age alone never causes an older target, a deferral, or a downgrade. The
83
+ commands below and the configuration policy's exact-version rules make the
84
+ exemption effective in Taze, pnpm, and Actions Up. If another policy blocks
85
+ latest, report the blocker and the retained version.
86
+ - **Consumer ranges:** review the newest stable version allowed by each runtime
87
+ dependency's declared range, not only the locked version; consumers resolve
88
+ it regardless of this repository's lockfile and maturity settings. Holding one
89
+ back needs an approved, genuinely restrictive published range such as `~1.8.0`
90
+ instead of `^1.8.0`; an older lockfile or a local override is no substitute.
91
+ - **No weakening:** never relax tests, lint rules, type checking, or security to
92
+ get a pass, and never accept changed snapshots or generated output unread.
93
+ Trace and report every new warning, deprecation, and peer issue against the
94
+ recorded baseline; the configuration policy defines the only permitted
95
+ suppressions.
118
96
 
119
97
  ## Environment
120
98
 
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.
99
+ Expect Claude Code in GitHub Actions with Node.js, pnpm and pnpx, curl, jq, git,
100
+ Bash, and network access to `registry.npmjs.org`, `raw.githubusercontent.com`,
101
+ `api.github.com`, `nodejs.org`, and upstream documentation hosts. Prefer
102
+ registry metadata and raw changelogs over GitHub API calls, and cache responses
103
+ for reuse between reviewers. Diagnose actual failures rather than assuming
104
+ sandbox restrictions, and never add sandbox workarounds.
105
+
106
+ The run directory is `${RUNNER_TEMP:-${TMPDIR:-/tmp}}/ksc-update/`. Keep every
107
+ baseline, log, fetched metadata file, and decision record there; it survives
108
+ pnpm rebuilding `node_modules` and never enters the pull request. Preserve exit
109
+ codes when capturing logs, for example with `set -o pipefail` before
110
+ `cmd 2>&1 | tee log`.
111
+
112
+ ### Bundled scripts
113
+
114
+ `scripts/` holds helpers for the mechanical parts of a run. Each documents its
115
+ usage in a header comment; the references say where each fits.
116
+
117
+ | Script | Purpose |
118
+ | ------------------------ | ------------------------------------------------------------- |
119
+ | `consumer-ranges.mjs` | Newest version each published runtime range allows (step 3) |
120
+ | `release-age.mjs` | Exemption inventory and young-version detection (steps 0–6) |
121
+ | `production-engines.mjs` | Declared engines across a production tree |
122
+ | `packed-fixture.mjs` | Packed or published consumer fixture install |
123
+ | `run-at-node.mjs` | Command at an exact Node.js release, with child-process proof |
124
+ | `compare-outputs.mjs` | Normalized comparison of captured outputs and build trees |
125
+
126
+ The scripts are conveniences, not requirements; the procedures they serve are.
127
+ When one fails for a reason that is not the repository's fault, produces output
128
+ that disagrees with what direct inspection shows, or does not fit this
129
+ repository's layout, make at most one quick attempt to understand why, then
130
+ abandon it: write a replacement for that step in the run directory, or do the
131
+ step by hand, and continue. Never let a broken helper stall the run, never edit
132
+ the bundled copy during a run (it is synced from the published package and
133
+ overwritten), and never weaken a check to make a script pass. Name each
134
+ abandoned or replaced script and the reason in the report's gaps so it can be
135
+ fixed upstream. Verify any script's result against one or two direct
136
+ observations before relying on it.
137
+
138
+ ## Step 0: Setup
139
+
140
+ 1. Read repository instructions, including run-specific instructions, and
141
+ preserve uncommitted changes. Run-specific instructions also live in the
142
+ `instructions:` input of the skill-running step in
143
+ `.github/workflows/update-dependencies.yml`; read it even when running
144
+ locally, where the workflow does not pass it, and follow it as if it had
145
+ been. Leave files changed by others during the run alone and report them.
146
+ Keep compatibility validation inside this repository and isolated
147
+ package-install fixtures. Record the latest release tag and the commits
148
+ since it (`git describe --tags --abbrev=0`, then `git log <tag>..HEAD`);
149
+ they explain differences between the published release and the current
150
+ build and feed the release recommendation.
151
+ 2. Map maintained package roots, shared lockfiles, catalogs, overrides,
152
+ `pnpm-workspace.yaml`, and Taze config, excluding fixtures, generated files,
153
+ and dependency directories. Run the workflow once per shared-lockfile
154
+ workspace and separately for each independent root. Check Taze config for
155
+ mode overrides, maturity exemptions, and automatic writes or installs; Taze
156
+ and `pnpm update` also read `minimumReleaseAge`, `minimumReleaseAgeExclude`,
157
+ and `update.ignoreDeps` from `pnpm-workspace.yaml`. Record project and
158
+ published package versions. Before any edit, copy the starting manifests,
159
+ lockfile, build approvals, and exact `publicHoistPattern` into the run
160
+ directory, and inventory release-age exclusions as the configuration policy
161
+ describes; `scripts/release-age.mjs inventory` classifies each entry once
162
+ the authored list from item 5 exists.
163
+ 3. Sync the workspace root's `packageManager` before any install or parsed pnpm
164
+ output: fetch the [Homebrew pnpm formula](https://raw.githubusercontent.com/Homebrew/homebrew-core/refs/heads/main/Formula/p/pnpm.rb),
165
+ read the stable version from its source URL or explicit `version`, and set
166
+ `pnpm@<homebrew-version>` by direct manifest edit, even across a major.
167
+ Homebrew is the only source and need not be installed; never substitute the
168
+ installed pnpm, npm's `latest` tag, or an age-filtered version, and report an
169
+ unavailable or unreadable formula as an incomplete sync. Review pnpm release
170
+ notes for lockfile and settings changes, confirm CI installs the selected
171
+ version, and record the formula URL and version. Make all later specifier
172
+ and engine changes by direct edit too, preserving other fields.
173
+ 4. Apply the configuration policy's build-trust decisions and exclusion
174
+ normalization, then install the starting declarations:
203
175
 
204
176
  ```bash
205
177
  pnpm install --frozen-lockfile
206
178
  ```
207
179
 
208
- On `ERR_PNPM_OUTDATED_LOCKFILE` only, run this as a separate bare command:
209
-
210
- ```bash
211
- pnpm install --no-frozen-lockfile
212
- ```
180
+ Use `--no-frozen-lockfile` only for `ERR_PNPM_OUTDATED_LOCKFILE` and diagnose
181
+ every other failure individually; a pnpm major change can require a lockfile
182
+ format migration, which is expected drift to record. Keep the saved originals
183
+ even if installation fails, and label checks after a repair as repaired.
184
+ Record the [baseline](references/verification.md#baselines): install
185
+ attempts, build, test, lint, build artifacts, Node.js requirements, the
186
+ production-engine inventory, the advisory report, and packed-install fixture
187
+ results.
213
188
 
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:
189
+ 5. Discover authored packages, those whose registry metadata lists
190
+ `kitschpatrol` in `maintainers`. The ownership endpoint is a shortcut for the
191
+ full list:
238
192
 
239
193
  ```bash
240
194
  set -euo pipefail
241
- mkdir -p node_modules/.cache/ksc-update
195
+ run_dir="${RUNNER_TEMP:-${TMPDIR:-/tmp}}/ksc-update"
196
+ mkdir -p "$run_dir"
242
197
  curl -fsS https://registry.npmjs.org/-/user/kitschpatrol/package \
243
198
  | jq -er 'keys | join(",") | select(length > 0)' \
244
- > node_modules/.cache/ksc-update/authored-packages.txt
199
+ > "$run_dir/authored-packages.txt"
245
200
  ```
246
201
 
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.
202
+ If it fails or returns nothing, check each direct dependency's registry
203
+ metadata instead and report the fallback; do not stop the run. Intersect
204
+ ownership with the direct dependency names across maintained manifests,
205
+ including dev, optional, peer, catalog, and npm-alias dependencies, and save
206
+ that intersection separately; it may be empty. `<authored-packages>` below
207
+ means those exact names, comma-separated, with no wildcards; omit
208
+ `--maturity-period-exclude` when the list is empty. Keep the full ownership
209
+ list for packages met later.
255
210
 
256
- ## 1. Workflow actions
211
+ ## Step 1: Workflow actions
257
212
 
258
213
  ```bash
259
- pnpx actions-up --yes --min-age 1 --style sha
214
+ pnpx actions-up --yes --min-age 1 --min-age-exclude '^kitschpatrol/' --style sha \
215
+ --dir .github
260
216
  ```
261
217
 
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.
218
+ Add a `--dir` for every other directory of workflows the repository maintains or
219
+ ships, such as templates that an init command copies into consumer projects
220
+ (for example `packages/*/init/.github`); by default only `.github` is scanned.
221
+ Find them with a search for `workflows` directories outside dependency and
222
+ fixture folders.
223
+
224
+ `Skipped`, `Failed`, or `Rate Limit` anywhere in the output means incomplete,
225
+ even beside "All actions are up to date"; fix the cause and rerun, and report
226
+ unresolved access or service failures instead of claiming success.
265
227
 
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.
228
+ Review major bumps and runner, input, output, and permission changes. Pin every
229
+ external action and reusable workflow, including `kitschpatrol/*`, to a verified
230
+ full commit SHA with its version comment, covering branch and tag refs,
231
+ unchanged versions, and the retained version of a deferred update. Pin container
232
+ actions by digest; local `./` actions use the checkout. Remove zizmor
233
+ `unpinned-uses` exceptions the pins make contradictory. Keep only reviewed
234
+ changes and preserve user edits; local tests do not validate remote workflows.
276
235
 
277
- ## 2. Discover all candidates (read-only)
236
+ ## Step 2: Discover candidates
278
237
 
279
238
  ```bash
280
239
  pnpx taze major -r --force --include-locked \
@@ -284,134 +243,88 @@ pnpx taze major -r --force --include-locked \
284
243
  --maturity-period-exclude '<authored-packages>'
285
244
  ```
286
245
 
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.
246
+ Major mode lists every update size; confirm authored candidates are the latest
247
+ stable across majors. Do not opt into new prerelease channels.
248
+ `--include-locked` surfaces exact pins without authorizing their removal;
249
+ `@types/node` and `pnpm` are managed by the configuration policy and Setup. This
250
+ discovery does not replace the consumer-range review in step 3.
251
+
252
+ ## Step 3: Evaluate candidates
253
+
254
+ ### Scope and consumer ranges
255
+
256
+ For every runtime dependency of a published package, read registry metadata for
257
+ the newest stable version its declared range allows, accounting for catalogs and
258
+ aliases, and record the range, locked version, newest allowed version, and
259
+ proposed range or version. Review the allowed release even when it is already in
260
+ range or too young to install here, and report untested consumer exposure. Keep
261
+ the published release's fresh-install behavior, the updated build, and the old
262
+ locked baseline distinct; existing in-range exposure is not a break introduced
263
+ by this release. `scripts/consumer-ranges.mjs` builds this table from the
264
+ workspace root and flags rows where consumers resolve something newer than the
265
+ lockfile or something too young to install here; resolve catalog specifiers it
266
+ marks for manual review by hand.
267
+
268
+ Review direct candidates and production-tree changes fully; shipped or bundled
269
+ tooling belongs to consumer review even when used only for development here.
270
+ For development-only transitives, check advisories, deprecations, and engines,
271
+ and read release notes when those findings, validation failures, or output
272
+ differences warrant it. A full review reads release notes, migration guides, and
273
+ advisories and assesses:
274
+
275
+ - Security fixes or regressions, publishing or ownership anomalies, and new
276
+ install scripts or permissions.
277
+ - APIs, types, defaults, configuration, module format, peers, and engines
278
+ against actual repository usage and the versions this update produces,
279
+ reviewing coupled packages together since one update may need a newer
280
+ sibling.
281
+ - Adoptable fixes, performance, capabilities exposed to consumers, and optional
282
+ feature opportunities for the report. Do not implement extra features.
283
+
284
+ When delegating, split independent reviews among authored packages, remaining
285
+ runtime packages, and remaining development packages. Give each reviewer a
286
+ disjoint list, actual usage and source paths, consumer requirements, and the
287
+ version policy; reviewers return decisions and sources without editing, the
288
+ primary agent resolves coupling, and all share fetched metadata and the GitHub
289
+ API budget.
290
+
291
+ Record current and proposed versions, decision, evidence, and approval scope per
292
+ the authorization table. Do not defer a migration merely because it implies a
293
+ major release recommendation. Review exact pins under
294
+ [Version declarations](references/configuration.md#version-declarations).
333
295
 
334
296
  ### Node.js compatibility
335
297
 
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).
298
+ For every candidate, including minors and patches, check consumer and
299
+ development requirements separately:
300
+
301
+ - **Consumers:** compare full supported Node.js ranges across direct,
302
+ transitive, optional, peer, and workspace dependencies, bundled code, emitted
303
+ syntax, and runtime APIs. A higher effective minimum or a lost supported line
304
+ is a break even when `engines.node` is unchanged. Preserve the contract under
305
+ the authorization table; for accepted changes publish truthful engines in the
306
+ [LTS-only shape](references/configuration.md#nodejs-support) and validate the
307
+ resulting range.
308
+ - **Development:** higher requirements for development-only tools, builds, or
309
+ CI are fine while artifacts stay consumer-compatible. When they exceed
310
+ consumer requirements, add or update `devEngines.runtime` with `name: "node"`
311
+ and the actual range, at the root for shared tooling and in package manifests
312
+ for package-specific tools, preserving other entries. Align development pins
313
+ and CI while keeping tests at the applicable consumer minimums. Never raise
314
+ published `engines.node` for development tooling.
361
315
 
362
316
  ### TypeScript migrations
363
317
 
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:
318
+ Follow the [tsconfig.json policy](references/configuration.md#tsconfigjson)
319
+ with the accepted config release. When an authored update needs a newer compiler
320
+ major, offer that migration with its concrete effects instead of deferring the
321
+ update, apply it within the authorization table, then run type checks, the
322
+ build, and packed-install validation.
323
+
324
+ ## Step 4: Apply
325
+
326
+ Apply accepted candidates by exact package name, replacing the example list;
327
+ skip this when nothing was accepted:
415
328
 
416
329
  ```bash
417
330
  pnpx taze major -rw --force --include-locked \
@@ -422,265 +335,138 @@ pnpx taze major -rw --force --include-locked \
422
335
  --maturity-period-exclude '<authored-packages>'
423
336
  ```
424
337
 
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.
338
+ Set a reviewed older target by direct edit when latest was not accepted.
339
+ Acceptance in one workspace package does not apply to the others. Afterwards
340
+ check every manifest and catalog: only reviewed versions, range styles and
341
+ `workspace:` references intact, no deferred or excluded updates. Directly edit
342
+ missed catalogs and overrides, the reviewed compiler and Node-types versions,
343
+ and development Node.js notices. Apply the configuration policy's manifest rules
344
+ and keep Setup's `packageManager`.
436
345
 
437
- ## 5. Resolve and validate
346
+ ## Step 5: Resolve and validate
438
347
 
439
- Run each command as a separate invocation:
440
-
441
- ```bash
442
- pnpm update -r
443
- ```
348
+ Before anything can run install scripts, apply build-trust decisions, review
349
+ overrides and peer rules, and add the exact release-age exemptions that accepted
350
+ young authored targets need, all under the
351
+ [pnpm-workspace.yaml policy](references/configuration.md#pnpm-workspaceyaml).
352
+ Then resolve:
444
353
 
445
354
  ```bash
355
+ pnpm update -r --no-save
446
356
  pnpm dedupe --check
447
357
  ```
448
358
 
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.
359
+ `pnpm update -r --no-save` refreshes every direct and transitive dependency
360
+ within the declared ranges without rewriting manifests or catalogs; named
361
+ updates and `!pkg` selectors do not give that transitive refresh. Run
362
+ `pnpm dedupe` only when the check reports available deduplication, and diagnose
363
+ other failures; deduplication moves compatible references onto newer versions
364
+ already in the tree and cannot hold back a deferred release. Review newly
365
+ resolved packages under step 3, apply the consumer-range decision to deferred
366
+ in-range runtime releases, and confirm after each resolution that authored
367
+ packages reached their accepted targets, investigating mismatches with the
368
+ configuration policy's maturity procedure rather than assuming an age holdback.
369
+ After each resolution, run `scripts/release-age.mjs new-versions` against the
370
+ saved pre-resolution lockfile to list young versions it introduced, and diff
371
+ `minimumReleaseAgeExclude` against the entries you added: pnpm appends entries
372
+ itself when it falls back to young versions, and each one needs the policy's
373
+ review.
374
+
375
+ Run the [validation procedure](references/verification.md#updated-validation):
376
+ build, fix, rebuild when needed, test, lint, baseline and output comparison,
377
+ warning review, advisory comparison, packed consumer installs, and exact-floor
378
+ checks. Apply the configuration policy's compatibility fixes and warning rules.
379
+ Keep only changes the authorization table permits, revise decisions when
380
+ validation reveals a break, and add focused tests only for affected behavior
381
+ that is not already covered.
382
+
383
+ ## Step 6: Exclusion cleanup
384
+
385
+ If `minimumReleaseAgeExclude` was ever non-empty during the run, follow the
386
+ [release-age cleanup](references/configuration.md#release-age-exemptions), which
387
+ is version-preserving and names its own validation.
388
+
389
+ ## Step 7: Side effects
390
+
391
+ Evaluate each published package's shipped code against its `sideEffects`
392
+ declaration under the [side-effects policy](references/configuration.md#side-effects),
393
+ recording evidence and outcome even when nothing changes.
394
+
395
+ ## Step 8: Documentation
396
+
397
+ Review `readme.md` for stale installation instructions, requirements, commands,
398
+ examples, configuration guidance, and feature descriptions; for generated or
399
+ copied readmes, edit the maintained source and regenerate through the existing
400
+ workflow, never by running mdat from a different package's directory. Convert
401
+ sections that duplicate metadata, CLI help, source files, or other documentation
402
+ to mdat generation where that reduces duplication or drift without hurting
403
+ readability, preferring a bundled rule, then a suitable plugin, then a custom
404
+ rule in `mdat.config.ts`; keep explanatory prose that automation adds nothing
405
+ to. New plugin dependencies get the same review as any other candidate and go
406
+ through steps 5 and 6. Run generation and documentation checks, inspect the
407
+ rendered result, confirm a second generation changes nothing, and record
408
+ corrections and conversions.
409
+
410
+ ## Step 9: Final configuration cleanup
411
+
412
+ Recheck the complete configuration policy against the final tree and perform
413
+ [override minimization](references/configuration.md#final-override-minimization).
414
+ Run affected fixers and checks after the last edit, and account for every
415
+ override before recommending a release.
631
416
 
632
417
  ## Release recommendation
633
418
 
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.
419
+ Recommend from the final consumer-visible changes, following repository
420
+ conventions, with a rationale per published package or the highest level for a
421
+ shared release:
422
+
423
+ - **Patch:** compatible bug and security fixes, performance, and dependency or
424
+ tooling maintenance without new consumer capability, including
425
+ development-only Node.js increases with their notice and corrected or newly
426
+ added `sideEffects` declarations.
427
+ - **Minor:** backward-compatible functionality actually exposed to consumers;
428
+ explain the gain. For `0.x`, also accepted consumer breaks unless explicit
429
+ pre-1.0 repository conventions differ.
430
+ - **Major:** authorized consumer breaks in packages at 1.0.0 or later, including
431
+ a raised Node.js floor or a declared line removed by the LTS-only range.
432
+
433
+ Dependency version labels and development-only requirements never decide the
434
+ level. Separate pre-existing exposure through published ranges from new breaks.
435
+ Say that no release is needed when nothing releasable changed, and leave
436
+ repository versions unchanged.
437
+
438
+ The next release also ships every unreleased commit recorded in Setup. Give the
439
+ level this run's changes need and, when the unreleased commits raise it, the
440
+ level for the next release overall, citing those commits.
658
441
 
659
442
  ## Report
660
443
 
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
444
  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.
445
+ exemptions. Start the report with a summary of at most ten lines: what was
446
+ applied, the release recommendation per package, and the decisions needed. Raw
447
+ logs stay in the run directory. Then cover, from the decisions and evidence
448
+ recorded above and in both references:
449
+
450
+ - **Updates and decisions:** execution mode and reason, applied versions with
451
+ sources, approvals and applied breaks including `0.x`, declined and deferred
452
+ candidates, migrations, and optional feature opportunities. Under a
453
+ `Breaking changes available` heading list each deferred break's versions,
454
+ consumer impact, migration, validation or gaps, release level, and the
455
+ decision needed.
456
+ - **Consumer impact and release:** runtime ranges and fresh-install exposure,
457
+ approved restrictions, consumer Node.js before and after, development
458
+ requirements and notices, TypeScript migrations, and the release
459
+ recommendation with rationale.
460
+ - **Maintenance:** the Homebrew pnpm selection; every configuration decision
461
+ with its justification, including build trust, overrides and peers, preserved
462
+ hoisting, keywords, Node.js ranges and types, exact pins, CSpell, and side
463
+ effects; remaining age exemptions with reasons and removal dates;
464
+ documentation changes and mdat conversions.
465
+ - **Evidence and gaps:** the original versus Setup baseline distinction and any
466
+ lockfile drift, checks with their exact runtimes, installation and fixture
467
+ results, explained output differences, advisories, warnings and suppressions,
468
+ missing historical baselines, unresolved failures, blocked work, skipped
469
+ optional steps, and environment-driven deviations.
470
+
471
+ Passing checks do not prove the absence of breaks. Leave all changes
472
+ uncommitted.