@avi2dg/checks 0.21.0 → 0.22.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +58 -40
  2. package/CONTRIBUTING.md +11 -8
  3. package/README.md +15 -24
  4. package/bunfig.toml +1 -1
  5. package/docs/configs/commit-messages.md +5 -1
  6. package/docs/configs/dependency-rules.md +5 -2
  7. package/docs/configs/effect-rules.md +32 -33
  8. package/docs/configs/native-settings.md +74 -0
  9. package/docs/configs/typescript-rules.md +4 -0
  10. package/docs/design.md +24 -25
  11. package/docs/gates/checks-backtest.md +4 -0
  12. package/docs/gates/checks-ci-wiring.md +30 -93
  13. package/docs/gates/checks-comment-gate.md +4 -0
  14. package/docs/gates/checks-commit-identity.md +23 -27
  15. package/docs/gates/checks-docs.md +23 -21
  16. package/docs/gates/checks-flake.md +4 -10
  17. package/docs/gates/checks-lint-coverage.md +5 -1
  18. package/docs/gates/checks-lint.md +22 -104
  19. package/docs/gates/checks-mutation-compare.md +4 -0
  20. package/docs/gates/checks-quarantine-clock.md +4 -0
  21. package/docs/gates/checks-repetition.md +26 -41
  22. package/docs/gates/checks-subsumed-tests.md +4 -0
  23. package/docs/gates/checks-suppressions-ratchet.md +4 -0
  24. package/docs/gates/checks-test-layout.md +16 -8
  25. package/docs/gates/checks-test.md +68 -36
  26. package/docs/gates/checks-vendor.md +20 -13
  27. package/package.json +8 -21
  28. package/scripts/ci-wiring.ts +28 -97
  29. package/scripts/commit-identity.ts +32 -4
  30. package/scripts/doc-rules.ts +26 -11
  31. package/scripts/doc-templates.ts +2 -1
  32. package/scripts/docs.ts +4 -7
  33. package/scripts/gates.ts +0 -29
  34. package/scripts/git.ts +24 -1
  35. package/scripts/lint.ts +15 -34
  36. package/scripts/range-gate.ts +1 -2
  37. package/scripts/repetition.ts +40 -40
  38. package/scripts/shell-command.ts +7 -1
  39. package/scripts/swc.ts +46 -0
  40. package/scripts/test-layout.ts +40 -56
  41. package/scripts/test-skips.ts +180 -0
  42. package/scripts/test.ts +33 -38
  43. package/scripts/vendor.ts +55 -11
  44. package/dist/feature-rules.js +0 -354
  45. package/docs/configs/quality-file.md +0 -103
  46. package/docs/gates/checks-feature-owners.md +0 -113
  47. package/docs/gates/checks-quality.md +0 -111
  48. package/docs/gates/checks-size-budget.md +0 -107
  49. package/quality.schema.json +0 -514
  50. package/scripts/feature-owners.ts +0 -139
  51. package/scripts/quality-file.ts +0 -353
  52. package/scripts/quality.ts +0 -363
  53. package/scripts/size-budget.ts +0 -285
  54. package/scripts/size-rules.ts +0 -126
package/CHANGELOG.md CHANGED
@@ -2,13 +2,31 @@
2
2
 
3
3
  Every release of `@avi2dg/checks`, newest first, written by the release from its conventional commits.
4
4
 
5
+ ## 0.22.0
6
+
7
+ Released 2026-09-26.
8
+
9
+ ### Breaking changes
10
+
11
+ - replace quality.json with native configs and workflow gates [#72](https://github.com/avi2d/checks/pull/72)
12
+ - declare test skips inline and add live and pixel test tiers [#71](https://github.com/avi2d/checks/pull/71)
13
+
14
+ ### Features
15
+
16
+ - create GitHub releases with linked changelogs [#70](https://github.com/avi2d/checks/pull/70)
17
+
18
+ ### Fixes
19
+
20
+ - **scripts:** run generated commitlint through bun so the runner needs no node [#69](https://github.com/avi2d/checks/pull/69)
21
+ - **test:** allow npm pack enough time on release runners [#68](https://github.com/avi2d/checks/pull/68)
22
+
5
23
  ## 0.21.0
6
24
 
7
25
  Released 2026-09-26.
8
26
 
9
27
  ### Features
10
28
 
11
- - **scripts:** let quality.json set the runs-on of generated workflows (#66)
29
+ - **scripts:** let quality.json set the runs-on of generated workflows [#66](https://github.com/avi2d/checks/pull/66)
12
30
 
13
31
  ## 0.20.0
14
32
 
@@ -16,12 +34,12 @@ Released 2026-09-26.
16
34
 
17
35
  ### Features
18
36
 
19
- - **scripts:** pin node from .node-version in the generated CI workflow (#64)
20
- - **scripts:** add checks-subsumed-tests to report tests another test subsumes in a (#62)
37
+ - **scripts:** pin node from .node-version in the generated CI workflow [#64](https://github.com/avi2d/checks/pull/64)
38
+ - **scripts:** add checks-subsumed-tests to report tests another test subsumes in a [#62](https://github.com/avi2d/checks/pull/62)
21
39
 
22
40
  ### Fixes
23
41
 
24
- - **scripts:** lint a PR title that starts with # in the generated commitlint workflow (#63)
42
+ - **scripts:** lint a PR title that starts with # in the generated commitlint workflow [#63](https://github.com/avi2d/checks/pull/63)
25
43
 
26
44
  ## 0.19.0
27
45
 
@@ -29,9 +47,9 @@ Released 2026-09-26.
29
47
 
30
48
  ### Features
31
49
 
32
- - **scripts:** judge checks-mutation-compare mutant by mutant instead of by score (#58)
33
- - **scripts:** fail a test left in tests/quarantine past 30 days (#59)
34
- - **scripts:** pin shared read-only library clones with checks-vendor (#57)
50
+ - **scripts:** judge checks-mutation-compare mutant by mutant instead of by score [#58](https://github.com/avi2d/checks/pull/58)
51
+ - **scripts:** fail a test left in tests/quarantine past 30 days [#59](https://github.com/avi2d/checks/pull/59)
52
+ - **scripts:** pin shared read-only library clones with checks-vendor [#57](https://github.com/avi2d/checks/pull/57)
35
53
 
36
54
  ## 0.18.0
37
55
 
@@ -39,11 +57,11 @@ Released 2026-09-26.
39
57
 
40
58
  ### Features
41
59
 
42
- - **scripts:** generate commitlint and CI workflows with checks-quality (#54)
60
+ - **scripts:** generate commitlint and CI workflows with checks-quality [#54](https://github.com/avi2d/checks/pull/54)
43
61
 
44
62
  ### Fixes
45
63
 
46
- - **scripts:** make checks-quality refuse a config that drops the kit's extends (#55)
64
+ - **scripts:** make checks-quality refuse a config that drops the kit's extends [#55](https://github.com/avi2d/checks/pull/55)
47
65
 
48
66
  ## 0.17.0
49
67
 
@@ -51,9 +69,9 @@ Released 2026-09-25.
51
69
 
52
70
  ### Features
53
71
 
54
- - **effect-channel:** add a cognitive complexity rule and make it the size budget's (#50)
55
- - **scripts:** export the refused directive names from comment-matchers (#49)
56
- - refuse undeclared package imports and deprecated symbol use (#48)
72
+ - **effect-channel:** add a cognitive complexity rule and make it the size budget's [#50](https://github.com/avi2d/checks/pull/50)
73
+ - **scripts:** export the refused directive names from comment-matchers [#49](https://github.com/avi2d/checks/pull/49)
74
+ - refuse undeclared package imports and deprecated symbol use [#48](https://github.com/avi2d/checks/pull/48)
57
75
 
58
76
  ## 0.16.0
59
77
 
@@ -61,8 +79,8 @@ Released 2026-09-25.
61
79
 
62
80
  ### Features
63
81
 
64
- - **scripts:** add checks-repetition to hold new repetition in production code (#46)
65
- - **scripts:** add the recommended size limits, a tests budget and an overrun ratchet (#45)
82
+ - **scripts:** add checks-repetition to hold new repetition in production code [#46](https://github.com/avi2d/checks/pull/46)
83
+ - **scripts:** add the recommended size limits, a tests budget and an overrun ratchet [#45](https://github.com/avi2d/checks/pull/45)
66
84
 
67
85
  ## 0.15.0
68
86
 
@@ -70,7 +88,7 @@ Released 2026-09-25.
70
88
 
71
89
  ### Features
72
90
 
73
- - **scripts:** hold living docs to prose rules and resolvable references in checks-docs (#42)
91
+ - **scripts:** hold living docs to prose rules and resolvable references in checks-docs [#42](https://github.com/avi2d/checks/pull/42)
74
92
 
75
93
  ## 0.14.0
76
94
 
@@ -78,8 +96,8 @@ Released 2026-09-25.
78
96
 
79
97
  ### Features
80
98
 
81
- - **scripts:** generate README blocks, check CONTRIBUTING.md, and give each bin a page (#39)
82
- - **scripts:** generate CHANGELOG.md from conventional commits and ship it in the package (#40)
99
+ - **scripts:** generate README blocks, check CONTRIBUTING.md, and give each bin a page [#39](https://github.com/avi2d/checks/pull/39)
100
+ - **scripts:** generate CHANGELOG.md from conventional commits and ship it in the package [#40](https://github.com/avi2d/checks/pull/40)
83
101
 
84
102
  ## 0.13.0
85
103
 
@@ -87,7 +105,7 @@ Released 2026-09-25.
87
105
 
88
106
  ### Features
89
107
 
90
- - **scripts:** add checks-docs gate holding doc files to shared templates (#37)
108
+ - **scripts:** add checks-docs gate holding doc files to shared templates [#37](https://github.com/avi2d/checks/pull/37)
91
109
 
92
110
  ## 0.12.0
93
111
 
@@ -95,11 +113,11 @@ Released 2026-09-24.
95
113
 
96
114
  ### Features
97
115
 
98
- - **scripts:** add size budget, feature-owner rules and change-signal gates (#35)
116
+ - **scripts:** add size budget, feature-owner rules and change-signal gates [#35](https://github.com/avi2d/checks/pull/35)
99
117
 
100
118
  ### Fixes
101
119
 
102
- - release 0.12.0 and read local exports in checks-feature-owners (#36)
120
+ - release 0.12.0 and read local exports in checks-feature-owners [#36](https://github.com/avi2d/checks/pull/36)
103
121
 
104
122
  ## 0.11.0
105
123
 
@@ -107,7 +125,7 @@ Released 2026-09-24.
107
125
 
108
126
  ### Features
109
127
 
110
- - **scripts:** add quality.json with schema, loader and checks-quality fragment generator (#33)
128
+ - **scripts:** add quality.json with schema, loader and checks-quality fragment generator [#33](https://github.com/avi2d/checks/pull/33)
111
129
 
112
130
  ## 0.10.0
113
131
 
@@ -115,7 +133,7 @@ Released 2026-09-24.
115
133
 
116
134
  ### Features
117
135
 
118
- - **scripts:** add checks-test skip gate and checks-flake seed recorder (#31)
136
+ - **scripts:** add checks-test skip gate and checks-flake seed recorder [#31](https://github.com/avi2d/checks/pull/31)
119
137
 
120
138
  ## 0.9.0
121
139
 
@@ -123,14 +141,14 @@ Released 2026-09-24.
123
141
 
124
142
  ### Features
125
143
 
126
- - **scripts:** let ciWiring.lintGates select the gates checks-lint runs (#29)
127
- - **oxlintrc:** turn on no-unsafe-type-assertion and no-non-null-assertion (#26)
144
+ - **scripts:** let ciWiring.lintGates select the gates checks-lint runs [#29](https://github.com/avi2d/checks/pull/29)
145
+ - **oxlintrc:** turn on no-unsafe-type-assertion and no-non-null-assertion [#26](https://github.com/avi2d/checks/pull/26)
128
146
 
129
147
  ### Fixes
130
148
 
131
- - **scripts:** split Effect-free comment matchers out for hosts without node_modules (#30)
132
- - **scripts:** judge a repository's first commit against the empty tree in the range gates (#28)
133
- - **lint:** cruise the whole repo; lint-coverage counts skips and exits 2 on a failed walk (#27)
149
+ - **scripts:** split Effect-free comment matchers out for hosts without node_modules [#30](https://github.com/avi2d/checks/pull/30)
150
+ - **scripts:** judge a repository's first commit against the empty tree in the range gates [#28](https://github.com/avi2d/checks/pull/28)
151
+ - **lint:** cruise the whole repo; lint-coverage counts skips and exits 2 on a failed walk [#27](https://github.com/avi2d/checks/pull/27)
134
152
 
135
153
  ## 0.8.0
136
154
 
@@ -138,8 +156,8 @@ Released 2026-09-24.
138
156
 
139
157
  ### Features
140
158
 
141
- - **scripts:** add checks-lint to run every kit lint gate over one resolved range (#25)
142
- - **scripts:** run the bins on Effect and hold scripts/ to Effect-native IO (#22)
159
+ - **scripts:** add checks-lint to run every kit lint gate over one resolved range [#25](https://github.com/avi2d/checks/pull/25)
160
+ - **scripts:** run the bins on Effect and hold scripts/ to Effect-native IO [#22](https://github.com/avi2d/checks/pull/22)
143
161
 
144
162
  ## 0.6.0
145
163
 
@@ -147,7 +165,7 @@ Released 2026-09-24.
147
165
 
148
166
  ### Features
149
167
 
150
- - add checks-suppressions-ratchet to refuse a raised oxlint suppression count (#21)
168
+ - add checks-suppressions-ratchet to refuse a raised oxlint suppression count [#21](https://github.com/avi2d/checks/pull/21)
151
169
 
152
170
  ## 0.5.0
153
171
 
@@ -155,7 +173,7 @@ Released 2026-09-24.
155
173
 
156
174
  ### Features
157
175
 
158
- - **effect-channel:** add opt-in no-throw and no-try-catch rules (#20)
176
+ - **effect-channel:** add opt-in no-throw and no-try-catch rules [#20](https://github.com/avi2d/checks/pull/20)
159
177
 
160
178
  ## 0.4.0
161
179
 
@@ -163,11 +181,11 @@ Released 2026-09-24.
163
181
 
164
182
  ### Features
165
183
 
166
- - add checks-ci-wiring to confirm CI runs each declared gate on pull requests (#19)
184
+ - add checks-ci-wiring to confirm CI runs each declared gate on pull requests [#19](https://github.com/avi2d/checks/pull/19)
167
185
 
168
186
  ### Fixes
169
187
 
170
- - pin the quarantine pathIgnorePatterns in the test-layout bunfig check (#18)
188
+ - pin the quarantine pathIgnorePatterns in the test-layout bunfig check [#18](https://github.com/avi2d/checks/pull/18)
171
189
 
172
190
  ## 0.3.0
173
191
 
@@ -175,8 +193,8 @@ Released 2026-09-23.
175
193
 
176
194
  ### Features
177
195
 
178
- - add checks-mutation-compare no-regression gate for Stryker reports (#17)
179
- - ship a shared Stryker mutation-testing preset (#16)
196
+ - add checks-mutation-compare no-regression gate for Stryker reports [#17](https://github.com/avi2d/checks/pull/17)
197
+ - ship a shared Stryker mutation-testing preset [#16](https://github.com/avi2d/checks/pull/16)
180
198
 
181
199
  ## 0.2.0
182
200
 
@@ -184,11 +202,11 @@ Released 2026-09-23.
184
202
 
185
203
  ### Features
186
204
 
187
- - expose runnable scripts as checks- bins for consumer package scripts (#15)
188
- - rename npm package from @avi2d/checks to @avi2dg/checks (#14)
189
- - add a shared comment gate and backtest command (#12)
190
- - publish @avi2d/checks to the public npm registry (#11)
205
+ - expose runnable scripts as checks- bins for consumer package scripts [#15](https://github.com/avi2d/checks/pull/15)
206
+ - rename npm package from @avi2d/checks to @avi2dg/checks [#14](https://github.com/avi2d/checks/pull/14)
207
+ - add a shared comment gate and backtest command [#12](https://github.com/avi2d/checks/pull/12)
208
+ - publish @avi2d/checks to the public npm registry [#11](https://github.com/avi2d/checks/pull/11)
191
209
 
192
210
  ### Fixes
193
211
 
194
- - count violation lines from file top, drop dead moduleStart (#10)
212
+ - count violation lines from file top, drop dead moduleStart [#10](https://github.com/avi2d/checks/pull/10)
package/CONTRIBUTING.md CHANGED
@@ -16,7 +16,9 @@ To check a change the way CI does:
16
16
  1. Run `bun run typecheck`.
17
17
  1. Run `bun run test`, which runs the suite through `scripts/test.ts`.
18
18
 
19
- CI runs the commands `gates.ci` lists in `quality.json`, which include `git diff --exit-code` over the whole tree after the build and the commit lint on the pull request title.
19
+ Declare each skip with `skipReason(reason, name)` beside the native Bun test call, as [checks-test](docs/gates/checks-test.md) says.
20
+
21
+ CI runs the commands in `.github/workflows/ci.yml` and lints the pull request title in `.github/workflows/commitlint.yml`.
20
22
 
21
23
  ## Regenerate what is committed
22
24
 
@@ -24,9 +26,8 @@ Each generated file is committed, and lint, the suite or CI's diff after the bui
24
26
 
25
27
  To regenerate after an edit:
26
28
 
27
- 1. After editing `sources.effect` in `quality.json` or a file in `presets/`, run `bun scripts/quality.ts generate`, which rewrites `oxlintrc.quality.json` and `tsconfig.quality.json`.
28
- 1. After editing `effect-channel/`, `scripts/feature-rules.ts`, the schema in `scripts/quality-file.ts` or the templates in `scripts/doc-templates.ts`, run `bun run build`.
29
- It rewrites `dist/index.js`, `dist/feature-rules.js`, `quality.schema.json` and `templates/`.
29
+ 1. After editing `effect-channel/` or the templates in `scripts/doc-templates.ts`, run `bun run build`.
30
+ It rewrites `dist/index.js` and `templates/`.
30
31
  1. After editing anything a generated block names as its source in its opening marker, run `bun run build`, which rewrites every generated block.
31
32
  1. Commit what the command rewrote in the same commit as the edit.
32
33
 
@@ -49,7 +50,9 @@ To release a version:
49
50
  ```
50
51
 
51
52
  1. Watch the `release` workflow.
52
- It refuses a tag off `main` or one that disagrees with `package.json`, and reruns the build, the check that the build changed no committed file, lint, typecheck and the suite before it publishes.
53
+ It refuses a tag off `main` or one that disagrees with `package.json`.
54
+ It reruns the build, the check that the build changed no committed file, lint, typecheck and the suite before it publishes to npm.
55
+ After npm publish succeeds, the workflow creates or updates the GitHub release with the matching `CHANGELOG.md` section.
53
56
 
54
57
  `publishConfig.access` in `package.json` is what makes the scoped package public.
55
58
  npm attaches a trusted publisher only to a package that already exists, so a package's first version goes out by hand.
@@ -66,15 +69,15 @@ To place a change:
66
69
  | --- | --- |
67
70
  | `scripts/` | every bin, and the modules they share |
68
71
  | `effect-channel/` | the oxlint plugin with the Effect error-channel and cognitive complexity rules |
69
- | `dist/` | the committed bundles of the plugin and of `featureRules` |
70
- | `presets/` | the Effect presets `checks-quality` builds its fragments from |
72
+ | `dist/` | the committed oxlint plugin bundle |
73
+ | `presets/` | the Effect rule blocks consumers copy into native configs |
71
74
  | `templates/` | one template per kind of doc file, which `bun run build` renders |
72
75
  | `CHANGELOG.md` | every release, which `bun run build` writes from the conventional commits |
73
76
  | `tests/` | the suite, with the tests that spawn a process under `tests/e2e/` |
74
77
  | `docs/gates/` | one reference page per bin |
75
78
  | `docs/configs/` | one reference page per shipped config a bin does not own |
76
79
  | `docs/design.md` | why the kit is shaped the way it is |
77
- | the root configs | `oxlintrc.json`, `tsconfig.effect.json`, `bunfig.toml`, `commitlint.config.js`, `dependency-cruiser.config.js`, `stryker.preset.js` and `quality.schema.json`, which a consuming repository extends or copies |
80
+ | the root configs | `oxlintrc.json`, `tsconfig.effect.json`, `bunfig.toml`, `commitlint.config.js`, `dependency-cruiser.config.js`, `stryker.preset.js`, which a consuming repository extends or copies |
78
81
 
79
82
  1. Change the page under `docs/` that describes the behaviour in the same commit as the behaviour.
80
83
  A new bin gets its page under `docs/gates/`, and the suite fails until it has one.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `@avi2dg/checks` is the kit of deterministic checks a TypeScript repository installs to hold its code, tests, commits, CI wiring and docs to one shared standard.
4
4
  It ships the lint gates `checks-lint` runs over each pull request, the test runners, and the configs a repository extends for oxlint, tsc, dependency-cruiser, commitlint, bun and Stryker.
5
- A repository declares what it opts into once, in `quality.json`, and each check decides its constraint the same way on every run.
5
+ Each repository owns its workflows and native tool configs, as [Native settings](docs/configs/native-settings.md) maps.
6
6
 
7
7
  ## Before you begin
8
8
 
@@ -59,30 +59,22 @@ To consume the kit from a repository:
59
59
  }
60
60
  ```
61
61
 
62
- 1. Declare the commands CI runs in `quality.json` at the repository root:
63
-
64
- ```json
65
- {
66
- "$schema": "./node_modules/@avi2dg/checks/quality.schema.json",
67
- "gates": { "ci": ["bun run lint", "bun run typecheck", "bun run test"] }
68
- }
69
- ```
70
-
71
62
  1. Copy the bunfig preset:
72
63
 
73
64
  ```sh
74
65
  cp node_modules/@avi2dg/checks/bunfig.toml bunfig.toml
75
66
  ```
76
67
 
77
- 1. Add three scripts to `package.json`:
68
+ 1. Add scripts to `package.json`, replacing the build entry with the repository's own build command:
78
69
 
79
70
  ```json
71
+ "build": "bun build src/index.ts --outdir dist --target node",
80
72
  "lint": "oxlint --type-aware && checks-lint",
81
73
  "typecheck": "tsc --noEmit && effect-tsgo diagnostics --project tsconfig.json --format text --strict",
82
74
  "test": "checks-test"
83
75
  ```
84
76
 
85
- 1. Run the three on every pull request in `.github/workflows/ci.yml`, fetching the whole history the range needs:
77
+ 1. Run the scripts on every pull request in `.github/workflows/ci.yml`, fetching the whole history the range needs:
86
78
 
87
79
  ```yaml
88
80
  on:
@@ -96,17 +88,20 @@ To consume the kit from a repository:
96
88
  fetch-depth: 0
97
89
  - uses: oven-sh/setup-bun@v2
98
90
  - run: bun install --frozen-lockfile
91
+ - run: bun run build
92
+ - run: git diff --exit-code
99
93
  - run: bun run lint
100
94
  - run: bun run typecheck
101
95
  - run: bun run test
102
96
  ```
103
97
 
98
+ Add a pull request title lint step in another workflow using `./node_modules/.bin/commitlint`.
104
99
  `bun run lint` then ends with `checks-lint: <count> gate(s) pass`.
105
100
 
106
101
  ## What runs
107
102
 
108
103
  `checks-lint` runs these gates in this order, each over the working tree or over the range it resolves, and names every one that fails.
109
- A repository leaves out a gate that does not apply to it through `gates.lint`, as [Gate selection](docs/gates/checks-lint.md#gate-selection) says.
104
+ `checks-lint` runs every applicable gate, including the TypeScript gates once the repository tracks TypeScript.
110
105
 
111
106
  <!-- generated gates: bun run build writes it from KIT_GATES in scripts/gates.ts and scripts/doc-blocks.ts -->
112
107
 
@@ -119,22 +114,19 @@ A repository leaves out a gate that does not apply to it through `gates.lint`, a
119
114
  | [`checks-suppressions-ratchet`](docs/gates/checks-suppressions-ratchet.md) | the range | every repository |
120
115
  | [`checks-ci-wiring`](docs/gates/checks-ci-wiring.md) | the working tree | every repository |
121
116
  | [`checks-docs`](docs/gates/checks-docs.md) | the range | every repository |
122
- | [`checks-quality`](docs/gates/checks-quality.md) | the working tree | a repository tracking `quality.json` |
123
- | [`checks-size-budget`](docs/gates/checks-size-budget.md) | the range | a repository tracking `*.ts` or `*.tsx` |
124
117
  | [`checks-repetition`](docs/gates/checks-repetition.md) | the range | a repository tracking `*.ts` or `*.tsx` |
125
- | [`checks-feature-owners`](docs/gates/checks-feature-owners.md) | the range | a repository tracking `*.ts` or `*.tsx` |
126
118
  | [`checks-quarantine-clock`](docs/gates/checks-quarantine-clock.md) | the range | every repository |
127
119
 
128
120
  <!-- end generated gates -->
129
121
 
130
122
  These bins run on their own:
131
123
 
132
- - [`checks-test`](docs/gates/checks-test.md) runs the suite as `scripts.test` and refuses a skip the repository has not declared.
124
+ - [`checks-test`](docs/gates/checks-test.md) runs the suite as `scripts.test` and refuses a skip without a reason at its test site.
133
125
  - [`checks-flake`](docs/gates/checks-flake.md) runs the suite on a schedule and records the seeds a flaky test fails with.
134
126
  - [`checks-mutation-compare`](docs/gates/checks-mutation-compare.md) holds every mutant in a pull request to no regression.
135
127
  - [`checks-subsumed-tests`](docs/gates/checks-subsumed-tests.md) lists each test another test subsumes in a mutation run.
136
128
  - [`checks-backtest`](docs/gates/checks-backtest.md) reports what the comment check would have refused in recent history.
137
- - [`checks-vendor`](docs/gates/checks-vendor.md) pins each library `quality.json` declares to a shared read-only clone and links it under `repos/`.
129
+ - [`checks-vendor`](docs/gates/checks-vendor.md) pins each library its `prepare` arguments name to a shared read-only clone and links it under `repos/`.
138
130
 
139
131
  `checks-lint` has [its own page](docs/gates/checks-lint.md), which says which range it resolves.
140
132
  The oxlint base, the dependency-cruiser base and the commitlint config run through their own tools, as the pages under Related topics say.
@@ -144,13 +136,13 @@ The oxlint base, the dependency-cruiser base and the commitlint config run throu
144
136
  To move a repository to a newer release of the kit:
145
137
 
146
138
  1. Run the install line again, which moves the kit to its newest release and the peers to the versions it pins.
147
- 1. Run `bun run checks-quality generate` when `quality.json` declares `sources.effect`, since a release that changes a preset reaches the fragments only through it.
139
+ 1. Review the Effect overrides in `.oxlintrc.json` and `tsconfig.json` when a release changes their presets.
148
140
  1. Copy `node_modules/@avi2dg/checks/bunfig.toml` over `bunfig.toml` again, since `checks-test-layout` compares the copy with the installed preset.
149
141
  1. Run `bun run lint`, `bun run typecheck` and `bun run test`.
150
142
 
151
143
  The repository's lockfile pins the kit, so a repository moves only when it runs these steps.
152
144
  [CHANGELOG.md](CHANGELOG.md), shipped in the package, lists what each release changed.
153
- A repository that still declares `ciWiring` or `commitIdentity` in `package.json` moves them into `quality.json`, as [Keys moved from package.json](docs/configs/quality-file.md#keys-moved-from-packagejson) maps.
145
+ A repository that tracks `quality.json` moves its settings as [Native settings](docs/configs/native-settings.md#consumer-migration) maps.
154
146
 
155
147
  ## Where things are
156
148
 
@@ -168,18 +160,17 @@ Every path is relative to the installed package, `node_modules/@avi2dg/checks/`.
168
160
  | `dependency-cruiser.config.js` | the shared dependency-cruiser base |
169
161
  | `scripts/` | every bin, which a package script calls by its `checks-` name |
170
162
  | `templates/` | one template per kind of doc file, which a new doc file starts from |
171
- | `presets/` | the Effect rule blocks `checks-quality generate` writes into the fragments |
172
- | `quality.schema.json` | the schema of `quality.json`, which its `$schema` line names |
163
+ | `presets/` | the Effect rule blocks a repository copies into its native config |
173
164
  | `oxlintrc.json` | the oxlint base config `.oxlintrc.json` extends |
174
165
  | `stryker.preset.js` | the Stryker mutation-testing preset |
175
166
  | `tsconfig.effect.json` | the tsconfig fragment with the Effect language-service block |
176
- | `dist/` | the compiled oxlint plugin with the Effect error-channel and cognitive complexity rules, and `featureRules` |
167
+ | `dist/` | the compiled oxlint plugin with the Effect error-channel and cognitive complexity rules |
177
168
 
178
169
  <!-- end generated shipped -->
179
170
 
180
171
  ## Related topics
181
172
 
182
- - [The quality file](docs/configs/quality-file.md)
173
+ - [Native settings](docs/configs/native-settings.md)
183
174
  - [The Effect rules](docs/configs/effect-rules.md)
184
175
  - [The TypeScript rules](docs/configs/typescript-rules.md)
185
176
  - [The dependency rules](docs/configs/dependency-rules.md)
package/bunfig.toml CHANGED
@@ -1,2 +1,2 @@
1
1
  [test]
2
- pathIgnorePatterns = ["**/tests/quarantine/**", "repos/**"]
2
+ pathIgnorePatterns = ["**/tests/quarantine/**", "**/tests/live/**", "**/tests/pixel/**", "repos/**"]
@@ -1,3 +1,7 @@
1
+ ---
2
+ kind: reference
3
+ audience: consumers
4
+ ---
1
5
  # The commit message lint
2
6
 
3
7
  The shared commitlint config holds each pull request title to conventional commits, and a reader looks it up to wire the lint into a repository's CI.
@@ -10,7 +14,7 @@ It arrives with the kit, since `@commitlint/cli` and `@commitlint/config-convent
10
14
  ## Workflow
11
15
 
12
16
  The lint runs in CI on pull requests, because `jj` never fires a git hook.
13
- `checks-quality generate` writes the workflow whole into `.github/workflows/commitlint.yml`, as [checks-quality](../gates/checks-quality.md) says.
17
+ Each repository owns `.github/workflows/commitlint.yml` and runs the installed `commitlint` binary in a pull request step.
14
18
  The workflow lints with the installed kit's `commitlint.config.js`, so every repository holds titles to the same rules.
15
19
 
16
20
  ## What it lints
@@ -1,3 +1,7 @@
1
+ ---
2
+ kind: reference
3
+ audience: consumers
4
+ ---
1
5
  # The dependency rules
2
6
 
3
7
  The shared dependency-cruiser base holds a repository's imports to a set of rules every repository shares, and a reader looks it up to add a boundary of its own.
@@ -35,7 +39,7 @@ module.exports = {
35
39
 
36
40
  A rule that restates a base name overrides it field by field.
37
41
  That is how an entry point stops being an orphan: redeclare `no-orphans` with the entry added to its `pathNot`.
38
- A repository that declares feature owners spreads the rules `quality.json` compiles to into the same `forbidden`, as [checks-feature-owners](../gates/checks-feature-owners.md#import-boundary) says.
42
+ A repository with an import boundary writes its rule directly under `forbidden`.
39
43
 
40
44
  ## Running it
41
45
 
@@ -59,5 +63,4 @@ jobs:
59
63
 
60
64
  ## Related topics
61
65
 
62
- - [checks-feature-owners](../gates/checks-feature-owners.md)
63
66
  - [Why it is shaped this way](../design.md)
@@ -1,49 +1,48 @@
1
+ ---
2
+ kind: reference
3
+ audience: consumers
4
+ ---
1
5
  # The Effect rules
2
6
 
3
- The oxlint base config and the tsconfig fragment hold a repository's Effect code to its error channel and to Effect-native IO, and a reader looks them up to learn what each rule refuses and how a path opts in.
7
+ The oxlint base and Effect language service check paths a repository writes with Effect.
4
8
 
5
- ## Base config
9
+ ## Oxlint override
6
10
 
7
- The base config, `oxlintrc.json`, loads the `effect-channel` plugin and turns on `effect-channel/no-error-channel-escape`.
8
- That rule refuses `Effect.ignore`, `Effect.ignoreCause`, the `Effect.catchCause` family, and an `Effect.catch` whose handler takes no error or names it `_`.
9
-
10
- Two more rules ship off, because a repository writes only some of its paths in Effect, and code a host loads without `node_modules`, such as a hook bundle or this oxlint plugin, cannot import it:
11
-
12
- - `effect-channel/no-throw` refuses a `throw` statement.
13
- - `effect-channel/no-try-catch` refuses a `try` statement with a `catch` clause, and `try`/`finally` stays allowed.
14
-
15
- Each refusal says what to write instead: a `Schema.TaggedError` failed through `Effect.fail`, a throwing call wrapped in `Effect.try` or `Effect.tryPromise`, and recovery by tag with `Effect.catchTag`.
16
-
17
- ## Effect paths
18
-
19
- A repository turns the rules on for the paths it writes in Effect by declaring those paths in `quality.json` and extending the fragments [checks-quality](../gates/checks-quality.md) generates:
11
+ The shared `oxlintrc.json` loads `effect-channel/no-error-channel-escape` across the tree.
12
+ The repo's `.oxlintrc.json` owns its Effect paths and exemptions in an override:
20
13
 
21
14
  ```json
22
- "sources": {
23
- "effect": { "paths": ["src/**/*.ts"], "exempt": ["src/host/*.ts"] }
15
+ {
16
+ "extends": ["./node_modules/@avi2dg/checks/oxlintrc.json"],
17
+ "plugins": ["typescript", "oxc", "eslint", "import"],
18
+ "overrides": [{
19
+ "files": ["src/**/*.ts"],
20
+ "excludeFiles": ["src/host/*.ts"],
21
+ "plugins": ["typescript", "oxc", "eslint", "import", "node", "promise", "unicorn"],
22
+ "rules": {
23
+ "node/no-sync": "error",
24
+ "oxc/no-async-await": "error",
25
+ "promise/avoid-new": "error",
26
+ "unicorn/no-process-exit": "error",
27
+ "effect-channel/no-throw": "error",
28
+ "effect-channel/no-try-catch": "error"
29
+ }
30
+ }]
24
31
  }
25
32
  ```
26
33
 
27
- The fragment's override carries the kit's Effect rule block, `presets/effect.oxlint.json`.
28
- It holds the two rules above, plus `node/no-sync`, `oxc/no-async-await`, `promise/avoid-new` and `unicorn/no-process-exit`.
29
- Files under `exempt` answer to none of them.
30
-
31
- oxlint resolves `files` against the directory of the config that holds the override, so a config passed with `-c` from outside the repository matches nothing and reports nothing.
32
-
33
- `unicorn/no-process-exit` passes over any file that opens with a shebang.
34
- A repository whose bins open with one bans `process.exit` itself with `no-restricted-properties` in its own `.oxlintrc.json`, as the kit's own repository does.
35
- The preset leaves that rule out because a repository's own `no-restricted-properties` list for the same files would replace it, or be replaced by it.
36
- Sites standing when the declaration lands go in oxlint's own baseline, `oxlint --suppress-all`, so their count can only fall, as [checks-suppressions-ratchet](../gates/checks-suppressions-ratchet.md) holds.
34
+ The kit ships the rule block in `presets/effect.oxlint.json` for copying into the override.
35
+ Each config in an oxlint `extends` chain sets `plugins` explicitly, because an omitted list enables defaults across the chain.
36
+ `unicorn/no-process-exit` does not check a shebang script, so a bin can use `eslint/no-restricted-properties` for `process.exit`.
37
37
 
38
38
  ## Language service
39
39
 
40
- The language service holds the same paths to Effect-native IO through the tsconfig fragment's override, whose severities are `presets/effect.language-service.json`.
41
- `nodeBuiltinImport`, `asyncFunction`, `newPromise` and `extendsNativeError` are all errors.
42
- effect-tsgo keeps the severities `tsconfig.effect.json` sets when a later config in `extends` restates the plugin with only its overrides.
40
+ The repository's `tsconfig.json` holds its Effect override under `compilerOptions.plugins`.
41
+ The override includes the same source paths and excludes the same exempt paths as oxlint.
42
+ The kit ships severity values in `presets/effect.language-service.json` for the override's `options`.
43
+ The kit's `tsconfig.effect.json` keeps the shared language service diagnostics.
43
44
 
44
45
  ## Related topics
45
46
 
46
47
  - [The TypeScript rules](typescript-rules.md)
47
- - [checks-quality](../gates/checks-quality.md)
48
- - [The quality file](quality-file.md)
49
- - [Why it is shaped this way](../design.md)
48
+ - [Native settings](native-settings.md)
@@ -0,0 +1,74 @@
1
+ ---
2
+ kind: reference
3
+ audience: consumers
4
+ ---
5
+ # Native settings
6
+
7
+ A consuming repository puts each setting in the file its tool reads.
8
+
9
+ ## Settings by file
10
+
11
+ | File | Setting | Reader |
12
+ | --- | --- | --- |
13
+ | `.github/workflows/*.yml` | Pull request commands, scheduled commands, runner labels | GitHub Actions and `checks-ci-wiring` |
14
+ | `.oxlintrc.json` | Effect paths, exemptions, file size, function size, statements, cognitive complexity and depth | oxlint |
15
+ | `oxlint-suppressions.json` | The existing violations oxlint suppresses, per file and rule | oxlint and `checks-suppressions-ratchet` |
16
+ | `.jscpd.json` | The `path` and `ignore` globs of the files repetition is measured in | jscpd and `checks-repetition` |
17
+ | `tsconfig.json` | Effect language service scope and severity | TypeScript and Effect language service |
18
+ | `package.json` | `scripts` with the `checks-vendor` arguments in `prepare`, `author` and `contributors` | Bun, `checks-commit-identity` and `checks-vendor` |
19
+ | `bunfig.toml` | Test discovery and quarantine exclusion | Bun and `checks-test-layout` |
20
+ | `.dependency-cruiser.cjs` | Import rules | dependency-cruiser |
21
+ | `stryker.conf.mjs` | Mutation settings | Stryker |
22
+ | Each page under `docs/` | Diátaxis mode in `kind` front matter, and `audience: consumers` on a page that speaks to a consuming repository | `checks-docs` |
23
+
24
+ Every page under `docs/` names its mode in `kind` front matter, whatever directory holds it.
25
+ A page whose front matter sets `audience: consumers` names commands a consuming repository runs, so `checks-docs` does not hold them to this `package.json`.
26
+ Every other living doc names commands this repository runs, and `checks-docs` holds each one to its `package.json`.
27
+
28
+ ## Consumer migration
29
+
30
+ The following table maps the former fields to their owners.
31
+
32
+ | Former field | New owner |
33
+ | --- | --- |
34
+ | `defaultBranch` | Git's `refs/remotes/origin/HEAD`, or the pull request base or event repository in CI |
35
+ | `runsOn`, `gates.ci`, `gates.scheduled` | `runs-on` and `run` steps in `.github/workflows/*.yml` |
36
+ | `gates.lint` | `checks-lint` runs every kit gate |
37
+ | `commitIdentity.authors` | `author` and `contributors` in `package.json` |
38
+ | `sources.production` | `path` and `ignore` in `.jscpd.json` |
39
+ | `size.production`, `size.tests` | File overrides and native size rules in `.oxlintrc.json` |
40
+ | `sources.effect.paths`, `sources.effect.exempt` | Overrides in `.oxlintrc.json` and `tsconfig.json` |
41
+ | `sources.libraries` | `checks-vendor` arguments in the `prepare` script of `package.json` |
42
+ | `docs.pages` | `kind` front matter on each page |
43
+ | `docs.forConsumers` | `audience: consumers` front matter on each page |
44
+ | `features`, `changeSignal`, `agentRules` | No active declarations used these fields |
45
+
46
+ The kit has no general configuration manifest or generated workflow.
47
+ `checks-ci-wiring` requires title lint on opened and synchronized pull requests.
48
+ It also requires lint, build, typecheck and test for each of those scripts that `package.json` defines, and a clean git diff after a build.
49
+ `checks-repetition` runs jscpd with the repository's own `.jscpd.json`, so its `path` and `ignore` globs decide which files are measured.
50
+
51
+ ## Size limits
52
+
53
+ The size rules are plain oxlint rules at `error` in `.oxlintrc.json`, and `bun run lint` enforces them on the whole tree.
54
+ A repository records its existing violations with `oxlint --suppress-all`, which writes them to `oxlint-suppressions.json`.
55
+ `checks-suppressions-ratchet` refuses any count in that file that rises, so the recorded debt only falls.
56
+ The kit's own `.oxlintrc.json` sets these limits for each size override, and a repository may copy them:
57
+
58
+ <!-- generated size-limits: bun run build writes it from .oxlintrc.json, SIZE_RULES in scripts/size-rules.ts and scripts/doc-blocks.ts -->
59
+
60
+ | Limits | oxlint rule | `effect-channel/**/*.ts`, `scripts/**/*.ts` | `tests/**/*.ts` |
61
+ | --- | --- | --- | --- |
62
+ | The most lines a file may hold, blank and comment lines counted | `max-lines` | 400 | 600 |
63
+ | The most lines a function may span, blank and comment lines counted | `max-lines-per-function` | 100 | off |
64
+ | The most statements a function may hold | `max-statements` | 30 | 50 |
65
+ | The highest cognitive complexity a function may reach, a switch counted once | `effect-channel/cognitive-complexity` | 15 | 15 |
66
+ | The deepest a block may nest inside a function | `max-depth` | 4 | 4 |
67
+
68
+ <!-- end generated size-limits -->
69
+
70
+ ## Related topics
71
+
72
+ - [The Effect rules](effect-rules.md)
73
+ - [The CI wiring check](../gates/checks-ci-wiring.md)
74
+ - [The suppressions ratchet](../gates/checks-suppressions-ratchet.md)
@@ -1,3 +1,7 @@
1
+ ---
2
+ kind: reference
3
+ audience: consumers
4
+ ---
1
5
  # The TypeScript rules
2
6
 
3
7
  The oxlint base config holds a repository's TypeScript to a set of rules, and a reader looks it up to learn what each rule refuses and which rules need type information.