@descent-vtt/spec-guard 0.11.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 +443 -31
- package/README.md +403 -41
- package/dist/cites.d.ts +192 -0
- package/dist/cites.d.ts.map +1 -0
- package/dist/cites.js +599 -0
- package/dist/cites.js.map +1 -0
- package/dist/cli.d.ts +14 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +315 -22
- package/dist/cli.js.map +1 -1
- package/dist/comments.d.ts +1 -1
- package/dist/comments.js +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +46 -5
- package/dist/config.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +38 -14
- package/dist/engine.js.map +1 -1
- package/dist/glob.d.ts +128 -24
- package/dist/glob.d.ts.map +1 -1
- package/dist/glob.js +304 -61
- package/dist/glob.js.map +1 -1
- package/dist/impact.d.ts +179 -0
- package/dist/impact.d.ts.map +1 -0
- package/dist/impact.js +360 -0
- package/dist/impact.js.map +1 -0
- package/dist/index.d.ts +15 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +22 -75
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +206 -370
- package/dist/mcp.js.map +1 -1
- package/dist/overlay.d.ts +39 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +133 -0
- package/dist/overlay.js.map +1 -0
- package/dist/parser.d.ts +41 -24
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +217 -160
- package/dist/parser.js.map +1 -1
- package/dist/prove.d.ts +46 -0
- package/dist/prove.d.ts.map +1 -0
- package/dist/prove.js +549 -0
- package/dist/prove.js.map +1 -0
- package/dist/query.d.ts +18 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +9 -3
- package/dist/query.js.map +1 -1
- package/dist/reporter.d.ts +139 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +593 -21
- package/dist/reporter.js.map +1 -1
- package/dist/rules.js +3 -3
- package/dist/rules.js.map +1 -1
- package/dist/runner.d.ts +31 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +85 -21
- package/dist/runner.js.map +1 -1
- package/dist/specs.d.ts +27 -1
- package/dist/specs.d.ts.map +1 -1
- package/dist/specs.js +45 -10
- package/dist/specs.js.map +1 -1
- package/dist/structure.d.ts.map +1 -1
- package/dist/structure.js +7 -6
- package/dist/structure.js.map +1 -1
- package/dist/types.d.ts +193 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vendor/spec-core/jsonrpc/index.d.ts +3 -0
- package/dist/vendor/spec-core/jsonrpc/index.d.ts.map +1 -0
- package/dist/vendor/spec-core/jsonrpc/index.js +2 -0
- package/dist/vendor/spec-core/jsonrpc/index.js.map +1 -0
- package/dist/vendor/spec-core/jsonrpc/mcp.d.ts +158 -0
- package/dist/vendor/spec-core/jsonrpc/mcp.d.ts.map +1 -0
- package/dist/vendor/spec-core/jsonrpc/mcp.js +353 -0
- package/dist/vendor/spec-core/jsonrpc/mcp.js.map +1 -0
- package/dist/vendor/spec-core/markdown/frontmatter.d.ts +104 -0
- package/dist/vendor/spec-core/markdown/frontmatter.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/frontmatter.js +459 -0
- package/dist/vendor/spec-core/markdown/frontmatter.js.map +1 -0
- package/dist/vendor/spec-core/markdown/headings.d.ts +46 -0
- package/dist/vendor/spec-core/markdown/headings.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/headings.js +199 -0
- package/dist/vendor/spec-core/markdown/headings.js.map +1 -0
- package/dist/vendor/spec-core/markdown/index.d.ts +6 -0
- package/dist/vendor/spec-core/markdown/index.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/index.js +4 -0
- package/dist/vendor/spec-core/markdown/index.js.map +1 -0
- package/dist/vendor/spec-core/markdown/layout.d.ts +40 -0
- package/dist/vendor/spec-core/markdown/layout.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/layout.js +28 -0
- package/dist/vendor/spec-core/markdown/layout.js.map +1 -0
- package/dist/vendor/spec-core/markdown/links.d.ts +26 -0
- package/dist/vendor/spec-core/markdown/links.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/links.js +394 -0
- package/dist/vendor/spec-core/markdown/links.js.map +1 -0
- package/dist/vendor/spec-core/markdown/lists.d.ts +23 -0
- package/dist/vendor/spec-core/markdown/lists.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/lists.js +127 -0
- package/dist/vendor/spec-core/markdown/lists.js.map +1 -0
- package/dist/vendor/spec-core/markdown/scan.d.ts +37 -0
- package/dist/vendor/spec-core/markdown/scan.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/scan.js +463 -0
- package/dist/vendor/spec-core/markdown/scan.js.map +1 -0
- package/dist/vendor/spec-core/markdown/syntax.d.ts +76 -0
- package/dist/vendor/spec-core/markdown/syntax.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/syntax.js +181 -0
- package/dist/vendor/spec-core/markdown/syntax.js.map +1 -0
- package/dist/vendor/spec-core/markdown/tables.d.ts +19 -0
- package/dist/vendor/spec-core/markdown/tables.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/tables.js +86 -0
- package/dist/vendor/spec-core/markdown/tables.js.map +1 -0
- package/dist/vendor/spec-core/markdown/types.d.ts +291 -0
- package/dist/vendor/spec-core/markdown/types.d.ts.map +1 -0
- package/dist/vendor/spec-core/markdown/types.js +9 -0
- package/dist/vendor/spec-core/markdown/types.js.map +1 -0
- package/dist/vendor/spec-core/path/index.d.ts +2 -0
- package/dist/vendor/spec-core/path/index.d.ts.map +1 -0
- package/dist/vendor/spec-core/path/index.js +2 -0
- package/dist/vendor/spec-core/path/index.js.map +1 -0
- package/dist/vendor/spec-core/path/posix.d.ts +84 -0
- package/dist/vendor/spec-core/path/posix.d.ts.map +1 -0
- package/dist/vendor/spec-core/path/posix.js +150 -0
- package/dist/vendor/spec-core/path/posix.js.map +1 -0
- package/dist/vendor/spec-core/pattern/automaton.d.ts +130 -0
- package/dist/vendor/spec-core/pattern/automaton.d.ts.map +1 -0
- package/dist/vendor/spec-core/pattern/automaton.js +340 -0
- package/dist/vendor/spec-core/pattern/automaton.js.map +1 -0
- package/dist/vendor/spec-core/pattern/charset.d.ts +59 -0
- package/dist/vendor/spec-core/pattern/charset.d.ts.map +1 -0
- package/dist/vendor/spec-core/pattern/charset.js +116 -0
- package/dist/vendor/spec-core/pattern/charset.js.map +1 -0
- package/dist/vendor/spec-core/pattern/glob.d.ts +122 -0
- package/dist/vendor/spec-core/pattern/glob.d.ts.map +1 -0
- package/dist/vendor/spec-core/pattern/glob.js +481 -0
- package/dist/vendor/spec-core/pattern/glob.js.map +1 -0
- package/dist/vendor/spec-core/pattern/index.d.ts +7 -0
- package/dist/vendor/spec-core/pattern/index.d.ts.map +1 -0
- package/dist/vendor/spec-core/pattern/index.js +4 -0
- package/dist/vendor/spec-core/pattern/index.js.map +1 -0
- package/dist/vendor/spec-core/pattern/regex.d.ts +68 -0
- package/dist/vendor/spec-core/pattern/regex.d.ts.map +1 -0
- package/dist/vendor/spec-core/pattern/regex.js +813 -0
- package/dist/vendor/spec-core/pattern/regex.js.map +1 -0
- package/dist/vendor/spec-core/text/index.d.ts +3 -0
- package/dist/vendor/spec-core/text/index.d.ts.map +1 -0
- package/dist/vendor/spec-core/text/index.js +2 -0
- package/dist/vendor/spec-core/text/index.js.map +1 -0
- package/dist/vendor/spec-core/text/lines.d.ts +73 -0
- package/dist/vendor/spec-core/text/lines.d.ts.map +1 -0
- package/dist/vendor/spec-core/text/lines.js +156 -0
- package/dist/vendor/spec-core/text/lines.js.map +1 -0
- package/package.json +9 -2
- package/src/vendor/spec-core/LICENSE +21 -0
- package/src/vendor/spec-core/README.md +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,416 @@ 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
|
+
|
|
69
|
+
## 0.12.0
|
|
70
|
+
|
|
71
|
+
The family's core, and three commands. Patterns and Markdown are read through
|
|
72
|
+
spec-core, copied in and checked by hash: a pattern that cannot be read is
|
|
73
|
+
refused rather than matched as a literal, a glob no longer backtracks, and
|
|
74
|
+
directives are found as CommonMark finds code, comments and front matter.
|
|
75
|
+
`prove` shows every rule in force catching a violation, `cites` holds code
|
|
76
|
+
comments to the specs they cite, and `impact` names who depends on a path.
|
|
77
|
+
`archived` withholds a document.
|
|
78
|
+
|
|
79
|
+
### Upgrading
|
|
80
|
+
|
|
81
|
+
Run this release beside the one it replaces, each with `--json`, and compare
|
|
82
|
+
`summary.total` before trusting a green run - and, if the totals differ, each
|
|
83
|
+
result's `spec` file and line, which say which rule moved. A rule that stops
|
|
84
|
+
running reads exactly like one that passes. On a consumer of 114 specs and 301
|
|
85
|
+
assertions, both releases ran the same 301 at the same places with the same
|
|
86
|
+
counts. What can differ, and where this changelog says why:
|
|
87
|
+
|
|
88
|
+
- **A run that exits 2**, or a directive that is invalid, where one ran: a
|
|
89
|
+
pattern that cannot be read - `**` inside a name (`docs/**.md`), an
|
|
90
|
+
extended glob, an unclosed `[` or `{` - in `specs`, `exclude`, `--spec`,
|
|
91
|
+
`--exclude` or a directive's attributes.
|
|
92
|
+
- **`summary.total` moving** because a directive moved between prose and code:
|
|
93
|
+
the shapes under Fixed. Every directive-shaped comment left in code, raw
|
|
94
|
+
HTML or front matter is on one line of the report and in `maskedDirectives`.
|
|
95
|
+
- **`summary.inactive` moving**: `archived` withholds a document; a
|
|
96
|
+
front-matter `status` the reader cannot read - text after a closing quote,
|
|
97
|
+
`: ` in a plain value - keeps its document in force with a warning, where
|
|
98
|
+
0.11.0 took its first word, and nothing below the front matter is read in
|
|
99
|
+
its place; and an invalid directive in a draft is counted once, as invalid.
|
|
100
|
+
- **Warnings that fail nothing**, in `specWarnings`: a front-matter status
|
|
101
|
+
that cannot be read, a block never closed.
|
|
102
|
+
- **`impact` exits 2** when no spec matched, as `query` does.
|
|
103
|
+
|
|
104
|
+
### Added
|
|
105
|
+
|
|
106
|
+
- **`spec-guard impact <paths...>`: who depends on this?** For each path, the
|
|
107
|
+
files that import it, transitively, each with its distance and the import
|
|
108
|
+
that takes it one step closer, and the rules in force that govern the path or
|
|
109
|
+
any of them, by `query`'s arithmetic. The import graph is ADR-0011's, read
|
|
110
|
+
backwards over the whole tree: relative JavaScript and TypeScript imports by
|
|
111
|
+
its resolution table, and relative Python imports, which name a module
|
|
112
|
+
beside the importing file. Go, Rust, C# and absolute Python references name
|
|
113
|
+
modules and are counted rather than followed; a path in one of those
|
|
114
|
+
languages says its dependents are not computed. An import naming no file, an
|
|
115
|
+
alias or a dynamic `import(name)` is listed, never guessed. `--depth <n>`,
|
|
116
|
+
`--ignore-status`, and `--json` with `formatVersion`. A path that does not
|
|
117
|
+
exist is exit 2, and so is a run in which no spec matched, as for `query`:
|
|
118
|
+
the dependents are written, and `--allow-empty` exits 0 with them. `impactOf`
|
|
119
|
+
is the API. [ADR-0018](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0018-impact.md).
|
|
120
|
+
- **`get_dependents` on the MCP server**, a third tool beside
|
|
121
|
+
`get_architectural_rules` and `check_architecture`: `impact` for a list of
|
|
122
|
+
paths, with `depth` and `include_inactive`. Its structured content is the
|
|
123
|
+
document `impact --json` writes and its text the command's report, and it is
|
|
124
|
+
annotated read-only, as the other two are. Its description, and the server's
|
|
125
|
+
instructions, tell an agent to call it before changing a file others import.
|
|
126
|
+
A path that does not exist is a tool error the model can read. A client
|
|
127
|
+
that pinned the tool list sees three. `impactDocument` is the API for the
|
|
128
|
+
document both answer with. ADR-0018's amendment.
|
|
129
|
+
- **`spec-guard cites`: do the comments cite decisions in force?** A comment
|
|
130
|
+
such as `// ADR-0011: the domain imports no infrastructure` is a claim, and it
|
|
131
|
+
goes stale when the document is never written or is superseded. `cites` reads
|
|
132
|
+
the comment text of every source file - by the classifier's reading, so never
|
|
133
|
+
a string - for the ids of the families a project names in a new `cites`
|
|
134
|
+
option, `[{ "id": "ADR-{n}", "files": "docs/adr/{n}-*.md" }]`, where `{n}` is
|
|
135
|
+
a number (`ADR-7`, `ADR-007` and `0007-x.md` are one document). Without it, a
|
|
136
|
+
directory of numbered specs whose titles all begin with one id and their own
|
|
137
|
+
number is read as a family; anything less is a note and exit 0, not a guess.
|
|
138
|
+
A **ghost** citation, of no document, is an error with the nearest ids as its
|
|
139
|
+
hint. A **stale** one, of a document superseded, deprecated, rejected or
|
|
140
|
+
archived, is a warning (an error under `--strict`) that names the successor
|
|
141
|
+
the document's status line gives, followed to the one in force. Ids another
|
|
142
|
+
project qualifies - `spec-core's ADR-0005` - are counted and not checked,
|
|
143
|
+
and so are ids in a link: after a `/`, `#`, `=` or `?`, or past a `://`,
|
|
144
|
+
as in `https://github.com/org/repo/blob/main/docs/adr/ADR-0042.md`.
|
|
145
|
+
Markdown, spec files, excluded paths and files in no known language are not
|
|
146
|
+
read, and are counted. Human, `--json` (with `formatVersion`), SARIF, GitHub
|
|
147
|
+
and GitLab output; exit 1 on a ghost, 2 for a family whose files match no
|
|
148
|
+
document. `findCitations` is the API.
|
|
149
|
+
[ADR-0017](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0017-citations-in-comments.md).
|
|
150
|
+
- **`spec-guard prove`: can each rule actually fail?** A passing rule cannot
|
|
151
|
+
say whether the code holds or the rule cannot see the code. `prove` shows
|
|
152
|
+
each rule in force a violation of itself - a file holding the forbidden text,
|
|
153
|
+
a file importing the forbidden module, a cycle, an import across layers, a
|
|
154
|
+
misnamed file, a required entry or a partner taken away, a required file
|
|
155
|
+
removed - and runs the rule over it, in memory, through the door every read
|
|
156
|
+
goes through: nothing is written to disk and nothing touches git. Each rule
|
|
157
|
+
is `killed`, `survived` (the finding, with the violation shown) or
|
|
158
|
+
`unprovable` (with the reason). Exit 1 when a rule survived, and under
|
|
159
|
+
`--strict` when one is unprovable; `--json` is versioned by `formatVersion`,
|
|
160
|
+
and `--format sarif` puts a survivor on its directive.
|
|
161
|
+
`proveSpecGuard` is the same for a caller of the API. The first proof of
|
|
162
|
+
this repository's own rules found one that could not fail as written, and
|
|
163
|
+
CI now proves every rule the repository states on each change.
|
|
164
|
+
[ADR-0016](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0016-rules-seen-to-fail.md).
|
|
165
|
+
- **`RunOptions.io`: a run over a tree that is not on disk.** `runSpecGuard`
|
|
166
|
+
reads through the `Io` it is given - finding and reading the specs, checking
|
|
167
|
+
targets exist, walking them, scanning files, reading imports and listing
|
|
168
|
+
directories - and through `nodeIo` when it is given none, as before. The run
|
|
169
|
+
had the door all along and handed the filesystem to every reader itself.
|
|
170
|
+
ripgrep reads the disk in a process of its own, where no door reaches, so
|
|
171
|
+
`engine: 'ripgrep'` with an `io` is refused with a message that says so, and
|
|
172
|
+
`auto` with one searches with the built-in scanner. A search that fails
|
|
173
|
+
outright through the door fails the run, rather than falling back to the
|
|
174
|
+
scanner that reads the disk. [ADR-0014](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0014-configuration-and-watch.md).
|
|
175
|
+
- **`--format gitlab` and `--format github`**, for the run, `prove` and
|
|
176
|
+
`cites`. `gitlab` writes a GitLab Code Quality report - `description`,
|
|
177
|
+
`check_name`, a `fingerprint`, a `severity` and a `location` - which a
|
|
178
|
+
merge request shows beside its changes. The fingerprint is the SHA-256 of
|
|
179
|
+
what a finding is about - a rule's document, kind, subject and targets, as
|
|
180
|
+
SARIF's is; a citation's file, family and id; a document's path - and never
|
|
181
|
+
of its message, which holds the count of matches and the directive's line:
|
|
182
|
+
one more match, or a line added above a directive, would otherwise have
|
|
183
|
+
closed every open issue and opened a new one. Findings that share an
|
|
184
|
+
identity, one ghost cited on two lines, are numbered in order. `github` writes one workflow command per finding, which a job's log
|
|
185
|
+
turns into an annotation on the pull request with no upload step. Both place
|
|
186
|
+
the findings SARIF places: a failing assertion or a surviving rule is
|
|
187
|
+
`critical`, a directive that could not be read `major`, a rule `prove` could
|
|
188
|
+
make no violation for `minor`, and a document not in force is named, as
|
|
189
|
+
`info`, on its first line. `formatGitlab`, `formatGithub`, `runAnnotations`,
|
|
190
|
+
`proveAnnotations` and `citesAnnotations` are the API.
|
|
191
|
+
- **What was not run is counted.** A comment shaped like a directive in code,
|
|
192
|
+
raw HTML or front matter is not run, and a report now says how many and
|
|
193
|
+
where: one dim line in the human report - "7 directive-shaped comments in
|
|
194
|
+
code, raw HTML or front matter were not run: README.md:120, ..." - naming
|
|
195
|
+
the first five, or every one under `--verbose`, and `maskedDirectives` in
|
|
196
|
+
the `--json` of a run and of `prove`, each with what hid it. Most are
|
|
197
|
+
examples; the ones that are not are rules 0.11.0 ran that this release does
|
|
198
|
+
not, such as a directive in an indented line or under a leading `---` read
|
|
199
|
+
as front matter. Warnings about how a document was read - a front-matter
|
|
200
|
+
status that cannot be read, a block never closed - are `specWarnings`.
|
|
201
|
+
Both fields are added, so no `formatVersion` moves.
|
|
202
|
+
[ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment.
|
|
203
|
+
- **`formatVersion: 1` on the run's `--json` and on `query --json`**, as
|
|
204
|
+
`prove --json` has had from the start: a field removed or renamed moves it,
|
|
205
|
+
a field added does not. Both documents are otherwise unchanged; this is one
|
|
206
|
+
field more, first in each.
|
|
207
|
+
- **`io` on `loadRuleSet` and `queryRules`, too.** A query found and read the
|
|
208
|
+
specs, and asked whether each path exists, through the filesystem whatever
|
|
209
|
+
the caller had; it now goes through the door it is given, as a run does, so
|
|
210
|
+
a query over a tree in memory sees that tree.
|
|
211
|
+
|
|
212
|
+
### Fixed
|
|
213
|
+
|
|
214
|
+
- **An invalid directive in a document not in force was counted twice**, as
|
|
215
|
+
invalid and again as a rule not in force, so one bad directive in a draft
|
|
216
|
+
read "1 invalid · 1 not in force". It is counted once, as invalid, in the
|
|
217
|
+
summary, in the document's own line, and in the `inactive` of every JSON
|
|
218
|
+
report: it is no rule the document would run in force.
|
|
219
|
+
- **A glob could take a minute to fail one file name.** Every pattern was
|
|
220
|
+
compiled to a `RegExp`, and `*-*-*-*-*-*x` against a name of 121 dashes made
|
|
221
|
+
V8 try every way of dividing the name between six `[^/]*` groups: 55 seconds,
|
|
222
|
+
measured. Patterns are now read by the glob engine the spec-* tools share,
|
|
223
|
+
spec-core's, whose automaton keeps a set of live states and cannot backtrack:
|
|
224
|
+
the same match takes under a millisecond. spec-core is copied into
|
|
225
|
+
`src/vendor/spec-core` and verified by hash, so `dependencies` stays empty,
|
|
226
|
+
and its MIT notice ships in the package at `src/vendor/spec-core/LICENSE`.
|
|
227
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
228
|
+
- **ripgrep and the scanner still read some patterns differently**, so the same
|
|
229
|
+
rule could count differently on either side of the tree size at which `auto`
|
|
230
|
+
changes engine. ripgrep anchored every alternative of `{src/*.ts,*.md}`
|
|
231
|
+
because one held a `/`, dropped the empty one in `{,src/}a.ts`, matched
|
|
232
|
+
nothing for `src/./a.ts`, and failed on a `}` that closes nothing. It is now
|
|
233
|
+
handed each alternative as a glob of its own, spelled as the scanner reads
|
|
234
|
+
it. And ripgrep applies no glob to a path named on its command line, so a
|
|
235
|
+
rule whose target is a file its `glob` does not match, or a directory its
|
|
236
|
+
`exclude` does, counted under ripgrep what the scanner left out; its list of
|
|
237
|
+
files is now held to the same filters. ADR-0015.
|
|
238
|
+
- **What is code in a spec is what CommonMark says it is.** Directives inside
|
|
239
|
+
code never execute, and what counted as code was decided by `maskCode`'s own
|
|
240
|
+
rules. It is now decided by spec-core's Markdown scanner, which every spec-*
|
|
241
|
+
tool reads documents with, copied into `src/vendor/spec-core` from `cbe2223`
|
|
242
|
+
and verified by hash; `maskCode` is still exported, and is the scanner's
|
|
243
|
+
mask. [ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment.
|
|
244
|
+
|
|
245
|
+
Directives that were hidden, and now execute:
|
|
246
|
+
- **A backtick fence's info string may not hold a backtick.** A line that
|
|
247
|
+
reads ```` ```js`x ```` is prose that opens with a code span. Read as a
|
|
248
|
+
fence, it hid every line under it, a real directive included, until
|
|
249
|
+
something closed it - and nothing said a rule had gone quiet.
|
|
250
|
+
- **A code span ends with its paragraph.** A backtick that closes nothing
|
|
251
|
+
there, as in ``press ` to open the console``, paired with the next
|
|
252
|
+
backtick anywhere in the document and hid every directive between the
|
|
253
|
+
two. An escaped backtick opens nothing.
|
|
254
|
+
- **A fence shown inside a comment opens nothing.** A template that showed
|
|
255
|
+
one hid every directive after it.
|
|
256
|
+
- **A fence line shown as code in a list item opens nothing.** Four columns
|
|
257
|
+
past an item's text is indented code, so a fence line written there - six
|
|
258
|
+
spaces under a `-` item, seven under `1.`, deeper in a nested item - is a
|
|
259
|
+
line of code. The first copy of the scanner read no indented code inside a
|
|
260
|
+
list, took the line for an opener that nothing closed, and hid every
|
|
261
|
+
directive after it.
|
|
262
|
+
|
|
263
|
+
And a code fence or a `<pre>`, `<script>`, `<style>` or `<textarea>`
|
|
264
|
+
block that is never closed, and runs to the end of the document, is a
|
|
265
|
+
warning on its opening line (`specWarnings`), since no directive after it
|
|
266
|
+
runs. It fails nothing: it is read as every renderer shows it, as code.
|
|
267
|
+
|
|
268
|
+
Directives that executed, and are now code:
|
|
269
|
+
- **A closing fence has no info string.** Inside a block opened by three
|
|
270
|
+
backticks, a line of three backticks followed by `js` is a line of the
|
|
271
|
+
block. It used to close it, and a directive shown after it executed.
|
|
272
|
+
- **A fence may be indented with the list item it sits in.** CommonMark
|
|
273
|
+
counts its three spaces from the item, so a fence in a `1.` item nested in
|
|
274
|
+
a `-` item is five or more spaces from the margin. It was not recognised,
|
|
275
|
+
and a directive shown inside it executed: always behind `~~~`, and behind
|
|
276
|
+
backticks whenever the prose above mentioned one, since the two fence lines
|
|
277
|
+
otherwise paired as a code span by accident. An opener may sit at any
|
|
278
|
+
indentation outside indented code, and a closer at most three columns
|
|
279
|
+
deeper than its opener.
|
|
280
|
+
- **Indented code, raw-text HTML and front matter are not read.** Four
|
|
281
|
+
columns past the margin, or past the text of the list item a line sits
|
|
282
|
+
in, after a blank line, are code in every renderer;
|
|
283
|
+
`<script>`, `<pre>`, `<style>` and `<textarea>` hold no Markdown; front
|
|
284
|
+
matter is metadata. `<details>` and `<div>` hold Markdown, and are read.
|
|
285
|
+
|
|
286
|
+
And a backtick inside a comment is a character, so a directive holding one
|
|
287
|
+
keeps it: ``symbol="`eval`"`` is searched for as written, where the two
|
|
288
|
+
backticks paired and the rule searched for six spaces.
|
|
289
|
+
|
|
290
|
+
This repository's own specs execute the same assertions, at the same lines,
|
|
291
|
+
and every directive in the 143 Markdown files of the five spec-* repositories
|
|
292
|
+
is read as before. A test holds the scanner to 0.11.0's masking on every
|
|
293
|
+
Markdown file here, and on random documents built from lines both read alike,
|
|
294
|
+
and shows it parting from 0.11.0 on each shape above.
|
|
295
|
+
|
|
296
|
+
### Changed
|
|
297
|
+
|
|
298
|
+
- **Mutation testing in CI runs in eight shards**, not four. Three of the four
|
|
299
|
+
took 23 to 28 minutes on the sweep that merged this release's code, and the
|
|
300
|
+
fourth was cancelled at the 30-minute job limit. ADR-0003 has the per-file
|
|
301
|
+
minutes and the split; the longest of the eight took 16m16s.
|
|
302
|
+
- **A pattern that cannot be read is refused.** An unclosed `[` or `{`, an
|
|
303
|
+
extended glob such as `+(a|b)` (a group holding a `|`: `C++(notes).md` and
|
|
304
|
+
`*(2017).md` are names with parentheses), a `..`, or a range that runs
|
|
305
|
+
backwards, in `glob`, `exclude`, `module`, `order`, `pattern`, `dirs` or
|
|
306
|
+
`required`, makes the directive invalid; in `exclude` in the configuration or `--exclude`, or in
|
|
307
|
+
a spec pattern, it is exit 2. Each used to be read as a literal or as whatever
|
|
308
|
+
its `RegExp` happened to mean, which is a filter that matches nothing and
|
|
309
|
+
passes. So is an alternative that names no path, as in `{dist/**,}`, whose
|
|
310
|
+
empty alternative matched the empty string. A brace group with a comma in it
|
|
311
|
+
in a directive is one more case: a list attribute splits on commas, so
|
|
312
|
+
`glob="*.{ts,tsx}"` was always the two patterns `*.{ts` and `tsx}`, and the
|
|
313
|
+
message now says so. A configuration's `exclude` is a JSON array, where braces
|
|
314
|
+
keep their commas. Nothing restores the old readings.
|
|
315
|
+
[ADR-0015](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0015-globs-from-spec-core.md).
|
|
316
|
+
- **`**` inside a name is refused**: `docs/**.md`, `src/**.ts`, `**.ts`,
|
|
317
|
+
`a**b`. The message says what `**` means and gives the two ways to write
|
|
318
|
+
what was meant, `docs/**/*.md` for any depth and `*.md` for one level. It
|
|
319
|
+
used to cross directories under the scanner and not under ripgrep, so a rule
|
|
320
|
+
counted differently by engine; read as `*`, as `.gitignore` reads it,
|
|
321
|
+
`"specs": ["docs/**.md"]` would quietly have stopped finding every nested
|
|
322
|
+
document. In a directive the directive is invalid, in a draft as in a
|
|
323
|
+
document in force. A spec pattern is refused before any command starts: in
|
|
324
|
+
the configuration's `specs`, naming the file, and on the command line or in
|
|
325
|
+
`--spec`, for `query`, `impact`, `cites`, `prove` and `mcp` as for a run -
|
|
326
|
+
exit 2, as `exclude` in the configuration and `--exclude` are.
|
|
327
|
+
`specPatternError` is the check, for a caller of the API.
|
|
328
|
+
- **A `.` or empty segment is no segment** (`src/./a.ts` is `src/a.ts`), and
|
|
329
|
+
**a leading `/` anchors a `glob`** at the root, as it anchors an `exclude`.
|
|
330
|
+
Both matched nothing in the scanner before; ripgrep already anchored.
|
|
331
|
+
- **`archived` withholds a document**, a sixth word beside `draft`,
|
|
332
|
+
`proposed`, `rejected`, `deprecated` and `superseded`. `spec-brief` closes a
|
|
333
|
+
task brief's round by setting `status: archived` and moving the brief to an
|
|
334
|
+
archive directory. Its directives stated the round's premises and goals,
|
|
335
|
+
which are history once the round is closed, and executed anyway they failed.
|
|
336
|
+
An archived document is still parsed, validated and named in every output
|
|
337
|
+
format. `--ignore-status` executes it as before. The list stays closed:
|
|
338
|
+
`done`, `closed`, `archive` and every other near word stay in force, 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
|
|
340
|
+
no other.
|
|
341
|
+
- **A status is found by the scanner's headings and front-matter reader.**
|
|
342
|
+
The three spellings, their order and the words are unchanged, and every
|
|
343
|
+
status in the five spec-* repositories reads as it did. Where the scanner
|
|
344
|
+
reads a document differently, the status follows it:
|
|
345
|
+
- A `## Status` kept in a comment - a template not yet filled in - no longer
|
|
346
|
+
withholds the document, and a `##` in a comment or in code no longer ends
|
|
347
|
+
the preamble where the `**Status:**` label is read.
|
|
348
|
+
- An underlined heading is a heading. An underlined `Status` is the section,
|
|
349
|
+
and an underlined section ends the preamble, so a `status: draft` line with
|
|
350
|
+
`---` directly under it is a heading, as every renderer shows it, and not a
|
|
351
|
+
label.
|
|
352
|
+
- Front matter is read by spec-core's reader, the family's: a quoted value
|
|
353
|
+
to its closing quote and a plain one to a comment, as before. A value it
|
|
354
|
+
refuses declares nothing - a `: ` in a plain value, text after a closing
|
|
355
|
+
quote, a value continued on the next line, `*Draft*`, which YAML reads as
|
|
356
|
+
an alias - and a `status` nested under another key is that key's. Front
|
|
357
|
+
matter behind a byte-order mark, or closed by `...`, is read as front
|
|
358
|
+
matter.
|
|
359
|
+
- A front-matter `status` decides even when it cannot be read. A value the
|
|
360
|
+
reader refuses, an empty one, one with no word or a list leaves the
|
|
361
|
+
status unrecognised and the document in force, and the `## Status`
|
|
362
|
+
section and the `Status:` label are not read in its place: under 0.11.0
|
|
363
|
+
`status: "accepted" (2024-05-01)` was accepted, and falling through to a
|
|
364
|
+
section still saying `Proposed` would have withheld its rules. Every
|
|
365
|
+
format says so, on the key's line: a warning in the human report, a
|
|
366
|
+
`specWarnings` entry in `--json` (run and `prove`), a SARIF notification
|
|
367
|
+
and a `spec-warning` annotation for GitHub and GitLab.
|
|
368
|
+
|
|
369
|
+
[ADR-0010](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0010-spec-status.md)'s second amendment.
|
|
370
|
+
- **A title is the first level-one heading as the scanner reads it.** An
|
|
371
|
+
underlined one (`===`) is a title and one kept in a comment is not; a code
|
|
372
|
+
span in it is kept as written, where it was blanked, and a comment in it is
|
|
373
|
+
dropped. A first level-one heading with no text leaves the document
|
|
374
|
+
untitled rather than promoting the next. In this repository one title
|
|
375
|
+
changed: ADR-0009's keeps its `` `--fix` ``.
|
|
376
|
+
- **`maskCode` keeps a carriage return inside code**, where it blanked one:
|
|
377
|
+
every line terminator stays where it was, a lone `\r` included.
|
|
378
|
+
- **Reading a spec costs about four times what it did**: 17 ms against 4 ms
|
|
379
|
+
over this repository's 18 ADRs, and 23 ms against 9 ms for a warm query of
|
|
380
|
+
one path, past the 20 ms ADR-0012 set out to meet. The scanner finds list
|
|
381
|
+
items, links and tables that nothing here reads.
|
|
382
|
+
[ADR-0002](https://github.com/DescentVTT/spec-guard/blob/main/docs/adr/0002-directive-format.md)'s amendment says where the
|
|
383
|
+
remedy lies.
|
|
384
|
+
- **The MCP server speaks the protocol through spec-core.** Classifying each
|
|
385
|
+
request, the two eras, dispatch, result shapes and the stdio framing are
|
|
386
|
+
spec-core's `jsonrpc` module, copied from `f085f29` and verified by hash;
|
|
387
|
+
`src/mcp.ts` keeps the instructions, the tools and the resources. What a
|
|
388
|
+
client sees is unchanged, and every test of the server passes as it was
|
|
389
|
+
written. One edge moved: a last line cut inside a UTF-8 character when stdin
|
|
390
|
+
closes is read as far as it goes rather than dropped. The protocol's names
|
|
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).
|
|
392
|
+
- **API:**
|
|
393
|
+
- `createGlobMatcher`, `createExcludeMatcher` and `expandSpecPatterns` throw
|
|
394
|
+
for a pattern spec-core refuses - an unclosed `[` or `{`, an extended
|
|
395
|
+
glob, a `..`, `**` inside a name - naming the pattern, where they read it
|
|
396
|
+
as a literal or as whatever its `RegExp` meant. `globPatternError` and the
|
|
397
|
+
new `specPatternError` say why without throwing.
|
|
398
|
+
- `Annotation` has a required `identity`, which the GitLab fingerprint is
|
|
399
|
+
made of. `SpecSet` and `RunPlan` have required `warnings` and `masked`;
|
|
400
|
+
`RunReport` and `ProveReport` have optional `specWarnings` and
|
|
401
|
+
`maskedDirectives`, and `ParseResult` optional `warnings` and `masked`.
|
|
402
|
+
An `InactiveSpec`'s `directives` counts only those that resolve.
|
|
403
|
+
- New: `proveSpecGuard`, `PROVE_NAME`, `overlayIo` and `readOnce`;
|
|
404
|
+
`findCitations`, `findDocuments`, `deriveFamilies`, `scanCitations`,
|
|
405
|
+
`inComments`, `qualified`, `isStale`, `numberKey`, `documentNumber`,
|
|
406
|
+
`parseIdTemplate`, `parseFilesTemplate`, `citeIdError`, `citeFilesError`,
|
|
407
|
+
`CitesError` and `NUMBER`; `impactOf`, `impactDocument`, `dependentsOf`,
|
|
408
|
+
`buildReverseGraph`, `resolvePython`, `formatImpact`, `formatImpactJson`
|
|
409
|
+
and `ImpactError`; `formatProve`, `formatProveJson`, `formatProveSarif`,
|
|
410
|
+
`formatCites`, `formatCitesJson`, `formatCitesSarif`, `formatGitlab`,
|
|
411
|
+
`formatGithub`, `runAnnotations`, `proveAnnotations` and
|
|
412
|
+
`citesAnnotations`; `RUN_FORMAT_VERSION`, `QUERY_FORMAT_VERSION`,
|
|
413
|
+
`PROVE_FORMAT_VERSION`, `CITES_FORMAT_VERSION` and
|
|
414
|
+
`IMPACT_FORMAT_VERSION`; `globPatternError` and `specPatternError`; and
|
|
415
|
+
the types that go with them, `SpecWarning`, `MaskedDirective` and
|
|
416
|
+
`MaskedContext` among them.
|
|
417
|
+
|
|
8
418
|
## 0.11.0
|
|
9
419
|
|
|
10
420
|
The literal this lexer never read. A JavaScript or TypeScript regular
|
|
@@ -12,7 +422,7 @@ expression can hold a quote — `/'/`, `/["']/`, `replace(/\/\//g, '')` — and
|
|
|
12
422
|
without a rule for `/`, that quote opened a string that closed somewhere else
|
|
13
423
|
entirely. Every text rule over a TypeScript project reads through this
|
|
14
424
|
classifier, and this repository's own `src/parser.ts` was one of the files it
|
|
15
|
-
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).
|
|
16
426
|
|
|
17
427
|
### Fixed
|
|
18
428
|
|
|
@@ -44,9 +454,11 @@ lost its place in. [ADR-0006](docs/adr/0006-comment-classification.md).
|
|
|
44
454
|
code from there. It used to run to the end of the file. This is what JSX text
|
|
45
455
|
costs as well: `<p>Don't click</p>` opens a literal nothing closes, and it
|
|
46
456
|
now costs that line rather than everything after it.
|
|
47
|
-
-
|
|
48
|
-
`shell
|
|
49
|
-
|
|
457
|
+
- **The `shell-like` profile split in two.** `.sh`, `.bash` and `.zsh` are
|
|
458
|
+
read as `shell`, `.yaml` and `.yml` as `yaml`, because their quoting
|
|
459
|
+
differs: a shell's quotes open mid-word and YAML's open only where a value
|
|
460
|
+
starts. The names themselves are internal — no output reports them — so what
|
|
461
|
+
changed for a caller is the reading, described above.
|
|
50
462
|
|
|
51
463
|
Counts may move on a project that has any of these. A text rule over `.ts`,
|
|
52
464
|
`.tsx`, `.yaml` or `.yml` can now see code it could not see before, and can
|
|
@@ -69,8 +481,8 @@ question asked per character has to be paid for per character.
|
|
|
69
481
|
Fixes from running 0.10.2 over a Rust and .NET monorepo, where an import rule
|
|
70
482
|
missed five `use` declarations in one crate and said nothing, and from probing
|
|
71
483
|
every other language profile for the same mistake.
|
|
72
|
-
[ADR-0006](docs/adr/0006-comment-classification.md),
|
|
73
|
-
[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).
|
|
74
486
|
|
|
75
487
|
### Fixed
|
|
76
488
|
|
|
@@ -118,8 +530,8 @@ regular expression literal holding a quote, `/["']/` - is recorded in ADR-0006.
|
|
|
118
530
|
Fixes from running 0.10.1 over a .NET solution, where a layer rule passed while
|
|
119
531
|
the domain imported the application, and from reading C# as it is written in
|
|
120
532
|
2026 while fixing that.
|
|
121
|
-
[ADR-0011](docs/adr/0011-layers-and-cycles.md),
|
|
122
|
-
[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).
|
|
123
535
|
|
|
124
536
|
### Fixed
|
|
125
537
|
|
|
@@ -192,7 +604,7 @@ the domain imported the application, and from reading C# as it is written in
|
|
|
192
604
|
|
|
193
605
|
Fixes from running 0.10.0 over a large monorepo, and from testing each exclude
|
|
194
606
|
shape under both engines while making them.
|
|
195
|
-
[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).
|
|
196
608
|
|
|
197
609
|
### Fixed
|
|
198
610
|
|
|
@@ -268,8 +680,8 @@ shape under both engines while making them.
|
|
|
268
680
|
Improvements from running 0.9.2 over a large polyglot monorepo: a
|
|
269
681
|
configuration a Rust, Go or .NET root can hold, exclusions a whole project
|
|
270
682
|
shares, and a cycle rule that can leave lazy loading out.
|
|
271
|
-
[ADR-0014](docs/adr/0014-configuration-and-watch.md),
|
|
272
|
-
[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).
|
|
273
685
|
|
|
274
686
|
### Added
|
|
275
687
|
|
|
@@ -333,7 +745,7 @@ shares, and a cycle rule that can leave lazy loading out.
|
|
|
333
745
|
unanalysable, as does `/*` inside JSX text.
|
|
334
746
|
- Tracking JSX text in general was turned down: a TypeScript cast or a
|
|
335
747
|
generic arrow read as markup would skip real code without a word.
|
|
336
|
-
[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).
|
|
337
749
|
|
|
338
750
|
## 0.9.1
|
|
339
751
|
|
|
@@ -349,13 +761,13 @@ shares, and a cycle rule that can leave lazy loading out.
|
|
|
349
761
|
- `/>` anywhere else still starts a regular expression, so
|
|
350
762
|
`replace(/>/g, '>')` reads as before.
|
|
351
763
|
|
|
352
|
-
[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).
|
|
353
765
|
|
|
354
766
|
## 0.9.0
|
|
355
767
|
|
|
356
768
|
A project's policy can live in its `package.json`, and `spec-guard --watch`
|
|
357
769
|
reports again as the tree changes, re-executing only the rules a change
|
|
358
|
-
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).
|
|
359
771
|
|
|
360
772
|
### Added
|
|
361
773
|
|
|
@@ -423,7 +835,7 @@ affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
|
423
835
|
reported every other shard's files with the previous sweep's verdicts. The
|
|
424
836
|
merge refused that sweep.
|
|
425
837
|
- No mutants were left out, the per-mutant timeout is unchanged, and the gate
|
|
426
|
-
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).
|
|
427
839
|
|
|
428
840
|
### Fixed
|
|
429
841
|
|
|
@@ -445,7 +857,7 @@ affected. [ADR-0014](docs/adr/0014-configuration-and-watch.md).
|
|
|
445
857
|
|
|
446
858
|
An architecture document can now state conventions about names and layout: what
|
|
447
859
|
the files in a directory are called, what every package holds, and which files
|
|
448
|
-
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).
|
|
449
861
|
|
|
450
862
|
### Added
|
|
451
863
|
|
|
@@ -496,7 +908,7 @@ come in pairs. [ADR-0013](docs/adr/0013-structure-assertions.md).
|
|
|
496
908
|
had, less one in `glob.ts` that the new tests turned into a genuine hang. A
|
|
497
909
|
local sweep had reported four survivors in the new listing cache as killed; CI
|
|
498
910
|
found them, and they are tested. See
|
|
499
|
-
[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).
|
|
500
912
|
|
|
501
913
|
## 0.7.0
|
|
502
914
|
|
|
@@ -526,7 +938,7 @@ than every release, and it is fixed below.
|
|
|
526
938
|
`types="ignore"` asks the runtime question. JavaScript and TypeScript only,
|
|
527
939
|
because a cycle needs to know which file an import *is*; imports that should
|
|
528
940
|
have become an edge and did not are reported, and fail under `--strict`.
|
|
529
|
-
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,
|
|
530
942
|
and for why the other four languages are not in the graph.
|
|
531
943
|
- `buildGraph`, `resolveReference`, `stronglyConnected`, `cyclicComponents`,
|
|
532
944
|
`witness`, `checkLayers` and `referenceForms` are exported, with their types.
|
|
@@ -538,7 +950,7 @@ than every release, and it is fixed below.
|
|
|
538
950
|
scripts. Rules in documents that are not in force are counted and named, and
|
|
539
951
|
listed with `--ignore-status`. The arithmetic behind it is tested against the
|
|
540
952
|
files a real run searches, under both engines and on random trees; see
|
|
541
|
-
[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.
|
|
542
954
|
- **`spec-guard mcp`** - a Model Context Protocol server on stdio, with no
|
|
543
955
|
dependency on the MCP SDK. Tools `get_architectural_rules` (the query) and
|
|
544
956
|
`check_architecture` (a run, narrowed to the rules governing given paths, each
|
|
@@ -588,7 +1000,7 @@ than every release, and it is fixed below.
|
|
|
588
1000
|
mutated build against the real one on thousands of random inputs. The query
|
|
589
1001
|
and the server (`query.ts`, `rules.ts`, `mcp.ts`, `specs.ts`) are all at 100%;
|
|
590
1002
|
most of the survivors found on the way were code nothing could observe, and it
|
|
591
|
-
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
|
|
592
1004
|
accounts, and for why one sweep's count is good to about three.
|
|
593
1005
|
- `version(manifest?)` takes the manifest to read, so its fallback for a broken
|
|
594
1006
|
install - `0.0.0` rather than a crash - is tested.
|
|
@@ -633,7 +1045,7 @@ making sure a rule that stops running can never look like a rule that passed.
|
|
|
633
1045
|
are still checked for typos, bad attributes and unresolvable values, so a
|
|
634
1046
|
draft's mistake is found on the day it is written rather than on the day
|
|
635
1047
|
everyone agrees the rule is right and stops looking at it.
|
|
636
|
-
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
|
|
637
1049
|
no per-directive `if-status` attribute.
|
|
638
1050
|
- `--ignore-status` executes every directive whatever its document declares -
|
|
639
1051
|
how to ask whether a draft would pass if you accepted it today.
|
|
@@ -657,7 +1069,7 @@ making sure a rule that stops running can never look like a rule that passed.
|
|
|
657
1069
|
the whole suite per mutant, so on a loaded machine an unrelated test timing
|
|
658
1070
|
out is scored as a kill. Those patterns are now verified by applying every
|
|
659
1071
|
mutant by hand, `scripts/mutation-regex.mjs`, and the account is in
|
|
660
|
-
[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).
|
|
661
1073
|
|
|
662
1074
|
## 0.5.1
|
|
663
1075
|
|
|
@@ -706,7 +1118,7 @@ new features, and nothing a user has to change.
|
|
|
706
1118
|
individually and produce byte-identical output, so that figure is the ceiling
|
|
707
1119
|
rather than a way-point — and 29 that were assumed equivalent turned out not
|
|
708
1120
|
to be, and are now tested. See
|
|
709
|
-
[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
|
|
710
1122
|
limitation found on the way: a mutant that stops a test file *loading* is
|
|
711
1123
|
reported as survived even though the suite is killing it.
|
|
712
1124
|
- **`src/imports.ts` went from 73.74% to 95.89%.** The tokenizer was tested as a
|
|
@@ -744,13 +1156,13 @@ scope holds no files at all.
|
|
|
744
1156
|
Not four new tokenizers: the comment and string lexer from ADR-0006 masks the
|
|
745
1157
|
source and the readers work on what is left. Tree-sitter measured 94 MB
|
|
746
1158
|
unpacked against this package's 0.33 MB. See
|
|
747
|
-
[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).
|
|
748
1160
|
- **`baseline` and `ratchet`** on the absence assertions, for adopting a strict
|
|
749
1161
|
rule on a codebase that already breaks it. `baseline="src/legacy/a.ts:2"`
|
|
750
1162
|
names the debt by file and count. The ratchet is two-sided: new violations
|
|
751
1163
|
fail, and so does an entry the code no longer supports, because a baseline
|
|
752
1164
|
that only grows is an `exclude` with extra steps. `ratchet="one-way"` relaxes
|
|
753
|
-
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).
|
|
754
1166
|
- **`--print-baseline`** prints the attribute that would exempt today's
|
|
755
1167
|
violations, for a human to paste. It prints; it does not edit. That is the
|
|
756
1168
|
whole answer to `--fix`, and ADR-0009 argues it.
|
|
@@ -780,7 +1192,7 @@ scope holds no files at all.
|
|
|
780
1192
|
starts finding dependencies it previously reported as unanalysable.
|
|
781
1193
|
- **Mutation testing in CI runs in two tiers**: incremental on branches,
|
|
782
1194
|
a full authoritative sweep on `main` and nightly. The gate stays at 85 in
|
|
783
|
-
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).
|
|
784
1196
|
|
|
785
1197
|
### Fixed
|
|
786
1198
|
|
|
@@ -828,7 +1240,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
828
1240
|
- **The engines are one implementation.** ripgrep now answers only *which files
|
|
829
1241
|
contain this text*; the scanner does all counting, comment classification,
|
|
830
1242
|
binary handling and reporting for both. `--engine` changes how long a run
|
|
831
|
-
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).
|
|
832
1244
|
|
|
833
1245
|
### Added
|
|
834
1246
|
|
|
@@ -867,7 +1279,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
867
1279
|
directions. A zero-dependency tokenizer resolves `import`, `export … from`,
|
|
868
1280
|
`import type`, dynamic `import()` with a literal, and `require()`. Module
|
|
869
1281
|
references it cannot resolve statically are reported, never counted as clean.
|
|
870
|
-
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).
|
|
871
1283
|
- **`comments` attribute.** See Changed, below.
|
|
872
1284
|
- **`--allow-missing-targets`** to restore the previous handling of a `target`
|
|
873
1285
|
path that does not exist.
|
|
@@ -883,7 +1295,7 @@ found two and ripgrep found four, and neither said anything about the rest.
|
|
|
883
1295
|
uncertain the text counts as code, and every run reports how many matches it
|
|
884
1296
|
excluded — a pass caused by comment exclusion is never silent.
|
|
885
1297
|
`comments="include"` restores counting per assertion.
|
|
886
|
-
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).
|
|
887
1299
|
- **A `target` path that does not exist now fails the run** instead of warning
|
|
888
1300
|
and searching what remained. An assertion pointed at a renamed directory used
|
|
889
1301
|
to search nothing, find nothing, and report success. `--allow-missing-targets`
|
|
@@ -919,9 +1331,9 @@ first published 0.3.0.
|
|
|
919
1331
|
enough for the JavaScript scanner to beat a ripgrep process spawn. The probe
|
|
920
1332
|
is the work — the enumeration it performs is reused by the scanner, so
|
|
921
1333
|
choosing costs nothing when the scanner wins.
|
|
922
|
-
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).
|
|
923
1335
|
- **Mutation testing** with Stryker, wired into CI on every push, plus the tests
|
|
924
|
-
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).
|
|
925
1337
|
|
|
926
1338
|
### Changed
|
|
927
1339
|
|