Docs: VuePress plugin to strip [V<n>] citation markers and §Sources footers at build#1679
Docs: VuePress plugin to strip [V<n>] citation markers and §Sources footers at build#1679marcin-kordas-hoc wants to merge 5 commits into
Conversation
…ooters at build
Internal authoring uses an audit-harness convention where factual claims
are annotated with inline `[V<n>]` markers and pages carry a trailing
`§ Sources` footer. These annotations let the audit-harness re-verify
every claim before content ships - they are never meant for end users.
When any annotated spec or note ends up published as docs, the markers
must not leak into the rendered site. This adds a small markdown-it
plugin (~120 LOC) wired into the existing `extendMarkdown` hook in
`docs/.vuepress/config.js`. It walks the token stream and:
- Removes inline `[V<n>]` markers (only the bare form; real markdown
links like `[V12](url)` are preserved).
- Removes the `Sources` / `§ Sources` heading and everything below it
up to the next top-level (`h1`) heading.
- Leaves `code_inline`, `code_block` and `fence` tokens untouched so
docs that document the audit-harness syntax itself still render
correctly.
Verified by:
- A standalone Node test
(`docs/.vuepress/plugins/strip-citation-markers/test.js`) covering
six assertions against
`docs/.vuepress/plugins/strip-citation-markers/test-fixture.md`.
- A full `vuepress build docs` run with the fixture temporarily placed
under `docs/guide/`; grep of `docs/.vuepress/dist` confirmed zero
`[V<n>]` markers outside `<code>`/`<pre>` blocks and zero `§Sources`
occurrences in rendered HTML.
✅ Deploy Preview for hyperformula-dev-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for hyperformula-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Performance comparison of head (01a3e9b) vs base (508d78f) |
…st §Sources splice Bugbot #3297000925 caught that `transformTokens` in the strip-citation-markers plugin spliced from a `§ Sources` heading all the way to either the next h1 or end-of-stream. Because `config.js` also registers `markdown-it-footnote`, which appends `footnote_block` / `footnote_anchor` / `footnote_open` / `footnote_close` / `footnote_ref` tokens at the END of the token stream, a page that ended with a Sources footer AND had footnote references would silently lose its footnotes. `findFooterEnd` now also stops at the first token whose type starts with `footnote_`, so footnote tokens always survive the splice. Added one synthetic token-stream assertion and one full-pipeline assertion (running markdown-it with markdown-it-footnote AND the strip plugin) to lock the invariant in.
…markdown-it-footnote ordering Tier 2 hardening for the strip-citation-markers plugin (#1679). Mutation testing (manual analysis, 50% baseline score) flagged 5 surviving mutants. Five new assertions added to test.js (10 -> 15 total): - M1: zero-digit '[V]' must NOT be stripped (regex requires \d+) - M2: link text 'V12' anchored so removing the (?!\() lookahead is caught - M3: lowercase '## sources' heading must also be stripped (i flag) - M5: h1 boundary in findFooterEnd respected (h2 -> h1 mutation no longer silent) - M11: double-space collapse after marker removal is verified SFDIPOT P0 finding: plugin-order coupling with markdown-it-footnote is load-bearing. Added test-plugin-order.js with 10 assertions covering: - Negative control (no footnote plugin): markers/footer still stripped, but no footnote anchor appears (locks the 'footnote tokens come from a separate plugin' assumption) - Positive control (config.js ordering): footnotes survive, markers and footer stripped - Rule-chain invariant: footnote_tail must appear BEFORE strip-citation-markers in md.core.ruler — this is the actual mechanism that makes the wiring work and the primitive that future refactors must preserve vuepress build verified clean.
Tier 2 hardening — mutation gaps + plugin-order lock-inFollow-up to address two QE findings from the Tier 1 review. Mutation testing (50% -> closed)Manual mutation analysis of the strip plugin (
SFDIPOT P0 — plugin-order couplingThe strip plugin's
Why option (A) and not (B)Considered an assertion inside the plugin's Verification
Commit: 4f0d2e7 |
…n match Bugbot flagged that `isSourcesHeading` tested the strict end-anchored SOURCES_HEADING_PATTERN against the raw heading inline content. Because footer detection runs before inline [V<n>] stripping, an authored heading like `§ Sources [V1]` failed the `\s*$` anchor and the Sources footer was never detected for such pages. Normalize the heading content via the existing pure `stripInlineMarkers` helper before the regex test. Add tests for both the Bugbot edge case (`§ Sources [V1]` heading) and a mutation-killer guarding that the plain `§ Sources` heading still triggers the strip.
… test fixture VuePress 1 does not recognise \`text\` as a valid Prism fence language. Replace with an unlabelled fence to avoid the I5 harness check failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1679 +/- ##
========================================
Coverage 97.16% 97.16%
========================================
Files 175 176 +1
Lines 15319 15322 +3
Branches 3356 3356
========================================
+ Hits 14884 14887 +3
Misses 427 427
Partials 8 8 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 01a3e9b. Configure here.
|
|
||
| // 2. §Sources footer must be gone. | ||
| assert( | ||
| !/Sources/i.test(renderedWithoutCode) || !/source-1/.test(rendered), |
There was a problem hiding this comment.
Test assertion uses OR instead of AND
Medium Severity
The assertion on line 48 uses || (OR) between the two conditions, but the intent is to verify that both the Sources heading text and the source-1 footer body URL are removed. With ||, the assertion passes even if only one condition is met — for example, the heading could leak into the rendered output as long as source-1 is absent, or vice versa. This weakens the test and could mask regressions where the footer is only partially stripped. The operator needs to be &&.
Reviewed by Cursor Bugbot for commit 01a3e9b. Configure here.


Summary
Adds a small markdown-it plugin (~165 LOC) wired into the existing
extendMarkdownhook indocs/.vuepress/config.jsthat strips internal audit-harness annotations at build time so they never appear in customer-facing docs.Why
Internal authoring uses an audit-harness convention: factual claims are annotated inline with
[V<n>]markers, and pages carry a trailing§ Sourcesfooter that lists the underlying sources. These exist so the audit-harness can re-verify every claim before content ships - they are never meant for end users. When any annotated spec or note ends up published as docs, the markers must not leak into the rendered site.What it does
[V<n>]markers (only the bare form; real markdown links like[V12](url)are preserved).Sources/§ Sourcesheading and everything below it up to the next top-level (h1) heading.code_inline,code_blockandfencetokens untouched so pages that document the audit-harness syntax itself still render correctly.Files
docs/.vuepress/plugins/strip-citation-markers/index.js(plugin, ~165 LOC)docs/.vuepress/plugins/strip-citation-markers/test-fixture.md(fixture)docs/.vuepress/plugins/strip-citation-markers/test.js(Node test, 20 assertions)docs/.vuepress/plugins/strip-citation-markers/test-plugin-order.js(plugin-order integration test)docs/.vuepress/config.js(wire-up: 2 lines)Test plan
node docs/.vuepress/plugins/strip-citation-markers/test.js->PASS strip-citation-markers (20 assertions)vuepress build docswith the fixture temporarily placed underdocs/guide/; grep ofdocs/.vuepress/distconfirms:[V<n>]markers outside<code>/<pre>blocks in rendered HTML§Sourcesoccurrences[V12](url)rendered as a real link`[V99]`and fenced[V7]preservednpm run docs:build, and confirming the body text is cleanNote
Low Risk
Docs-only markdown transform with tests; main risk is mis-stripping footers or links if plugin order or regex rules change.
Overview
Adds a markdown-it plugin wired in
docs/.vuepress/config.jsso customer-facing docs never show internal audit-harness markup.At build time it removes bare inline
[V<n>]citation markers (with light whitespace cleanup), drops theSources/§ Sourcessection through the nexth1or before footnote tokens, and leaves real[Vn](url)links and code blocks untouched. The plugin hooks beforereplacementsso heading anchors see cleaned text.Standalone Node tests cover rendering edge cases, footnote + footer interaction, and
footnote_tailvsstrip-citation-markersrule order to match the VuePress plugin stack.Reviewed by Cursor Bugbot for commit 01a3e9b. Bugbot is set up for automated code reviews on this repo. Configure here.