@kitschpatrol/shared-config 8.12.1 → 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.
@@ -0,0 +1,373 @@
1
+ # Configuration policy
2
+
3
+ Read this during Setup and apply it through the final cleanup. The authorization
4
+ table in the main skill governs decisions; the specific requirements here take
5
+ precedence over general preservation and minimization. Judge existing approvals,
6
+ hoist patterns, and pins from the starting checkout and need from the final
7
+ tree. Record each configuration decision, its evidence, and any unresolved issue
8
+ for the report.
9
+
10
+ ## pnpm-workspace.yaml
11
+
12
+ ### Build approvals
13
+
14
+ Keep `allowBuilds` limited to packages that remain in the dependency tree and
15
+ still need an explicit build-script decision. Inspect the resolved packages'
16
+ scripts and installation requirements; remove absent packages, packages whose
17
+ scripts no longer matter, and redundant entries. Do not copy the whole trust
18
+ list into every workspace.
19
+
20
+ These packages may be set to `true` whenever needed:
21
+
22
+ ```text
23
+ @github/keytar
24
+ esbuild
25
+ @vscode/vsce-sign
26
+ unrs-resolver
27
+ skia-canvas
28
+ sharp
29
+ canvas
30
+ electron-winstaller
31
+ electron
32
+ netlify-cli
33
+ workerd
34
+ puppeteer
35
+ oxc-resolver
36
+ ```
37
+
38
+ Preserve any other build already trusted in the starting checkout while it is
39
+ still needed; absence from the list above is not a reason to disable it. A new
40
+ approval outside the list needs explicit authorization. Without it, write `name:
41
+ false` so the install proceeds under `strictDepBuilds`, and report the pending
42
+ decision and any blocker it causes. pnpm itself appends placeholder entries for
43
+ unreviewed build scripts during installs; resolve them the same way.
44
+
45
+ `core-js` and `@tsparticles/engine` are always `false` when present, even if the
46
+ starting checkout enabled them; this denial beats prior approvals and broader
47
+ selectors. Keep an explicit denial while the installed package still needs a
48
+ decision, and remove entries for absent packages rather than keeping a permanent
49
+ deny list. Apply build decisions before any installation that can run dependency
50
+ scripts, including the baseline install, and record changes to the starting
51
+ policy.
52
+
53
+ ### Overrides and peer rules
54
+
55
+ Review every `overrides` and `peerDependencyRules` entry, including existing
56
+ suppressions, with the [final minimization
57
+ procedure](#final-override-minimization). Remove peer rules for absent packages,
58
+ resolved upstream declarations, or versions no longer installed, and keep
59
+ remaining exceptions scoped to the affected parent and the tested peer range.
60
+ Never use broad `allowAny`, disable strict peer checks, or use overrides to
61
+ evade the consumer-range decision.
62
+
63
+ For each new warning, deprecation, or peer issue, trace its origin with `pnpm
64
+ why` and search upstream, then report the finding and its source. When checks
65
+ pass with the installed peer combination and no upstream report contradicts
66
+ compatibility, add a scoped `allowedVersions` entry such as
67
+ `"parent@range>peer": "tested-range"` to the consuming repository's
68
+ `pnpm-workspace.yaml`. This is authorized in both modes, including for warnings
69
+ that arrive through authored packages, but it is a suppression, not a fix:
70
+ report the evidence and the upstream fix separately. If the combination is
71
+ incompatible, resolve or defer the update instead. Every other suppression
72
+ follows the authorization table. Known entries are listed under [Current
73
+ exceptions](#current-exceptions).
74
+
75
+ ### Hoisting and sorting
76
+
77
+ Preserve `publicHoistPattern` exactly, including patterns, order, and presence
78
+ or absence, and exclude it from minimization; negated patterns can be
79
+ order-sensitive. After the last workspace edit run `pnpm ksc-eslint fix
80
+ pnpm-workspace.yaml` and its lint check, keep the fixer's key ordering and
81
+ order-insensitive list ordering, including age exemptions, and verify
82
+ `publicHoistPattern` kept its original value.
83
+
84
+ ### Release-age exemptions
85
+
86
+ Leave `minimumReleaseAge` as the repository declares it, or undeclared; do not
87
+ add or change it. pnpm 11 and later default to 1440 minutes, and Taze and
88
+ Actions Up enforce the same age for the candidates a run introduces. Without an
89
+ explicit setting pnpm falls back to a young version when no mature version
90
+ satisfies a range; report such a version as a finding instead of changing pnpm
91
+ settings. When it does so, pnpm 12 also appends the version to
92
+ `minimumReleaseAgeExclude` itself ("Added N entries to
93
+ minimumReleaseAgeExclude"), so after every install or update compare the list
94
+ with the entries the run added and apply the table below to each new one; a
95
+ young third-party entry pnpm added is removed and reported. pnpm also re-checks
96
+ the age of locked versions on install, so removing an exemption for a
97
+ still-young locked version can break or re-resolve the install; handle that with
98
+ the table below.
99
+
100
+ Every `minimumReleaseAgeExclude` entry names one exact `package@version`; no
101
+ package-only entries, wildcards, ranges, inequalities, or unions. Keep the
102
+ smallest effective set, remove the key when it is empty, and preserve
103
+ neighboring keys and comments. Exact entries implement the authored-package
104
+ exemption without exempting unreviewed future releases or third-party
105
+ dependencies.
106
+
107
+ **Before the baseline install:** inventory the starting exclusions, resolve
108
+ broad entries against the starting lockfile, and record the concrete versions
109
+ and their registry `time` values. Rewrite the list with these rules:
110
+
111
+ | Version state | Action |
112
+ | -------------------------------------------------------- | ------------------------------------------------------------------------- |
113
+ | Neither locked nor targeted | Remove. |
114
+ | At least 24 hours old at the run's start | Remove; it needs no exemption. |
115
+ | Young authored version installed or accepted as a target | Keep or add its exact exemption. |
116
+ | Young third-party version already locked before this run | Keep only that exact version to avoid a downgrade; record when it can go. |
117
+ | Newly introduced young third-party version | Do not exempt. |
118
+
119
+ **Before and after resolution:** add exact exemptions for accepted young
120
+ authored targets before `pnpm update`. Confirm afterwards that each accepted
121
+ version resolved. If one did not, inspect ranges, peers, overrides, and age
122
+ filtering; a lower version alone does not prove an age holdback. When age is the
123
+ cause, add the missing exact authored exemption and resolve again. Never exempt
124
+ an authored package's third-party dependencies: if they are too young, defer the
125
+ authored update, keep the previously locked version, and report the date it
126
+ becomes installable. Never silently settle for an older target or claim latest
127
+ was reached.
128
+
129
+ **Cleanup in step 6:** skip when the list was empty throughout. Otherwise save
130
+ the pre-cleanup lockfile, reevaluate every entry with the same rules, edit the
131
+ list, repeat step 5's resolution and deduplication, and run the workspace fixer.
132
+ Compare the result with the saved lockfile and the accepted targets, never with
133
+ an unaccepted latest candidate; cleanup must not downgrade a package or change
134
+ an accepted target. If a removed exemption caused a downgrade, restore only that
135
+ exact entry and resolve again. Then validate by the resulting diff: rerun only
136
+ `pnpm lint` when the lockfile is byte-identical and no range or build setting
137
+ changed; otherwise run build, test, and lint, and repeat the consumer
138
+ compatibility checks when resolution changed. Record retained exemptions with
139
+ reasons and removal dates. Cleanup must never undo the exemption of a
140
+ still-young accepted authored release.
141
+
142
+ ### Trust policy
143
+
144
+ When `trustPolicy` is set, keep it. Treat `trustPolicyExclude` exactly like
145
+ release-age exclusions: exact `package@version` entries only, each reviewed,
146
+ reported, and removed when no longer needed. Never relax the policy to make an
147
+ install succeed; report the blocked update instead.
148
+
149
+ ## CSpell
150
+
151
+ For each unknown word, use context to tell a misspelling from a legitimate term,
152
+ identifier, brand, or technical vocabulary. Fix misspellings; otherwise add the
153
+ word to `words` in `cspell.config.ts`. Err toward adding legitimate words rather
154
+ than rewriting correct text or renaming identifiers to satisfy the checker. `ksc
155
+ fix` removes unused words and sorts the array; accept that, do not restore
156
+ unused entries or manual ordering, and remove the `words` key if the array
157
+ becomes empty. Recheck after any later edit that adds or removes vocabulary.
158
+
159
+ ## tsconfig.json
160
+
161
+ Select TypeScript within the accepted `@kitschpatrol/typescript-config`
162
+ release's compiler peer range, intersected with other required peers; never
163
+ hard-code a version. Without that config, follow the project's compiler policy
164
+ and peers. Read the accepted release's base configuration and evaluate the
165
+ effective settings before changing source to satisfy them, and prefer shared
166
+ defaults and the framework preset over copied local options.
167
+
168
+ Svelte projects inherit in this order:
169
+
170
+ ```json
171
+ {
172
+ "extends": ["@kitschpatrol/typescript-config/svelte", "./.svelte-kit/tsconfig.json"]
173
+ }
174
+ ```
175
+
176
+ Astro projects use:
177
+
178
+ ```json
179
+ {
180
+ "extends": "@kitschpatrol/typescript-config/astro"
181
+ }
182
+ ```
183
+
184
+ Review effective inheritance, including framework-generated settings; regenerate
185
+ those through the project workflow and edit only maintained configs. Remove
186
+ redundant or obsolete options only after checking the installed presets and
187
+ actual needs. Keep defensive exclusions for expected build and generated paths
188
+ such as `./dist`, even when absent. Document local overrides in adjacent JSONC
189
+ comments; basic `@types/` entries in `compilerOptions.types`, such as `"node"`,
190
+ need none.
191
+
192
+ During compiler or config migrations:
193
+
194
+ - Add `"node"` to `compilerOptions.types` where needed, preserving other entries
195
+ and browser-code separation.
196
+ - Fix errors from newly enabled strict options instead of disabling them.
197
+ - Check `target`, `lib`, `types`, module settings, emitted syntax, declarations,
198
+ and runtime APIs against browser targets and consumer Node.js floors. Compiler
199
+ libraries do not polyfill runtime APIs. Keep documented compatibility
200
+ overrides even when they add local configuration.
201
+
202
+ Run `ksc fix`, keep its ordering while preserving meaningful `extends` order,
203
+ verify the effective configuration, and run the relevant TypeScript or framework
204
+ checks, the build, and packed-install validation.
205
+
206
+ ## Compatibility-preserving lint fixes
207
+
208
+ Review fixer changes before accepting them. If a fix changes behavior, retain or
209
+ restore the compatible code and add an inline disable that explains why, for
210
+ example that default parameters do not replace `null`. For code that can run in
211
+ browsers, including alongside Node.js, also disable fixes that introduce regex
212
+ flags or DOM APIs unsupported by the project's browser targets; this protection
213
+ applies to `0.x` too, but not to Node.js-only projects. Report every disable,
214
+ resolve remaining lint errors by hand, and use the output comparisons in the
215
+ verification reference.
216
+
217
+ ## package.json
218
+
219
+ Apply these rules to each maintained package manifest, updating shared catalogs
220
+ where they supply the specifiers. Evaluate each package's own publication and
221
+ runtime requirements rather than copying root metadata.
222
+
223
+ ### Node.js support
224
+
225
+ Published packages support LTS release lines only. Start from the minimum the
226
+ compatibility review establishes, or the declared minimum while it is still
227
+ true, and exclude every line between it and the newest release that never enters
228
+ LTS: the odd-numbered lines through Node 25. From Node 27 on, Node.js releases
229
+ annually and every major enters LTS, so no newer line is excluded. Write the
230
+ smallest union of ranges, for example `^24.16.0 || >=26.3.0` while an excluded
231
+ line sits between the floor and the newest release, or `>=26.3.0` when none
232
+ does; prerelease builds such as a Node 27 alpha never satisfy these ranges.
233
+ Apply the same shape to Node entries in `devEngines.runtime`, and align runtime
234
+ pins, CI matrices, and documented support with the result.
235
+
236
+ This exclusion is pre-authorized, but removing a line the package previously
237
+ declared is a consumer compatibility change for the release recommendation.
238
+ Raising the floor itself is a separate decision under the authorization table.
239
+
240
+ ### Keywords
241
+
242
+ Add each keyword when its condition holds and remove it when incorrectly
243
+ present, preserving unrelated keywords.
244
+
245
+ | Keyword | Condition |
246
+ | ------------------ | ----------------------------------------------------------------------------- |
247
+ | `npm-package` | The package is published to npm or another registry, including a private one. |
248
+ | `cli` | The package ships a `bin` exposing a CLI. |
249
+ | `homebrew-formula` | The package is distributed as a Homebrew formula. |
250
+ | `homebrew-cask` | The package is distributed as a Homebrew cask. |
251
+
252
+ Check publish configuration, release workflows, shipped bins, documentation, and
253
+ the actual tap definition, starting with `kitschpatrol/homebrew-tap` and
254
+ verifying the formula or cask against the project's release configuration. Never
255
+ infer publication from a name or an installation snippet; a private workspace
256
+ root is not a published package because its children are.
257
+
258
+ A private workspace root's keywords are a special case, preserve any
259
+ hand-written keywords, and then make sure all the keywords from the table above
260
+ that are present in workspace projects are aggregated in the root package.json's
261
+ keywords list. Likewise, remove the table keywords if not present in any
262
+ workspace projects. Tooling such as `kitschpatrol/github-action-repo-sync`
263
+ publishes root keywords as repository topics, so a root may describe what its
264
+ children publish and ship.
265
+
266
+ ### Version declarations
267
+
268
+ - **pnpm:** `packageManager` is the version in Homebrew's current stable formula
269
+ from Step 0.3, even across a major. Keep it after dependency tools and fixers
270
+ run.
271
+ - **TypeScript:** when present in `devDependencies`, declare the selected
272
+ compatible version with `~`, for example `"typescript": "~6.0.3"`; the version
273
+ is illustrative, the range style is the rule. For a catalog reference, put the
274
+ `~` range in the catalog and keep the reference.
275
+ - **Node types:** when `@types/node` is present, find the minimum Node.js
276
+ version the package supports through `engines.node`, match its major and minor
277
+ with the highest patch the maturity policy allows, and declare
278
+ `~<major>.<minor>.<patch>`. When engines describe only development, use the
279
+ minimum development requirement, including `devEngines.runtime`; a published
280
+ package with both uses the consumer minimum even though the types are a
281
+ development dependency. If the exact minor is unavailable, use the highest
282
+ lower minor in the same major and report the fallback; if the major has no
283
+ suitable release, report the blocker rather than choosing an unrelated major.
284
+ Verify runtime APIs against the actual minimum; types prove nothing. Update
285
+ supplying catalogs and overrides consistently, splitting shared catalog
286
+ entries when package minimums differ, and never add `@types/node` to a package
287
+ that does not use it.
288
+ - **Exact pins:** inspect each exact version, including catalogs and overrides.
289
+ Check nearby comments, history, and linked upstream issues for why it was
290
+ pinned and whether the fix shipped. Keep a still-needed pin, updating it to a
291
+ reviewed exact release when appropriate; restore the normal range only when
292
+ the reason is resolved and validation supports it; when the reason is unclear,
293
+ keep the pin and report the uncertainty. The `~` rules for TypeScript and Node
294
+ types take precedence over pin preservation.
295
+
296
+ Recheck these declarations after resolution and `ksc fix`.
297
+
298
+ ### Side effects
299
+
300
+ For each published package, inspect `sideEffects` against the shipped
301
+ entrypoints and every module they reach, including bundled dependencies,
302
+ `dist/`, and the `files` list. Look for import-time effects: global or prototype
303
+ assignments, polyfills, registrations such as `customElements.define`,
304
+ listeners, process or environment setup, CSS and assets, and bare imports kept
305
+ for their effects.
306
+
307
+ Use `false` for a pure package, an array naming the exact shipped files with
308
+ effects when only some have them, or `true` when most do; absence means `true`.
309
+ Leave bin-only packages without an importable entrypoint unchanged. An incorrect
310
+ `false` removes required consumer behavior; a newly valid `false` enables tree
311
+ shaking. Record each package's inspected modules, effects, declaration before
312
+ and after, and justification even when unchanged. Treat corrections as bug fixes
313
+ and a newly added `false` as a performance improvement for the release
314
+ recommendation.
315
+
316
+ ## Final override minimization
317
+
318
+ After the full workflow, recheck every policy in this reference. Inventory all
319
+ shared-config-related root configuration: individual `@kitschpatrol/*-config`
320
+ packages, dotfiles, companion ignores, and settings in `package.json`, including
321
+ rules, options, globs, ignores, pnpm overrides, and peer workarounds added
322
+ during the run. Preserve the hoisting and the defensive and compatibility
323
+ exceptions defined above.
324
+
325
+ For every override, compare the exact installed defaults and effective
326
+ configuration, the current targeted code, the dependency graph and constraints,
327
+ and relevant upstream fixes. Remove duplicates, obsolete settings with no
328
+ defensive purpose, and resolved workarounds. Passing checks with an override
329
+ enabled prove neither its necessity nor its redundancy; when evidence is
330
+ insufficient, keep it and report what is missing.
331
+
332
+ Try removals in small groups, resolving again after dependency changes. Run
333
+ affected checks without caches, covering targeted files and files newly included
334
+ by ignore removal, and recheck effective configuration where matching or merge
335
+ order matters. Keep overrides that serve a concrete current requirement with a
336
+ recorded justification. After edits, run affected fixers, the build, test, type,
337
+ and lint checks, and the output comparisons from the verification reference.
338
+ Account for every override as removed with evidence, retained with
339
+ justification, or unresolved with the missing evidence named.
340
+
341
+ Trial removals without editing the real configuration where the tool allows it:
342
+
343
+ - **Knip:** configuration hints are truncated ("…N more similar hints") and the
344
+ JSON reporter omits them. Write a temporary config next to the real one with
345
+ the local `ignore*` lists removed, run `knip -c <temporary config>
346
+ --no-config-hints`, and keep exactly the entries whose removal produces a
347
+ report. Also compare local entries with the shared config's defaults; a
348
+ duplicate of a shared default is removable.
349
+ - **ESLint:** write a temporary config that imports the real one and filters out
350
+ the blocks under test, then run `eslint --no-cache -c <temporary config>` on
351
+ exactly the files those blocks target. A block whose `files` match nothing in
352
+ the repository and in its generators is obsolete. A crash workaround is still
353
+ needed when removing it reproduces the crash.
354
+ - Delete temporary configs afterwards; they must never reach the diff.
355
+
356
+ ## Current exceptions
357
+
358
+ Time-bound entries that the rules above reference. Remove each one when its
359
+ condition is met and update this list.
360
+
361
+ - **`eslint-plugin-jsx-a11y` 6 with ESLint 10:** after verifying compatibility
362
+ by the standard in [Overrides and peer rules](#overrides-and-peer-rules), use
363
+ exactly this entry and these comments, merged with other still-needed rules.
364
+ Remove it once the installed plugin declares ESLint 10 support.
365
+
366
+ ```yaml
367
+ peerDependencyRules:
368
+ allowedVersions:
369
+ # Remove once the installed version declares ESLint 10 support.
370
+ # https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/issues/1075
371
+ # https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/pull/1081
372
+ eslint-plugin-jsx-a11y@6>eslint: ^10.0.0
373
+ ```