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 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 baked into the templates
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.5.0 check path/to/bundle
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
- const CITATION_RE = /([\w./-]+\.(?:ts|js|mjs|md|yml|yaml|json)):(\d+)(?:-(\d+))?/g;
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
- function checkTarget(citedPath, startLine, endLine, resolvedPath) {
371
- const read = readTarget(resolvedPath);
372
- if ("rule" in read)
373
- return read;
374
- const content = read.content;
375
- const lines = splitLines(content);
376
- const lineCount = lines.length;
377
- const bound = checkRangeBound(startLine, endLine, lineCount);
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
- function pushDrift(findings, file, citation, rule, message, resolvedTo) {
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: "warning",
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 = checkTarget(citedPath, startLine, endLine, resolution.path);
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okf-kit",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "CLI that validates OKF v0.1 knowledge bundles for structural correctness",
5
5
  "type": "module",
6
6
  "bin": {