Skip to content

Fix/remove boilerplate crossref rule - #1365

Open
jth-nw wants to merge 11 commits into
devfrom
fix/remove-boilerplate-crossref-rule
Open

Fix/remove boilerplate crossref rule#1365
jth-nw wants to merge 11 commits into
devfrom
fix/remove-boilerplate-crossref-rule

Conversation

@jth-nw

@jth-nw jth-nw commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

jth-nw and 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 owner August 11, 2026 17:23
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

3 issues fixed, 5 skipped across 1 files

Category Fixes
Dale: passive-voice 1
Dale: wordiness 2
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

Category Fixes
Dale: wordiness 2
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

Category Fixes
Dale: xy-slop 1
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

Category Fixes
Dale: wordiness 1
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

Documentation PR Review

Editorial Review

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

  • Clarity — Line 49: The rewrite turned a conditional recommendation into an unconditional one, which now contradicts the rest of the section. Line 49 reads "Netwrix recommends pinning to a specific release to control when upgrades happen," but line 30 says omitting the version "is appropriate for initial deployments and any time you want the latest release," and line 80 presents both options as equally valid ("either omit this variable to stay on the latest release or pin to a specific version"). A reader following the section top to bottom gets told to omit, then that Netwrix recommends pinning, then that either is fine. Suggested fix: restore the conditional framing so the recommendation applies to a situation rather than to everyone — "Netwrix recommends pinning to a specific release when you need to control when upgrades happen during your organization's patching cycle."

  • Completeness — Line 114: The note states the installer reads the bind password "from an interactive prompt or piped stdin," but the cross-reference now points to Step 4 only "for the interactive prompt." Quick Install Step 4 (quickinstall.md:267) documents only the interactive wizard prompt — piped stdin appears nowhere in it. The reader who wants to script the install is told piped stdin is supported and then given a link that explicitly won't cover it, with no other pointer. Suggested fix: either restore a reference that covers both methods — "See Quick Install — Step 4 for the interactive prompt, and pipe the password to dspm-installer on stdin for unattended installs." — or add a short piped-stdin example here so the second method is documented somewhere.

  • Clarity — Line 256: Dropping "In some cases" left a bare assertion about the reader — "You may know the warning is acceptable for your environment." — sitting between two sentences it no longer connects. As written it tells the reader what they know instead of stating a condition. Suggested fix: fold it into the following sentence as a condition — "By default, the installer stops when it detects a preflight warning. If you determine 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 — omitting the version is being justified by the outcome it produces, so the second half tells the reader nothing new. Suggested fix: give the second case substance or drop it — "This is appropriate for initial deployments and for test environments that should track the latest release."

  • Clarity — Line 80: "either omit this variable" doesn't name the variable anywhere in the surrounding prose. TARGET_REVISION appears only inside the code block at line 56 and in the Environment Variables table further down, so a reader who lands on the version-strings table from the sidebar or a search result has no way to tell which variable to omit. Suggested fix: name it — "For most deployments, either omit TARGET_REVISION to stay on the latest release or pin to a specific version, such as 1.0.8."

Summary

5 editorial suggestions across 1 file. The other files in this PR (.claude/, .github/, .vale/, CONTRIBUTING.md, docs/CLAUDE.md) are tooling and contributor-guide changes, not product documentation, so they were not editorially reviewed. Vale and Dale issues are auto-fixed separately.


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

1 issues fixed, 5 skipped across 1 files

Category Fixes
Dale: passive-voice 1
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.

@github-actions

Copy link
Copy Markdown
Contributor

Code Review

Scope: correctness only (bugs, side effects, security, build/routing, scripts, workflows). Content and style are left to the editorial workflow.

The Vale rule removal is clean, and the workflow change is directionally right. Two issues in the new Phase 2/Phase 3 prompt text, plus two stale-reference nits.

1. The new anchor instruction contradicts the line directly above it (.github/workflows/vale-autofix.yml:170-172, 215-217)

Each phase now says both:

Note: if your fixes change any heading text, do not update anchor links — the workflow repairs all anchor links automatically after all fixes are complete.

…if it reports a broken anchor, find the correct heading … and fix it

When a Vale/Dale fix rewrites a heading (question headings, casing, and wordiness rules all do this), scripts/check-anchors.sh reports the now-stale in-file anchors pointing at the old slug. At that point the two instructions point in opposite directions, and the model's choice is arbitrary. The downstream Fix heading anchors step (:240, vale-autofix.sh --anchors-only origin/dev) then does its own heading-diff → product-folder-wide sed pass.

Concrete divergence: the two scripts slugify differently. check-anchors.sh:41-50 deliberately mirrors github-slugger (hyphen runs not collapsed — ## Step 4 — Configurestep-4--configure), while vale-autofix.sh:20-26 collapses and trims (step-4-configure). So if the agent hand-fixes the anchor in the touched file from the Available: list while --anchors-only rewrites the same slug in sibling files, the two ends of the same link set disagree — and the collapsed form is the wrong one for Docusaurus.

Suggested fix: scope the new instruction to anchors the agent itself introduced in this run, and keep the carve-out that heading-rename fallout belongs to the later step. For example: "…only for #anchor links you add or change; do not repair anchors that broke because you renamed a heading."

2. check-anchors.sh reports file-wide findings, but the prompt reads as if they are all the agent's (:172, :217)

"run bash scripts/check-anchors.sh <file> … on every file you touched; if it reports a broken anchor … fix it" gives the agent no way to separate its own breakage from what was already there. The script checks every link in the file and exits 1:

  • Pre-existing broken anchors elsewhere in the file get pulled in, expanding the diff beyond the Vale/Dale scope and landing under the fix(vale): auto-fix style issues (Vale + Dale) commit — silently, since both phases are continue-on-error: true.
  • Missing-file errors (check-anchors.sh:136-149, emitted for any unresolvable .md target) are not anchor problems at all, so "find the correct heading" has no valid action. The escape hatch — "SKIP the violation" — does not map either: a pre-existing broken link corresponds to no Vale or Dale violation and has no summary-JSON slot to be skipped into.

Worth adding: ignore findings on lines you did not touch, and treat a non-zero exit as informational unless it points at your own edit.

3. Stale reference to the deleted rule (.claude/skills/kb-pr-open/SKILL.md:71)

The deletion was propagated to vale-rule-writer.md, kb-pr-review/SKILL.md, and docs/CLAUDE.md, but kb-pr-open still says:

BoilerplateCrossRef is not part of NetwrixKB (it lives only in .vale/styles/Netwrix/), so it never fires on docs/kb/ files…

Harmless in effect (the guidance is "do not act on it"), but the parenthetical is now false. Same one-line removal as the others.

4. Adjacent, pre-existing: the rule inventory in vale-rule-writer.md is missing 12 rules

After removing the BoilerplateCrossRef bullet the list has 31 entries, but .vale/styles/Netwrix/ has 43 files — the number this PR correctly writes into CONTRIBUTING.md and docs/CLAUDE.md. Since the agent is told "Check all of them before writing a new rule to avoid duplication or conflict," a 12-rule gap undercuts that check. Not introduced here, but this PR edits that exact list and fixes the count in two other files, so it is a cheap one to close.

Verified clean

  • Rule deletion is config-safe. .vale.ini uses whole-style BasedOnStyles = Netwrix / NetwrixKB, so no per-rule config references the removed file, and nothing outside the four docs/skill files mentions it. WeakLinkText.yml and the Dale rules do not cover for more information, so the behavior is genuinely gone rather than half-removed.
  • Rule count 3043 is accurate and consistent across CONTRIBUTING.md and docs/CLAUDE.md.
  • allowedTools additions work. scripts/check-anchors.sh exists, takes one-or-more file args, and is committed 100755, so all three permitted invocation forms resolve (bash … does not need the exec bit anyway — note the workflow's own chmod +x at :247 runs after both phases). The entries are narrowly prefix-scoped to the one script rather than a blanket Bash, and the prompt's "no chaining with other commands" closes the obvious prefix-rule bypass. Triggers, permissions:, and secret usage (VALE_TOKEN / GITHUB_TOKEN / ANTHROPIC_API_KEY) are untouched.
  • No build or routing risk. No changes to products.js, docusaurus.config.js, sidebars, or copy-kb-to-versions.mjs. The one touched link in install-commands.md (quickinstall.md#step-4-run-the-installer) still resolves to ### Step 4: Run the installer (quickinstall.md:267).

Sign up for free to 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