Skip to content

Fix/remove boilerplate crossref rule - #1365

Merged
jth-nw merged 15 commits into
devfrom
fix/remove-boilerplate-crossref-rule
Aug 14, 2026
Merged

Fix/remove boilerplate crossref rule#1365
jth-nw merged 15 commits into
devfrom
fix/remove-boilerplate-crossref-rule

Conversation

@jth-nw

Copy link
Copy Markdown
Collaborator

No description provided.

jth-nwand others added 2 commits August 11, 2026 12:06
BoilerplateCrossRef flagged the literal phrase "for more information,"
contradicting the style guide's own cross-reference example and firing
on 1,136 pre-existing, unaddressed instances. Its Phase 2 auto-fix path
is also what introduced a broken anchor into
docs/accessanalyzer/2601/install/install-commands.md: the AI rewriter
pattern-matched heading-like text inside a fenced code block (simulated
installer output) and linked to it as if it were a real heading.
Also have the Phase 2/3 auto-fix prompts verify any anchor they add or
change against scripts/check-anchors.sh before finishing, so a similar
mistake by a different rule can't slip through the same way.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The anchor pointed at a fake heading (`## Required Actions`) inside a
fenced code block simulating installer summary output — never a real
heading, so it never resolved. Point at the interactive Bind Password
prompt in quickinstall.md's Step 4 instead, the only place password
entry is actually documented; the note's "piped stdin" claim isn't
documented anywhere currently, so the link no longer overpromises.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jth-nw
jth-nw requested a review from a team as a code ownerAugust 11, 2026 17:23
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

3 issues fixed, 5 skipped across 1 files

CategoryFixes
Dale: passive-voice1
Dale: wordiness2
Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:114 — Dale: xy-slop | "the installer doesn't honor it — the installer always reads the bind password via an interactive prompt or piped stdin" resembles the negative-positive form, but the negation carries load-bearing technical information (the exported value is overwritten). Any rewrite risked losing that warning. |
| docs/accessanalyzer/2601/install/install-commands.md:269 — Dale: passive-voice | "the k3s paths listed in the warning output" is a reduced relative clause used attributively; the active rewrite ("the k3s paths the warning output lists") is more awkward than the original. |
| docs/accessanalyzer/2601/install/install-commands.md:30 — Dale: wordiness | "This is appropriate for initial deployments and when you want to install the latest release" has a parallelism mismatch, but every concise rewrite either shifted the meaning of "appropriate" or made the sentence circular (omitting the version already means latest). |
| docs/accessanalyzer/2601/install/install-commands.md:80 — Dale: wordiness | The trailing clause "to control when upgrades happen during your organization's patching cycle" duplicates line 49 verbatim, but trimming it deletes content rather than tightening the sentence — an editorial call outside a confident Dale fix. |
| docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: passive-voice | "Terminal progress output isn't affected" is passive, but it sits inside the HTML comment block (lines 130-197) that is not rendered. |

Ask @claude on this PR if you'd like an explanation of any fix.

The Phase 2/3 auto-fix prompts instruct Claude to run
`bash scripts/check-anchors.sh <file>` before finishing, but both
steps' claude_args only allowlist Bash(git:*) — the check would be
silently denied in headless CI, exactly the failure mode this branch
is meant to close. Add Bash(bash scripts/check-anchors.sh:*) to both.
Also correct docs/CLAUDE.md's stale "30 Netwrix-specific rules" count
to 43, the current number of files in .vale/styles/Netwrix/.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

2 issues fixed, 4 skipped across 1 files

CategoryFixes
Dale: wordiness2
Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: passive-voice | 'Terminal progress output isn't affected' is passive, but the line sits inside the commented-out block (lines 130-197) and is not rendered; left the hidden draft content untouched |
| docs/accessanalyzer/2601/install/install-commands.md:114 — Dale: wordiness | 'the installer doesn't honor it — the installer always reads the bind password' repeats the subject, but collapsing the second 'the installer' to 'it' would create an ambiguous pronoun (LDAP_BIND_PASSWORD vs. the installer) |
| docs/accessanalyzer/2601/install/install-commands.md:80 — Dale: wordiness | Restates the pinning rationale already given at line 49, but trimming the trailing clause would drop the rationale from a sentence that stands on its own in the table's summary position |
| docs/accessanalyzer/2601/install/install-commands.md:246 — Dale: passive-voice | 'Known antivirus software detected' and 'No clock sync daemon detected' are passive fragments, but they are terse table cells naming preflight check results; rewriting to active voice would make the table columns inconsistent and harder to scan |

Ask @claude on this PR if you'd like an explanation of any fix.

- Remove BoilerplateCrossRef from vale-rule-writer's existing-rules
list (was risking false-duplicate rejection of a future rule) and
from kb-pr-review's fix guidance (the rule never even existed in
the NetwrixKB style set this skill covers).
- Fix CONTRIBUTING.md's rule count, stale at 30, to match the actual
43 files in .vale/styles/Netwrix/.
- Broaden the check-anchors.sh allowlist to cover ./scripts/... and
bare scripts/... invocations, and tell the agent explicitly to use
the one literal, unchained form — the exact-prefix Bash(cmd:*)
matching means any other invocation shape is silently denied.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

1 issues fixed, 5 skipped across 1 files

CategoryFixes
Dale: xy-slop1
Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:80 — Dale: wordiness | This paragraph restates the pinning guidance already given at line 49, but it also serves as the summary for the version-strings table directly preceding it. Removing or condensing it could drop guidance the author intended to repeat as a table takeaway. |
| docs/accessanalyzer/2601/install/install-commands.md:77 — Dale: passive-voice | "Pinned to exactly 1.0.8" is a table-cell fragment describing a state, not a sentence; rewriting to active voice would make the cell wordier without improving clarity. |
| docs/accessanalyzer/2601/install/install-commands.md:246 — Dale: passive-voice | "Known antivirus software detected" and similar preflight-result cells are status labels that mirror the installer's own output; rewording could misrepresent the literal strings users see. |
| docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: xy-slop | "Terminal progress output isn't affected — only the log file verbosity changes" sits inside the HIDDEN HTML comment block (lines 130-197), which is not rendered content. |
| docs/accessanalyzer/2601/install/install-commands.md:256 — Dale: wordiness | "You may know the warning is acceptable for your environment" could be folded into the following sentence as a conditional, but doing so would change the hedged permission into a stronger instruction. |

Ask @claude on this PR if you'd like an explanation of any fix.

…-crossref-rule
# Conflicts:
#	docs/accessanalyzer/2601/install/install-commands.md
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

1 issues fixed, 3 skipped across 1 files

CategoryFixes
Dale: wordiness1
Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:269 — Dale: passive-voice | "the k3s paths listed in the warning output" is a reduced relative clause; active rewrites are noticeably clunkier in a table cell |
| docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: passive-voice | "Terminal progress output isn't affected" sits inside a HIDDEN HTML comment block, so it is not rendered content |
| docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: xy-slop | "isn't affected — only the log file verbosity changes" is inside the HIDDEN HTML comment block; not rendered content |

Ask @claude on this PR if you'd like an explanation of any fix.

@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

1 issues fixed, 5 skipped across 1 files

CategoryFixes
Dale: passive-voice1
Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:243 — Dale: passive-voice | "Not loaded" is a terse table-cell condition fragment in the preflight check table, not a prose clause; rewriting it as active voice would break the table's parallel condition format. |
| docs/accessanalyzer/2601/install/install-commands.md:246 — Dale: passive-voice | "Known antivirus software detected" is a terse table-cell condition fragment describing a warn state; rewriting it as a full active sentence would break parallelism with the other rows. |
| docs/accessanalyzer/2601/install/install-commands.md:266 — Dale: passive-voice | "Overlay kernel module not loaded" is a table-cell warning label that mirrors the installer's own output text; changing it could no longer match what the reader sees on screen. |
| docs/accessanalyzer/2601/install/install-commands.md:269 — Dale: passive-voice | "Antivirus software detected" is a table-cell warning label mirroring installer output; changing it could no longer match what the reader sees on screen. |
| docs/accessanalyzer/2601/install/install-commands.md:213 — Dale: undefined-acronyms | "DN" (distinguished name) is standard LDAP/Active Directory terminology for this sysadmin audience, and line 212 already spells out "distinguished name" in the adjacent row. |

Ask @claude on this PR if you'd like an explanation of any fix.

…-crossref-rule
# Conflicts:
#	.claude/skills/kb-pr-review/SKILL.md
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

0 issues fixed, 4 skipped across 1 files

Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:267 — Dale: undefined-acronyms | RHEL is a well-known Linux distribution abbreviation for a sysadmin audience, not a product-specific acronym — excluded by the rule. |
| docs/accessanalyzer/2601/install/install-commands.md:269 — Dale: passive-voice | 'the k3s paths listed in the warning output' is a reduced relative clause modifying a noun; rewriting to active voice would be more awkward and change emphasis. |
| docs/accessanalyzer/2601/install/install-commands.md:204 — Dale: passive-voice | '(recommended for most customers)' is an elliptical parenthetical; naming an agent would add words without improving clarity. |
| docs/accessanalyzer/2601/install/install-commands.md:130 — Dale: all | Lines 130-197 are inside an HTML comment (HIDDEN block) and are not rendered content; left untouched. |

Ask @claude on this PR if you'd like an explanation of any fix.

…anchor-fix instruction
kb-pr-open/SKILL.md carried the same stale BoilerplateCrossRef sentence
already fixed in kb-pr-review/SKILL.md. vale-autofix.yml's anchor
paragraph told the agent to hand-fix any broken anchor in a touched
file, which conflicts with the automated heading-rename remap in the
Fix heading anchors step — scoped it to anchors the agent's own edit
introduced.
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

1 issues fixed, 4 skipped across 1 files

CategoryFixes
Dale: passive-voice1
Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:269 — Dale: passive-voice | "the k3s paths listed in the warning output" is a reduced passive relative clause. Common, idiomatic technical usage; rewriting to an active clause ("the k3s paths that the warning output lists") reads worse, and dropping "listed" risks implying the paths are the output rather than named in it. |
| docs/accessanalyzer/2601/install/install-commands.md:256 — Dale: wordiness | "You may know the warning is acceptable for your environment." could merge into the following sentence as a conditional, but "You may know" vs. "If you know" carries a different epistemic hedge — not confident the merge preserves the author's intent. |
| docs/accessanalyzer/2601/install/install-commands.md:127 — Dale: misplaced-modifiers | "depending on network speed and hardware" is a technically dangling participle, but it is standard accepted usage and any rewrite would be more awkward without improving clarity. |
| docs/accessanalyzer/2601/install/install-commands.md:130 — Dale: all | Lines 130-197 are inside an HTML comment block () and do not render. Left unedited; no violations identified there in any case. |

Ask @claude on this PR if you'd like an explanation of any fix.

@github-actions

Copy link
Copy Markdown
Contributor

Documentation PR Review

Editorial Review

docs/accessanalyzer/2601/install/install-commands.md

  • Clarity — Line 49: The reworded sentence now states the recommendation unconditionally ("Netwrix recommends pinning to a specific release to control when upgrades happen..."), where the previous wording conditioned it on the reader wanting that control. As written it contradicts line 30 ("appropriate for initial deployments and any time you want the latest release") and line 80 ("either omit this variable... or pin"), so the reader gets three different signals about what Netwrix actually recommends. Suggested fix: restore the condition — "If you need to control when upgrades happen during your organization's patching cycle, Netwrix recommends pinning to a specific release." — or make line 80 agree that pinning is the recommended default.

  • Completeness — Line 80: "For most deployments, either omit this variable to stay on the latest release or pin to a specific version, such as 1.0.8." The edit removed the reason for pinning ("to control when upgrades happen during your organization's patching cycle"), which was the only criterion the reader had for choosing between the two options. The sentence now presents a choice with no basis for making it. Suggested fix: "For most deployments, omit this variable to stay on the latest release. Pin to a specific version, such as 1.0.8, when you need to control upgrade timing during your organization's patching cycle."

  • Clarity — Line 80: "this variable" has no antecedent in the surrounding text. The paragraph above (line 72) says "Version strings," the table header says "Value," and TARGET_REVISION is named only inside the code block at line 56 — so a reader scanning the table and this paragraph never sees which variable to omit. Suggested fix: name it — "either omit TARGET_REVISION to stay on the latest release or..."

  • Completeness — Line 114: The note says the installer reads the password "from an interactive prompt or piped stdin," but the cross-reference now points to Quick Install — Step 4 "for the interactive prompt." The previous text pointed there "for the two supported ways to provide the password." Narrowing the pointer to one of the two methods leaves the reader who wants the piped-stdin approach with nowhere to go, and undersells what the destination actually covers. Suggested fix: "See Quick Install — Step 4 for both supported ways to provide the password."

  • Clarity — Line 256: "You may know the warning is acceptable for your environment." Dropping "In some cases" turned a conditional aside into a flat assertion about the reader, which reads as though the doc is telling them what they know. It also no longer connects to the following sentence as a condition for using the flag. Suggested fix: fold it into the instruction — "If you have confirmed the warning is acceptable for your environment, use --accept-warnings to allow installation to continue:"

  • Clarity — Line 30: "This is appropriate for initial deployments and any time you want the latest release" is circular — the preceding sentence already says omitting the version downloads the latest stable release, so the second clause restates the premise as a reason. Suggested fix: tie it to a real condition the reader can evaluate, for example "This is appropriate for initial deployments and for environments where automatic upgrades within the 1.x line are acceptable." This also connects the paragraph to the behavior table at lines 74–78.

  • Clarity — Line 84: "see the Quick Install for an end-to-end example" — "the Quick Install" reads as a fragment because the article is a page title, not a noun phrase. Suggested fix: "see Quick Install for an end-to-end example" or "see the Quick Install guide for an end-to-end example."

Summary

7 editorial suggestions across 1 file. Vale and Dale issues are auto-fixed separately.

Note: this PR also changes files outside docs/ (Vale rule set, workflow config, and .claude/ skill and reference files) and docs/CLAUDE.md/CONTRIBUTING.md. Those are not part of the editorial review scope.


What to do next:

Comment @claude on this PR followed by your instructions to get help:

  • @claude fix all issues — fix all editorial issues
  • @claude help improve the flow of this document — get writing assistance
  • @claude explain the voice issues — understand why something was flagged

You can ask Claude anything about the review or about Netwrix writing standards.

Automated fixes are only available for branches in this repository, not forks.

@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

0 issues fixed, 3 skipped across 1 files

Skipped (needs manual review)Reason

| docs/accessanalyzer/2601/install/install-commands.md:246 — Dale: passive-voice | "Known antivirus software detected" is a reduced passive, but it is a terse condition label in the Warn column of the preflight table. Every other cell in that column is a parallel noun phrase ("Not loaded", "SELinux in enforcing mode"), and these labels mirror the installer's own output. Rewriting to active voice would break the column's parallel structure and the correspondence with what users see on screen. |
| docs/accessanalyzer/2601/install/install-commands.md:248 — Dale: passive-voice | "No clock sync daemon detected" is the same case as line 246 — a terse, parallel condition label in the preflight table that matches installer output text, not body prose. |
| docs/accessanalyzer/2601/install/install-commands.md:256 — Dale: wordiness | "You may know the warning is acceptable for your environment." reads as a standalone assertion where a condition is intended, and could fold into the next sentence. At 10 words it is not actually wordy, and merging it changes the author's sentence structure on a judgment call rather than a clear rule violation, so left as written. |

Ask @claude on this PR if you'd like an explanation of any fix.

@github-actions

Copy link
Copy Markdown
Contributor

Code Review

No blocking correctness issues. The change set is coherent: the Vale rule file is deleted, and every reference to it is removed in the same PR. Details of what I verified, plus one minor caveat.

Verified

  • No lingering BoilerplateCrossRef references.git grep -i BoilerplateCrossRef against the PR head returns nothing — no leftovers in .vale.ini, scripts/vale-autofix.sh (Phase 1 mechanical fixer), workflows, skills, or agents. The rule was only ever in .vale/styles/Netwrix/, never NetwrixKB/, so KB scope is unaffected.
  • Rule count is accurate..vale/styles/Netwrix/ contains exactly 43 .yml rules after the deletion, matching the updated counts in CONTRIBUTING.md:95 and docs/CLAUDE.md:69. Those were the only two places carrying a count.
  • --allowedTools additions work. All three permitted forms are viable: scripts/check-anchors.sh is committed mode 100755, so ./scripts/check-anchors.sh and scripts/check-anchors.sh execute even though the workflow's chmod +x doesn't run until the later "Check anchor links" step, and the bash scripts/... form the prompt actually recommends needs no exec bit. The script's only external deps (perl, realpath, bash 4 mapfile) are present on ubuntu-latest.
  • No workflow trigger/permission/secret changes.vale-autofix.yml only gains prompt text and two claude_args tool patterns. Triggers, permissions:, VALE_TOKEN/ANTHROPIC_API_KEY usage, and both phases' continue-on-error: true are untouched, so a denied or failing script call can't fail the job.
  • No routing/build surface touched — nothing in products.js, docusaurus.config.js, sidebars/, or the KB copy pipeline.
  • Anchor in the edited doc still resolves.install-commands.md keeps quickinstall.md#step-4-run-the-installer, and quickinstall.md:267 is ### Step 4: Run the installer → slug step-4-run-the-installer.

Minor — the new instruction over-promises what check-anchors.sh validates

Both new prompt paragraphs (vale-autofix.yml:172 and :217) present bash scripts/check-anchors.sh <file> as the gate for a newly added #anchor. The script only validates anchors on relative .md/.mdx links. In scripts/check-anchors.sh:136-149, a target that does not exist on disk is reported only if its path ends in .md/.mdx, and it continues before the anchor check at line 152 either way. So a fix that adds a site-absolute Docusaurus link — [text](/docs/accessanalyzer/12_0/page#some-anchor), the dominant form in these docs — resolves to <repo>/docs/accessanalyzer/12_0/page, which is not a file and not .md, and the script prints All anchor links valid. without ever checking #some-anchor. With onBrokenAnchors: 'throw' (docusaurus.config.js:75), that anchor still fails the production build.

This is pre-existing script behavior that the PR inherits rather than introduces (the existing "Check anchor links" step at line 242 has the same blind spot), so it is not a regression. But since the paragraph's purpose is to stop the agent from inventing anchors, it is worth either scoping the claim ("this check only covers relative .md links; for /docs/... links, confirm the heading by reading the target file") or teaching the script to map site-absolute paths back to source files.

Nit

The two added paragraphs are near-verbatim duplicates across Phase 2 and Phase 3, differing only in the parenthetical example. Fine as-is, just a spot where future edits can drift out of sync.

@jth-nw
jth-nw merged commit d411e8a into devAug 14, 2026
11 checks passed
@jth-nw
jth-nw deleted the fix/remove-boilerplate-crossref-rule branch August 14, 2026 18:12
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jth-nw