okf-kit 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +253 -0
- package/README.md +35 -3
- package/dist/rules/citations-resolve.js +723 -13
- package/dist/rules/citations-resolve.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,259 @@ All notable changes to `okf-kit` are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.6.0] - 2026-08-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `citations-resolve` now also resolves **short-form** citations: a bare
|
|
15
|
+
(no backtick, no file name) `:N-M` colon-range, collected only when the
|
|
16
|
+
nearest preceding non-whitespace text is a serial connective (`,`, `;`,
|
|
17
|
+
`(`, or the word `and`/`or`) and bound to the last full `path:N-M`
|
|
18
|
+
citation named earlier in the same paragraph (a paragraph boundary is a
|
|
19
|
+
blank line), with no further check on the two ranges' relationship. A
|
|
20
|
+
gate-cleared candidate with no full citation earlier in its own
|
|
21
|
+
paragraph is reported `short-form-unbound` (notice), not silently
|
|
22
|
+
skipped; a candidate the gate rejects is dropped before binding is ever
|
|
23
|
+
attempted and produces no finding of any kind. Only a range form is
|
|
24
|
+
recognised (`:580-588`); a bare single number (`:5`) is not, since it is
|
|
25
|
+
too easily an unrelated enumeration marker (e.g. a numbered list) rather
|
|
26
|
+
than a citation. Never collected at all inside a fenced/indented code
|
|
27
|
+
block, an inline code span, or a Markdown table row. Reserved files
|
|
28
|
+
(`index.md`, `log.md`) are excluded from short-form matching: they are
|
|
29
|
+
append-only narrative journals that routinely describe historical "old
|
|
30
|
+
:N-M -> new :X-Y" line-number deltas as prose, not live citations
|
|
31
|
+
against current content; full/continuation citations in reserved files
|
|
32
|
+
are unaffected. A bare parenthesized range `(N-M)` is deliberately NOT
|
|
33
|
+
collected as a short-form citation at all -- see "Fixed" below for why.
|
|
34
|
+
See "Short-form citations" in the README for the full shape/exclusion
|
|
35
|
+
rules and their known limitations.
|
|
36
|
+
- `citations-resolve` now additionally checks, for a short-form citation's
|
|
37
|
+
range into a test file (`.test.ts`/`.spec.ts`, and the `.js`/`.mjs`
|
|
38
|
+
equivalents), that the range starts on a `describe(`/`it(` head line
|
|
39
|
+
(`test-range-start-not-head`, a **warning**) and ends on a matching
|
|
40
|
+
closing `});` line (`test-range-end-not-closing`, a **notice**: a
|
|
41
|
+
correct start with a short end is also consistent with a deliberate
|
|
42
|
+
partial citation, not necessarily drift).
|
|
43
|
+
- `citations-resolve` now additionally checks, for any short-form
|
|
44
|
+
citation's range into a Markdown target, whether its start or end line
|
|
45
|
+
is a bare bracket (`)`, `]`, `}`, `(`, `[`, `{`, optionally with a
|
|
46
|
+
trailing `,`/`;`) or a bare code-fence delimiter -- a common signature of
|
|
47
|
+
a boundary that drifted onto structural punctuation rather than real
|
|
48
|
+
content. This is a **notice**, not a warning (`markdown-range-boundary-bracket-or-fence`):
|
|
49
|
+
mechanical verification of "is this still the same block" is far less
|
|
50
|
+
reliable for prose than for code brace structure. A range starting on a
|
|
51
|
+
genuine *opening* fence line is exempted from the fence-as-drift-signal
|
|
52
|
+
part of this check: citing a fenced block starting at its own opening
|
|
53
|
+
delimiter is the natural, correct way to cite it.
|
|
54
|
+
- `citations-resolve` now supports an optional **anchor** on a full
|
|
55
|
+
citation: `` `path:N-M#anchor` `` (e.g. `` `CHANGELOG.md:50-144#0.24.0` ``),
|
|
56
|
+
closing a gap the range/blank/closing-brace checks above cannot: a
|
|
57
|
+
CHANGELOG.md that grows by insertion at the top shifts every later
|
|
58
|
+
entry's absolute line numbers on every release, so a citation that lands
|
|
59
|
+
15 lines off in the wrong release section is exactly as green as before
|
|
60
|
+
the shift (the motivating case: 16 `docs/okf/*.md` -> `CHANGELOG.md`
|
|
61
|
+
citations in this repo's own `orchestrator-workflow` bundle, migrated to
|
|
62
|
+
this form as part of the same change -- see that package's CHANGELOG).
|
|
63
|
+
Two forms, told apart by the anchor text itself:
|
|
64
|
+
- **Heading form** (bare/unquoted, e.g. `#0.24.0` or `#[0.24.0]`): the
|
|
65
|
+
citation's nearest *enclosing* Markdown heading must contain the
|
|
66
|
+
anchor text, and no heading of the same or shallower level may start
|
|
67
|
+
before the range's end line -- i.e. the heading must enclose the
|
|
68
|
+
*whole* range, not merely precede its start. Deliberately capped at
|
|
69
|
+
heading level 2: a Keep-a-Changelog `CHANGELOG.md` nests `## [x.y.z]`
|
|
70
|
+
release headings around identically-named `### Added`/`### Changed`/
|
|
71
|
+
`### Fixed` subsections repeated in every release, so "nearest heading
|
|
72
|
+
of any level" would make this check nearly useless (it would match the
|
|
73
|
+
wrong release's own `### Changed` just as readily as the right one's);
|
|
74
|
+
deeper subsection headings are transparent to the search instead. The
|
|
75
|
+
anchor text itself matches word characters, `.`, and `-`, but never
|
|
76
|
+
starts or ends on a `.`/`-`, so a trailing sentence period or a
|
|
77
|
+
following `,`/`)` is never captured as part of it, and a hyphenated
|
|
78
|
+
token (`0.24.0-rc1`) is captured whole rather than truncated at the
|
|
79
|
+
first hyphen. A `#`-led comment line inside a fenced code block in the
|
|
80
|
+
*target* is excluded from the heading search on both ends of the
|
|
81
|
+
enclosure check, the same way a citing doc's own fences are already
|
|
82
|
+
excluded from short-form matching. Mismatch is reported as
|
|
83
|
+
`anchor-heading-mismatch` (wrong section) or
|
|
84
|
+
`anchor-heading-does-not-enclose` (right section, but the range runs
|
|
85
|
+
past its end); no heading at all precedes the citation is
|
|
86
|
+
`anchor-heading-not-found`. All three are **warnings**.
|
|
87
|
+
- **String form** (double-quoted, e.g. `#"reproduction requirement"`):
|
|
88
|
+
the anchor text must occur, verbatim, on at least one line of the
|
|
89
|
+
cited range itself -- "occurs inside it" rather than "encloses it", so
|
|
90
|
+
this form also works against a non-Markdown target where "enclosing
|
|
91
|
+
heading" has no meaning. The quoted text cannot cross a line break or
|
|
92
|
+
a backtick, so an unterminated opening quote fails to parse as an
|
|
93
|
+
anchor at all instead of greedily consuming everything up to some
|
|
94
|
+
unrelated later quote character in the document -- which would
|
|
95
|
+
otherwise silently hide every citation in between from this rule
|
|
96
|
+
entirely. Mismatch is `anchor-not-found-in-range`, a **warning**.
|
|
97
|
+
Anchors are full-citation-only (a continuation or short-form citation
|
|
98
|
+
never carries its own path to hang one on) and strictly additive: the
|
|
99
|
+
`#anchor` suffix is optional, so an existing anchorless citation matches
|
|
100
|
+
and is checked exactly as before. Three rejected alternatives: embedding
|
|
101
|
+
the literal heading markup (`` #"## [0.24.0]" ``) was rejected as reading
|
|
102
|
+
worse in prose for no additional precision over the shorter heading-form
|
|
103
|
+
token; a detached anchor elsewhere in the sentence was rejected as
|
|
104
|
+
needing a second, unparseable-without-a-new-grammar citation site that
|
|
105
|
+
is easy to leave behind when a sentence is edited later; a named-capture
|
|
106
|
+
slug matching `sources-fresh`'s YAML shape was rejected because it would
|
|
107
|
+
require a second citation site (frontmatter plus prose) to stay in sync,
|
|
108
|
+
the exact class of drift this rule exists to catch.
|
|
109
|
+
**Known limitations:** the heading form's containment check is a plain
|
|
110
|
+
substring match against the heading's raw text, not a token-boundary
|
|
111
|
+
match (an anchor `0.1` matches a heading containing `[0.10.0]`); this is
|
|
112
|
+
a deliberate mechanical simplification, not a semantic guarantee. The
|
|
113
|
+
heading form also runs against a target's raw lines regardless of file
|
|
114
|
+
type, so a `# comment` line in a `.yml`/`.json` target is matched as a
|
|
115
|
+
heading; restricting the heading form to `.md` targets is left as a
|
|
116
|
+
known limitation rather than implemented in this change.
|
|
117
|
+
**Measured** (this change; see the PR for the full mutation-probe log):
|
|
118
|
+
the migrated `orchestrator-workflow` bundle (3 docs, 16 anchored
|
|
119
|
+
citations) reports the same 0 errors / 13 warnings / 22 notices with the
|
|
120
|
+
anchors present as without them (0 true findings, since all 16 were
|
|
121
|
+
already correct; 0 false positives from the new check, in this corpus).
|
|
122
|
+
A read-only sample against `agent-grounding/docs/okf` (not migrated to
|
|
123
|
+
this form, out of scope for this change, and carrying no anchors at all)
|
|
124
|
+
serves as a backward-compatibility check rather than a false-positive
|
|
125
|
+
measurement of the anchor check itself: it reports 0 anchor findings,
|
|
126
|
+
confirming an anchorless corpus is unaffected, as expected from the
|
|
127
|
+
backward-compatible design. Two mutation probes against the
|
|
128
|
+
`orchestrator-workflow` bundle: shifting one migrated citation's range
|
|
129
|
+
into its neighbouring release section raised the warning count from 13
|
|
130
|
+
to 14 (`anchor-heading-mismatch`), reverted to 13 clean; inserting an
|
|
131
|
+
8-line dummy entry at the top of that package's `CHANGELOG.md`
|
|
132
|
+
(simulating a normal release-note insertion) raised the warning count
|
|
133
|
+
from 13 to 29, flagging all 16 migrated citations as
|
|
134
|
+
`anchor-heading-mismatch` (the historical failure mode this change
|
|
135
|
+
targets), reverted to 13 clean.
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
|
|
139
|
+
- The test-file block-boundary check above previously applied only to
|
|
140
|
+
paren-form short forms, on the documented theory that a colon-form short
|
|
141
|
+
form inside a compound `path:N-M, :X-Y, :Z-W`-style list marked an
|
|
142
|
+
approximate detail location rather than a block citation. Reviewing that
|
|
143
|
+
claim by sampling this rule's own dogfood bundle -- replacing the
|
|
144
|
+
paren-only gate with an unconditional check locally raised the dogfood
|
|
145
|
+
finding count from 1 to 14, and reading a sample of the new findings
|
|
146
|
+
against both the citing prose and the cited file showed every one was a
|
|
147
|
+
whole cited block shifted by the same constant line offset, i.e. real
|
|
148
|
+
drift the carve-out was hiding for the dominant colon-form syntax, not a
|
|
149
|
+
granularity convention. The carve-out is removed; see the new
|
|
150
|
+
warning/notice severity split above for how a wrong start (strong drift
|
|
151
|
+
evidence) and a wrong end (also consistent with a deliberate partial
|
|
152
|
+
citation) are now told apart instead of one gating the whole check by
|
|
153
|
+
syntax form.
|
|
154
|
+
- `short-form-unbound` previously fired at warning severity, so an
|
|
155
|
+
unrecognised bare `N-M` range anywhere in ordinary prose (a year range,
|
|
156
|
+
a port range, a small plain-English number range) could fail a
|
|
157
|
+
consumer's `--strict` run. It is now a notice.
|
|
158
|
+
- Short-form matching previously scanned fenced code blocks, indented code
|
|
159
|
+
blocks, Markdown table rows, and (partially -- only a match directly
|
|
160
|
+
touching a backtick was excluded) inline code spans for bare ranges. All
|
|
161
|
+
four are now excluded from short-form matching entirely.
|
|
162
|
+
- The README stated the test-file block-boundary check applied "for a
|
|
163
|
+
paren-form short form only", including for the Markdown notice; the
|
|
164
|
+
Markdown notice was never actually gated that way in code (the CHANGELOG
|
|
165
|
+
already said so correctly). Both are now stated accurately and
|
|
166
|
+
consistently (moot for the test-file check specifically, now that its
|
|
167
|
+
paren-only gate is removed).
|
|
168
|
+
- The `short-form-unbound` message ("no target document named earlier in
|
|
169
|
+
this paragraph") was inaccurate for a paragraph that does name a target
|
|
170
|
+
document but without a `:N` line number (e.g. this rule's own dogfood
|
|
171
|
+
target, `log.md`, narrating historical deltas): the target document was
|
|
172
|
+
named, `CITATION_RE` just never matched it as a full citation. Reworded
|
|
173
|
+
to "no full `path:N` citation earlier in this paragraph to bind to".
|
|
174
|
+
- Three successive rounds tried to separate a real short-form citation
|
|
175
|
+
from ordinary prose that merely contains an N-M-shaped number pair by
|
|
176
|
+
deciding from the range's *values*: an inverted-pair/span-cap check,
|
|
177
|
+
then a year/well-known-port plausibility gate, then a
|
|
178
|
+
containment-or-adjacency check against the paragraph's last full
|
|
179
|
+
citation (`isContainedOrAdjacent`, now removed -- there is no longer a
|
|
180
|
+
second value-shape filter layered behind the gate). All three were
|
|
181
|
+
defeated by the same class of false positive: a doc with
|
|
182
|
+
`src/t.test.ts:3-7` followed by "covers phases (1-2), (2-4), and (5-6)"
|
|
183
|
+
produced two false `test-range-start-not-head` warnings under the
|
|
184
|
+
containment/adjacency version, because every real paren-form citation
|
|
185
|
+
this rule was ever built against has the identical shape
|
|
186
|
+
`<English word> (N-M)` as ordinary prose -- there is no lexical signal
|
|
187
|
+
that tells them apart. The bare parenthesized form `(N-M)` is therefore
|
|
188
|
+
no longer collected as a short-form citation candidate at all. Measured
|
|
189
|
+
against this rule's own dogfood bundle
|
|
190
|
+
(`packages/orchestrator-workflow/docs/okf`), a compiled copy with paren
|
|
191
|
+
collection disabled produced an identical finding count to one with it
|
|
192
|
+
enabled (39 findings / 17 warnings / 22 notices either way) -- dropping
|
|
193
|
+
it cost nothing.
|
|
194
|
+
- The colon form does not have the paren form's problem, but still needs
|
|
195
|
+
a gate to avoid the same false-positive class: a candidate `:N-M` is
|
|
196
|
+
now collected only when the nearest preceding non-whitespace text is a
|
|
197
|
+
serial connective -- `,`, `;`, `(`, or the word `and`/`or` -- and, once
|
|
198
|
+
collected, binds unconditionally to the paragraph's last full citation
|
|
199
|
+
(the containment-or-adjacency check above is gone; a bound candidate is
|
|
200
|
+
simply checked, with no further gate on the two ranges' relationship).
|
|
201
|
+
Measured over the 137 markdown files in this repo: 37 bare `:N-M`
|
|
202
|
+
occurrences preceded by whitespace or punctuation, 29 of them
|
|
203
|
+
serial-connective-preceded, and all 29 are genuine citations (13
|
|
204
|
+
preceded by `(`, 12 by a comma, 4 by `and`) -- the comma is
|
|
205
|
+
load-bearing at 12 of 29, so the gate is not narrowed to `(` and `and`
|
|
206
|
+
only. The 8 non-serial occurrences the gate correctly excludes are this
|
|
207
|
+
package's own README quoting false-positive examples (now removed from
|
|
208
|
+
the README along with the plausibility-gate description they
|
|
209
|
+
illustrated), this rule's own test fixture, and `docs/okf/log.md`'s
|
|
210
|
+
"old :N-M -> new :X-Y" delta narration (a reserved file, already
|
|
211
|
+
skipped regardless of the gate). Documented residual, not fixed: a
|
|
212
|
+
prose shape where the serial connective happens to precede a bare range
|
|
213
|
+
that is still not a real citation (e.g. "the exposed ports, :80-443,
|
|
214
|
+
stayed open") still binds and can produce a false warning; not observed
|
|
215
|
+
anywhere in the 137-file corpus.
|
|
216
|
+
- Net effect on this rule's own dogfood bundle
|
|
217
|
+
(`packages/orchestrator-workflow/docs/okf`): 49 findings / 16 warnings /
|
|
218
|
+
33 notices (previous round, containment-or-adjacency) -> 39 findings /
|
|
219
|
+
17 warnings / 22 notices (this round). The delta is exactly the 11 false
|
|
220
|
+
`short-form-unbound` notices the containment/adjacency gate was
|
|
221
|
+
producing disappearing, plus exactly one warning appearing:
|
|
222
|
+
`init.ts:538-569 (short-form)`, `closing-brace-start-line` -- see "Known
|
|
223
|
+
finding" below, this is a real, previously-suppressed finding, not a
|
|
224
|
+
new false positive. All findings present before this round's gate
|
|
225
|
+
change are unaffected.
|
|
226
|
+
|
|
227
|
+
### Known finding
|
|
228
|
+
|
|
229
|
+
Dogfooding this change against `packages/orchestrator-workflow/docs/okf`
|
|
230
|
+
surfaces citation drift beyond the single pre-existing one already known
|
|
231
|
+
(`install-fence-mechanics.md`'s `init.ts:538-569`, a short-form landing on
|
|
232
|
+
a lone closing brace, restored to a warning by this round's gate change --
|
|
233
|
+
see "Fixed" above): a compound colon-form list in the same doc, citing
|
|
234
|
+
`test/init.test.ts`'s `describe("tier variants (\`--tiers\`)")` block,
|
|
235
|
+
names 15 short-form sub-ranges. 13 of them produce a citations-resolve
|
|
236
|
+
finding (12 `test-range-start-not-head` warnings, 1
|
|
237
|
+
`test-range-end-not-closing` notice on `:1229-1265`); 11 of those 13 are
|
|
238
|
+
exact-length blocks shifted by a constant offset from their real
|
|
239
|
+
`describe`/`it` block (+33 lines for three of them, +116 for the other
|
|
240
|
+
eight -- consistent with roughly two rounds of content having been
|
|
241
|
+
inserted earlier in the same block without the rest of the list being
|
|
242
|
+
re-numbered). The other 2 of the 13 do not fit that pattern: `:1229-1265`
|
|
243
|
+
is at offset 0 (its start line is the real block head) but cites a
|
|
244
|
+
37-line span against a real 70-line block that grew; `:1636-1725` cites a
|
|
245
|
+
90-line span against a real 91-line block. Of the 2 remaining
|
|
246
|
+
citations that produce no finding at all: `:1170-1227` is genuinely
|
|
247
|
+
correct (not drifted); `:1614-1626` is drifted by the same +116 pattern
|
|
248
|
+
as the 8 above but produces no finding -- a known, inherent blind spot of
|
|
249
|
+
this mechanical, non-semantic checker: its cited start line coincidentally
|
|
250
|
+
lands on a real (but different) `describe`/`it` head, and its cited end
|
|
251
|
+
line coincidentally lands on a real (but unrelated, nested) closing
|
|
252
|
+
`});`, so the check cannot distinguish it from a correct citation. Fixing
|
|
253
|
+
any of these citations is out of scope for this change (no content fixes
|
|
254
|
+
to consumer-bundle citations).
|
|
255
|
+
|
|
256
|
+
Separately, the reserved-file carve-out (see "Fixed" above) leaves
|
|
257
|
+
genuine short-form citations in `index.md`/`log.md` completely unchecked.
|
|
258
|
+
The current dogfood bundle has four such citations, around
|
|
259
|
+
`log.md:362-370`.
|
|
260
|
+
|
|
8
261
|
## [0.5.0] - 2026-08-22
|
|
9
262
|
|
|
10
263
|
### Added
|
package/README.md
CHANGED
|
@@ -53,11 +53,12 @@ okf-kit init path/to/bundle --force
|
|
|
53
53
|
|
|
54
54
|
Every template doc except `benchmark-template.md` ships with `sources: [path/to/covered/source]`, a placeholder, not a real path. Running `okf-kit check` against the freshly scaffolded bundle (with a repo root available, explicit or auto-detected) will report that placeholder as a `sources-shape` "does not exist" error on every template doc. That is intentional: it is the tool telling you which docs still need a real source path, not a bug in the scaffold. The `init` completion message repeats this so it isn't missed. Replace each placeholder with the real repo-root-relative path(s) the doc describes as you write it, and the error clears doc by doc.
|
|
55
55
|
|
|
56
|
-
### Authoring guidance
|
|
56
|
+
### Authoring guidance
|
|
57
57
|
|
|
58
58
|
- **`timestamp` means "last verified against sources," not "created on."** Bump it, and add a line to `log.md`, every time you re-verify a doc against its sources. Always use the real instant of verification (`new Date().toISOString()` or equivalent); never hand-write an artificial midnight datetime, `sources-fresh` staleness comparisons depend on it being real.
|
|
59
59
|
- **Never list the bundle's own directory in `sources`.** A bundle directory changes on every doc edit inside it, so a self-referential `sources` entry goes permanently stale. This happened to the OKF pilot's own `BENCHMARK.md` (`agent-tasks` `docs/okf/BENCHMARK.md`, `sources: [docs/okf/]`); `benchmark-template.md` here omits `sources` entirely for the same reason, since a benchmark record measures the bundle rather than describing a piece of the codebase.
|
|
60
60
|
- **Keep all links same-directory relative.** Use `name.md`, not `/name.md`; see `no-absolute-links` above for why a leading slash breaks once the bundle is viewed outside its own repository.
|
|
61
|
+
- **Write a sibling short-form citation as a connective-led `:N-M`, not `(N-M)`.** When a paragraph cites several sub-ranges of a source already named by a full `path:N-M` citation earlier in the same paragraph, write each later one as a `:N-M` led by one of the serial connectives the gate accepts -- `,`, `;`, `(`, or a trailing `and`/`or` -- right after the phrase it points at (e.g. `review finding L1 (:1170-1227, ...)`). `citations-resolve` only recognises the colon form; a parenthesized `(N-M)` is never checked, so it can drift silently. This convention is not demonstrated by any scaffolded template; it is a `citations-resolve` authoring rule. See "Citation resolution (citations-resolve)" below.
|
|
61
62
|
|
|
62
63
|
## Check catalog
|
|
63
64
|
|
|
@@ -69,7 +70,7 @@ Every template doc except `benchmark-template.md` ships with `sources: [path/to/
|
|
|
69
70
|
| `no-absolute-links` | warning | Link targets should not start with `/`. GitHub resolves a leading slash against the repository root, not the bundle root, so an absolute link 404s once the bundle is viewed outside its own repository. Use a same-directory relative link instead. |
|
|
70
71
|
| `sources-shape` | error | Frontmatter `sources`, when present, must be a non-empty array of non-empty strings. With a repo root (explicit or auto-detected), each listed path (file or directory) must also exist under it. |
|
|
71
72
|
| `sources-fresh` | warning / notice | For docs with a `sources` list and a repo root, flags a source path whose last git commit is newer than both the doc's `timestamp` and the doc file's own last commit. See "Staleness (sources-fresh)" below. |
|
|
72
|
-
| `citations-resolve` | warning / notice | For docs with a repo root, flags a `` `path:N`/`path:N-M` `` citation (and its `` `:N` ``/`` -`M` ``/`` (`N`) `` continuations) whose target file is missing, whose range is inverted or exceeds the file, or whose start line is blank or (for a non-markdown target) only a closing brace. See "Citation resolution (citations-resolve)" below. |
|
|
73
|
+
| `citations-resolve` | warning / notice | For docs with a repo root, flags a `` `path:N`/`path:N-M` `` citation (and its `` `:N` ``/`` -`M` ``/`` (`N`) `` continuations, and bare paragraph-bound short forms `:N-M`/`(N-M)`) whose target file is missing, whose range is inverted or exceeds the file, or whose start line is blank or (for a non-markdown target) only a closing brace. A full citation may also carry an optional `#anchor` (e.g. `` `CHANGELOG.md:50-144#0.24.0` ``), checked against the target's own structure/content instead of just its line numbers. A short-form citation's range into a test file is also checked for a describe/it block boundary. See "Citation resolution (citations-resolve)" below. |
|
|
73
74
|
|
|
74
75
|
## repo-root auto-detection
|
|
75
76
|
|
|
@@ -114,9 +115,40 @@ Known limitation: the doc-commit comparison suppresses staleness for every sourc
|
|
|
114
115
|
| `closing-brace-start-line` | For a non-markdown target, the start line is only a closing brace/bracket/paren (`}`, `)`, `]`, optionally with a trailing `,`/`;`) -- a common signature of a cited block having moved. |
|
|
115
116
|
| `unresolved-ambiguous` | More than one file in the repo matches the cited path; reported as a `notice` (never counted toward `--strict`), not guessed at. |
|
|
116
117
|
| `unreadable-target` | The resolved target file exists but could not be read (e.g. permission denied); reported as a `notice` (never counted toward `--strict`) with the OS error code in `detail`, since an unreadable file is not evidence the citation itself is wrong. |
|
|
118
|
+
| `short-form-unbound` | A short-form citation (see below) has no full citation earlier in its own paragraph to bind to; reported as a `notice` (never counted toward `--strict`). |
|
|
119
|
+
| `test-range-start-not-head` | A short-form citation's range into a test file does not start on a `describe(`/`it(` head line. A wrong start is strong drift evidence, so this is a **warning**. |
|
|
120
|
+
| `test-range-end-not-closing` | A short-form citation's range into a test file has a correct start (a real `describe(`/`it(` head) but does not end on a matching closing `});` line; reported as a `notice` (never counted toward `--strict`), since a correct start with a short end is also consistent with a deliberate partial citation. |
|
|
121
|
+
| `markdown-range-boundary-bracket-or-fence` | A short-form citation's range into a Markdown target starts or ends on a bare bracket, or (except see the fence-opening exception below) a bare code-fence line; reported as a `notice` (never counted toward `--strict`). |
|
|
122
|
+
| `anchor-heading-mismatch` | A heading-anchored citation's (see below) nearest enclosing heading does not contain the anchor text -- the range now lands in the wrong section. **Warning**. |
|
|
123
|
+
| `anchor-heading-does-not-enclose` | A heading-anchored citation's anchor text matches its nearest enclosing heading, but the range runs past that heading's own section (a heading of the same or shallower level starts before the range ends). **Warning**. |
|
|
124
|
+
| `anchor-heading-not-found` | A heading-anchored citation has no heading (level 1 or 2) anywhere before its start line to anchor against; use a string anchor (`#"..."`) instead against a target with no heading structure. **Warning**. |
|
|
125
|
+
| `anchor-not-found-in-range` | A string-anchored citation's (see below) anchor text does not occur, verbatim, on any line of the cited range. **Warning**. |
|
|
126
|
+
|
|
127
|
+
**Anchored citations.** A full citation may carry an anchor directly after its range: `` `path:N-M#anchor` ``, e.g. `` `CHANGELOG.md:50-144#0.24.0` ``. This closes a gap the checks above cannot: a CHANGELOG.md that grows by inserting each new release at the top shifts every later entry's absolute line numbers, so a citation that lands 15 lines off in the *wrong* release section is exactly as green as before the shift -- none of `missing-file`/`inverted-range`/`range-exceeds-file`/`blank-start-line`/`closing-brace-start-line` can tell the difference. An anchor pins the citation to a piece of the target's own structure or content that a pure line-shift does not preserve. Two forms, told apart by the anchor text itself:
|
|
128
|
+
|
|
129
|
+
- **Heading form** (bare/unquoted, e.g. `#0.24.0` or `#[0.24.0]`): the citation's nearest *enclosing* Markdown heading (level 1 or 2 only -- see below) must contain the anchor text, and the range must not run past that heading's own section (no heading of the same or shallower level may start before the range's end line). Capped at heading level 2 deliberately: a Keep-a-Changelog `CHANGELOG.md` nests `## [x.y.z]` release headings around identically-named `### Added`/`### Changed`/`### Fixed` subsections repeated in every release, so matching "the nearest heading of any level" would make this check nearly useless there (it would match the wrong release's own `### Changed` just as readily as the right one's); deeper subsection headings are transparent to the search instead. The anchor text itself may contain word characters, `.`, and `-`, but never starts or ends on a `.` or `-`, so a trailing sentence period or a following `,`/`)` never becomes part of it (e.g. `` `path:7-8#0.24.0.` `` at the end of a sentence captures `0.24.0`, not `0.24.0.`); a hyphenated token like `0.24.0-rc1` is captured whole. A fenced code block inside the *target* (e.g. a `` ```bash `` example containing a `#`-led comment) is excluded from the heading search the same way a citing doc's own fences are already excluded from short-form matching (see below): a comment line inside an example is never mistaken for a real heading, on either end of the enclosure check.
|
|
130
|
+
- **String form** (double-quoted, e.g. `#"reproduction requirement"`): the anchor text must occur, verbatim, on at least one line of the cited range itself -- "occurs inside it" rather than "encloses it", so this form also works against a non-Markdown target (`.ts`/`.js`/...) where "enclosing heading" has no meaning. The quoted text cannot cross a line break or a backtick: an unterminated opening quote (a typo) fails to parse as an anchor at all (the citation is then checked as if no anchor had been written, with no diagnostic) rather than greedily consuming the rest of the document up to some unrelated later quote character, which would otherwise silently hide every citation in between from this rule entirely.
|
|
131
|
+
|
|
132
|
+
Anchors are checked only once the base checks above (blank-start-line, closing-brace-start-line, inverted-range, range-exceeds-file) already came back clean for that citation. Anchors are full-citation-only: a continuation or a short-form citation never carries its own path, so there is nowhere natural to hang one on. The `#anchor` suffix is entirely optional and strictly additive: an existing anchorless citation matches and is checked exactly as it was before this feature existed.
|
|
133
|
+
|
|
134
|
+
**Anchor syntax note.** Any `#` immediately following a citation's range is read as the start of an anchor, with no other signal required -- there is no way to write a bare range immediately followed by an unrelated `#` and have it ignored. This means a Markdown link like `` [note](path:1-2#x) `` or an editor-style fragment such as `path:1-2#L7` is interpreted as an anchored citation (`x` and `L7` respectively), whether that was intended or not. The recommended, unambiguous form is the one used throughout this doc: the whole citation, range and anchor together, inside a single pair of backticks, e.g. `` `path:1-2#L7` ``.
|
|
135
|
+
|
|
136
|
+
**Known limitations.** The heading form's `heading.text.includes(anchor.text)` check is a plain substring match against the heading's raw text, not a token-boundary match: an anchor `0.1` matches a heading containing `[0.10.0]` (and, by the same construction, `[0.24.0]` "contains" `24.0`). This is a deliberate simplification, not implemented as token-boundary matching in this round; treat a heading-anchored citation as a strong drift signal, not a semantic guarantee, the same way the rest of this rule's checks are mechanical rather than semantic. Separately, the heading form runs `MD_HEADING_RE` (a bare `` `#{1,6}\s+...` `` match) against the target's raw lines regardless of the target's own file type, so a `# comment` line in a `.yml` or `.json` target is matched as if it were a Markdown heading; restricting the heading form to `.md` targets is left as a known limitation rather than implemented here.
|
|
117
137
|
|
|
118
138
|
**Continuation citations.** Once a sentence states a full `path:N` citation, prose commonly repeats just the line (or range) for a later reference in the same sentence: `` `:N` ``/`` `:N-M` `` (bare colon-prefixed), `` -`M` ``/`` –`M` `` (hyphen- or en-dash-led, the tail of a split range like `` `path:N`-`M` ``), or `` (`N`) `` (parenthesized). Each resolves against the nearest preceding citation in the same doc that resolved to a real file; a continuation right after an unresolved, ambiguous, or out-of-scope citation is silently skipped, not misattributed to an earlier, unrelated file.
|
|
119
139
|
|
|
140
|
+
**Short-form citations.** Distinct from a continuation above: a *bare* (no backtick, no file name at all) colon-range `:N-M`, e.g. `:580-588` in running prose. A short-form citation binds to **the last full `path:N-M` citation named earlier in the same paragraph** -- not the nearest preceding citation anywhere in the doc (that is what a continuation does); a paragraph boundary is a blank (empty or whitespace-only) line. A short-form citation with no full citation earlier in its own paragraph is reported `short-form-unbound`, not silently skipped. Only a range is recognised, never a bare single number (`:5`): a bare number is too easily an unrelated enumeration marker (e.g. a numbered list item) to detect mechanically without a large false-positive cost. A resolved short-form citation gets every check a full citation gets, plus the test-file/Markdown block-boundary check above (`test-range-*` / `markdown-range-boundary-bracket-or-fence`).
|
|
141
|
+
|
|
142
|
+
**Serial-connective gate, and why the paren form is not collected at all.** Three earlier rounds each tried to separate a real short-form citation from ordinary prose that merely contains an N-M-shaped number pair ("the window (2026-2027)", "follow steps (2-4)", "three engineers (1-3)") by deciding from the range's *values*: an inverted-pair check, a span cap plus a year/well-known-port plausibility gate, then a containment-or-adjacency check against the paragraph's last full citation. All three were eventually defeated by the same class of false positive, because every real paren-form citation this rule was ever built against has the identical shape `<English word> (N-M)` as ordinary prose -- there is no lexical signal that tells them apart. The bare parenthesized form `(N-M)` is therefore not collected as a short-form citation candidate at all; measured against this repo's own dogfood bundle, dropping it changed nothing (39 findings / 17 warnings / 22 notices, identical with and without it).
|
|
143
|
+
|
|
144
|
+
The colon form does not have this problem, but still needs a gate: a candidate `:N-M` is collected only when the nearest preceding non-whitespace text, after trimming whitespace, is one of `,`, `;`, `(`, or ends in the word `and`/`or` -- the shape a short-form citation takes in a serial list of sub-ranges ("the `TODO` cells, :72-74 (the ...), and :92-97 (the ...)", "review finding L1 (:1170-1227, ...)"). This is a measured, not a guessed, gate: see the CHANGELOG for the corpus sample it was calibrated against. The comma is load-bearing, not just `(` and `and`; do not narrow the gate to those two. A candidate the gate rejects is dropped before any paragraph-binding is attempted -- it is not a citation, and produces nothing at all, not even `short-form-unbound`.
|
|
145
|
+
|
|
146
|
+
**Documented residual (not fixed).** A prose shape where the serial connective happens to precede a bare range that is still not a real citation -- e.g. "the exposed ports, :80-443, stayed open" -- still binds to the paragraph's last full citation and can produce a false warning. This was not observed anywhere in the corpus this gate was calibrated against (see the CHANGELOG); it is a known, accepted limitation of a mechanical (non-semantic) gate rather than something this round attempted to close.
|
|
147
|
+
|
|
148
|
+
**Excluded from short-form matching entirely** (not collected, regardless of the serial-connective gate): a match inside a fenced code block, an indented code block, an inline code span (`` `like this` ``), or a Markdown table row -- a bare numeric range in any of these is virtually never a citation. Also excluded: reserved files (`index.md`, `log.md`), which are append-only narrative journals that routinely narrate historical "old :N-M -> new :X-Y" line-number deltas as prose about the past, not live citations against current content; full/continuation citations in reserved files are still checked as normal. This carve-out has a known cost: it also leaves genuine short-form citations in those files completely unchecked (see the CHANGELOG for the current dogfood bundle's gap).
|
|
149
|
+
|
|
150
|
+
**Markdown fence-opening exception.** A range boundary landing on a bare bracket line is always a drift signal. A bare code-fence delimiter (```` ``` ```` or `~~~`) at the range's END is also always a drift signal, but at the range's START it is exempted when that line is a genuine *opening* fence (determined by replaying the doc's own fence open/close state from the top, not by the line's text alone, since an untagged opening fence and a closing fence are lexically identical): citing a fenced code block starting at its own opening delimiter is the natural, correct way to cite it, not drift.
|
|
151
|
+
|
|
120
152
|
**Hard-wrapped prose.** A doc that hard-wraps prose at a fixed column can split a hyphenated filename across a line break right after its trailing `-` (e.g. `run-state-lifecycle-and-markers.md` wrapping to `run-state-lifecycle-and-\nmarkers.md`). A `` `path:N` `` match is skipped entirely (not checked, not counted as a citation) when it starts at column 0 of its line -- optionally after only whitespace or a list/quote marker (`-`, `*`, `>`, digits, `.`) -- and the previous line ends with `-`/`–`: the signature of a wrapped continuation rather than a genuine citation to a short bare filename.
|
|
121
153
|
|
|
122
154
|
**Path resolution**, tried in order: (1) the doc's own frontmatter `sources` list, matched by exact suffix, only when exactly one source matches; (2) for a citedPath with no `/` only, doc-relative and then each ancestor directory of the doc up to the repo root, nearest first (so a bare filename like `README.md` prefers the README *for the package the doc lives in* over a same-named file that merely happens to also sit at the repo root); (3) repo-root-relative; (4) doc-relative; (5) the nearest earlier citation in the same doc whose path contains a `/` and ends with the same suffix (the "full path was mentioned earlier" convention); (6) a repo-wide search by basename. A cited path starting with `/` is treated as an absolute or placeholder path (e.g. inside a fabricated example stack trace) and skipped without a finding.
|
|
@@ -137,7 +169,7 @@ This is advisory: don't fail the build on warnings unless you pass `--strict`. U
|
|
|
137
169
|
|
|
138
170
|
```yaml
|
|
139
171
|
- name: OKF bundle check
|
|
140
|
-
run: npx okf-kit@0.
|
|
172
|
+
run: npx okf-kit@0.6.0 check path/to/bundle
|
|
141
173
|
```
|
|
142
174
|
|
|
143
175
|
Pin the version: an unpinned `npx okf-kit` picks up new rules on their release day, which turns an unrelated PR red.
|
|
@@ -130,7 +130,206 @@ const RULE_ID = "citations-resolve";
|
|
|
130
130
|
* this rule emits a single bundle-level notice, matching `sources-fresh`'s
|
|
131
131
|
* "not inside a git work tree" posture.
|
|
132
132
|
*/
|
|
133
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Anchored citations. A full citation (never a continuation or short-form
|
|
135
|
+
* atom -- see below) may carry an anchor directly after its range,
|
|
136
|
+
* `path:N-M#anchor`, e.g. `` `CHANGELOG.md:50-144#0.24.0` ``. Motivation: a
|
|
137
|
+
* CHANGELOG.md grows by insertion at the TOP (newest entry first), so every
|
|
138
|
+
* later entry's absolute line numbers shift on every release; the checks
|
|
139
|
+
* above (missing-file, inverted-range, range-exceeds-file, blank-start-line,
|
|
140
|
+
* closing-brace-start-line) are structurally blind to a citation that
|
|
141
|
+
* shifted a whole release section over and now lands, still non-blank and
|
|
142
|
+
* in-bounds, inside the WRONG section -- a citation `CHANGELOG.md:738-748`
|
|
143
|
+
* meant for the "0.7.4" entry that quietly now points at "0.7.3" prose is
|
|
144
|
+
* exactly as green as before the shift. An anchor closes that gap by
|
|
145
|
+
* pinning the citation to a piece of the target's own structure/content that
|
|
146
|
+
* the line-shift does not preserve automatically.
|
|
147
|
+
*
|
|
148
|
+
* Two anchor kinds, told apart by the raw anchor text (group 4 of
|
|
149
|
+
* `CITATION_RE`, see `parseAnchor`):
|
|
150
|
+
* - **Heading form** (bare, unquoted, e.g. `#0.24.0` or `#[0.24.0]`):
|
|
151
|
+
* the target's nearest *enclosing* Markdown heading -- see
|
|
152
|
+
* `findEnclosingHeading` -- must contain the anchor text, and no
|
|
153
|
+
* heading of the same or shallower level may start before the range's
|
|
154
|
+
* end line (i.e. the heading must actually enclose the whole range, not
|
|
155
|
+
* merely precede its start -- see `checkAnchor`). Deliberately capped at
|
|
156
|
+
* `ANCHOR_HEADING_MAX_LEVEL` (2): a Keep-a-Changelog CHANGELOG.md nests
|
|
157
|
+
* `## [x.y.z]` release headings around identically-named `### Added` /
|
|
158
|
+
* `### Changed` / `### Fixed` subsections repeated in every release;
|
|
159
|
+
* treating "nearest heading of any level" as the anchor target would
|
|
160
|
+
* make a heading anchor nearly useless here (matching the wrong
|
|
161
|
+
* release's own "Changed" subsection just as readily as the right
|
|
162
|
+
* one's), so subsection headings are transparent to this check and only
|
|
163
|
+
* level-1/level-2 headings are ever considered.
|
|
164
|
+
* - **String form** (double-quoted, e.g. `#"reproduction requirement"`):
|
|
165
|
+
* the anchor text must occur, verbatim, on at least one line of the
|
|
166
|
+
* cited range itself (`checkAnchor`'s string branch) -- "occurs inside
|
|
167
|
+
* it" rather than "encloses it". No heading structure required, so this
|
|
168
|
+
* form also works against a non-Markdown target (`.ts`/`.js`/...) where
|
|
169
|
+
* "nearest enclosing heading" has no meaning.
|
|
170
|
+
* An anchor mismatch is its own drift finding (`anchor-heading-not-found`,
|
|
171
|
+
* `anchor-heading-mismatch`, `anchor-heading-does-not-enclose`,
|
|
172
|
+
* `anchor-not-found-in-range`), checked only once the base start/range
|
|
173
|
+
* checks (blank-start-line, closing-brace-start-line, inverted-range,
|
|
174
|
+
* range-exceeds-file) already came back clean -- same "one problem per
|
|
175
|
+
* citation, base checks first" pattern `checkShortFormTarget` already uses
|
|
176
|
+
* for the block-boundary check.
|
|
177
|
+
*
|
|
178
|
+
* Backward compatible by construction: the `#anchor` suffix is optional in
|
|
179
|
+
* `CITATION_RE`, so an existing anchorless citation matches exactly as
|
|
180
|
+
* before and is checked exactly as before (this section adds a new check
|
|
181
|
+
* gated on the anchor being present, it does not change any existing one).
|
|
182
|
+
* Deliberately scoped to full citations only: a continuation (`` `:M` ``
|
|
183
|
+
* etc.) or a short-form `:N-M` never carries its own path, so there is
|
|
184
|
+
* nowhere natural to hang an anchor on one without inventing a second,
|
|
185
|
+
* detached syntax; the migration this rule was built for (CHANGELOG.md
|
|
186
|
+
* citations) is written as full citations throughout the corpus it targets.
|
|
187
|
+
*
|
|
188
|
+
* Rejected alternatives (see the PR/CHANGELOG for the fuller writeup):
|
|
189
|
+
* - Embedding the literal heading markup itself, e.g.
|
|
190
|
+
* `` `CHANGELOG.md:50-144#"## [0.24.0]"` `` -- verbatim-correct but
|
|
191
|
+
* `#`, `[`, `]`, and the space all need quoting/escaping right next to
|
|
192
|
+
* the citation, which reads worse in prose than a bare version token
|
|
193
|
+
* and gains nothing the structural heading-enclosure check does not
|
|
194
|
+
* already provide from the shorter form.
|
|
195
|
+
* - A detached anchor, e.g. a trailing parenthetical `(see "0.24.0")`
|
|
196
|
+
* elsewhere in the sentence -- unparseable without a second, separate
|
|
197
|
+
* grammar next to the existing continuation/short-form machinery, and
|
|
198
|
+
* easy to leave behind (or attach to the wrong citation) when a
|
|
199
|
+
* sentence is edited later.
|
|
200
|
+
* - A named-capture-group slug matching `sources-fresh`'s YAML shape --
|
|
201
|
+
* rejected because it would require a second citation site (frontmatter
|
|
202
|
+
* plus prose) to stay in sync, the exact class of drift this rule
|
|
203
|
+
* exists to catch.
|
|
204
|
+
*/
|
|
205
|
+
const ANCHOR_HEADING_MAX_LEVEL = 2;
|
|
206
|
+
const MD_HEADING_RE = /^(#{1,6})\s+(.*)$/;
|
|
207
|
+
/**
|
|
208
|
+
* Parses `CITATION_RE`'s optional 4th capture group (the raw anchor text,
|
|
209
|
+
* including its surrounding quotes or brackets if any) into an `Anchor`, or
|
|
210
|
+
* `null` when the citation carried no `#anchor` suffix at all. A
|
|
211
|
+
* double-quoted raw value (`"..."`) is the string form, text taken verbatim
|
|
212
|
+
* between the quotes; anything else is the heading form, with a single
|
|
213
|
+
* wrapping `[...]` stripped (so `#[0.24.0]` and `#0.24.0` compare
|
|
214
|
+
* identically) -- compared as a plain substring against the heading's own
|
|
215
|
+
* raw text (`findEnclosingHeading`'s `text`, itself never stripped of any
|
|
216
|
+
* brackets it happens to carry), not a stripped copy of it -- see the
|
|
217
|
+
* "Anchored citations" doc block above.
|
|
218
|
+
*/
|
|
219
|
+
function parseAnchor(raw) {
|
|
220
|
+
if (!raw)
|
|
221
|
+
return null;
|
|
222
|
+
if (raw.length >= 2 && raw.startsWith('"') && raw.endsWith('"')) {
|
|
223
|
+
return { kind: "string", text: raw.slice(1, -1) };
|
|
224
|
+
}
|
|
225
|
+
const text = raw.startsWith("[") && raw.endsWith("]") ? raw.slice(1, -1) : raw;
|
|
226
|
+
return { kind: "heading", text };
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 0-based line indices that fall inside a fenced code block (```` ``` ````
|
|
230
|
+
* or `~~~`, optionally with a trailing language tag), delimiters included --
|
|
231
|
+
* the target-side twin of `computeFencedSpans` above, which does the same
|
|
232
|
+
* job for the *citing* doc's short-form matching. Anchor heading-search
|
|
233
|
+
* needs its own copy because it works from an already-split `lines` array
|
|
234
|
+
* (see `checkFullTarget`), not the raw `content` string `computeFencedSpans`
|
|
235
|
+
* takes, and because it must ignore a target's `# not a heading` sitting
|
|
236
|
+
* inside a fenced example exactly the same way a citing doc's own fences
|
|
237
|
+
* are already ignored for short-form matching -- without this, a `#`-led
|
|
238
|
+
* comment line inside e.g. a fenced shell example in the target is
|
|
239
|
+
* indistinguishable from a real Markdown heading to `MD_HEADING_RE`, and
|
|
240
|
+
* both `findEnclosingHeading` (picks the wrong "nearest" heading) and the
|
|
241
|
+
* enclosure walk in `checkAnchor` (treats it as a section boundary) would
|
|
242
|
+
* misfire on it.
|
|
243
|
+
*/
|
|
244
|
+
function computeFencedLineIndices(lines) {
|
|
245
|
+
const fenced = new Set();
|
|
246
|
+
let fenceMarker;
|
|
247
|
+
let fenceStart = -1;
|
|
248
|
+
for (let i = 0; i < lines.length; i++) {
|
|
249
|
+
const trimmed = (lines[i] ?? "").trim();
|
|
250
|
+
if (!fenceMarker && MD_FENCE_DELIM_RE.test(trimmed)) {
|
|
251
|
+
fenceMarker = trimmed.slice(0, 3);
|
|
252
|
+
fenceStart = i;
|
|
253
|
+
}
|
|
254
|
+
else if (fenceMarker && trimmed.startsWith(fenceMarker)) {
|
|
255
|
+
for (let j = fenceStart; j <= i; j++)
|
|
256
|
+
fenced.add(j);
|
|
257
|
+
fenceMarker = undefined;
|
|
258
|
+
fenceStart = -1;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (fenceMarker && fenceStart >= 0) {
|
|
262
|
+
for (let j = fenceStart; j < lines.length; j++)
|
|
263
|
+
fenced.add(j);
|
|
264
|
+
}
|
|
265
|
+
return fenced;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Nearest Markdown heading at or before `startLine` (1-based), considering
|
|
269
|
+
* only heading levels up to `ANCHOR_HEADING_MAX_LEVEL` -- see the "Anchored
|
|
270
|
+
* citations" doc block above for why subsection headings are transparent to
|
|
271
|
+
* this search. `fencedLines` (see `computeFencedLineIndices`) excludes any
|
|
272
|
+
* line inside a fenced code block from matching, so a `#`-led comment
|
|
273
|
+
* inside a fenced example is never mistaken for a heading. Returns `null`
|
|
274
|
+
* when no such heading precedes `startLine` at all (e.g. the citation
|
|
275
|
+
* lands above the target's first release heading).
|
|
276
|
+
*/
|
|
277
|
+
function findEnclosingHeading(lines, startLine, fencedLines) {
|
|
278
|
+
for (let i = startLine - 1; i >= 0; i--) {
|
|
279
|
+
if (fencedLines.has(i))
|
|
280
|
+
continue;
|
|
281
|
+
const m = (lines[i] ?? "").match(MD_HEADING_RE);
|
|
282
|
+
if (m && m[1].length <= ANCHOR_HEADING_MAX_LEVEL) {
|
|
283
|
+
return { level: m[1].length, text: m[2].trim(), lineNo: i + 1 };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Checks an anchored full citation's anchor against its already-resolved,
|
|
290
|
+
* already-range-checked target -- see the "Anchored citations" doc block
|
|
291
|
+
* above for the two forms' semantics. `endLine` is the citation's end line,
|
|
292
|
+
* or its start line for a single-line citation (a size-1 range).
|
|
293
|
+
*/
|
|
294
|
+
function checkAnchor(anchor, startLine, endLine, lines) {
|
|
295
|
+
if (anchor.kind === "string") {
|
|
296
|
+
for (let i = startLine - 1; i <= endLine - 1 && i < lines.length; i++) {
|
|
297
|
+
if ((lines[i] ?? "").includes(anchor.text))
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
rule: "anchor-not-found-in-range",
|
|
302
|
+
message: `anchor "${anchor.text}" does not occur in the cited range (${startLine}-${endLine})`,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const fencedLines = computeFencedLineIndices(lines);
|
|
306
|
+
const heading = findEnclosingHeading(lines, startLine, fencedLines);
|
|
307
|
+
if (!heading) {
|
|
308
|
+
return {
|
|
309
|
+
rule: "anchor-heading-not-found",
|
|
310
|
+
message: `no heading (level <= ${ANCHOR_HEADING_MAX_LEVEL}) precedes line ${startLine} to anchor against; use a string anchor (#"...") instead against a target with no heading structure`,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
if (!heading.text.includes(anchor.text)) {
|
|
314
|
+
return {
|
|
315
|
+
rule: "anchor-heading-mismatch",
|
|
316
|
+
message: `nearest enclosing heading ("${heading.text}") does not contain anchor "${anchor.text}"`,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
for (let i = heading.lineNo; i <= endLine - 1; i++) {
|
|
320
|
+
if (fencedLines.has(i))
|
|
321
|
+
continue;
|
|
322
|
+
const m = (lines[i] ?? "").match(MD_HEADING_RE);
|
|
323
|
+
if (m && m[1].length <= heading.level) {
|
|
324
|
+
return {
|
|
325
|
+
rule: "anchor-heading-does-not-enclose",
|
|
326
|
+
message: `range extends past its enclosing heading's section (next heading "${m[2].trim()}" at line ${i + 1})`,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
const CITATION_RE = /([\w./-]+\.(?:ts|js|mjs|md|yml|yaml|json)):(\d+)(?:-(\d+))?(?:#(\[?\w(?:[\w.-]*\w)?\]?|"[^"\n`]*"))?/g;
|
|
134
333
|
// Continuation citation forms (see the "Continuation citations" doc block
|
|
135
334
|
// above). Each requires the backtick delimiter as part of the match so it
|
|
136
335
|
// can never overlap a CITATION_RE match: a full citation's regex match
|
|
@@ -141,6 +340,28 @@ const CONT_DASH_RE = /[-–]`(\d+)`/g;
|
|
|
141
340
|
const CONT_PAREN_RE = /\(`(\d+)`\)/g;
|
|
142
341
|
const CLOSING_ONLY_EXTS = new Set(["ts", "js", "mjs", "yml", "yaml", "json"]);
|
|
143
342
|
const CLOSING_BRACE_RE = /^[)\]}][;,]?$/;
|
|
343
|
+
// Short-form (paragraph-bound) citation form, see the "Short-form
|
|
344
|
+
// citations" doc block below. Requires an explicit N-M range: a bare single
|
|
345
|
+
// number (`:5`) is not matched -- see that doc block for why. Only the
|
|
346
|
+
// colon form is collected; a bare `(N-M)` is never a short-form citation
|
|
347
|
+
// candidate at all -- see the same doc block for why the paren form was
|
|
348
|
+
// dropped rather than gated.
|
|
349
|
+
const SHORT_FORM_COLON_RE = /:(\d+)-(\d+)/g;
|
|
350
|
+
// Test-file block-boundary check (see checkRangeBoundary): a citation's
|
|
351
|
+
// range into a `.test.ts`/`.spec.ts` (or `.js`/`.mjs` equivalent) target
|
|
352
|
+
// must start on a describe(/it( head line and end on its matching closing
|
|
353
|
+
// `});` line.
|
|
354
|
+
const TEST_FILE_RE = /\.(test|spec)\.(ts|js|mjs)$/i;
|
|
355
|
+
const TEST_HEAD_LINE_RE = /^\s*(?:describe|it)\s*\(/;
|
|
356
|
+
const TEST_CLOSING_LINE_RE = /^\s*\}\)\s*;\s*$/;
|
|
357
|
+
// Markdown block-boundary check (see checkRangeBoundary): a range boundary
|
|
358
|
+
// line that is nothing but a bracket (open or close), optionally with a
|
|
359
|
+
// trailing `,`/`;`, is always a drift signal. A bare code-fence delimiter is
|
|
360
|
+
// its own, separate signal (see MD_FENCE_DELIM_RE): unlike a bracket, a
|
|
361
|
+
// fence line is sometimes the deliberately-correct start of a citation (see
|
|
362
|
+
// checkRangeBoundary's markdown branch for the opening-fence exception).
|
|
363
|
+
const MD_BARE_BRACKET_RE = /^(?:[)\]}][;,]?|[[({])$/;
|
|
364
|
+
const MD_FENCE_DELIM_RE = /^(?:`{3,}\S*|~{3,}\S*)$/;
|
|
144
365
|
const EXCLUDED_DIRS = new Set([
|
|
145
366
|
"node_modules",
|
|
146
367
|
".git",
|
|
@@ -367,14 +588,15 @@ function readTarget(resolvedPath) {
|
|
|
367
588
|
};
|
|
368
589
|
}
|
|
369
590
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
591
|
+
/**
|
|
592
|
+
* The non-I/O half of checkTarget: every check that only needs the
|
|
593
|
+
* target's already-read `lines`, not the filesystem. Split out so a caller
|
|
594
|
+
* that needs a second, different check against the same target (see
|
|
595
|
+
* checkShortFormTarget) can read the file once and reuse `lines` for both,
|
|
596
|
+
* instead of checkTarget re-reading it internally.
|
|
597
|
+
*/
|
|
598
|
+
function checkTargetLines(citedPath, startLine, endLine, lines) {
|
|
599
|
+
const bound = checkRangeBound(startLine, endLine, lines.length);
|
|
378
600
|
if (bound)
|
|
379
601
|
return bound;
|
|
380
602
|
const startText = lines[startLine - 1] ?? "";
|
|
@@ -391,6 +613,34 @@ function checkTarget(citedPath, startLine, endLine, resolvedPath) {
|
|
|
391
613
|
}
|
|
392
614
|
return null;
|
|
393
615
|
}
|
|
616
|
+
function checkTarget(citedPath, startLine, endLine, resolvedPath) {
|
|
617
|
+
const read = readTarget(resolvedPath);
|
|
618
|
+
if ("rule" in read)
|
|
619
|
+
return read;
|
|
620
|
+
return checkTargetLines(citedPath, startLine, endLine, splitLines(read.content));
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* A full citation's complete check: `checkTargetLines`'s existing checks
|
|
624
|
+
* (unreadable-target, inverted-range, range-exceeds-file, blank-start-line,
|
|
625
|
+
* closing-brace-start-line), plus, only when those all pass and the
|
|
626
|
+
* citation carried an anchor, the anchor check above (see the "Anchored
|
|
627
|
+
* citations" doc block). Reads the resolved target once, mirroring
|
|
628
|
+
* `checkShortFormTarget`'s reasoning for the block-boundary check. Anchors
|
|
629
|
+
* are full-citation-only (see that doc block for why), so `checkTarget`
|
|
630
|
+
* itself is untouched and still used as-is for a cont-fresh atom.
|
|
631
|
+
*/
|
|
632
|
+
function checkFullTarget(citedPath, startLine, endLine, resolvedPath, anchor) {
|
|
633
|
+
const read = readTarget(resolvedPath);
|
|
634
|
+
if ("rule" in read)
|
|
635
|
+
return read;
|
|
636
|
+
const lines = splitLines(read.content);
|
|
637
|
+
const base = checkTargetLines(citedPath, startLine, endLine, lines);
|
|
638
|
+
if (base)
|
|
639
|
+
return base;
|
|
640
|
+
if (!anchor)
|
|
641
|
+
return null;
|
|
642
|
+
return checkAnchor(anchor, startLine, endLine ?? startLine, lines);
|
|
643
|
+
}
|
|
394
644
|
// A cont-ext atom only ever extends the *end* of a range whose start line
|
|
395
645
|
// was already fully checked (blank / closing-brace) when it was cited as
|
|
396
646
|
// its own full citation or cont-fresh atom -- re-running checkTarget here
|
|
@@ -405,6 +655,175 @@ function checkRangeBoundOnly(startLine, endLine, resolvedPath) {
|
|
|
405
655
|
const lineCount = splitLines(read.content).length;
|
|
406
656
|
return checkRangeBound(startLine, endLine, lineCount);
|
|
407
657
|
}
|
|
658
|
+
function isTestFile(citedPath) {
|
|
659
|
+
return TEST_FILE_RE.test(citedPath);
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* True when the line at `lines[lineIndex]` is a fence delimiter
|
|
663
|
+
* (```` ``` ```` or `~~~`, optionally with a trailing language tag) that
|
|
664
|
+
* *opens* a fenced code block, as opposed to closing one -- determined by
|
|
665
|
+
* replaying the same open/close state machine `stripFencedCode`-style
|
|
666
|
+
* scanners use from the top of the document, not by the line's own text
|
|
667
|
+
* (a bare closing fence and an untagged opening fence are lexically
|
|
668
|
+
* identical). Used by checkRangeBoundary's markdown branch: citing a
|
|
669
|
+
* fenced block starting at its own opening fence line is the natural,
|
|
670
|
+
* correct way to cite it, so that specific case is exempted from the
|
|
671
|
+
* fence-as-drift-signal check (see there).
|
|
672
|
+
*/
|
|
673
|
+
function isFenceOpeningLine(lines, lineIndex) {
|
|
674
|
+
let inFence = false;
|
|
675
|
+
let fenceMarker;
|
|
676
|
+
for (let i = 0; i <= lineIndex; i++) {
|
|
677
|
+
const trimmed = (lines[i] ?? "").trim();
|
|
678
|
+
if (!inFence && MD_FENCE_DELIM_RE.test(trimmed)) {
|
|
679
|
+
if (i === lineIndex)
|
|
680
|
+
return true;
|
|
681
|
+
inFence = true;
|
|
682
|
+
fenceMarker = trimmed.slice(0, 3);
|
|
683
|
+
}
|
|
684
|
+
else if (inFence && fenceMarker && trimmed.startsWith(fenceMarker)) {
|
|
685
|
+
if (i === lineIndex)
|
|
686
|
+
return false;
|
|
687
|
+
inFence = false;
|
|
688
|
+
fenceMarker = undefined;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* True when `lines[endLineIndex]` is the closing delimiter that matches
|
|
695
|
+
* the *opening* fence at `lines[startLineIndex]` (the caller must already
|
|
696
|
+
* have confirmed the start line is a genuine opening fence, via
|
|
697
|
+
* isFenceOpeningLine, before calling this) -- the first line after the
|
|
698
|
+
* opener whose trimmed text starts with the same fence marker. Used by
|
|
699
|
+
* checkRangeBoundary's markdown branch to also exempt a range's END from
|
|
700
|
+
* the fence-as-drift-signal check when the range legitimately cites a
|
|
701
|
+
* whole fenced code block from its own opening delimiter to its own
|
|
702
|
+
* closing delimiter: the natural, correct way to cite such a block, not
|
|
703
|
+
* drift, the same reasoning the start-side exception already applies.
|
|
704
|
+
*/
|
|
705
|
+
function isMatchingFenceClosingLine(lines, startLineIndex, endLineIndex) {
|
|
706
|
+
const fenceMarker = (lines[startLineIndex] ?? "").trim().slice(0, 3);
|
|
707
|
+
for (let i = startLineIndex + 1; i < lines.length; i++) {
|
|
708
|
+
const trimmed = (lines[i] ?? "").trim();
|
|
709
|
+
if (trimmed.startsWith(fenceMarker)) {
|
|
710
|
+
return i === endLineIndex;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Additional block-boundary check for a short-form citation's range (see
|
|
717
|
+
* the "Short-form citations" doc block below), layered on top of
|
|
718
|
+
* checkTarget's existing per-start-line checks via checkShortFormTarget.
|
|
719
|
+
* Deliberately scoped to short-form citations only, not wired into
|
|
720
|
+
* checkTarget/checkRangeBoundOnly (the full/continuation citation paths):
|
|
721
|
+
* applying it there too was tried first and rejected -- the real bundle
|
|
722
|
+
* this rule was built against has legitimate full citations into test
|
|
723
|
+
* files that cite a couple of arbitrary lines (e.g. two lines of a shared
|
|
724
|
+
* regex definition), not a describe/it block, and flagging those as newly
|
|
725
|
+
* broken would have regressed the existing 0-warning baseline. Short-form
|
|
726
|
+
* citations are the demonstrated motivating case (a paragraph naming a
|
|
727
|
+
* test file once, then citing several of its describe/it blocks by bare
|
|
728
|
+
* range alone), so the check is scoped to exactly that mechanism.
|
|
729
|
+
*
|
|
730
|
+
* Test-file targets (`.test.ts`/`.spec.ts`, and their `.js`/`.mjs`
|
|
731
|
+
* equivalents): the range must start on a `describe(`/`it(` head line and
|
|
732
|
+
* end on a matching closing `});` line. Severity split, by evidence
|
|
733
|
+
* strength: a wrong START line is a
|
|
734
|
+
* *warning* (`test-range-start-not-head`) -- the range beginning somewhere
|
|
735
|
+
* other than a block head is strong drift evidence. A range whose start IS
|
|
736
|
+
* correct but whose END is not the matching `});` is only a *notice*
|
|
737
|
+
* (`test-range-end-not-closing`): this also matches a deliberate partial
|
|
738
|
+
* citation (citing from a block's head to partway through it), which is not
|
|
739
|
+
* drift. The start is checked first and returned alone, matching
|
|
740
|
+
* checkTarget's existing single-problem-per-citation pattern (never both at
|
|
741
|
+
* once).
|
|
742
|
+
*
|
|
743
|
+
* Markdown targets: mechanical verification of "is this still the same
|
|
744
|
+
* block" is far less reliable for prose than for TS/JS brace structure, so
|
|
745
|
+
* this is a notice, not a warning (see this rule's own risk note on
|
|
746
|
+
* markdown false positives). The range's start or end line landing on a
|
|
747
|
+
* bare bracket (MD_BARE_BRACKET_RE) is always a heads-up that the boundary
|
|
748
|
+
* likely drifted onto structural punctuation rather than real prose. A bare
|
|
749
|
+
* code-fence delimiter (MD_FENCE_DELIM_RE) is also always a drift signal at
|
|
750
|
+
* either boundary, with two exceptions carved out for the one legitimate
|
|
751
|
+
* way to cite a whole fenced code block by its own delimiters: the START is
|
|
752
|
+
* exempted when that line is itself a genuine *opening* fence (see
|
|
753
|
+
* isFenceOpeningLine), and, only when the start already qualified for that
|
|
754
|
+
* exemption, the END is exempted when it is that same fence's matching
|
|
755
|
+
* *closing* delimiter (see isMatchingFenceClosingLine) -- citing a fenced
|
|
756
|
+
* block from its own opening delimiter through its own closing delimiter is
|
|
757
|
+
* the natural, correct way to cite it, not drift.
|
|
758
|
+
*/
|
|
759
|
+
function checkRangeBoundary(citedPath, startLine, endLine, lines) {
|
|
760
|
+
if (isTestFile(citedPath)) {
|
|
761
|
+
const startText = lines[startLine - 1] ?? "";
|
|
762
|
+
if (!TEST_HEAD_LINE_RE.test(startText)) {
|
|
763
|
+
return {
|
|
764
|
+
rule: "test-range-start-not-head",
|
|
765
|
+
message: `range start is not a "describe(" or "it(" head line ("${startText.trim()}")`,
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
const endText = lines[endLine - 1] ?? "";
|
|
769
|
+
if (!TEST_CLOSING_LINE_RE.test(endText)) {
|
|
770
|
+
return {
|
|
771
|
+
rule: "test-range-end-not-closing",
|
|
772
|
+
message: `range end is not a matching closing "});" line ("${endText.trim()}")`,
|
|
773
|
+
severity: "notice",
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
return null;
|
|
777
|
+
}
|
|
778
|
+
if (citedPath.toLowerCase().endsWith(".md")) {
|
|
779
|
+
const startTrim = (lines[startLine - 1] ?? "").trim();
|
|
780
|
+
const startIsFence = MD_FENCE_DELIM_RE.test(startTrim);
|
|
781
|
+
if (MD_BARE_BRACKET_RE.test(startTrim) ||
|
|
782
|
+
(startIsFence && !isFenceOpeningLine(lines, startLine - 1))) {
|
|
783
|
+
return {
|
|
784
|
+
rule: "markdown-range-boundary-bracket-or-fence",
|
|
785
|
+
message: `range start is a bare bracket/fence line ("${startTrim}")`,
|
|
786
|
+
severity: "notice",
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
const endTrim = (lines[endLine - 1] ?? "").trim();
|
|
790
|
+
const endIsFence = MD_FENCE_DELIM_RE.test(endTrim);
|
|
791
|
+
const endIsMatchingClose = startIsFence &&
|
|
792
|
+
endIsFence &&
|
|
793
|
+
isMatchingFenceClosingLine(lines, startLine - 1, endLine - 1);
|
|
794
|
+
if (MD_BARE_BRACKET_RE.test(endTrim) ||
|
|
795
|
+
(endIsFence && !endIsMatchingClose)) {
|
|
796
|
+
return {
|
|
797
|
+
rule: "markdown-range-boundary-bracket-or-fence",
|
|
798
|
+
message: `range end is a bare bracket/fence line ("${endTrim}")`,
|
|
799
|
+
severity: "notice",
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* A short-form citation's full check: checkTarget's existing checks
|
|
808
|
+
* (unreadable-target, inverted-range, range-exceeds-file, blank-start-line,
|
|
809
|
+
* closing-brace-start-line), plus, only when those all pass, the
|
|
810
|
+
* test-file/markdown block-boundary check above (see checkRangeBoundary).
|
|
811
|
+
* Reads the resolved target from disk exactly once (a dogfood bundle can
|
|
812
|
+
* run this against the same target file a dozen-plus times for one
|
|
813
|
+
* compound short-form list) and reuses the same `lines` array for both
|
|
814
|
+
* checks, instead of checkTarget and checkRangeBoundary each reading and
|
|
815
|
+
* re-splitting it independently.
|
|
816
|
+
*/
|
|
817
|
+
function checkShortFormTarget(citedPath, startLine, endLine, resolvedPath) {
|
|
818
|
+
const read = readTarget(resolvedPath);
|
|
819
|
+
if ("rule" in read)
|
|
820
|
+
return read;
|
|
821
|
+
const lines = splitLines(read.content);
|
|
822
|
+
const base = checkTargetLines(citedPath, startLine, endLine, lines);
|
|
823
|
+
if (base)
|
|
824
|
+
return base;
|
|
825
|
+
return checkRangeBoundary(citedPath, startLine, endLine, lines);
|
|
826
|
+
}
|
|
408
827
|
/**
|
|
409
828
|
* Collects every continuation-citation atom (see the "Continuation
|
|
410
829
|
* citations" doc block above) in `content`, sorted by document position.
|
|
@@ -462,10 +881,231 @@ function collectContinuationAtoms(content) {
|
|
|
462
881
|
}
|
|
463
882
|
return atoms;
|
|
464
883
|
}
|
|
465
|
-
|
|
884
|
+
/**
|
|
885
|
+
* True when the nearest non-whitespace text before `matchIndex` in
|
|
886
|
+
* `content` is a serial connective: the single character `,`, `;`, or `(`,
|
|
887
|
+
* or the word `and`/`or` (case-insensitive, word-boundary-matched so it
|
|
888
|
+
* does not fire on the tail of a longer word like "brand"). See the
|
|
889
|
+
* "Short-form citations" doc block above for why this is the gate.
|
|
890
|
+
*/
|
|
891
|
+
function isSerialConnectivePreceded(content, matchIndex) {
|
|
892
|
+
const before = content.slice(0, matchIndex).trimEnd();
|
|
893
|
+
if (before === "")
|
|
894
|
+
return false;
|
|
895
|
+
const lastChar = before[before.length - 1];
|
|
896
|
+
if (lastChar === "," || lastChar === ";" || lastChar === "(")
|
|
897
|
+
return true;
|
|
898
|
+
return /\b(?:and|or)$/i.test(before);
|
|
899
|
+
}
|
|
900
|
+
function isWithinAnySpan(index, spans) {
|
|
901
|
+
return spans.some(([start, end]) => index >= start && index < end);
|
|
902
|
+
}
|
|
903
|
+
function collectShortFormMatches(content, excludedSpans) {
|
|
904
|
+
const out = [];
|
|
905
|
+
const colonRe = new RegExp(SHORT_FORM_COLON_RE.source, "g");
|
|
906
|
+
let m;
|
|
907
|
+
while ((m = colonRe.exec(content)) !== null) {
|
|
908
|
+
if (isWithinAnySpan(m.index, excludedSpans))
|
|
909
|
+
continue;
|
|
910
|
+
if (content[m.index - 1] === "`")
|
|
911
|
+
continue;
|
|
912
|
+
if (content[m.index + m[0].length] === "`")
|
|
913
|
+
continue;
|
|
914
|
+
if (!isSerialConnectivePreceded(content, m.index))
|
|
915
|
+
continue;
|
|
916
|
+
const startLine = Number(m[1]);
|
|
917
|
+
const endLine = Number(m[2]);
|
|
918
|
+
out.push({ index: m.index, startLine, endLine });
|
|
919
|
+
}
|
|
920
|
+
return out.sort((a, b) => a.index - b.index);
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Char spans of every fenced code block in `content` (```` ``` ```` or
|
|
924
|
+
* `~~~`, optionally with a trailing language tag), each span running from
|
|
925
|
+
* the start of the opening fence line to the end of the closing fence line
|
|
926
|
+
* inclusive. An unterminated fence (no matching close before end of doc) is
|
|
927
|
+
* treated as running to the end of the content -- conservative, since an
|
|
928
|
+
* unterminated fence is itself a doc problem outside this rule's scope, not
|
|
929
|
+
* a reason to scan its contents for short-form citations.
|
|
930
|
+
*/
|
|
931
|
+
function computeFencedSpans(content) {
|
|
932
|
+
const spans = [];
|
|
933
|
+
const lines = content.split("\n");
|
|
934
|
+
let offset = 0;
|
|
935
|
+
let fenceMarker;
|
|
936
|
+
let fenceStart = -1;
|
|
937
|
+
for (const line of lines) {
|
|
938
|
+
const trimmed = line.trim();
|
|
939
|
+
const lineEnd = offset + line.length;
|
|
940
|
+
if (!fenceMarker && MD_FENCE_DELIM_RE.test(trimmed)) {
|
|
941
|
+
fenceMarker = trimmed.slice(0, 3);
|
|
942
|
+
fenceStart = offset;
|
|
943
|
+
}
|
|
944
|
+
else if (fenceMarker && trimmed.startsWith(fenceMarker)) {
|
|
945
|
+
spans.push([fenceStart, lineEnd]);
|
|
946
|
+
fenceMarker = undefined;
|
|
947
|
+
fenceStart = -1;
|
|
948
|
+
}
|
|
949
|
+
offset = lineEnd + 1; // +1 for the newline joining this line to the next
|
|
950
|
+
}
|
|
951
|
+
if (fenceMarker && fenceStart >= 0) {
|
|
952
|
+
spans.push([fenceStart, content.length]);
|
|
953
|
+
}
|
|
954
|
+
return spans;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Char spans of every CommonMark-style indented code block in `content`: a
|
|
958
|
+
* maximal run of consecutive non-blank lines, each indented by at least
|
|
959
|
+
* four spaces or a leading tab, whose first line is preceded by a blank
|
|
960
|
+
* line or the start of the document (an indented code block cannot
|
|
961
|
+
* interrupt a paragraph). A blank line inside the run does not itself end
|
|
962
|
+
* it, matching CommonMark. Simplified relative to the full CommonMark
|
|
963
|
+
* spec (no list-item-context awareness); adequate for this mechanical,
|
|
964
|
+
* warn-only rule.
|
|
965
|
+
*/
|
|
966
|
+
function computeIndentedCodeSpans(content) {
|
|
967
|
+
const spans = [];
|
|
968
|
+
const lines = content.split("\n");
|
|
969
|
+
let offset = 0;
|
|
970
|
+
let blockStart = -1;
|
|
971
|
+
let blockEnd = -1;
|
|
972
|
+
let prevBlank = true;
|
|
973
|
+
for (const line of lines) {
|
|
974
|
+
const lineStart = offset;
|
|
975
|
+
const lineEnd = offset + line.length;
|
|
976
|
+
const isBlank = line.trim() === "";
|
|
977
|
+
const isIndented = /^( {4,}|\t)/.test(line);
|
|
978
|
+
if (!isBlank && isIndented && (blockStart !== -1 || prevBlank)) {
|
|
979
|
+
if (blockStart === -1)
|
|
980
|
+
blockStart = lineStart;
|
|
981
|
+
blockEnd = lineEnd;
|
|
982
|
+
}
|
|
983
|
+
else if (isBlank && blockStart !== -1) {
|
|
984
|
+
// blank line inside an open block: keep it open, don't extend blockEnd
|
|
985
|
+
}
|
|
986
|
+
else if (!isBlank) {
|
|
987
|
+
if (blockStart !== -1)
|
|
988
|
+
spans.push([blockStart, blockEnd]);
|
|
989
|
+
blockStart = -1;
|
|
990
|
+
blockEnd = -1;
|
|
991
|
+
}
|
|
992
|
+
prevBlank = isBlank;
|
|
993
|
+
offset = lineEnd + 1;
|
|
994
|
+
}
|
|
995
|
+
if (blockStart !== -1)
|
|
996
|
+
spans.push([blockStart, blockEnd]);
|
|
997
|
+
return spans;
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Char spans of every inline code span in `content` (`` `...` ``, or a
|
|
1001
|
+
* longer run of backticks as the delimiter). This is a superset of the
|
|
1002
|
+
* narrower "immediately adjacent to a backtick" guard already applied in
|
|
1003
|
+
* collectShortFormMatches: that guard only rejects a match directly
|
|
1004
|
+
* touching a backtick, so a short form embedded further inside a longer
|
|
1005
|
+
* inline code span (e.g. `` `ports (1-3)` ``) was previously matched and
|
|
1006
|
+
* bound; this closes that gap.
|
|
1007
|
+
*
|
|
1008
|
+
* Confined to a single line (the pairing regex excludes `\n`): CommonMark
|
|
1009
|
+
* inline code spans cannot themselves span multiple lines in the sense
|
|
1010
|
+
* this rule cares about, but more importantly, an unmatched backtick run
|
|
1011
|
+
* (a typo, or a literal backtick in prose) previously paired greedily with
|
|
1012
|
+
* the *next* backtick run anywhere later in the whole document, silently
|
|
1013
|
+
* treating everything in between -- potentially several unrelated
|
|
1014
|
+
* sentences and any short-form citation among them -- as one giant inline
|
|
1015
|
+
* code span. Confining the match to a single line means a backtick run
|
|
1016
|
+
* with no partner on the same line produces no span at all, instead of
|
|
1017
|
+
* reaching across a newline for one.
|
|
1018
|
+
*/
|
|
1019
|
+
function computeInlineCodeSpans(content) {
|
|
1020
|
+
const spans = [];
|
|
1021
|
+
const re = /(`+)[^`\n]*?\1/g;
|
|
1022
|
+
let m;
|
|
1023
|
+
while ((m = re.exec(content)) !== null) {
|
|
1024
|
+
spans.push([m.index, m.index + m[0].length]);
|
|
1025
|
+
}
|
|
1026
|
+
return spans;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Char spans of every Markdown table row in `content`: a line whose
|
|
1030
|
+
* trimmed form starts and ends with `|`. Decision (documented in the
|
|
1031
|
+
* README): a short-form citation inside a table cell is never recognised,
|
|
1032
|
+
* the same way one inside a code span is not -- excluded here rather than
|
|
1033
|
+
* left to the plausibility gate, since a table cell's content is prose-like
|
|
1034
|
+
* and can otherwise carry a range shape the gate would not reject (e.g.
|
|
1035
|
+
* `| col (5-9) |`).
|
|
1036
|
+
*/
|
|
1037
|
+
function computeTableRowSpans(content) {
|
|
1038
|
+
const spans = [];
|
|
1039
|
+
const lines = content.split("\n");
|
|
1040
|
+
let offset = 0;
|
|
1041
|
+
for (const line of lines) {
|
|
1042
|
+
const trimmed = line.trim();
|
|
1043
|
+
if (trimmed.startsWith("|") &&
|
|
1044
|
+
trimmed.endsWith("|") &&
|
|
1045
|
+
trimmed.length > 1) {
|
|
1046
|
+
spans.push([offset, offset + line.length]);
|
|
1047
|
+
}
|
|
1048
|
+
offset += line.length + 1;
|
|
1049
|
+
}
|
|
1050
|
+
return spans;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* All char spans short-form matching must never fire inside: fenced code,
|
|
1054
|
+
* indented code, inline code spans, and Markdown table rows. Computed once
|
|
1055
|
+
* per doc and combined with fullSpans (see scanDoc) via the existing
|
|
1056
|
+
* isWithinAnySpan helper -- the same mechanism a full citation's own span
|
|
1057
|
+
* already uses, not a second one.
|
|
1058
|
+
*/
|
|
1059
|
+
function computeExcludedSpans(content) {
|
|
1060
|
+
return [
|
|
1061
|
+
...computeFencedSpans(content),
|
|
1062
|
+
...computeIndentedCodeSpans(content),
|
|
1063
|
+
...computeInlineCodeSpans(content),
|
|
1064
|
+
...computeTableRowSpans(content),
|
|
1065
|
+
];
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Paragraph-start offsets in `content`, ascending, always including 0. A
|
|
1069
|
+
* paragraph boundary is a blank (empty or whitespace-only) line.
|
|
1070
|
+
*/
|
|
1071
|
+
function computeParagraphStarts(content) {
|
|
1072
|
+
const starts = [0];
|
|
1073
|
+
const re = /\n[ \t]*\n+/g;
|
|
1074
|
+
let m;
|
|
1075
|
+
while ((m = re.exec(content)) !== null) {
|
|
1076
|
+
starts.push(m.index + m[0].length);
|
|
1077
|
+
}
|
|
1078
|
+
return starts;
|
|
1079
|
+
}
|
|
1080
|
+
/** The start offset of the paragraph containing `index` (see computeParagraphStarts). */
|
|
1081
|
+
function paragraphStartFor(starts, index) {
|
|
1082
|
+
let result = starts[0];
|
|
1083
|
+
for (const s of starts) {
|
|
1084
|
+
if (s > index)
|
|
1085
|
+
break;
|
|
1086
|
+
result = s;
|
|
1087
|
+
}
|
|
1088
|
+
return result;
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* The nearest full citation strictly before `beforeIndex` and at or after
|
|
1092
|
+
* `paragraphStart` -- "the last target document named earlier in the same
|
|
1093
|
+
* paragraph" -- or null when none exists.
|
|
1094
|
+
*/
|
|
1095
|
+
function findLastNamedTargetInParagraph(fullAtoms, paragraphStart, beforeIndex) {
|
|
1096
|
+
let best = null;
|
|
1097
|
+
for (const a of fullAtoms) {
|
|
1098
|
+
if (a.index >= paragraphStart && a.index < beforeIndex) {
|
|
1099
|
+
if (!best || a.index > best.index)
|
|
1100
|
+
best = a;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
return best;
|
|
1104
|
+
}
|
|
1105
|
+
function pushDrift(findings, file, citation, rule, message, resolvedTo, severity = "warning") {
|
|
466
1106
|
findings.push({
|
|
467
1107
|
ruleId: RULE_ID,
|
|
468
|
-
severity
|
|
1108
|
+
severity,
|
|
469
1109
|
file,
|
|
470
1110
|
message: `\`${citation}\`: ${message} [${rule}]`,
|
|
471
1111
|
...(resolvedTo ? { detail: `resolvedTo: ${resolvedTo}` } : {}),
|
|
@@ -514,6 +1154,10 @@ function scanDoc(cache, root, bundleDir, doc) {
|
|
|
514
1154
|
const sources = getValidSources(doc.frontmatter.parsed) ?? [];
|
|
515
1155
|
const docAbsPath = path.join(bundleDir, doc.relPath);
|
|
516
1156
|
const fullAtoms = [];
|
|
1157
|
+
// Char spans of every matched full citation, used to keep short-form
|
|
1158
|
+
// matching (see collectShortFormMatches) from re-matching the tail of a
|
|
1159
|
+
// real `path:N-M` citation as a bare short form.
|
|
1160
|
+
const fullSpans = [];
|
|
517
1161
|
const re = new RegExp(CITATION_RE.source, "g");
|
|
518
1162
|
let m;
|
|
519
1163
|
while ((m = re.exec(content)) !== null) {
|
|
@@ -525,7 +1169,9 @@ function scanDoc(cache, root, bundleDir, doc) {
|
|
|
525
1169
|
citedPath: m[1],
|
|
526
1170
|
startLine: Number(m[2]),
|
|
527
1171
|
endLine: m[3] ? Number(m[3]) : null,
|
|
1172
|
+
anchor: parseAnchor(m[4]),
|
|
528
1173
|
});
|
|
1174
|
+
fullSpans.push([m.index, m.index + m[0].length]);
|
|
529
1175
|
}
|
|
530
1176
|
const atoms = [...fullAtoms, ...collectContinuationAtoms(content)].sort((a, b) => a.index - b.index);
|
|
531
1177
|
// `governing`: nearest preceding citation (full or continuation) that
|
|
@@ -564,7 +1210,7 @@ function scanDoc(cache, root, bundleDir, doc) {
|
|
|
564
1210
|
lastStartLine = startLine;
|
|
565
1211
|
continue; // governing (same file) carries over unchanged
|
|
566
1212
|
}
|
|
567
|
-
const { citedPath, startLine, endLine } = atom;
|
|
1213
|
+
const { citedPath, startLine, endLine, anchor } = atom;
|
|
568
1214
|
const citation = `${citedPath}:${startLine}${endLine ? "-" + endLine : ""}`;
|
|
569
1215
|
if (hasParentSegment(citedPath)) {
|
|
570
1216
|
pushDrift(findings, doc.relPath, citation, "path-traversal-rejected", `citedPath contains a ".." segment and was rejected without resolving: ${citedPath}`);
|
|
@@ -590,7 +1236,7 @@ function scanDoc(cache, root, bundleDir, doc) {
|
|
|
590
1236
|
lastStartLine = null;
|
|
591
1237
|
continue;
|
|
592
1238
|
}
|
|
593
|
-
const problem =
|
|
1239
|
+
const problem = checkFullTarget(citedPath, startLine, endLine, resolution.path, anchor);
|
|
594
1240
|
if (problem?.rule === "unreadable-target") {
|
|
595
1241
|
pushUnreadable(findings, doc.relPath, citation, path.relative(root, resolution.path), problem.code ?? "UNKNOWN");
|
|
596
1242
|
}
|
|
@@ -600,6 +1246,70 @@ function scanDoc(cache, root, bundleDir, doc) {
|
|
|
600
1246
|
governing = { citedPath, resolvedPath: resolution.path };
|
|
601
1247
|
lastStartLine = startLine;
|
|
602
1248
|
}
|
|
1249
|
+
// Short-form (paragraph-bound) citations -- see that doc block above.
|
|
1250
|
+
// Deliberately independent of `governing`/`lastStartLine`: short-form
|
|
1251
|
+
// binding is paragraph-scoped by design, not chained through the
|
|
1252
|
+
// document-wide continuation state machine above. Reserved files
|
|
1253
|
+
// (index.md, log.md, see doc.isReserved) are skipped entirely: they are
|
|
1254
|
+
// append-only narrative journals, not `sources:`-driven reference docs,
|
|
1255
|
+
// and routinely narrate historical "old N-M -> new X-Y" line-number
|
|
1256
|
+
// deltas as prose data about past changes -- not live citations against
|
|
1257
|
+
// current content -- which this rule's bare-range matching cannot tell
|
|
1258
|
+
// apart from a real short-form citation. Full/continuation citations in
|
|
1259
|
+
// reserved files are still scanned as before; this carve-out is scoped
|
|
1260
|
+
// to short-form matching only.
|
|
1261
|
+
const shortFormMatches = doc.isReserved
|
|
1262
|
+
? []
|
|
1263
|
+
: collectShortFormMatches(content, [
|
|
1264
|
+
...fullSpans,
|
|
1265
|
+
...computeExcludedSpans(content),
|
|
1266
|
+
]);
|
|
1267
|
+
if (shortFormMatches.length > 0) {
|
|
1268
|
+
const paragraphStarts = computeParagraphStarts(content);
|
|
1269
|
+
const namedFullAtoms = [];
|
|
1270
|
+
for (const a of fullAtoms) {
|
|
1271
|
+
if (a.kind === "full") {
|
|
1272
|
+
namedFullAtoms.push({
|
|
1273
|
+
index: a.index,
|
|
1274
|
+
citedPath: a.citedPath,
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
for (const sf of shortFormMatches) {
|
|
1279
|
+
const paragraphStart = paragraphStartFor(paragraphStarts, sf.index);
|
|
1280
|
+
const target = findLastNamedTargetInParagraph(namedFullAtoms, paragraphStart, sf.index);
|
|
1281
|
+
const rangeLabel = `${sf.startLine}-${sf.endLine}`;
|
|
1282
|
+
if (!target) {
|
|
1283
|
+
pushDrift(findings, doc.relPath, `${rangeLabel} (short-form)`, "short-form-unbound", "no full `path:N` citation earlier in this paragraph to bind to", undefined, "notice");
|
|
1284
|
+
continue;
|
|
1285
|
+
}
|
|
1286
|
+
const targetPath = target.citedPath;
|
|
1287
|
+
const citation = `${targetPath}:${rangeLabel} (short-form)`;
|
|
1288
|
+
if (hasParentSegment(targetPath)) {
|
|
1289
|
+
// The full citation that named this target already reported
|
|
1290
|
+
// path-traversal-rejected for itself; not re-flagged a second time.
|
|
1291
|
+
continue;
|
|
1292
|
+
}
|
|
1293
|
+
const resolution = resolveCitation(cache, root, docAbsPath, content, sources, targetPath, sf.index);
|
|
1294
|
+
if (!resolution) {
|
|
1295
|
+
pushDrift(findings, doc.relPath, citation, "missing-file", `could not resolve ${targetPath}: tried doc sources, ancestor climb (bare filenames only), repo-root, doc-relative, nearest prior qualified mention, repo-wide search; no candidate file exists`);
|
|
1296
|
+
continue;
|
|
1297
|
+
}
|
|
1298
|
+
if ("skip" in resolution)
|
|
1299
|
+
continue;
|
|
1300
|
+
if ("ambiguous" in resolution) {
|
|
1301
|
+
pushAmbiguous(findings, doc.relPath, citation, resolution.candidates);
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
const problem = checkShortFormTarget(targetPath, sf.startLine, sf.endLine, resolution.path);
|
|
1305
|
+
if (problem?.rule === "unreadable-target") {
|
|
1306
|
+
pushUnreadable(findings, doc.relPath, citation, path.relative(root, resolution.path), problem.code ?? "UNKNOWN");
|
|
1307
|
+
}
|
|
1308
|
+
else if (problem) {
|
|
1309
|
+
pushDrift(findings, doc.relPath, citation, problem.rule, problem.message, path.relative(root, resolution.path), problem.severity);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
603
1313
|
return findings;
|
|
604
1314
|
}
|
|
605
1315
|
export const citationsResolveRule = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"citations-resolve.js","sourceRoot":"","sources":["../../src/rules/citations-resolve.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"citations-resolve.js","sourceRoot":"","sources":["../../src/rules/citations-resolve.ts"],"names":[],"mappings":"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"}
|