@descent-vtt/spec-guard 0.12.0 → 0.12.1
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 +101 -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 +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,67 @@ 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.1
|
|
9
|
+
|
|
10
|
+
The query is fast again. A warm `query` in the MCP server took 27 ms over this
|
|
11
|
+
repository's specs after 0.12.0 moved to spec-core's scanner, past the 20 ms
|
|
12
|
+
ADR-0012 set; it now takes about 6 ms, faster than 0.11.0. The scanner makes
|
|
13
|
+
only what it is asked for, and the server parses a spec again only when its
|
|
14
|
+
bytes change. The shipped README and changelog link to the ADRs by address,
|
|
15
|
+
so the links lead somewhere on npmjs.com and inside `node_modules`.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **`createDocumentMemo`, and `documents` on `runSpecGuard`, `loadRuleSet`,
|
|
20
|
+
`queryRules` and `impactOf`**: parsed spec documents kept from one call to
|
|
21
|
+
the next, for a process that reads the specs on every request. Every spec
|
|
22
|
+
is still found and read, so an edit is seen by the next call; a document is
|
|
23
|
+
parsed again only when its bytes change. It holds one parse of each
|
|
24
|
+
document the spec set read last names, and forgets one removed, left out or
|
|
25
|
+
edited at the next read. The MCP server keeps one for its lifetime; a
|
|
26
|
+
command run once takes none, and parses every document and hashes none, as
|
|
27
|
+
before.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **The README's and the changelog's links to the ADRs lead somewhere on
|
|
32
|
+
npmjs.com and in node_modules.** They were relative, and the package ships
|
|
33
|
+
neither `docs/` nor `.github/`, so outside the repository the 66 links to
|
|
34
|
+
ADRs and the one to the release workflow led nowhere. Each is an absolute
|
|
35
|
+
URL to the file on GitHub now, and a link to a file the package ships stays
|
|
36
|
+
relative. `tests/package.test.ts` holds every Markdown document the package
|
|
37
|
+
ships to that, and each absolute link to a file the repository holds.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `npm publish` in a checkout refuses to run outside GitHub Actions, so a
|
|
42
|
+
version cannot reach npm from a workstation by mistake, without provenance;
|
|
43
|
+
spec-harness 0.1.0 did. The release never runs it: it stages a tarball it
|
|
44
|
+
packed.
|
|
45
|
+
- **spec-core is copied again, from `8840d36`**, `markdown` alone, and
|
|
46
|
+
verified by hash. Its scanner makes links, list items and the directives
|
|
47
|
+
mask the first time each is read, and keeps them, where every scan made all
|
|
48
|
+
three; spec-guard reads the directives mask and neither of the others. It
|
|
49
|
+
also lists an image inside a link's text - a badge wrapped in a link - as a
|
|
50
|
+
link of its own, after the link. Nothing here reads links: over the 145
|
|
51
|
+
Markdown files of the five spec-* repositories every directive, error,
|
|
52
|
+
status, title and warning reads as it did, and a run, `prove` and `cites` of
|
|
53
|
+
this repository answer as they did.
|
|
54
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
55
|
+
- **A warm query in the MCP server meets its 20 ms budget again**, over
|
|
56
|
+
this repository's 19 specs as over its 18 ADRs. 0.12.0 had lost it to
|
|
57
|
+
spec-core's scanner, which costs about three times what the parser it
|
|
58
|
+
replaced did. Measured together in one process, a query of one path took a
|
|
59
|
+
median of 6.3 ms, against 23.8 ms with `8840d36`'s lazy scan alone,
|
|
60
|
+
27.4 ms for 0.12.0 and 7.9 ms for 0.11.0; over the ADRs alone, 6.0 ms
|
|
61
|
+
against 18.7, 22.4 and 6.3 ms. The lazy scan takes 13 to 21% off, run to
|
|
62
|
+
run; the rest is the server parsing only a document whose bytes changed. A server's first
|
|
63
|
+
request, and one after an edit, still parse what they read: 24.3 ms for a
|
|
64
|
+
first request here. The 23 ms recorded for 0.12.0 was most likely measured
|
|
65
|
+
over the ADRs alone; over the specs this repository names it was 29 ms.
|
|
66
|
+
[ADR-0012](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0012-query-and-mcp.md)'s
|
|
67
|
+
amendment has both measurements.
|
|
68
|
+
|
|
8
69
|
## 0.12.0
|
|
9
70
|
|
|
10
71
|
The family's core, and three commands. Patterns and Markdown are read through
|
|
@@ -55,7 +116,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
55
116
|
`--ignore-status`, and `--json` with `formatVersion`. A path that does not
|
|
56
117
|
exist is exit 2, and so is a run in which no spec matched, as for `query`:
|
|
57
118
|
the dependents are written, and `--allow-empty` exits 0 with them. `impactOf`
|
|
58
|
-
is the API. [ADR-0018](docs/adr/0018-impact.md).
|
|
119
|
+
is the API. [ADR-0018](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0018-impact.md).
|
|
59
120
|
- **`get_dependents` on the MCP server**, a third tool beside
|
|
60
121
|
`get_architectural_rules` and `check_architecture`: `impact` for a list of
|
|
61
122
|
paths, with `depth` and `include_inactive`. Its structured content is the
|
|
@@ -85,7 +146,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
85
146
|
read, and are counted. Human, `--json` (with `formatVersion`), SARIF, GitHub
|
|
86
147
|
and GitLab output; exit 1 on a ghost, 2 for a family whose files match no
|
|
87
148
|
document. `findCitations` is the API.
|
|
88
|
-
[ADR-0017](docs/adr/0017-citations-in-comments.md).
|
|
149
|
+
[ADR-0017](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0017-citations-in-comments.md).
|
|
89
150
|
- **`spec-guard prove`: can each rule actually fail?** A passing rule cannot
|
|
90
151
|
say whether the code holds or the rule cannot see the code. `prove` shows
|
|
91
152
|
each rule in force a violation of itself - a file holding the forbidden text,
|
|
@@ -100,7 +161,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
100
161
|
`proveSpecGuard` is the same for a caller of the API. The first proof of
|
|
101
162
|
this repository's own rules found one that could not fail as written, and
|
|
102
163
|
CI now proves every rule the repository states on each change.
|
|
103
|
-
[ADR-0016](docs/adr/0016-rules-seen-to-fail.md).
|
|
164
|
+
[ADR-0016](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0016-rules-seen-to-fail.md).
|
|
104
165
|
- **`RunOptions.io`: a run over a tree that is not on disk.** `runSpecGuard`
|
|
105
166
|
reads through the `Io` it is given - finding and reading the specs, checking
|
|
106
167
|
targets exist, walking them, scanning files, reading imports and listing
|
|
@@ -110,7 +171,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
110
171
|
`engine: 'ripgrep'` with an `io` is refused with a message that says so, and
|
|
111
172
|
`auto` with one searches with the built-in scanner. A search that fails
|
|
112
173
|
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).
|
|
174
|
+
scanner that reads the disk. [ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
114
175
|
- **`--format gitlab` and `--format github`**, for the run, `prove` and
|
|
115
176
|
`cites`. `gitlab` writes a GitLab Code Quality report - `description`,
|
|
116
177
|
`check_name`, a `fingerprint`, a `severity` and a `location` - which a
|
|
@@ -138,7 +199,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
138
199
|
as front matter. Warnings about how a document was read - a front-matter
|
|
139
200
|
status that cannot be read, a block never closed - are `specWarnings`.
|
|
140
201
|
Both fields are added, so no `formatVersion` moves.
|
|
141
|
-
[ADR-0002](docs/adr/0002-directive-format.md)'s amendment.
|
|
202
|
+
[ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment.
|
|
142
203
|
- **`formatVersion: 1` on the run's `--json` and on `query --json`**, as
|
|
143
204
|
`prove --json` has had from the start: a field removed or renamed moves it,
|
|
144
205
|
a field added does not. Both documents are otherwise unchanged; this is one
|
|
@@ -163,7 +224,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
163
224
|
the same match takes under a millisecond. spec-core is copied into
|
|
164
225
|
`src/vendor/spec-core` and verified by hash, so `dependencies` stays empty,
|
|
165
226
|
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).
|
|
227
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
167
228
|
- **ripgrep and the scanner still read some patterns differently**, so the same
|
|
168
229
|
rule could count differently on either side of the tree size at which `auto`
|
|
169
230
|
changes engine. ripgrep anchored every alternative of `{src/*.ts,*.md}`
|
|
@@ -179,7 +240,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
179
240
|
rules. It is now decided by spec-core's Markdown scanner, which every spec-*
|
|
180
241
|
tool reads documents with, copied into `src/vendor/spec-core` from `cbe2223`
|
|
181
242
|
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.
|
|
243
|
+
mask. [ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment.
|
|
183
244
|
|
|
184
245
|
Directives that were hidden, and now execute:
|
|
185
246
|
- **A backtick fence's info string may not hold a backtick.** A line that
|
|
@@ -251,7 +312,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
251
312
|
`glob="*.{ts,tsx}"` was always the two patterns `*.{ts` and `tsx}`, and the
|
|
252
313
|
message now says so. A configuration's `exclude` is a JSON array, where braces
|
|
253
314
|
keep their commas. Nothing restores the old readings.
|
|
254
|
-
[ADR-0015](docs/adr/0015-globs-from-spec-core.md).
|
|
315
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
255
316
|
- **`**` inside a name is refused**: `docs/**.md`, `src/**.ts`, `**.ts`,
|
|
256
317
|
`a**b`. The message says what `**` means and gives the two ways to write
|
|
257
318
|
what was meant, `docs/**/*.md` for any depth and `*.md` for one level. It
|
|
@@ -275,7 +336,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
275
336
|
An archived document is still parsed, validated and named in every output
|
|
276
337
|
format. `--ignore-status` executes it as before. The list stays closed:
|
|
277
338
|
`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
|
|
339
|
+
[ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md)'s amendment says why this word and
|
|
279
340
|
no other.
|
|
280
341
|
- **A status is found by the scanner's headings and front-matter reader.**
|
|
281
342
|
The three spellings, their order and the words are unchanged, and every
|
|
@@ -305,7 +366,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
305
366
|
`specWarnings` entry in `--json` (run and `prove`), a SARIF notification
|
|
306
367
|
and a `spec-warning` annotation for GitHub and GitLab.
|
|
307
368
|
|
|
308
|
-
[ADR-0010](docs/adr/0010-spec-status.md)'s second amendment.
|
|
369
|
+
[ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md)'s second amendment.
|
|
309
370
|
- **A title is the first level-one heading as the scanner reads it.** An
|
|
310
371
|
underlined one (`===`) is a title and one kept in a comment is not; a code
|
|
311
372
|
span in it is kept as written, where it was blanked, and a comment in it is
|
|
@@ -318,7 +379,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
318
379
|
over this repository's 18 ADRs, and 23 ms against 9 ms for a warm query of
|
|
319
380
|
one path, past the 20 ms ADR-0012 set out to meet. The scanner finds list
|
|
320
381
|
items, links and tables that nothing here reads.
|
|
321
|
-
[ADR-0002](docs/adr/0002-directive-format.md)'s amendment says where the
|
|
382
|
+
[ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment says where the
|
|
322
383
|
remedy lies.
|
|
323
384
|
- **The MCP server speaks the protocol through spec-core.** Classifying each
|
|
324
385
|
request, the two eras, dispatch, result shapes and the stdio framing are
|
|
@@ -327,7 +388,7 @@ counts. What can differ, and where this changelog says why:
|
|
|
327
388
|
client sees is unchanged, and every test of the server passes as it was
|
|
328
389
|
written. One edge moved: a last line cut inside a UTF-8 character when stdin
|
|
329
390
|
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).
|
|
391
|
+
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
392
|
- **API:**
|
|
332
393
|
- `createGlobMatcher`, `createExcludeMatcher` and `expandSpecPatterns` throw
|
|
333
394
|
for a pattern spec-core refuses - an unclosed `[` or `{`, an extended
|
|
@@ -361,7 +422,7 @@ expression can hold a quote — `/'/`, `/["']/`, `replace(/\/\//g, '')` — and
|
|
|
361
422
|
without a rule for `/`, that quote opened a string that closed somewhere else
|
|
362
423
|
entirely. Every text rule over a TypeScript project reads through this
|
|
363
424
|
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).
|
|
425
|
+
lost its place in. [ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md).
|
|
365
426
|
|
|
366
427
|
### Fixed
|
|
367
428
|
|
|
@@ -420,8 +481,8 @@ question asked per character has to be paid for per character.
|
|
|
420
481
|
Fixes from running 0.10.2 over a Rust and .NET monorepo, where an import rule
|
|
421
482
|
missed five `use` declarations in one crate and said nothing, and from probing
|
|
422
483
|
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).
|
|
484
|
+
[ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md),
|
|
485
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md).
|
|
425
486
|
|
|
426
487
|
### Fixed
|
|
427
488
|
|
|
@@ -469,8 +530,8 @@ regular expression literal holding a quote, `/["']/` - is recorded in ADR-0006.
|
|
|
469
530
|
Fixes from running 0.10.1 over a .NET solution, where a layer rule passed while
|
|
470
531
|
the domain imported the application, and from reading C# as it is written in
|
|
471
532
|
2026 while fixing that.
|
|
472
|
-
[ADR-0011](docs/adr/0011-layers-and-cycles.md),
|
|
473
|
-
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
533
|
+
[ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md),
|
|
534
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md).
|
|
474
535
|
|
|
475
536
|
### Fixed
|
|
476
537
|
|
|
@@ -543,7 +604,7 @@ the domain imported the application, and from reading C# as it is written in
|
|
|
543
604
|
|
|
544
605
|
Fixes from running 0.10.0 over a large monorepo, and from testing each exclude
|
|
545
606
|
shape under both engines while making them.
|
|
546
|
-
[ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
607
|
+
[ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
547
608
|
|
|
548
609
|
### Fixed
|
|
549
610
|
|
|
@@ -619,8 +680,8 @@ shape under both engines while making them.
|
|
|
619
680
|
Improvements from running 0.9.2 over a large polyglot monorepo: a
|
|
620
681
|
configuration a Rust, Go or .NET root can hold, exclusions a whole project
|
|
621
682
|
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).
|
|
683
|
+
[ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md),
|
|
684
|
+
[ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md).
|
|
624
685
|
|
|
625
686
|
### Added
|
|
626
687
|
|
|
@@ -684,7 +745,7 @@ shares, and a cycle rule that can leave lazy loading out.
|
|
|
684
745
|
unanalysable, as does `/*` inside JSX text.
|
|
685
746
|
- Tracking JSX text in general was turned down: a TypeScript cast or a
|
|
686
747
|
generic arrow read as markup would skip real code without a word.
|
|
687
|
-
[ADR-0005](docs/adr/0005-import-assertions.md).
|
|
748
|
+
[ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md).
|
|
688
749
|
|
|
689
750
|
## 0.9.1
|
|
690
751
|
|
|
@@ -700,13 +761,13 @@ shares, and a cycle rule that can leave lazy loading out.
|
|
|
700
761
|
- `/>` anywhere else still starts a regular expression, so
|
|
701
762
|
`replace(/>/g, '>')` reads as before.
|
|
702
763
|
|
|
703
|
-
[ADR-0005](docs/adr/0005-import-assertions.md).
|
|
764
|
+
[ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md).
|
|
704
765
|
|
|
705
766
|
## 0.9.0
|
|
706
767
|
|
|
707
768
|
A project's policy can live in its `package.json`, and `spec-guard --watch`
|
|
708
769
|
reports again as the tree changes, re-executing only the rules a change
|
|
709
|
-
affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
770
|
+
affected. [ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
710
771
|
|
|
711
772
|
### Added
|
|
712
773
|
|
|
@@ -774,7 +835,7 @@ affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
|
774
835
|
reported every other shard's files with the previous sweep's verdicts. The
|
|
775
836
|
merge refused that sweep.
|
|
776
837
|
- 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).
|
|
838
|
+
is unchanged. [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
778
839
|
|
|
779
840
|
### Fixed
|
|
780
841
|
|
|
@@ -796,7 +857,7 @@ affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
|
796
857
|
|
|
797
858
|
An architecture document can now state conventions about names and layout: what
|
|
798
859
|
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).
|
|
860
|
+
come in pairs. [ADR-0013](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0013-structure-assertions.md).
|
|
800
861
|
|
|
801
862
|
### Added
|
|
802
863
|
|
|
@@ -847,7 +908,7 @@ come in pairs. [ADR-0013](docs/adr/0013-structure-assertions.md).
|
|
|
847
908
|
had, less one in `glob.ts` that the new tests turned into a genuine hang. A
|
|
848
909
|
local sweep had reported four survivors in the new listing cache as killed; CI
|
|
849
910
|
found them, and they are tested. See
|
|
850
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
911
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
851
912
|
|
|
852
913
|
## 0.7.0
|
|
853
914
|
|
|
@@ -877,7 +938,7 @@ than every release, and it is fixed below.
|
|
|
877
938
|
`types="ignore"` asks the runtime question. JavaScript and TypeScript only,
|
|
878
939
|
because a cycle needs to know which file an import *is*; imports that should
|
|
879
940
|
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,
|
|
941
|
+
See [ADR-0011](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0011-layers-and-cycles.md) for the resolution table,
|
|
881
942
|
and for why the other four languages are not in the graph.
|
|
882
943
|
- `buildGraph`, `resolveReference`, `stronglyConnected`, `cyclicComponents`,
|
|
883
944
|
`witness`, `checkLayers` and `referenceForms` are exported, with their types.
|
|
@@ -889,7 +950,7 @@ than every release, and it is fixed below.
|
|
|
889
950
|
scripts. Rules in documents that are not in force are counted and named, and
|
|
890
951
|
listed with `--ignore-status`. The arithmetic behind it is tested against the
|
|
891
952
|
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.
|
|
953
|
+
[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
954
|
- **`spec-guard mcp`** - a Model Context Protocol server on stdio, with no
|
|
894
955
|
dependency on the MCP SDK. Tools `get_architectural_rules` (the query) and
|
|
895
956
|
`check_architecture` (a run, narrowed to the rules governing given paths, each
|
|
@@ -939,7 +1000,7 @@ than every release, and it is fixed below.
|
|
|
939
1000
|
mutated build against the real one on thousands of random inputs. The query
|
|
940
1001
|
and the server (`query.ts`, `rules.ts`, `mcp.ts`, `specs.ts`) are all at 100%;
|
|
941
1002
|
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
|
|
1003
|
+
was deleted. See [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md) for both
|
|
943
1004
|
accounts, and for why one sweep's count is good to about three.
|
|
944
1005
|
- `version(manifest?)` takes the manifest to read, so its fallback for a broken
|
|
945
1006
|
install - `0.0.0` rather than a crash - is tested.
|
|
@@ -984,7 +1045,7 @@ making sure a rule that stops running can never look like a rule that passed.
|
|
|
984
1045
|
are still checked for typos, bad attributes and unresolvable values, so a
|
|
985
1046
|
draft's mistake is found on the day it is written rather than on the day
|
|
986
1047
|
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
|
|
1048
|
+
See [ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md), which also records why there is
|
|
988
1049
|
no per-directive `if-status` attribute.
|
|
989
1050
|
- `--ignore-status` executes every directive whatever its document declares -
|
|
990
1051
|
how to ask whether a draft would pass if you accepted it today.
|
|
@@ -1008,7 +1069,7 @@ making sure a rule that stops running can never look like a rule that passed.
|
|
|
1008
1069
|
the whole suite per mutant, so on a loaded machine an unrelated test timing
|
|
1009
1070
|
out is scored as a kill. Those patterns are now verified by applying every
|
|
1010
1071
|
mutant by hand, `scripts/mutation-regex.mjs`, and the account is in
|
|
1011
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
1072
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
1012
1073
|
|
|
1013
1074
|
## 0.5.1
|
|
1014
1075
|
|
|
@@ -1057,7 +1118,7 @@ new features, and nothing a user has to change.
|
|
|
1057
1118
|
individually and produce byte-identical output, so that figure is the ceiling
|
|
1058
1119
|
rather than a way-point — and 29 that were assumed equivalent turned out not
|
|
1059
1120
|
to be, and are now tested. See
|
|
1060
|
-
[ADR-0003](docs/adr/0003-mutation-testing.md), which also records a Stryker
|
|
1121
|
+
[ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md), which also records a Stryker
|
|
1061
1122
|
limitation found on the way: a mutant that stops a test file *loading* is
|
|
1062
1123
|
reported as survived even though the suite is killing it.
|
|
1063
1124
|
- **`src/imports.ts` went from 73.74% to 95.89%.** The tokenizer was tested as a
|
|
@@ -1095,13 +1156,13 @@ scope holds no files at all.
|
|
|
1095
1156
|
Not four new tokenizers: the comment and string lexer from ADR-0006 masks the
|
|
1096
1157
|
source and the readers work on what is left. Tree-sitter measured 94 MB
|
|
1097
1158
|
unpacked against this package's 0.33 MB. See
|
|
1098
|
-
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
1159
|
+
[ADR-0008](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0008-polyglot-imports.md).
|
|
1099
1160
|
- **`baseline` and `ratchet`** on the absence assertions, for adopting a strict
|
|
1100
1161
|
rule on a codebase that already breaks it. `baseline="src/legacy/a.ts:2"`
|
|
1101
1162
|
names the debt by file and count. The ratchet is two-sided: new violations
|
|
1102
1163
|
fail, and so does an entry the code no longer supports, because a baseline
|
|
1103
1164
|
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).
|
|
1165
|
+
the second half. See [ADR-0009](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0009-debt-baselines.md).
|
|
1105
1166
|
- **`--print-baseline`** prints the attribute that would exempt today's
|
|
1106
1167
|
violations, for a human to paste. It prints; it does not edit. That is the
|
|
1107
1168
|
whole answer to `--fix`, and ADR-0009 argues it.
|
|
@@ -1131,7 +1192,7 @@ scope holds no files at all.
|
|
|
1131
1192
|
starts finding dependencies it previously reported as unanalysable.
|
|
1132
1193
|
- **Mutation testing in CI runs in two tiers**: incremental on branches,
|
|
1133
1194
|
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).
|
|
1195
|
+
both. See [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
1135
1196
|
|
|
1136
1197
|
### Fixed
|
|
1137
1198
|
|
|
@@ -1179,7 +1240,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
1179
1240
|
- **The engines are one implementation.** ripgrep now answers only *which files
|
|
1180
1241
|
contain this text*; the scanner does all counting, comment classification,
|
|
1181
1242
|
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).
|
|
1243
|
+
takes, not what it concludes. See [ADR-0007](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0007-search-scope.md).
|
|
1183
1244
|
|
|
1184
1245
|
### Added
|
|
1185
1246
|
|
|
@@ -1218,7 +1279,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
1218
1279
|
directions. A zero-dependency tokenizer resolves `import`, `export … from`,
|
|
1219
1280
|
`import type`, dynamic `import()` with a literal, and `require()`. Module
|
|
1220
1281
|
references it cannot resolve statically are reported, never counted as clean.
|
|
1221
|
-
See [ADR-0005](docs/adr/0005-import-assertions.md).
|
|
1282
|
+
See [ADR-0005](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0005-import-assertions.md).
|
|
1222
1283
|
- **`comments` attribute.** See Changed, below.
|
|
1223
1284
|
- **`--allow-missing-targets`** to restore the previous handling of a `target`
|
|
1224
1285
|
path that does not exist.
|
|
@@ -1234,7 +1295,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
1234
1295
|
uncertain the text counts as code, and every run reports how many matches it
|
|
1235
1296
|
excluded — a pass caused by comment exclusion is never silent.
|
|
1236
1297
|
`comments="include"` restores counting per assertion.
|
|
1237
|
-
See [ADR-0006](docs/adr/0006-comment-classification.md).
|
|
1298
|
+
See [ADR-0006](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0006-comment-classification.md).
|
|
1238
1299
|
- **A `target` path that does not exist now fails the run** instead of warning
|
|
1239
1300
|
and searching what remained. An assertion pointed at a renamed directory used
|
|
1240
1301
|
to search nothing, find nothing, and report success. `--allow-missing-targets`
|
|
@@ -1270,9 +1331,9 @@ first published 0.3.0.
|
|
|
1270
1331
|
enough for the JavaScript scanner to beat a ripgrep process spawn. The probe
|
|
1271
1332
|
is the work — the enumeration it performs is reused by the scanner, so
|
|
1272
1333
|
choosing costs nothing when the scanner wins.
|
|
1273
|
-
See [ADR-0004](docs/adr/0004-adaptive-engine.md).
|
|
1334
|
+
See [ADR-0004](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0004-adaptive-engine.md).
|
|
1274
1335
|
- **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).
|
|
1336
|
+
that closed the gaps it exposed. See [ADR-0003](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0003-mutation-testing.md).
|
|
1276
1337
|
|
|
1277
1338
|
### Changed
|
|
1278
1339
|
|
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';
|