@descent-vtt/spec-guard 0.12.0 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -40
- package/README.md +34 -27
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +6 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +8 -0
- package/dist/mcp.js.map +1 -1
- package/dist/query.d.ts +7 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +1 -1
- package/dist/query.js.map +1 -1
- package/dist/runner.d.ts +7 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +2 -1
- package/dist/runner.js.map +1 -1
- package/dist/specs.d.ts +22 -0
- package/dist/specs.d.ts.map +1 -1
- package/dist/specs.js +42 -11
- package/dist/specs.js.map +1 -1
- package/dist/vendor/spec-core/markdown/links.d.ts +3 -0
- package/dist/vendor/spec-core/markdown/links.d.ts.map +1 -1
- package/dist/vendor/spec-core/markdown/links.js +32 -2
- package/dist/vendor/spec-core/markdown/links.js.map +1 -1
- package/dist/vendor/spec-core/markdown/scan.d.ts.map +1 -1
- package/dist/vendor/spec-core/markdown/scan.js +31 -7
- package/dist/vendor/spec-core/markdown/scan.js.map +1 -1
- package/dist/vendor/spec-core/markdown/types.d.ts +4 -1
- package/dist/vendor/spec-core/markdown/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/vendor/spec-core/README.md +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,78 @@ All notable changes to this project are documented here. Versions follow
|
|
|
5
5
|
may change in a minor release — each such change is listed under **Changed**
|
|
6
6
|
with the flag that restores the previous behaviour.
|
|
7
7
|
|
|
8
|
+
## 0.12.2
|
|
9
|
+
|
|
10
|
+
A packaging fix: the tarball no longer carries spec-core's internal README.
|
|
11
|
+
Nothing a command does has changed.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **The package ships one README, its own.** `files` named `README.md`,
|
|
16
|
+
which npm reads as a name at any depth, so the tarball carried spec-core's
|
|
17
|
+
vendored README beside the licence it ships; the entry is `/README.md`.
|
|
18
|
+
|
|
19
|
+
## 0.12.1
|
|
20
|
+
|
|
21
|
+
The query is fast again. A warm `query` in the MCP server took 27 ms over this
|
|
22
|
+
repository's specs after 0.12.0 moved to spec-core's scanner, past the 20 ms
|
|
23
|
+
ADR-0012 set; it now takes about 6 ms, faster than 0.11.0. The scanner makes
|
|
24
|
+
only what it is asked for, and the server parses a spec again only when its
|
|
25
|
+
bytes change. The shipped README and changelog link to the ADRs by address,
|
|
26
|
+
so the links lead somewhere on npmjs.com and inside `node_modules`.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **`createDocumentMemo`, and `documents` on `runSpecGuard`, `loadRuleSet`,
|
|
31
|
+
`queryRules` and `impactOf`**: parsed spec documents kept from one call to
|
|
32
|
+
the next, for a process that reads the specs on every request. Every spec
|
|
33
|
+
is still found and read, so an edit is seen by the next call; a document is
|
|
34
|
+
parsed again only when its bytes change. It holds one parse of each
|
|
35
|
+
document the spec set read last names, and forgets one removed, left out or
|
|
36
|
+
edited at the next read. The MCP server keeps one for its lifetime; a
|
|
37
|
+
command run once takes none, and parses every document and hashes none, as
|
|
38
|
+
before.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- **The README's and the changelog's links to the ADRs lead somewhere on
|
|
43
|
+
npmjs.com and in node_modules.** They were relative, and the package ships
|
|
44
|
+
neither `docs/` nor `.github/`, so outside the repository the 66 links to
|
|
45
|
+
ADRs and the one to the release workflow led nowhere. Each is an absolute
|
|
46
|
+
URL to the file on GitHub now, and a link to a file the package ships stays
|
|
47
|
+
relative. `tests/package.test.ts` holds every Markdown document the package
|
|
48
|
+
ships to that, and each absolute link to a file the repository holds.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- `npm publish` in a checkout refuses to run outside GitHub Actions, so a
|
|
53
|
+
version cannot reach npm from a workstation by mistake, without provenance;
|
|
54
|
+
spec-harness 0.1.0 did. The release never runs it: it stages a tarball it
|
|
55
|
+
packed.
|
|
56
|
+
- **spec-core is copied again, from `8840d36`**, `markdown` alone, and
|
|
57
|
+
verified by hash. Its scanner makes links, list items and the directives
|
|
58
|
+
mask the first time each is read, and keeps them, where every scan made all
|
|
59
|
+
three; spec-guard reads the directives mask and neither of the others. It
|
|
60
|
+
also lists an image inside a link's text - a badge wrapped in a link - as a
|
|
61
|
+
link of its own, after the link. Nothing here reads links: over the 145
|
|
62
|
+
Markdown files of the five spec-* repositories every directive, error,
|
|
63
|
+
status, title and warning reads as it did, and a run, `prove` and `cites` of
|
|
64
|
+
this repository answer as they did.
|
|
65
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
66
|
+
- **A warm query in the MCP server meets its 20 ms budget again**, over
|
|
67
|
+
this repository's 19 specs as over its 18 ADRs. 0.12.0 had lost it to
|
|
68
|
+
spec-core's scanner, which costs about three times what the parser it
|
|
69
|
+
replaced did. Measured together in one process, a query of one path took a
|
|
70
|
+
median of 6.3 ms, against 23.8 ms with `8840d36`'s lazy scan alone,
|
|
71
|
+
27.4 ms for 0.12.0 and 7.9 ms for 0.11.0; over the ADRs alone, 6.0 ms
|
|
72
|
+
against 18.7, 22.4 and 6.3 ms. The lazy scan takes 13 to 21% off, run to
|
|
73
|
+
run; the rest is the server parsing only a document whose bytes changed. A server's first
|
|
74
|
+
request, and one after an edit, still parse what they read: 24.3 ms for a
|
|
75
|
+
first request here. The 23 ms recorded for 0.12.0 was most likely measured
|
|
76
|
+
over the ADRs alone; over the specs this repository names it was 29 ms.
|
|
77
|
+
[ADR-0012](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0012-query-and-mcp.md)'s
|
|
78
|
+
amendment has both measurements.
|
|
79
|
+
|
|
8
80
|
## 0.12.0
|
|
9
81
|
|
|
10
82
|
The family's core, and three commands. Patterns and Markdown are read through
|
|
@@ -55,7 +127,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
55
127
|
`--ignore-status`, and `--json` with `formatVersion`. A path that does not
|
|
56
128
|
exist is exit 2, and so is a run in which no spec matched, as for `query`:
|
|
57
129
|
the dependents are written, and `--allow-empty` exits 0 with them. `impactOf`
|
|
58
|
-
is the API. [ADR-0018](docs/adr/0018-impact.md).
|
|
130
|
+
is the API. [ADR-0018](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0018-impact.md).
|
|
59
131
|
- **`get_dependents` on the MCP server**, a third tool beside
|
|
60
132
|
`get_architectural_rules` and `check_architecture`: `impact` for a list of
|
|
61
133
|
paths, with `depth` and `include_inactive`. Its structured content is the
|
|
@@ -85,7 +157,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
85
157
|
read, and are counted. Human, `--json` (with `formatVersion`), SARIF, GitHub
|
|
86
158
|
and GitLab output; exit 1 on a ghost, 2 for a family whose files match no
|
|
87
159
|
document. `findCitations` is the API.
|
|
88
|
-
[ADR-0017](docs/adr/0017-citations-in-comments.md).
|
|
160
|
+
[ADR-0017](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0017-citations-in-comments.md).
|
|
89
161
|
- **`spec-guard prove`: can each rule actually fail?** A passing rule cannot
|
|
90
162
|
say whether the code holds or the rule cannot see the code. `prove` shows
|
|
91
163
|
each rule in force a violation of itself - a file holding the forbidden text,
|
|
@@ -100,7 +172,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
100
172
|
`proveSpecGuard` is the same for a caller of the API. The first proof of
|
|
101
173
|
this repository's own rules found one that could not fail as written, and
|
|
102
174
|
CI now proves every rule the repository states on each change.
|
|
103
|
-
[ADR-0016](docs/adr/0016-rules-seen-to-fail.md).
|
|
175
|
+
[ADR-0016](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0016-rules-seen-to-fail.md).
|
|
104
176
|
- **`RunOptions.io`: a run over a tree that is not on disk.** `runSpecGuard`
|
|
105
177
|
reads through the `Io` it is given - finding and reading the specs, checking
|
|
106
178
|
targets exist, walking them, scanning files, reading imports and listing
|
|
@@ -110,7 +182,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
110
182
|
`engine: 'ripgrep'` with an `io` is refused with a message that says so, and
|
|
111
183
|
`auto` with one searches with the built-in scanner. A search that fails
|
|
112
184
|
outright through the door fails the run, rather than falling back to the
|
|
113
|
-
scanner that reads the disk. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
185
|
+
scanner that reads the disk. [ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
114
186
|
- **`--format gitlab` and `--format github`**, for the run, `prove` and
|
|
115
187
|
`cites`. `gitlab` writes a GitLab Code Quality report - `description`,
|
|
116
188
|
`check_name`, a `fingerprint`, a `severity` and a `location` - which a
|
|
@@ -138,7 +210,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
138
210
|
as front matter. Warnings about how a document was read - a front-matter
|
|
139
211
|
status that cannot be read, a block never closed - are `specWarnings`.
|
|
140
212
|
Both fields are added, so no `formatVersion` moves.
|
|
141
|
-
[ADR-0002](docs/adr/0002-directive-format.md)'s amendment.
|
|
213
|
+
[ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment.
|
|
142
214
|
- **`formatVersion: 1` on the run's `--json` and on `query --json`**, as
|
|
143
215
|
`prove --json` has had from the start: a field removed or renamed moves it,
|
|
144
216
|
a field added does not. Both documents are otherwise unchanged; this is one
|
|
@@ -163,7 +235,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
163
235
|
the same match takes under a millisecond. spec-core is copied into
|
|
164
236
|
`src/vendor/spec-core` and verified by hash, so `dependencies` stays empty,
|
|
165
237
|
and its MIT notice ships in the package at `src/vendor/spec-core/LICENSE`.
|
|
166
|
-
[ADR-0015](docs/adr/0015-globs-from-spec-core.md).
|
|
238
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
167
239
|
- **ripgrep and the scanner still read some patterns differently**, so the same
|
|
168
240
|
rule could count differently on either side of the tree size at which `auto`
|
|
169
241
|
changes engine. ripgrep anchored every alternative of `{src/*.ts,*.md}`
|
|
@@ -179,7 +251,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
179
251
|
rules. It is now decided by spec-core's Markdown scanner, which every spec-*
|
|
180
252
|
tool reads documents with, copied into `src/vendor/spec-core` from `cbe2223`
|
|
181
253
|
and verified by hash; `maskCode` is still exported, and is the scanner's
|
|
182
|
-
mask. [ADR-0002](docs/adr/0002-directive-format.md)'s amendment.
|
|
254
|
+
mask. [ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment.
|
|
183
255
|
|
|
184
256
|
Directives that were hidden, and now execute:
|
|
185
257
|
- **A backtick fence's info string may not hold a backtick.** A line that
|
|
@@ -251,7 +323,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
251
323
|
`glob="*.{ts,tsx}"` was always the two patterns `*.{ts` and `tsx}`, and the
|
|
252
324
|
message now says so. A configuration's `exclude` is a JSON array, where braces
|
|
253
325
|
keep their commas. Nothing restores the old readings.
|
|
254
|
-
[ADR-0015](docs/adr/0015-globs-from-spec-core.md).
|
|
326
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
255
327
|
- **`**` inside a name is refused**: `docs/**.md`, `src/**.ts`, `**.ts`,
|
|
256
328
|
`a**b`. The message says what `**` means and gives the two ways to write
|
|
257
329
|
what was meant, `docs/**/*.md` for any depth and `*.md` for one level. It
|
|
@@ -275,7 +347,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
275
347
|
An archived document is still parsed, validated and named in every output
|
|
276
348
|
format. `--ignore-status` executes it as before. The list stays closed:
|
|
277
349
|
`done`, `closed`, `archive` and every other near word stay in force, and
|
|
278
|
-
[ADR-0010](docs/adr/0010-spec-status.md)'s amendment says why this word and
|
|
350
|
+
[ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md)'s amendment says why this word and
|
|
279
351
|
no other.
|
|
280
352
|
- **A status is found by the scanner's headings and front-matter reader.**
|
|
281
353
|
The three spellings, their order and the words are unchanged, and every
|
|
@@ -305,7 +377,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
305
377
|
`specWarnings` entry in `--json` (run and `prove`), a SARIF notification
|
|
306
378
|
and a `spec-warning` annotation for GitHub and GitLab.
|
|
307
379
|
|
|
308
|
-
[ADR-0010](docs/adr/0010-spec-status.md)'s second amendment.
|
|
380
|
+
[ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md)'s second amendment.
|
|
309
381
|
- **A title is the first level-one heading as the scanner reads it.** An
|
|
310
382
|
underlined one (`===`) is a title and one kept in a comment is not; a code
|
|
311
383
|
span in it is kept as written, where it was blanked, and a comment in it is
|
|
@@ -318,7 +390,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
318
390
|
over this repository's 18 ADRs, and 23 ms against 9 ms for a warm query of
|
|
319
391
|
one path, past the 20 ms ADR-0012 set out to meet. The scanner finds list
|
|
320
392
|
items, links and tables that nothing here reads.
|
|
321
|
-
[ADR-0002](docs/adr/0002-directive-format.md)'s amendment says where the
|
|
393
|
+
[ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment says where the
|
|
322
394
|
remedy lies.
|
|
323
395
|
- **The MCP server speaks the protocol through spec-core.** Classifying each
|
|
324
396
|
request, the two eras, dispatch, result shapes and the stdio framing are
|
|
@@ -327,7 +399,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
327
399
|
client sees is unchanged, and every test of the server passes as it was
|
|
328
400
|
written. One edge moved: a last line cut inside a UTF-8 character when stdin
|
|
329
401
|
closes is read as far as it goes rather than dropped. The protocol's names
|
|
330
|
-
are still exported from the package. [ADR-0015](docs/adr/0015-globs-from-spec-core.md).
|
|
402
|
+
are still exported from the package. [ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
331
403
|
- **API:**
|
|
332
404
|
- `createGlobMatcher`, `createExcludeMatcher` and `expandSpecPatterns` throw
|
|
333
405
|
for a pattern spec-core refuses - an unclosed `[` or `{`, an extended
|
|
@@ -361,7 +433,7 @@ expression can hold a quote — `/'/`, `/["']/`, `replace(/\/\//g, '')` — and
|
|
|
361
433
|
without a rule for `/`, that quote opened a string that closed somewhere else
|
|
362
434
|
entirely. Every text rule over a TypeScript project reads through this
|
|
363
435
|
classifier, and this repository's own `src/parser.ts` was one of the files it
|
|
364
|
-
lost its place in. [ADR-0006](docs/adr/0006-comment-classification.md).
|
|
436
|
+
lost its place in. [ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md).
|
|
365
437
|
|
|
366
438
|
### Fixed
|
|
367
439
|
|
|
@@ -420,8 +492,8 @@ question asked per character has to be paid for per character.
|
|
|
420
492
|
Fixes from running 0.10.2 over a Rust and .NET monorepo, where an import rule
|
|
421
493
|
missed five `use` declarations in one crate and said nothing, and from probing
|
|
422
494
|
every other language profile for the same mistake.
|
|
423
|
-
[ADR-0006](docs/adr/0006-comment-classification.md),
|
|
424
|
-
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
495
|
+
[ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md),
|
|
496
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md).
|
|
425
497
|
|
|
426
498
|
### Fixed
|
|
427
499
|
|
|
@@ -469,8 +541,8 @@ regular expression literal holding a quote, `/["']/` - is recorded in ADR-0006.
|
|
|
469
541
|
Fixes from running 0.10.1 over a .NET solution, where a layer rule passed while
|
|
470
542
|
the domain imported the application, and from reading C# as it is written in
|
|
471
543
|
2026 while fixing that.
|
|
472
|
-
[ADR-0011](docs/adr/0011-layers-and-cycles.md),
|
|
473
|
-
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
544
|
+
[ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md),
|
|
545
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md).
|
|
474
546
|
|
|
475
547
|
### Fixed
|
|
476
548
|
|
|
@@ -543,7 +615,7 @@ the domain imported the application, and from reading C# as it is written in
|
|
|
543
615
|
|
|
544
616
|
Fixes from running 0.10.0 over a large monorepo, and from testing each exclude
|
|
545
617
|
shape under both engines while making them.
|
|
546
|
-
[ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
618
|
+
[ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
547
619
|
|
|
548
620
|
### Fixed
|
|
549
621
|
|
|
@@ -619,8 +691,8 @@ shape under both engines while making them.
|
|
|
619
691
|
Improvements from running 0.9.2 over a large polyglot monorepo: a
|
|
620
692
|
configuration a Rust, Go or .NET root can hold, exclusions a whole project
|
|
621
693
|
shares, and a cycle rule that can leave lazy loading out.
|
|
622
|
-
[ADR-0014](docs/adr/0014-configuration-and-watch.md),
|
|
623
|
-
[ADR-0011](docs/adr/0011-layers-and-cycles.md).
|
|
694
|
+
[ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md),
|
|
695
|
+
[ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md).
|
|
624
696
|
|
|
625
697
|
### Added
|
|
626
698
|
|
|
@@ -684,7 +756,7 @@ shares, and a cycle rule that can leave lazy loading out.
|
|
|
684
756
|
unanalysable, as does `/*` inside JSX text.
|
|
685
757
|
- Tracking JSX text in general was turned down: a TypeScript cast or a
|
|
686
758
|
generic arrow read as markup would skip real code without a word.
|
|
687
|
-
[ADR-0005](docs/adr/0005-import-assertions.md).
|
|
759
|
+
[ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md).
|
|
688
760
|
|
|
689
761
|
## 0.9.1
|
|
690
762
|
|
|
@@ -700,13 +772,13 @@ shares, and a cycle rule that can leave lazy loading out.
|
|
|
700
772
|
- `/>` anywhere else still starts a regular expression, so
|
|
701
773
|
`replace(/>/g, '>')` reads as before.
|
|
702
774
|
|
|
703
|
-
[ADR-0005](docs/adr/0005-import-assertions.md).
|
|
775
|
+
[ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md).
|
|
704
776
|
|
|
705
777
|
## 0.9.0
|
|
706
778
|
|
|
707
779
|
A project's policy can live in its `package.json`, and `spec-guard --watch`
|
|
708
780
|
reports again as the tree changes, re-executing only the rules a change
|
|
709
|
-
affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
781
|
+
affected. [ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
710
782
|
|
|
711
783
|
### Added
|
|
712
784
|
|
|
@@ -774,7 +846,7 @@ affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
|
774
846
|
reported every other shard's files with the previous sweep's verdicts. The
|
|
775
847
|
merge refused that sweep.
|
|
776
848
|
- No mutants were left out, the per-mutant timeout is unchanged, and the gate
|
|
777
|
-
is unchanged. [ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
849
|
+
is unchanged. [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
778
850
|
|
|
779
851
|
### Fixed
|
|
780
852
|
|
|
@@ -796,7 +868,7 @@ affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
|
796
868
|
|
|
797
869
|
An architecture document can now state conventions about names and layout: what
|
|
798
870
|
the files in a directory are called, what every package holds, and which files
|
|
799
|
-
come in pairs. [ADR-0013](docs/adr/0013-structure-assertions.md).
|
|
871
|
+
come in pairs. [ADR-0013](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0013-structure-assertions.md).
|
|
800
872
|
|
|
801
873
|
### Added
|
|
802
874
|
|
|
@@ -847,7 +919,7 @@ come in pairs. [ADR-0013](docs/adr/0013-structure-assertions.md).
|
|
|
847
919
|
had, less one in `glob.ts` that the new tests turned into a genuine hang. A
|
|
848
920
|
local sweep had reported four survivors in the new listing cache as killed; CI
|
|
849
921
|
found them, and they are tested. See
|
|
850
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
922
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
851
923
|
|
|
852
924
|
## 0.7.0
|
|
853
925
|
|
|
@@ -877,7 +949,7 @@ than every release, and it is fixed below.
|
|
|
877
949
|
`types="ignore"` asks the runtime question. JavaScript and TypeScript only,
|
|
878
950
|
because a cycle needs to know which file an import *is*; imports that should
|
|
879
951
|
have become an edge and did not are reported, and fail under `--strict`.
|
|
880
|
-
See [ADR-0011](docs/adr/0011-layers-and-cycles.md) for the resolution table,
|
|
952
|
+
See [ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md) for the resolution table,
|
|
881
953
|
and for why the other four languages are not in the graph.
|
|
882
954
|
- `buildGraph`, `resolveReference`, `stronglyConnected`, `cyclicComponents`,
|
|
883
955
|
`witness`, `checkLayers` and `referenceForms` are exported, with their types.
|
|
@@ -889,7 +961,7 @@ than every release, and it is fixed below.
|
|
|
889
961
|
scripts. Rules in documents that are not in force are counted and named, and
|
|
890
962
|
listed with `--ignore-status`. The arithmetic behind it is tested against the
|
|
891
963
|
files a real run searches, under both engines and on random trees; see
|
|
892
|
-
[ADR-0012](docs/adr/0012-query-and-mcp.md) for the three things it cannot see.
|
|
964
|
+
[ADR-0012](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0012-query-and-mcp.md) for the three things it cannot see.
|
|
893
965
|
- **`spec-guard mcp`** - a Model Context Protocol server on stdio, with no
|
|
894
966
|
dependency on the MCP SDK. Tools `get_architectural_rules` (the query) and
|
|
895
967
|
`check_architecture` (a run, narrowed to the rules governing given paths, each
|
|
@@ -939,7 +1011,7 @@ than every release, and it is fixed below.
|
|
|
939
1011
|
mutated build against the real one on thousands of random inputs. The query
|
|
940
1012
|
and the server (`query.ts`, `rules.ts`, `mcp.ts`, `specs.ts`) are all at 100%;
|
|
941
1013
|
most of the survivors found on the way were code nothing could observe, and it
|
|
942
|
-
was deleted. See [ADR-0003](docs/adr/0003-mutation-testing.md) for both
|
|
1014
|
+
was deleted. See [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md) for both
|
|
943
1015
|
accounts, and for why one sweep's count is good to about three.
|
|
944
1016
|
- `version(manifest?)` takes the manifest to read, so its fallback for a broken
|
|
945
1017
|
install - `0.0.0` rather than a crash - is tested.
|
|
@@ -984,7 +1056,7 @@ making sure a rule that stops running can never look like a rule that passed.
|
|
|
984
1056
|
are still checked for typos, bad attributes and unresolvable values, so a
|
|
985
1057
|
draft's mistake is found on the day it is written rather than on the day
|
|
986
1058
|
everyone agrees the rule is right and stops looking at it.
|
|
987
|
-
See [ADR-0010](docs/adr/0010-spec-status.md), which also records why there is
|
|
1059
|
+
See [ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md), which also records why there is
|
|
988
1060
|
no per-directive `if-status` attribute.
|
|
989
1061
|
- `--ignore-status` executes every directive whatever its document declares -
|
|
990
1062
|
how to ask whether a draft would pass if you accepted it today.
|
|
@@ -1008,7 +1080,7 @@ making sure a rule that stops running can never look like a rule that passed.
|
|
|
1008
1080
|
the whole suite per mutant, so on a loaded machine an unrelated test timing
|
|
1009
1081
|
out is scored as a kill. Those patterns are now verified by applying every
|
|
1010
1082
|
mutant by hand, `scripts/mutation-regex.mjs`, and the account is in
|
|
1011
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
1083
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
1012
1084
|
|
|
1013
1085
|
## 0.5.1
|
|
1014
1086
|
|
|
@@ -1057,7 +1129,7 @@ new features, and nothing a user has to change.
|
|
|
1057
1129
|
individually and produce byte-identical output, so that figure is the ceiling
|
|
1058
1130
|
rather than a way-point — and 29 that were assumed equivalent turned out not
|
|
1059
1131
|
to be, and are now tested. See
|
|
1060
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md), which also records a Stryker
|
|
1132
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md), which also records a Stryker
|
|
1061
1133
|
limitation found on the way: a mutant that stops a test file *loading* is
|
|
1062
1134
|
reported as survived even though the suite is killing it.
|
|
1063
1135
|
- **`src/imports.ts` went from 73.74% to 95.89%.** The tokenizer was tested as a
|
|
@@ -1095,13 +1167,13 @@ scope holds no files at all.
|
|
|
1095
1167
|
Not four new tokenizers: the comment and string lexer from ADR-0006 masks the
|
|
1096
1168
|
source and the readers work on what is left. Tree-sitter measured 94 MB
|
|
1097
1169
|
unpacked against this package's 0.33 MB. See
|
|
1098
|
-
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
1170
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md).
|
|
1099
1171
|
- **`baseline` and `ratchet`** on the absence assertions, for adopting a strict
|
|
1100
1172
|
rule on a codebase that already breaks it. `baseline="src/legacy/a.ts:2"`
|
|
1101
1173
|
names the debt by file and count. The ratchet is two-sided: new violations
|
|
1102
1174
|
fail, and so does an entry the code no longer supports, because a baseline
|
|
1103
1175
|
that only grows is an `exclude` with extra steps. `ratchet="one-way"` relaxes
|
|
1104
|
-
the second half. See [ADR-0009](docs/adr/0009-debt-baselines.md).
|
|
1176
|
+
the second half. See [ADR-0009](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0009-debt-baselines.md).
|
|
1105
1177
|
- **`--print-baseline`** prints the attribute that would exempt today's
|
|
1106
1178
|
violations, for a human to paste. It prints; it does not edit. That is the
|
|
1107
1179
|
whole answer to `--fix`, and ADR-0009 argues it.
|
|
@@ -1131,7 +1203,7 @@ scope holds no files at all.
|
|
|
1131
1203
|
starts finding dependencies it previously reported as unanalysable.
|
|
1132
1204
|
- **Mutation testing in CI runs in two tiers**: incremental on branches,
|
|
1133
1205
|
a full authoritative sweep on `main` and nightly. The gate stays at 85 in
|
|
1134
|
-
both. See [ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
1206
|
+
both. See [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
1135
1207
|
|
|
1136
1208
|
### Fixed
|
|
1137
1209
|
|
|
@@ -1179,7 +1251,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
1179
1251
|
- **The engines are one implementation.** ripgrep now answers only *which files
|
|
1180
1252
|
contain this text*; the scanner does all counting, comment classification,
|
|
1181
1253
|
binary handling and reporting for both. `--engine` changes how long a run
|
|
1182
|
-
takes, not what it concludes. See [ADR-0007](docs/adr/0007-search-scope.md).
|
|
1254
|
+
takes, not what it concludes. See [ADR-0007](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0007-search-scope.md).
|
|
1183
1255
|
|
|
1184
1256
|
### Added
|
|
1185
1257
|
|
|
@@ -1218,7 +1290,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
1218
1290
|
directions. A zero-dependency tokenizer resolves `import`, `export … from`,
|
|
1219
1291
|
`import type`, dynamic `import()` with a literal, and `require()`. Module
|
|
1220
1292
|
references it cannot resolve statically are reported, never counted as clean.
|
|
1221
|
-
See [ADR-0005](docs/adr/0005-import-assertions.md).
|
|
1293
|
+
See [ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md).
|
|
1222
1294
|
- **`comments` attribute.** See Changed, below.
|
|
1223
1295
|
- **`--allow-missing-targets`** to restore the previous handling of a `target`
|
|
1224
1296
|
path that does not exist.
|
|
@@ -1234,7 +1306,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
1234
1306
|
uncertain the text counts as code, and every run reports how many matches it
|
|
1235
1307
|
excluded — a pass caused by comment exclusion is never silent.
|
|
1236
1308
|
`comments="include"` restores counting per assertion.
|
|
1237
|
-
See [ADR-0006](docs/adr/0006-comment-classification.md).
|
|
1309
|
+
See [ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md).
|
|
1238
1310
|
- **A `target` path that does not exist now fails the run** instead of warning
|
|
1239
1311
|
and searching what remained. An assertion pointed at a renamed directory used
|
|
1240
1312
|
to search nothing, find nothing, and report success. `--allow-missing-targets`
|
|
@@ -1270,9 +1342,9 @@ first published 0.3.0.
|
|
|
1270
1342
|
enough for the JavaScript scanner to beat a ripgrep process spawn. The probe
|
|
1271
1343
|
is the work — the enumeration it performs is reused by the scanner, so
|
|
1272
1344
|
choosing costs nothing when the scanner wins.
|
|
1273
|
-
See [ADR-0004](docs/adr/0004-adaptive-engine.md).
|
|
1345
|
+
See [ADR-0004](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0004-adaptive-engine.md).
|
|
1274
1346
|
- **Mutation testing** with Stryker, wired into CI on every push, plus the tests
|
|
1275
|
-
that closed the gaps it exposed. See [ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
1347
|
+
that closed the gaps it exposed. See [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
1276
1348
|
|
|
1277
1349
|
### Changed
|
|
1278
1350
|
|
package/README.md
CHANGED
|
@@ -331,9 +331,9 @@ These read the dependency rather than the text, in **five languages**:
|
|
|
331
331
|
No parser and no new dependency. JavaScript gets a full tokenizer because a
|
|
332
332
|
module reference can appear anywhere in an expression; the other four are read
|
|
333
333
|
by masking comments and string literals with the classifier from
|
|
334
|
-
[ADR-0006](docs/adr/0006-comment-classification.md) and then reading statements
|
|
334
|
+
[ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md) and then reading statements
|
|
335
335
|
off what is left. Tree-sitter would have cost 94 MB unpacked against this
|
|
336
|
-
package's 0.33 MB - [ADR-0008](docs/adr/0008-polyglot-imports.md) has the
|
|
336
|
+
package's 0.33 MB - [ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md) has the
|
|
337
337
|
measurements, and the list of things a real parser would genuinely see that
|
|
338
338
|
this does not.
|
|
339
339
|
|
|
@@ -384,7 +384,7 @@ and reported too, so a rule pointed at the wrong tree says "analysed 2 of 3
|
|
|
384
384
|
files; 1 is in a language whose imports spec-guard cannot read (.razor)" rather than quietly passing - and if *none* of them can be read, the
|
|
385
385
|
assertion fails rather than passing on an empty analysis.
|
|
386
386
|
|
|
387
|
-
[ADR-0005](docs/adr/0005-import-assertions.md) has the measurements and the
|
|
387
|
+
[ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md) has the measurements and the
|
|
388
388
|
reasoning behind each boundary.
|
|
389
389
|
|
|
390
390
|
### `@assert-layers` - dependencies point one way
|
|
@@ -546,7 +546,7 @@ did not - a relative path matching no file, or an alias like `@/db` or
|
|
|
546
546
|
`--strict`. An alias spelled like a real package, `@app/db` through `tsconfig`
|
|
547
547
|
paths, is the one thing it cannot see and cannot report: that would mean
|
|
548
548
|
reading `tsconfig.json`, which is the resolver
|
|
549
|
-
[ADR-0011](docs/adr/0011-layers-and-cycles.md) declines to become, for the
|
|
549
|
+
[ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md) declines to become, for the
|
|
550
550
|
reasons it gives.
|
|
551
551
|
|
|
552
552
|
### `@assert-structure` - what files are called, and what comes with them
|
|
@@ -639,7 +639,7 @@ src/handlers/invoice.ts (does not exist yet)
|
|
|
639
639
|
partner: src/handlers/invoice.test.ts
|
|
640
640
|
```
|
|
641
641
|
|
|
642
|
-
[ADR-0013](docs/adr/0013-structure-assertions.md) has the design and what it
|
|
642
|
+
[ADR-0013](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0013-structure-assertions.md) has the design and what it
|
|
643
643
|
costs.
|
|
644
644
|
|
|
645
645
|
### `@assert-present` - this file exists
|
|
@@ -741,7 +741,7 @@ spec-guard docs/adr.md --print-baseline
|
|
|
741
741
|
```
|
|
742
742
|
|
|
743
743
|
prints the attribute that would exempt exactly today's violations, for you to
|
|
744
|
-
paste in. It prints; it does not edit. [ADR-0009](docs/adr/0009-debt-baselines.md)
|
|
744
|
+
paste in. It prints; it does not edit. [ADR-0009](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0009-debt-baselines.md)
|
|
745
745
|
explains why that distinction is the whole design, and why there is no `--fix`
|
|
746
746
|
for architecture rules.
|
|
747
747
|
|
|
@@ -806,7 +806,7 @@ found on the day it is written rather than on the day it is accepted.
|
|
|
806
806
|
`--ignore-status` runs everything, which is how you ask whether a draft would
|
|
807
807
|
pass if you accepted it today.
|
|
808
808
|
|
|
809
|
-
[ADR-0010](docs/adr/0010-spec-status.md) has the full reasoning, including why
|
|
809
|
+
[ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md) has the full reasoning, including why
|
|
810
810
|
there is no per-directive `if-status` attribute.
|
|
811
811
|
|
|
812
812
|
## Asking before writing - `query` and the MCP server
|
|
@@ -863,7 +863,7 @@ project's does not.
|
|
|
863
863
|
|
|
864
864
|
The arithmetic that decides whether a rule governs a path is tested against the
|
|
865
865
|
walk a real run makes, file for file, under both engines and on randomly
|
|
866
|
-
generated trees. [ADR-0012](docs/adr/0012-query-and-mcp.md) lists the three
|
|
866
|
+
generated trees. [ADR-0012](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0012-query-and-mcp.md) lists the three
|
|
867
867
|
things it cannot see: file content (binary, oversized, unreadable), symbolic
|
|
868
868
|
links, and letter case on case-insensitive filesystems.
|
|
869
869
|
|
|
@@ -958,7 +958,7 @@ and strictness.
|
|
|
958
958
|
|
|
959
959
|
A kill means the rule can fail, not that it catches the way the code is
|
|
960
960
|
written: `module="src/db.ts"` is killed by `import 'src/db.ts'` though every
|
|
961
|
-
file imports `./db.js`. [ADR-0016](docs/adr/0016-rules-seen-to-fail.md) has the
|
|
961
|
+
file imports `./db.js`. [ADR-0016](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0016-rules-seen-to-fail.md) has the
|
|
962
962
|
violations for each kind of rule, and what `unprovable` means.
|
|
963
963
|
|
|
964
964
|
## Do the comments cite decisions in force? - `cites`
|
|
@@ -1026,7 +1026,7 @@ as does a file read in part or a check that looked for nothing. A family whose
|
|
|
1026
1026
|
files match no document exits 2. `--json` (versioned by `formatVersion`),
|
|
1027
1027
|
`--format sarif`, `--format github` and `--format gitlab` carry the same
|
|
1028
1028
|
findings; `spec-guard cites src lib/a.ts` reads only those paths.
|
|
1029
|
-
[ADR-0017](docs/adr/0017-citations-in-comments.md) has the design, and what is
|
|
1029
|
+
[ADR-0017](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0017-citations-in-comments.md) has the design, and what is
|
|
1030
1030
|
out of scope: links to symbols, which need a parser the family does not ship.
|
|
1031
1031
|
|
|
1032
1032
|
## Who depends on this? - `impact`
|
|
@@ -1063,7 +1063,7 @@ src/db/client.ts
|
|
|
1063
1063
|
```
|
|
1064
1064
|
|
|
1065
1065
|
- **Followed**: relative JavaScript and TypeScript imports, by the table the
|
|
1066
|
-
cycle rule uses ([ADR-0011](docs/adr/0011-layers-and-cycles.md)), and relative
|
|
1066
|
+
cycle rule uses ([ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md)), and relative
|
|
1067
1067
|
Python imports, which name a module beside the importing file.
|
|
1068
1068
|
- **Counted, not followed**: Go imports, Rust `use`s, C# `using`s and absolute
|
|
1069
1069
|
Python imports name modules, and which file a module is depends on `go.mod`,
|
|
@@ -1081,7 +1081,7 @@ force, which are otherwise counted, as `query` does. `--json` is versioned by
|
|
|
1081
1081
|
written, but "no rules" over no specs is nothing measured. `--allow-empty`
|
|
1082
1082
|
asks for the dependents alone, and exits 0. The MCP server answers the same
|
|
1083
1083
|
question as `get_dependents`, with the same document.
|
|
1084
|
-
[ADR-0018](docs/adr/0018-impact.md) has the table and what it leaves out.
|
|
1084
|
+
[ADR-0018](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0018-impact.md) has the table and what it leaves out.
|
|
1085
1085
|
|
|
1086
1086
|
## CLI
|
|
1087
1087
|
|
|
@@ -1220,7 +1220,7 @@ pure function of a file's bytes - tokenizing, comment masking, scanning - is
|
|
|
1220
1220
|
remembered by the bytes' hash. Each of those is a way to report a tree that no
|
|
1221
1221
|
longer exists, so a test changes trees at random and requires every report a
|
|
1222
1222
|
session gives to equal a fresh run's, with six deliberately broken sessions
|
|
1223
|
-
that it has to catch. [ADR-0014](docs/adr/0014-configuration-and-watch.md) has
|
|
1223
|
+
that it has to catch. [ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md) has
|
|
1224
1224
|
the design, the measurements and the limits.
|
|
1225
1225
|
|
|
1226
1226
|
On this repository, from a change to the report, in the quietest of four runs
|
|
@@ -1403,7 +1403,7 @@ exceeds a budget, in which case ripgrep takes over. The crossover above sits
|
|
|
1403
1403
|
between 500 and 1,000 files, which is what the Windows budget of 512 encodes;
|
|
1404
1404
|
on Linux it is far lower, because what is really being measured is process
|
|
1405
1405
|
spawn cost. `scripts/bench-engines.mjs` reproduces this, and
|
|
1406
|
-
[ADR-0004](docs/adr/0004-adaptive-engine.md) has the full tables.
|
|
1406
|
+
[ADR-0004](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0004-adaptive-engine.md) has the full tables.
|
|
1407
1407
|
|
|
1408
1408
|
Treat single measurements from one machine with suspicion. On the development
|
|
1409
1409
|
machine used here, an absence assertion over 2,000 files measures 303 ms with
|
|
@@ -1514,6 +1514,13 @@ and is there for a caller who wants to try a change of its own.
|
|
|
1514
1514
|
and take an `io` as well; so do `loadRuleSet` and `queryRules`. Each command's
|
|
1515
1515
|
JSON is the report its function returns, with a `formatVersion` in front.
|
|
1516
1516
|
|
|
1517
|
+
A process that reads the specs again for every request, as the MCP server
|
|
1518
|
+
does, can keep what it parsed: pass one `createDocumentMemo()` as `documents`
|
|
1519
|
+
to `runSpecGuard`, `loadRuleSet`, `queryRules` or `impactOf`, every time. Every
|
|
1520
|
+
spec is still found and read, so an edit is seen by the next call; a document
|
|
1521
|
+
whose bytes have not changed is not parsed again, and the memo holds only the
|
|
1522
|
+
documents of the spec set read last. A single run gains nothing from one.
|
|
1523
|
+
|
|
1517
1524
|
## Design decisions
|
|
1518
1525
|
|
|
1519
1526
|
This tool was specified loosely and built opinionatedly. Where the
|
|
@@ -1539,7 +1546,7 @@ inside a comment is a character and `<!--` inside a code span is code, and a
|
|
|
1539
1546
|
code span ends with its paragraph, so a stray backtick cannot hide the
|
|
1540
1547
|
directives after it. A fence may be indented with the list item it sits in.
|
|
1541
1548
|
Masking preserves every offset and line terminator, so reported line numbers
|
|
1542
|
-
stay exact. [ADR-0002](docs/adr/0002-directive-format.md)'s amendment lists
|
|
1549
|
+
stay exact. [ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment lists
|
|
1543
1550
|
where this differs from 0.11.0.
|
|
1544
1551
|
|
|
1545
1552
|
What is masked is still counted. A comment shaped like a directive -
|
|
@@ -1587,7 +1594,7 @@ pattern - `glob`, `exclude`, `module`, a layer, a spec pattern - is read by the
|
|
|
1587
1594
|
glob engine the spec-* tools share, copied from spec-core and checked by hash.
|
|
1588
1595
|
A `RegExp` backtracks: `*-*-*-*-*-*x` took 55 seconds to fail one long file
|
|
1589
1596
|
name. The automaton cannot, and ripgrep is handed each pattern spelled as the
|
|
1590
|
-
automaton reads it ([ADR-0015](docs/adr/0015-globs-from-spec-core.md)).
|
|
1597
|
+
automaton reads it ([ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md)).
|
|
1591
1598
|
|
|
1592
1599
|
**Exit code 2 exists.** "Your specs failed" and "spec-guard could not run" are
|
|
1593
1600
|
different facts, and CI should be able to tell them apart.
|
|
@@ -1604,11 +1611,11 @@ forbidden symbol sat in `.github/workflows/ci.yml`; the scanner and ripgrep also
|
|
|
1604
1611
|
disagreed with each other, finding two matches and four on the same tree. Scope
|
|
1605
1612
|
is now one policy that both engines are driven by, the skip list is four names
|
|
1606
1613
|
long, and anything spec-guard could not inspect is reported rather than assumed
|
|
1607
|
-
clean ([ADR-0007](docs/adr/0007-search-scope.md)).
|
|
1614
|
+
clean ([ADR-0007](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0007-search-scope.md)).
|
|
1608
1615
|
|
|
1609
1616
|
**Comments are excluded by default, and the exclusion is reported.** Counting
|
|
1610
1617
|
the note that records a deletion as an occurrence of the thing deleted punishes
|
|
1611
|
-
the documentation this tool exists to keep honest ([ADR-0006](docs/adr/0006-comment-classification.md)).
|
|
1618
|
+
the documentation this tool exists to keep honest ([ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md)).
|
|
1612
1619
|
The reverse risk — a rule that quietly stops checking anything because every
|
|
1613
1620
|
match now sits in a comment — is why every run says how many matches it dropped.
|
|
1614
1621
|
|
|
@@ -1625,19 +1632,19 @@ comment and string lexer that already existed, masking the source with it, and
|
|
|
1625
1632
|
reading statements off what is left. Tree-sitter would have been the modern
|
|
1626
1633
|
answer and costs 94 MB unpacked against this package's 0.33 MB; the four things
|
|
1627
1634
|
a real parser would genuinely see that this cannot are listed in
|
|
1628
|
-
[ADR-0008](docs/adr/0008-polyglot-imports.md) rather than glossed over.
|
|
1635
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md) rather than glossed over.
|
|
1629
1636
|
|
|
1630
1637
|
**There is no `--fix`.** Every edit a machine can make to a failing boundary
|
|
1631
1638
|
assertion is an edit that records the rule no longer holding: widen the bound,
|
|
1632
1639
|
add an exclusion, append to the baseline, insert an ignore comment. A one-flag
|
|
1633
1640
|
path from red to green is a bad button for a person and a much worse one for an
|
|
1634
1641
|
agent whose loop terminates on a green build. `--print-baseline` prints what you
|
|
1635
|
-
could paste; it does not paste it ([ADR-0009](docs/adr/0009-debt-baselines.md)).
|
|
1642
|
+
could paste; it does not paste it ([ADR-0009](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0009-debt-baselines.md)).
|
|
1636
1643
|
|
|
1637
1644
|
## spec-guard checks itself
|
|
1638
1645
|
|
|
1639
|
-
The invariants in [`docs/adr/0001-invariants.md`](docs/adr/0001-invariants.md)
|
|
1640
|
-
and [`docs/adr/0002-directive-format.md`](docs/adr/0002-directive-format.md) are
|
|
1646
|
+
The invariants in [`docs/adr/0001-invariants.md`](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0001-invariants.md)
|
|
1647
|
+
and [`docs/adr/0002-directive-format.md`](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md) are
|
|
1641
1648
|
executed against this repository on every CI run. The CLI never calls
|
|
1642
1649
|
`console.log`, nothing outside the engine spawns a process, and the parser and
|
|
1643
1650
|
reporter never touch the filesystem - because those documents say so, and the
|
|
@@ -1671,13 +1678,13 @@ prebuilt binary and is never a runtime dependency.
|
|
|
1671
1678
|
|
|
1672
1679
|
Coverage says a line ran. It does not say an assertion would notice if the line
|
|
1673
1680
|
behaved differently. This repository measures the difference: line coverage is
|
|
1674
|
-
**100%**, and **99.20%** of 11,
|
|
1681
|
+
**100%**, and **99.20%** of 11,549 mutants are killed in CI, with 89 survivors and
|
|
1675
1682
|
no file below 95%. The second number is the one worth reading, and what was done
|
|
1676
1683
|
about the survivors matters more than the score. At 0.5.1 every surviving mutant
|
|
1677
1684
|
was checked individually, and the 101 left then produced byte-identical output.
|
|
1678
1685
|
Each release since has replayed the survivors its own code added before it
|
|
1679
1686
|
shipped: they were killed, deleted as dead code, or shown equivalent and
|
|
1680
|
-
recorded in [ADR-0003](docs/adr/0003-mutation-testing.md) with the evidence.
|
|
1687
|
+
recorded in [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md) with the evidence.
|
|
1681
1688
|
|
|
1682
1689
|
That gap is the point. The first run scored 77.23%, and the weakest file was the
|
|
1683
1690
|
reporter at 65.48% - not because it lacked tests, but because its tests were
|
|
@@ -1706,7 +1713,7 @@ applied one at a time and run through a fingerprint of 4,176 observations, and
|
|
|
1706
1713
|
that only matters when a second statement follows, a type-only test that marks
|
|
1707
1714
|
`import A, { B } from 'x'` type-only when loosened, a comment check that opens a
|
|
1708
1715
|
block comment on `2*3`. All 29 are now tested and all 29 die. All of it is in
|
|
1709
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md), including a Stryker limitation
|
|
1716
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md), including a Stryker limitation
|
|
1710
1717
|
found on the way: a mutant that stops a test file *loading* is reported as
|
|
1711
1718
|
survived even though the suite is in fact killing it.
|
|
1712
1719
|
|
|
@@ -1734,7 +1741,7 @@ suite takes hours against 43 minutes of hosted time, and it scores *higher*,
|
|
|
1734
1741
|
because far more mutants hang there and Stryker counts a hang as a kill. Linux
|
|
1735
1742
|
CI is the measurement.
|
|
1736
1743
|
|
|
1737
|
-
Eight cautionary tales are in [ADR-0003](docs/adr/0003-mutation-testing.md): a
|
|
1744
|
+
Eight cautionary tales are in [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md): a
|
|
1738
1745
|
run whose score was pure fiction because the mutants were never activated, a
|
|
1739
1746
|
tuning knob that lifted the score six points without adding a test, the platform
|
|
1740
1747
|
gap above, the baseline being re-anchored when a tokenizer arrived, and a score
|
|
@@ -1757,7 +1764,7 @@ npm version minor # or patch / major - writes package.json and makes the tag
|
|
|
1757
1764
|
git push origin main --follow-tags
|
|
1758
1765
|
```
|
|
1759
1766
|
|
|
1760
|
-
[`release.yml`](.github/workflows/release.yml) then:
|
|
1767
|
+
[`release.yml`](https://github.com/DescentVTT/spec-guard/blob/main/.github/workflows/release.yml) then:
|
|
1761
1768
|
|
|
1762
1769
|
1. refuses the release unless the tag, `package.json` and a `## <version>`
|
|
1763
1770
|
heading in `CHANGELOG.md` all agree;
|
package/dist/index.d.ts
CHANGED
|
@@ -50,8 +50,8 @@ export type { Listing, StructureCheck, StructureRequest, StructureViolation, Tre
|
|
|
50
50
|
export { lineStarts, locate, maskRanges } from './text.js';
|
|
51
51
|
export { maskCode, parseAttributes, parseDirectives, parseDocument, parseStatus, parseTitle, INACTIVE_STATUSES } from './parser.js';
|
|
52
52
|
export type { ParseContext, ParsedDocument } from './parser.js';
|
|
53
|
-
export { readSpecs, specPath } from './specs.js';
|
|
54
|
-
export type { SpecDocument, SpecSet } from './specs.js';
|
|
53
|
+
export { createDocumentMemo, readSpecs, specPath } from './specs.js';
|
|
54
|
+
export type { DocumentMemo, SpecDocument, SpecSet } from './specs.js';
|
|
55
55
|
export { governs, layerPosition, leftOutByOwnExclude, viewRule, within } from './rules.js';
|
|
56
56
|
export type { DocumentView, LayerPosition, PathShape, QueryPath, RuleView } from './rules.js';
|
|
57
57
|
export { answerQuery, formatQuery, formatQueryJson, inQueriedPaths, loadRuleSet, queryRules, resolveQueryPath, viewDocument, QueryPathError, QUERY_FORMAT_VERSION, } from './query.js';
|