@redocly/recheck 0.1.0 → 0.2.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/README.md +1006 -56
- package/dist/cli.js +27 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/markdoc-schema.d.ts +17 -0
- package/dist/commands/markdoc-schema.d.ts.map +1 -0
- package/dist/commands/markdoc-schema.js +127 -0
- package/dist/commands/markdoc-schema.js.map +1 -0
- package/dist/commands/run.d.ts +0 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +68 -5
- package/dist/commands/run.js.map +1 -1
- package/dist/config/load.d.ts +11 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +12 -2
- package/dist/config/load.js.map +1 -1
- package/dist/config/presets/google.d.ts +3 -0
- package/dist/config/presets/google.d.ts.map +1 -0
- package/dist/config/presets/google.js +1671 -0
- package/dist/config/presets/google.js.map +1 -0
- package/dist/config/presets/inclusive-language.d.ts +3 -0
- package/dist/config/presets/inclusive-language.d.ts.map +1 -0
- package/dist/config/presets/inclusive-language.js +321 -0
- package/dist/config/presets/inclusive-language.js.map +1 -0
- package/dist/config/presets/index.d.ts +67 -0
- package/dist/config/presets/index.d.ts.map +1 -0
- package/dist/config/presets/index.js +137 -0
- package/dist/config/presets/index.js.map +1 -0
- package/dist/config/presets/markdoc.d.ts +21 -0
- package/dist/config/presets/markdoc.d.ts.map +1 -0
- package/dist/config/presets/markdoc.js +101 -0
- package/dist/config/presets/markdoc.js.map +1 -0
- package/dist/config/presets/markdown-relaxed.d.ts +3 -0
- package/dist/config/presets/markdown-relaxed.d.ts.map +1 -0
- package/dist/config/presets/markdown-relaxed.js +98 -0
- package/dist/config/presets/markdown-relaxed.js.map +1 -0
- package/dist/config/presets/markdown.d.ts +43 -0
- package/dist/config/presets/markdown.d.ts.map +1 -0
- package/dist/config/presets/markdown.js +132 -0
- package/dist/config/presets/markdown.js.map +1 -0
- package/dist/config/presets/microsoft.d.ts +3 -0
- package/dist/config/presets/microsoft.d.ts.map +1 -0
- package/dist/config/presets/microsoft.js +2268 -0
- package/dist/config/presets/microsoft.js.map +1 -0
- package/dist/config/presets/minimal.d.ts +3 -0
- package/dist/config/presets/minimal.d.ts.map +1 -0
- package/dist/config/presets/minimal.js +21 -0
- package/dist/config/presets/minimal.js.map +1 -0
- package/dist/config/presets/plain-language.d.ts +3 -0
- package/dist/config/presets/plain-language.d.ts.map +1 -0
- package/dist/config/presets/plain-language.js +351 -0
- package/dist/config/presets/plain-language.js.map +1 -0
- package/dist/config/presets/prose.d.ts +52 -0
- package/dist/config/presets/prose.d.ts.map +1 -0
- package/dist/config/presets/prose.js +138 -0
- package/dist/config/presets/prose.js.map +1 -0
- package/dist/config/schema.d.ts +128 -22
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +105 -21
- package/dist/config/schema.js.map +1 -1
- package/dist/config/validate.d.ts +12 -2
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +1200 -44
- package/dist/config/validate.js.map +1 -1
- package/dist/core/auto-fix.d.ts +8 -13
- package/dist/core/auto-fix.d.ts.map +1 -1
- package/dist/core/auto-fix.js +94 -75
- package/dist/core/auto-fix.js.map +1 -1
- package/dist/core/case-preserve.d.ts +46 -0
- package/dist/core/case-preserve.d.ts.map +1 -0
- package/dist/core/case-preserve.js +57 -0
- package/dist/core/case-preserve.js.map +1 -0
- package/dist/core/directives.d.ts +9 -0
- package/dist/core/directives.d.ts.map +1 -0
- package/dist/core/directives.js +73 -0
- package/dist/core/directives.js.map +1 -0
- package/dist/core/files.d.ts +63 -0
- package/dist/core/files.d.ts.map +1 -1
- package/dist/core/files.js +185 -0
- package/dist/core/files.js.map +1 -1
- package/dist/core/inline-code.d.ts +87 -0
- package/dist/core/inline-code.d.ts.map +1 -0
- package/dist/core/inline-code.js +104 -0
- package/dist/core/inline-code.js.map +1 -0
- package/dist/core/line-endings.d.ts +32 -0
- package/dist/core/line-endings.d.ts.map +1 -0
- package/dist/core/line-endings.js +65 -0
- package/dist/core/line-endings.js.map +1 -0
- package/dist/core/markdoc-tags.d.ts +79 -0
- package/dist/core/markdoc-tags.d.ts.map +1 -0
- package/dist/core/markdoc-tags.js +131 -0
- package/dist/core/markdoc-tags.js.map +1 -0
- package/dist/core/runner.d.ts +92 -3
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +348 -110
- package/dist/core/runner.js.map +1 -1
- package/dist/core/timing.d.ts.map +1 -1
- package/dist/data/markdoc-realm-schema.d.ts +3 -0
- package/dist/data/markdoc-realm-schema.d.ts.map +1 -0
- package/dist/data/markdoc-realm-schema.js +760 -0
- package/dist/data/markdoc-realm-schema.js.map +1 -0
- package/dist/data/proper-nouns.d.ts +2 -0
- package/dist/data/proper-nouns.d.ts.map +1 -0
- package/dist/data/proper-nouns.js +208 -0
- package/dist/data/proper-nouns.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +152 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/formulas.d.ts +17 -0
- package/dist/metrics/formulas.d.ts.map +1 -0
- package/dist/metrics/formulas.js +70 -0
- package/dist/metrics/formulas.js.map +1 -0
- package/dist/metrics/index.d.ts +5 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +3 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/statistics.d.ts +27 -0
- package/dist/metrics/statistics.d.ts.map +1 -0
- package/dist/metrics/statistics.js +56 -0
- package/dist/metrics/statistics.js.map +1 -0
- package/dist/parser/index.d.ts +18 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +168 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/markdoc/extract-statics.d.ts +45 -0
- package/dist/parser/markdoc/extract-statics.d.ts.map +1 -0
- package/dist/parser/markdoc/extract-statics.js +139 -0
- package/dist/parser/markdoc/extract-statics.js.map +1 -0
- package/dist/parser/markdoc/pairing.d.ts +63 -0
- package/dist/parser/markdoc/pairing.d.ts.map +1 -0
- package/dist/parser/markdoc/pairing.js +94 -0
- package/dist/parser/markdoc/pairing.js.map +1 -0
- package/dist/parser/markdoc/schema.d.ts +85 -0
- package/dist/parser/markdoc/schema.d.ts.map +1 -0
- package/dist/parser/markdoc/schema.js +86 -0
- package/dist/parser/markdoc/schema.js.map +1 -0
- package/dist/parser/markdoc/span.d.ts +64 -0
- package/dist/parser/markdoc/span.d.ts.map +1 -0
- package/dist/parser/markdoc/span.js +729 -0
- package/dist/parser/markdoc/span.js.map +1 -0
- package/dist/parser/markdoc/structure.d.ts +28 -0
- package/dist/parser/markdoc/structure.d.ts.map +1 -0
- package/dist/parser/markdoc/structure.js +153 -0
- package/dist/parser/markdoc/structure.js.map +1 -0
- package/dist/parser/markdoc/syntax.d.ts +44 -0
- package/dist/parser/markdoc/syntax.d.ts.map +1 -0
- package/dist/parser/markdoc/syntax.js +317 -0
- package/dist/parser/markdoc/syntax.js.map +1 -0
- package/dist/parser/types.d.ts +18 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/reporter/fixes.d.ts.map +1 -1
- package/dist/reporter/fixes.js +22 -1
- package/dist/reporter/fixes.js.map +1 -1
- package/dist/reporter/statistics.d.ts +1 -8
- package/dist/reporter/statistics.d.ts.map +1 -1
- package/dist/reporter/statistics.js.map +1 -1
- package/dist/rules/registry.d.ts +15 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +81 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/rules/scope/capitalization.d.ts +3 -0
- package/dist/rules/scope/capitalization.d.ts.map +1 -0
- package/dist/rules/scope/capitalization.js +161 -0
- package/dist/rules/scope/capitalization.js.map +1 -0
- package/dist/rules/scope/conditional.d.ts +3 -0
- package/dist/rules/scope/conditional.d.ts.map +1 -0
- package/dist/rules/scope/conditional.js +112 -0
- package/dist/rules/scope/conditional.js.map +1 -0
- package/dist/rules/scope/consistency.d.ts +3 -0
- package/dist/rules/scope/consistency.d.ts.map +1 -0
- package/dist/rules/scope/consistency.js +178 -0
- package/dist/rules/scope/consistency.js.map +1 -0
- package/dist/rules/scope/length.d.ts +3 -0
- package/dist/rules/scope/length.d.ts.map +1 -0
- package/dist/rules/scope/length.js +69 -0
- package/dist/rules/scope/length.js.map +1 -0
- package/dist/rules/scope/max-image-size.d.ts +3 -0
- package/dist/rules/scope/max-image-size.d.ts.map +1 -0
- package/dist/rules/scope/max-image-size.js +65 -0
- package/dist/rules/scope/max-image-size.js.map +1 -0
- package/dist/rules/scope/metric.d.ts +17 -0
- package/dist/rules/scope/metric.d.ts.map +1 -0
- package/dist/rules/scope/metric.js +216 -0
- package/dist/rules/scope/metric.js.map +1 -0
- package/dist/rules/scope/occurrence.d.ts +3 -0
- package/dist/rules/scope/occurrence.d.ts.map +1 -0
- package/dist/rules/scope/occurrence.js +48 -0
- package/dist/rules/scope/occurrence.js.map +1 -0
- package/dist/rules/scope/pattern.d.ts +3 -0
- package/dist/rules/scope/pattern.d.ts.map +1 -0
- package/dist/rules/scope/pattern.js +75 -0
- package/dist/rules/scope/pattern.js.map +1 -0
- package/dist/rules/scope/repetition.d.ts +3 -0
- package/dist/rules/scope/repetition.d.ts.map +1 -0
- package/dist/rules/scope/repetition.js +139 -0
- package/dist/rules/scope/repetition.js.map +1 -0
- package/dist/rules/scope/semantic-line-breaks.d.ts +3 -0
- package/dist/rules/scope/semantic-line-breaks.d.ts.map +1 -0
- package/dist/rules/scope/semantic-line-breaks.js +213 -0
- package/dist/rules/scope/semantic-line-breaks.js.map +1 -0
- package/dist/rules/scope/spelling.d.ts +27 -0
- package/dist/rules/scope/spelling.d.ts.map +1 -0
- package/dist/rules/scope/spelling.js +227 -0
- package/dist/rules/scope/spelling.js.map +1 -0
- package/dist/rules/scope/swap.d.ts +3 -0
- package/dist/rules/scope/swap.d.ts.map +1 -0
- package/dist/rules/scope/swap.js +149 -0
- package/dist/rules/scope/swap.js.map +1 -0
- package/dist/rules/scope/title-case.d.ts +42 -0
- package/dist/rules/scope/title-case.d.ts.map +1 -0
- package/dist/rules/scope/title-case.js +264 -0
- package/dist/rules/scope/title-case.js.map +1 -0
- package/dist/rules/token/blanks-around-fences.d.ts +3 -0
- package/dist/rules/token/blanks-around-fences.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-fences.js +44 -0
- package/dist/rules/token/blanks-around-fences.js.map +1 -0
- package/dist/rules/token/blanks-around-headings.d.ts +3 -0
- package/dist/rules/token/blanks-around-headings.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-headings.js +108 -0
- package/dist/rules/token/blanks-around-headings.js.map +1 -0
- package/dist/rules/token/blanks-around-lists.d.ts +3 -0
- package/dist/rules/token/blanks-around-lists.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-lists.js +56 -0
- package/dist/rules/token/blanks-around-lists.js.map +1 -0
- package/dist/rules/token/blanks-around-tables.d.ts +3 -0
- package/dist/rules/token/blanks-around-tables.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-tables.js +42 -0
- package/dist/rules/token/blanks-around-tables.js.map +1 -0
- package/dist/rules/token/code-block-style.d.ts +3 -0
- package/dist/rules/token/code-block-style.d.ts.map +1 -0
- package/dist/rules/token/code-block-style.js +30 -0
- package/dist/rules/token/code-block-style.js.map +1 -0
- package/dist/rules/token/code-fence-style.d.ts +3 -0
- package/dist/rules/token/code-fence-style.d.ts.map +1 -0
- package/dist/rules/token/code-fence-style.js +35 -0
- package/dist/rules/token/code-fence-style.js.map +1 -0
- package/dist/rules/token/commands-show-output.d.ts +3 -0
- package/dist/rules/token/commands-show-output.d.ts.map +1 -0
- package/dist/rules/token/commands-show-output.js +38 -0
- package/dist/rules/token/commands-show-output.js.map +1 -0
- package/dist/rules/token/descriptive-link-text.d.ts +3 -0
- package/dist/rules/token/descriptive-link-text.d.ts.map +1 -0
- package/dist/rules/token/descriptive-link-text.js +53 -0
- package/dist/rules/token/descriptive-link-text.js.map +1 -0
- package/dist/rules/token/emphasis-style.d.ts +3 -0
- package/dist/rules/token/emphasis-style.d.ts.map +1 -0
- package/dist/rules/token/emphasis-style.js +51 -0
- package/dist/rules/token/emphasis-style.js.map +1 -0
- package/dist/rules/token/fenced-code-language.d.ts +3 -0
- package/dist/rules/token/fenced-code-language.d.ts.map +1 -0
- package/dist/rules/token/fenced-code-language.js +35 -0
- package/dist/rules/token/fenced-code-language.js.map +1 -0
- package/dist/rules/token/first-line-h1.d.ts +3 -0
- package/dist/rules/token/first-line-h1.d.ts.map +1 -0
- package/dist/rules/token/first-line-h1.js +107 -0
- package/dist/rules/token/first-line-h1.js.map +1 -0
- package/dist/rules/token/heading-increment.d.ts +3 -0
- package/dist/rules/token/heading-increment.d.ts.map +1 -0
- package/dist/rules/token/heading-increment.js +27 -0
- package/dist/rules/token/heading-increment.js.map +1 -0
- package/dist/rules/token/heading-start-left.d.ts +3 -0
- package/dist/rules/token/heading-start-left.d.ts.map +1 -0
- package/dist/rules/token/heading-start-left.js +31 -0
- package/dist/rules/token/heading-start-left.js.map +1 -0
- package/dist/rules/token/heading-style.d.ts +3 -0
- package/dist/rules/token/heading-style.d.ts.map +1 -0
- package/dist/rules/token/heading-style.js +41 -0
- package/dist/rules/token/heading-style.js.map +1 -0
- package/dist/rules/token/helpers.d.ts +313 -0
- package/dist/rules/token/helpers.d.ts.map +1 -0
- package/dist/rules/token/helpers.js +746 -0
- package/dist/rules/token/helpers.js.map +1 -0
- package/dist/rules/token/hr-style.d.ts +3 -0
- package/dist/rules/token/hr-style.d.ts.map +1 -0
- package/dist/rules/token/hr-style.js +28 -0
- package/dist/rules/token/hr-style.js.map +1 -0
- package/dist/rules/token/index.d.ts +75 -0
- package/dist/rules/token/index.d.ts.map +1 -0
- package/dist/rules/token/index.js +226 -0
- package/dist/rules/token/index.js.map +1 -0
- package/dist/rules/token/line-length.d.ts +3 -0
- package/dist/rules/token/line-length.d.ts.map +1 -0
- package/dist/rules/token/line-length.js +120 -0
- package/dist/rules/token/line-length.js.map +1 -0
- package/dist/rules/token/link-fragments.d.ts +3 -0
- package/dist/rules/token/link-fragments.d.ts.map +1 -0
- package/dist/rules/token/link-fragments.js +145 -0
- package/dist/rules/token/link-fragments.js.map +1 -0
- package/dist/rules/token/link-image-reference-definitions.d.ts +3 -0
- package/dist/rules/token/link-image-reference-definitions.d.ts.map +1 -0
- package/dist/rules/token/link-image-reference-definitions.js +50 -0
- package/dist/rules/token/link-image-reference-definitions.js.map +1 -0
- package/dist/rules/token/link-image-style.d.ts +3 -0
- package/dist/rules/token/link-image-style.d.ts.map +1 -0
- package/dist/rules/token/link-image-style.js +131 -0
- package/dist/rules/token/link-image-style.js.map +1 -0
- package/dist/rules/token/list-indent.d.ts +3 -0
- package/dist/rules/token/list-indent.d.ts.map +1 -0
- package/dist/rules/token/list-indent.js +60 -0
- package/dist/rules/token/list-indent.js.map +1 -0
- package/dist/rules/token/list-length.d.ts +3 -0
- package/dist/rules/token/list-length.d.ts.map +1 -0
- package/dist/rules/token/list-length.js +55 -0
- package/dist/rules/token/list-length.js.map +1 -0
- package/dist/rules/token/list-marker-space.d.ts +3 -0
- package/dist/rules/token/list-marker-space.d.ts.map +1 -0
- package/dist/rules/token/list-marker-space.js +52 -0
- package/dist/rules/token/list-marker-space.js.map +1 -0
- package/dist/rules/token/markdoc-attributes.d.ts +3 -0
- package/dist/rules/token/markdoc-attributes.d.ts.map +1 -0
- package/dist/rules/token/markdoc-attributes.js +269 -0
- package/dist/rules/token/markdoc-attributes.js.map +1 -0
- package/dist/rules/token/markdoc-pairing.d.ts +3 -0
- package/dist/rules/token/markdoc-pairing.d.ts.map +1 -0
- package/dist/rules/token/markdoc-pairing.js +73 -0
- package/dist/rules/token/markdoc-pairing.js.map +1 -0
- package/dist/rules/token/markdoc-syntax.d.ts +3 -0
- package/dist/rules/token/markdoc-syntax.d.ts.map +1 -0
- package/dist/rules/token/markdoc-syntax.js +119 -0
- package/dist/rules/token/markdoc-syntax.js.map +1 -0
- package/dist/rules/token/markdoc-unknown-tag.d.ts +3 -0
- package/dist/rules/token/markdoc-unknown-tag.d.ts.map +1 -0
- package/dist/rules/token/markdoc-unknown-tag.js +64 -0
- package/dist/rules/token/markdoc-unknown-tag.js.map +1 -0
- package/dist/rules/token/messages.d.ts +4 -0
- package/dist/rules/token/messages.d.ts.map +1 -0
- package/dist/rules/token/messages.js +20 -0
- package/dist/rules/token/messages.js.map +1 -0
- package/dist/rules/token/no-alt-text.d.ts +3 -0
- package/dist/rules/token/no-alt-text.d.ts.map +1 -0
- package/dist/rules/token/no-alt-text.js +47 -0
- package/dist/rules/token/no-alt-text.js.map +1 -0
- package/dist/rules/token/no-bare-urls.d.ts +3 -0
- package/dist/rules/token/no-bare-urls.d.ts.map +1 -0
- package/dist/rules/token/no-bare-urls.js +88 -0
- package/dist/rules/token/no-bare-urls.js.map +1 -0
- package/dist/rules/token/no-blanks-blockquote.d.ts +3 -0
- package/dist/rules/token/no-blanks-blockquote.d.ts.map +1 -0
- package/dist/rules/token/no-blanks-blockquote.js +39 -0
- package/dist/rules/token/no-blanks-blockquote.js.map +1 -0
- package/dist/rules/token/no-duplicate-heading.d.ts +3 -0
- package/dist/rules/token/no-duplicate-heading.d.ts.map +1 -0
- package/dist/rules/token/no-duplicate-heading.js +101 -0
- package/dist/rules/token/no-duplicate-heading.js.map +1 -0
- package/dist/rules/token/no-duplicate-link-destinations.d.ts +3 -0
- package/dist/rules/token/no-duplicate-link-destinations.d.ts.map +1 -0
- package/dist/rules/token/no-duplicate-link-destinations.js +65 -0
- package/dist/rules/token/no-duplicate-link-destinations.js.map +1 -0
- package/dist/rules/token/no-emphasis-as-heading.d.ts +3 -0
- package/dist/rules/token/no-emphasis-as-heading.d.ts.map +1 -0
- package/dist/rules/token/no-emphasis-as-heading.js +44 -0
- package/dist/rules/token/no-emphasis-as-heading.js.map +1 -0
- package/dist/rules/token/no-empty-headings.d.ts +3 -0
- package/dist/rules/token/no-empty-headings.d.ts.map +1 -0
- package/dist/rules/token/no-empty-headings.js +28 -0
- package/dist/rules/token/no-empty-headings.js.map +1 -0
- package/dist/rules/token/no-empty-links.d.ts +3 -0
- package/dist/rules/token/no-empty-links.d.ts.map +1 -0
- package/dist/rules/token/no-empty-links.js +67 -0
- package/dist/rules/token/no-empty-links.js.map +1 -0
- package/dist/rules/token/no-hard-tabs.d.ts +3 -0
- package/dist/rules/token/no-hard-tabs.d.ts.map +1 -0
- package/dist/rules/token/no-hard-tabs.js +76 -0
- package/dist/rules/token/no-hard-tabs.js.map +1 -0
- package/dist/rules/token/no-inline-html.d.ts +3 -0
- package/dist/rules/token/no-inline-html.d.ts.map +1 -0
- package/dist/rules/token/no-inline-html.js +45 -0
- package/dist/rules/token/no-inline-html.js.map +1 -0
- package/dist/rules/token/no-missing-space-atx.d.ts +3 -0
- package/dist/rules/token/no-missing-space-atx.d.ts.map +1 -0
- package/dist/rules/token/no-missing-space-atx.js +36 -0
- package/dist/rules/token/no-missing-space-atx.js.map +1 -0
- package/dist/rules/token/no-missing-space-closed-atx.d.ts +3 -0
- package/dist/rules/token/no-missing-space-closed-atx.d.ts.map +1 -0
- package/dist/rules/token/no-missing-space-closed-atx.js +45 -0
- package/dist/rules/token/no-missing-space-closed-atx.js.map +1 -0
- package/dist/rules/token/no-multiple-blanks.d.ts +3 -0
- package/dist/rules/token/no-multiple-blanks.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-blanks.js +35 -0
- package/dist/rules/token/no-multiple-blanks.js.map +1 -0
- package/dist/rules/token/no-multiple-space-atx.d.ts +13 -0
- package/dist/rules/token/no-multiple-space-atx.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-space-atx.js +50 -0
- package/dist/rules/token/no-multiple-space-atx.js.map +1 -0
- package/dist/rules/token/no-multiple-space-blockquote.d.ts +3 -0
- package/dist/rules/token/no-multiple-space-blockquote.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-space-blockquote.js +43 -0
- package/dist/rules/token/no-multiple-space-blockquote.js.map +1 -0
- package/dist/rules/token/no-multiple-space-closed-atx.d.ts +3 -0
- package/dist/rules/token/no-multiple-space-closed-atx.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-space-closed-atx.js +19 -0
- package/dist/rules/token/no-multiple-space-closed-atx.js.map +1 -0
- package/dist/rules/token/no-reversed-links.d.ts +3 -0
- package/dist/rules/token/no-reversed-links.d.ts.map +1 -0
- package/dist/rules/token/no-reversed-links.js +52 -0
- package/dist/rules/token/no-reversed-links.js.map +1 -0
- package/dist/rules/token/no-space-in-code.d.ts +3 -0
- package/dist/rules/token/no-space-in-code.d.ts.map +1 -0
- package/dist/rules/token/no-space-in-code.js +75 -0
- package/dist/rules/token/no-space-in-code.js.map +1 -0
- package/dist/rules/token/no-space-in-emphasis.d.ts +3 -0
- package/dist/rules/token/no-space-in-emphasis.d.ts.map +1 -0
- package/dist/rules/token/no-space-in-emphasis.js +79 -0
- package/dist/rules/token/no-space-in-emphasis.js.map +1 -0
- package/dist/rules/token/no-space-in-links.d.ts +3 -0
- package/dist/rules/token/no-space-in-links.d.ts.map +1 -0
- package/dist/rules/token/no-space-in-links.js +48 -0
- package/dist/rules/token/no-space-in-links.js.map +1 -0
- package/dist/rules/token/no-trailing-punctuation.d.ts +3 -0
- package/dist/rules/token/no-trailing-punctuation.d.ts.map +1 -0
- package/dist/rules/token/no-trailing-punctuation.js +38 -0
- package/dist/rules/token/no-trailing-punctuation.js.map +1 -0
- package/dist/rules/token/no-trailing-spaces.d.ts +3 -0
- package/dist/rules/token/no-trailing-spaces.d.ts.map +1 -0
- package/dist/rules/token/no-trailing-spaces.js +89 -0
- package/dist/rules/token/no-trailing-spaces.js.map +1 -0
- package/dist/rules/token/ol-prefix.d.ts +3 -0
- package/dist/rules/token/ol-prefix.d.ts.map +1 -0
- package/dist/rules/token/ol-prefix.js +70 -0
- package/dist/rules/token/ol-prefix.js.map +1 -0
- package/dist/rules/token/proper-names.d.ts +3 -0
- package/dist/rules/token/proper-names.d.ts.map +1 -0
- package/dist/rules/token/proper-names.js +93 -0
- package/dist/rules/token/proper-names.js.map +1 -0
- package/dist/rules/token/reference-links-images.d.ts +3 -0
- package/dist/rules/token/reference-links-images.d.ts.map +1 -0
- package/dist/rules/token/reference-links-images.js +36 -0
- package/dist/rules/token/reference-links-images.js.map +1 -0
- package/dist/rules/token/required-headings.d.ts +3 -0
- package/dist/rules/token/required-headings.d.ts.map +1 -0
- package/dist/rules/token/required-headings.js +83 -0
- package/dist/rules/token/required-headings.js.map +1 -0
- package/dist/rules/token/single-h1.d.ts +3 -0
- package/dist/rules/token/single-h1.d.ts.map +1 -0
- package/dist/rules/token/single-h1.js +56 -0
- package/dist/rules/token/single-h1.js.map +1 -0
- package/dist/rules/token/single-trailing-newline.d.ts +3 -0
- package/dist/rules/token/single-trailing-newline.d.ts.map +1 -0
- package/dist/rules/token/single-trailing-newline.js +25 -0
- package/dist/rules/token/single-trailing-newline.js.map +1 -0
- package/dist/rules/token/strong-style.d.ts +3 -0
- package/dist/rules/token/strong-style.d.ts.map +1 -0
- package/dist/rules/token/strong-style.js +51 -0
- package/dist/rules/token/strong-style.js.map +1 -0
- package/dist/rules/token/table-column-count.d.ts +3 -0
- package/dist/rules/token/table-column-count.d.ts.map +1 -0
- package/dist/rules/token/table-column-count.js +44 -0
- package/dist/rules/token/table-column-count.js.map +1 -0
- package/dist/rules/token/table-column-style.d.ts +3 -0
- package/dist/rules/token/table-column-style.d.ts.map +1 -0
- package/dist/rules/token/table-column-style.js +179 -0
- package/dist/rules/token/table-column-style.js.map +1 -0
- package/dist/rules/token/table-pipe-style.d.ts +3 -0
- package/dist/rules/token/table-pipe-style.d.ts.map +1 -0
- package/dist/rules/token/table-pipe-style.js +54 -0
- package/dist/rules/token/table-pipe-style.js.map +1 -0
- package/dist/rules/token/ul-indent.d.ts +3 -0
- package/dist/rules/token/ul-indent.d.ts.map +1 -0
- package/dist/rules/token/ul-indent.js +72 -0
- package/dist/rules/token/ul-indent.js.map +1 -0
- package/dist/rules/token/ul-style.d.ts +3 -0
- package/dist/rules/token/ul-style.d.ts.map +1 -0
- package/dist/rules/token/ul-style.js +80 -0
- package/dist/rules/token/ul-style.js.map +1 -0
- package/dist/rules/types.d.ts +81 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +2 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/utils.d.ts +29 -0
- package/dist/rules/utils.d.ts.map +1 -0
- package/dist/{assertions → rules}/utils.js +27 -0
- package/dist/rules/utils.js.map +1 -0
- package/dist/scopes/extractor.d.ts +7 -0
- package/dist/scopes/extractor.d.ts.map +1 -0
- package/dist/scopes/extractor.js +475 -0
- package/dist/scopes/extractor.js.map +1 -0
- package/dist/scopes/selector.d.ts +51 -0
- package/dist/scopes/selector.d.ts.map +1 -0
- package/dist/scopes/selector.js +121 -0
- package/dist/scopes/selector.js.map +1 -0
- package/dist/scopes/sentences.d.ts +7 -0
- package/dist/scopes/sentences.d.ts.map +1 -0
- package/dist/scopes/sentences.js +115 -0
- package/dist/scopes/sentences.js.map +1 -0
- package/dist/scopes/types.d.ts +44 -0
- package/dist/scopes/types.d.ts.map +1 -0
- package/dist/scopes/types.js +2 -0
- package/dist/scopes/types.js.map +1 -0
- package/dist/scopes/vocabulary.d.ts +16 -0
- package/dist/scopes/vocabulary.d.ts.map +1 -0
- package/dist/scopes/vocabulary.js +70 -0
- package/dist/scopes/vocabulary.js.map +1 -0
- package/dist/types/assertions.d.ts +95 -32
- package/dist/types/assertions.d.ts.map +1 -1
- package/dist/types/problems.d.ts +4 -5
- package/dist/types/problems.d.ts.map +1 -1
- package/dist/types/rules.d.ts +4 -6
- package/dist/types/rules.d.ts.map +1 -1
- package/examples/appendices/google.appendix.yaml +91 -0
- package/examples/appendices/inclusive-language.appendix.yaml +61 -0
- package/examples/appendices/microsoft.appendix.yaml +99 -0
- package/examples/appendices/plain-language.appendix.yaml +88 -0
- package/examples/google.yaml +1525 -0
- package/examples/inclusive-language.yaml +304 -0
- package/examples/microsoft.yaml +1542 -0
- package/examples/plain-language.yaml +325 -0
- package/package.json +49 -16
- package/presets/google/PROVENANCE.md +1022 -0
- package/presets/google/sources.json +192 -0
- package/presets/inclusive-language/PROVENANCE.md +174 -0
- package/presets/inclusive-language/sources.json +107 -0
- package/presets/microsoft/PROVENANCE.md +1555 -0
- package/presets/microsoft/sources.json +494 -0
- package/presets/plain-language/PROVENANCE.md +364 -0
- package/presets/plain-language/sources.json +108 -0
- package/dist/assertions/bullet-style.d.ts +0 -3
- package/dist/assertions/bullet-style.d.ts.map +0 -1
- package/dist/assertions/bullet-style.js +0 -60
- package/dist/assertions/bullet-style.js.map +0 -1
- package/dist/assertions/index.d.ts +0 -21
- package/dist/assertions/index.d.ts.map +0 -1
- package/dist/assertions/index.js +0 -30
- package/dist/assertions/index.js.map +0 -1
- package/dist/assertions/max-image-size.d.ts +0 -3
- package/dist/assertions/max-image-size.d.ts.map +0 -1
- package/dist/assertions/max-image-size.js +0 -73
- package/dist/assertions/max-image-size.js.map +0 -1
- package/dist/assertions/max-line-length.d.ts +0 -3
- package/dist/assertions/max-line-length.d.ts.map +0 -1
- package/dist/assertions/max-line-length.js +0 -68
- package/dist/assertions/max-line-length.js.map +0 -1
- package/dist/assertions/no-broken-fragment-links.d.ts +0 -3
- package/dist/assertions/no-broken-fragment-links.d.ts.map +0 -1
- package/dist/assertions/no-broken-fragment-links.js +0 -79
- package/dist/assertions/no-broken-fragment-links.js.map +0 -1
- package/dist/assertions/no-duplicate-headings.d.ts +0 -3
- package/dist/assertions/no-duplicate-headings.d.ts.map +0 -1
- package/dist/assertions/no-duplicate-headings.js +0 -66
- package/dist/assertions/no-duplicate-headings.js.map +0 -1
- package/dist/assertions/no-hard-tabs.d.ts +0 -3
- package/dist/assertions/no-hard-tabs.d.ts.map +0 -1
- package/dist/assertions/no-hard-tabs.js +0 -63
- package/dist/assertions/no-hard-tabs.js.map +0 -1
- package/dist/assertions/no-trailing-spaces.d.ts +0 -3
- package/dist/assertions/no-trailing-spaces.d.ts.map +0 -1
- package/dist/assertions/no-trailing-spaces.js +0 -72
- package/dist/assertions/no-trailing-spaces.js.map +0 -1
- package/dist/assertions/pattern.d.ts +0 -3
- package/dist/assertions/pattern.d.ts.map +0 -1
- package/dist/assertions/pattern.js +0 -39
- package/dist/assertions/pattern.js.map +0 -1
- package/dist/assertions/semantic-line-breaks.d.ts +0 -3
- package/dist/assertions/semantic-line-breaks.d.ts.map +0 -1
- package/dist/assertions/semantic-line-breaks.js +0 -152
- package/dist/assertions/semantic-line-breaks.js.map +0 -1
- package/dist/assertions/swap.d.ts +0 -3
- package/dist/assertions/swap.d.ts.map +0 -1
- package/dist/assertions/swap.js +0 -39
- package/dist/assertions/swap.js.map +0 -1
- package/dist/assertions/utils.d.ts +0 -8
- package/dist/assertions/utils.d.ts.map +0 -1
- package/dist/assertions/utils.js.map +0 -1
- package/dist/core/scope-parser.d.ts +0 -26
- package/dist/core/scope-parser.d.ts.map +0 -1
- package/dist/core/scope-parser.js +0 -110
- package/dist/core/scope-parser.js.map +0 -1
- package/dist/files.d.ts +0 -2
- package/dist/files.d.ts.map +0 -1
- package/dist/files.js +0 -39
- package/dist/files.js.map +0 -1
- package/dist/load-config.d.ts +0 -25
- package/dist/load-config.d.ts.map +0 -1
- package/dist/load-config.js +0 -104
- package/dist/load-config.js.map +0 -1
- package/dist/load.d.ts +0 -25
- package/dist/load.d.ts.map +0 -1
- package/dist/load.js +0 -112
- package/dist/load.js.map +0 -1
- package/dist/scope.d.ts +0 -26
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -110
- package/dist/scope.js.map +0 -1
- package/dist/types.d.ts +0 -109
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/validate.d.ts +0 -31
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -154
- package/dist/validate.js.map +0 -1
- /package/dist/{types.js → parser/types.js} +0 -0
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
# Provenance: `recheck/google`
|
|
2
|
+
|
|
3
|
+
Source: [Google developer documentation style guide](https://developers.google.com/style)
|
|
4
|
+
(canonical URL: `https://developers.google.com/style`). License:
|
|
5
|
+
[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Sync date: **2026-07-29**.
|
|
6
|
+
|
|
7
|
+
Modification note: rules are adapted to Recheck's assertion vocabulary
|
|
8
|
+
(`swap`, `pattern`, `capitalization`, `length`, plus a handful of
|
|
9
|
+
markdownlint-parity/Recheck-original token rules); wording is paraphrased
|
|
10
|
+
into each rule's `message`, not quoted verbatim from the guide. Every rule
|
|
11
|
+
carries a `link:` to its source page.
|
|
12
|
+
|
|
13
|
+
## How this table was produced
|
|
14
|
+
|
|
15
|
+
Five independent verification passes fetched the live guide directly
|
|
16
|
+
(`curl`, not a summarizing fetch) and confirmed or rejected each candidate
|
|
17
|
+
rule against the raw page text/HTML: four slice verifiers (`task-9-verify-A.md`
|
|
18
|
+
covering style guide §2.1-2.5, `task-9-verify-B.md` §2.6-2.10,
|
|
19
|
+
`task-9-verify-C.md` §3.1-3.5, `task-9-verify-D.md` §3.6-3.9) plus one
|
|
20
|
+
cross-check pass that re-parsed the word-list page with a stricter HTML5
|
|
21
|
+
parser and diffed every replacement value quoted by the other four
|
|
22
|
+
(`task-9-verify-crosscheck.md`). Together they checked ~380 candidate
|
|
23
|
+
rules/entries and found **6 fabrications** — rules that appeared in an
|
|
24
|
+
earlier research draft but do not exist anywhere on the live guide (see
|
|
25
|
+
"Fabrications" below). This preset is built **only** from entries those
|
|
26
|
+
five reports marked `CONFIRMED`; nothing here was sourced from the research
|
|
27
|
+
draft directly. Fetch date for the verification passes and for
|
|
28
|
+
`sources.json`'s hashes is the same day this preset was authored: 2026-07-29.
|
|
29
|
+
|
|
30
|
+
Every quote below is the verifier's own quote (or fetch-log citation),
|
|
31
|
+
reproduced here at second hand — see the verifier reports themselves for
|
|
32
|
+
the full text and additional context.
|
|
33
|
+
|
|
34
|
+
## Shipped rules
|
|
35
|
+
|
|
36
|
+
Severity policy: `error` is reserved for rules checking pure document
|
|
37
|
+
STRUCTURE (heading hierarchy/uniqueness, list-item mechanics, table
|
|
38
|
+
mechanics, link placement, alt-text presence, sentence length) where a
|
|
39
|
+
violation is unambiguous and mechanical; every word-choice, terminology,
|
|
40
|
+
punctuation-convention, and phrasing rule is `warn`. This is a
|
|
41
|
+
simplification of spec §2's severity table (which gives a shorter, purely
|
|
42
|
+
illustrative example list) applied uniformly here for predictability, at
|
|
43
|
+
the cost of a few punctuation-mechanics rules (Oxford comma, en dash,
|
|
44
|
+
single-space-between-sentences) that could arguably also be `error` — see
|
|
45
|
+
"Author's judgment calls" at the end of this document.
|
|
46
|
+
|
|
47
|
+
Four shipped rules are named exceptions to that split, not silent
|
|
48
|
+
inconsistencies with it: `no-code-in-heading` is heading-scoped (in the
|
|
49
|
+
STRUCTURE family above by location) but ships at `warn` because the guide
|
|
50
|
+
states it with hedged wording ("Avoid code items in headings," not
|
|
51
|
+
"don't"). `no-numbered-headings` is also heading-scoped and the guide
|
|
52
|
+
states it unconditionally ("Don't use numbers in headings..."), but ships
|
|
53
|
+
at `warn` because the shipped pattern is a narrowed heuristic (bare
|
|
54
|
+
leading ordinals and `Step N`/`Part N` markers only, to keep the
|
|
55
|
+
false-positive rate low), not a complete detector of every way a heading
|
|
56
|
+
could number a sequence — the rule's confidence is in what it does flag,
|
|
57
|
+
not full coverage of the guide's stated principle. `emphasis-style` and
|
|
58
|
+
`strong-style` ship at `warn` because the guide states its markup
|
|
59
|
+
preference as a recommendation ("we recommend underscores," "it's best to
|
|
60
|
+
use double asterisk"), not an unconditional "don't." So the actual policy
|
|
61
|
+
is: STRUCTURE, stated by the guide as an unconditional, completely
|
|
62
|
+
detectable rule → `error`; everything else — including these four
|
|
63
|
+
nominally-structural rules the guide itself hedges, or that need an
|
|
64
|
+
intentionally incomplete detection heuristic → `warn`.
|
|
65
|
+
|
|
66
|
+
### Structural (heading, list, table, link, alt-text, sentence mechanics) — `error`
|
|
67
|
+
|
|
68
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `google/heading-sentence-case` | [headings](https://developers.google.com/style/headings) | "Use sentence case for all headings and titles." | CONFIRMED |
|
|
71
|
+
| `google/heading-increment` | [headings](https://developers.google.com/style/headings) | "put an `<h3>` tag only under an `<h2>` tag" | CONFIRMED |
|
|
72
|
+
| `google/single-h1` | [headings](https://developers.google.com/style/headings) | "only use a level-1 heading once on a page" | CONFIRMED |
|
|
73
|
+
| `google/first-line-h1` | [headings](https://developers.google.com/style/headings) | "only use a level-1 heading once on a page" (same statement as `single-h1`; see "Author's judgment calls") | CONFIRMED |
|
|
74
|
+
| `google/no-duplicate-heading` | [headings](https://developers.google.com/style/headings) | "easier to jump between pages and sections...if the headings...are unique" | CONFIRMED |
|
|
75
|
+
| `google/no-trailing-punctuation` | [periods](https://developers.google.com/style/periods) | "Don't end headings with periods." | CONFIRMED |
|
|
76
|
+
| `google/no-empty-headings` | [headings](https://developers.google.com/style/headings) | "Don't use empty headings. Make sure headings are followed by content." | CONFIRMED |
|
|
77
|
+
| `google/no-emphasis-as-heading` | [accessibility](https://developers.google.com/style/accessibility) | "Tag headings using heading elements." | CONFIRMED (nuance: the engine's own token rule excludes a bold/italic lead-in followed by more text in the SAME paragraph, and a bold/italic-only paragraph that ends in required punctuation — but NOT a bold/italic-only paragraph with no ending punctuation whose description follows in a later paragraph, which the guide's own "run-in heading" pattern also permits; see verifier A row 12 and "Known limitations" below) |
|
|
78
|
+
| `google/no-link-in-heading` | [headings](https://developers.google.com/style/headings) | "Don't put links in headings." | CONFIRMED |
|
|
79
|
+
| `google/list-item-capital` | [lists](https://developers.google.com/style/lists) | "Start each list item with a capital letter" | CONFIRMED |
|
|
80
|
+
| `google/no-alt-text` | [accessibility](https://developers.google.com/style/accessibility) | "For every image, provide an alt attribute" | CONFIRMED |
|
|
81
|
+
| `google/no-merged-cells` | [accessibility](https://developers.google.com/style/accessibility) (also [tables](https://developers.google.com/style/tables)) | "Don't merge cells. Don't use colspan or rowspan attributes" | CONFIRMED |
|
|
82
|
+
| `google/sentence-length` | [accessibility](https://developers.google.com/style/accessibility) | "Try to use fewer than 26 words per sentence." | CONFIRMED — mapped to the new `length` assertion (`unit: words`, `max: 25`) per spec §5.6's stated-numbers table; this is the first non-prose preset to ship a `length`-backed rule (see "Engine/registry changes" below) |
|
|
83
|
+
|
|
84
|
+
### Headings (residual) / lists — `warn`
|
|
85
|
+
|
|
86
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
87
|
+
|---|---|---|---|
|
|
88
|
+
| `google/no-code-in-heading` | [headings](https://developers.google.com/style/headings) | "Avoid code items in headings." | CONFIRMED |
|
|
89
|
+
| `google/no-numbered-headings` | [headings](https://developers.google.com/style/headings) | "Don't use numbers in headings to indicate a sequence" | CONFIRMED |
|
|
90
|
+
| `google/list-length` | [lists](https://developers.google.com/style/lists) | "a single item isn't really a list" | CONFIRMED, but the verifier marked this specific line NOT-ENFORCEABLE (descriptive aside, not an imperative rule) — downgraded from the generic "list mechanics" `error` class to `warn` for that reason; ships via `list-length`'s own `min: 2` default, no `max` (Google states no upper bound; the 2-7 range is Microsoft's, spec §5.6) |
|
|
91
|
+
|
|
92
|
+
### Voice, person, tense, contractions — `warn`
|
|
93
|
+
|
|
94
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| `google/second-person` | [person](https://developers.google.com/style/person) | "use `you` or `your` instead of `we`, `our`, or `us`" | CONFIRMED (organizational-reference exception noted in the rule's message; detection-only). Fix wave A: `ignoreCase: true` replaced with an explicit `We/we/Our/our/Us/us` alternation so it stops also matching the all-caps abbreviation "US" — see "Fix wave A corrections" |
|
|
97
|
+
| `google/use-contractions` | [contractions](https://developers.google.com/style/contractions) | "we recommend using negation contractions such as isn't, don't, and can't" | CONFIRMED (`fix: false`: guide's own "is *not*" emphasis exception) |
|
|
98
|
+
| `google/no-triple-contractions` | [contractions](https://developers.google.com/style/contractions) | "Don't use three-word contractions such as mightn't've." | CONFIRMED |
|
|
99
|
+
| `google/no-lets` | [word-list#lets](https://developers.google.com/style/word-list#lets) | "Don't use if at all possible." | CONFIRMED — citation corrected: the draft cited "contractions", but `let's` is never mentioned there; the quote lives on the word-list page (verifier A row 14) |
|
|
100
|
+
| `google/no-please-note` | [word-list#please](https://developers.google.com/style/word-list#please) | "Don't use please in the normal course of explaining how to use a product" (the phrase `please note` specifically has no documented exception) | CONFIRMED. Fix wave A: `fix: false` added — the delete-swap left a capitalization/fragment mess behind ("Please note that X." -> "that X."); see "Fix wave A corrections" |
|
|
101
|
+
| `google/no-please` | [word-list#please](https://developers.google.com/style/word-list#please) | "Use please only when you're asking for permission or forgiveness...Recommended: If the issue persists, please contact your account representative." | CONFIRMED, **must be DETECT-ONLY, never a swap** — the guide's own recommended example sentence uses "please"; a delete-swap would rewrite text the guide endorses (per task-9-author-corrections.md) |
|
|
102
|
+
|
|
103
|
+
### Timeless documentation — `warn`
|
|
104
|
+
|
|
105
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
106
|
+
|---|---|---|---|
|
|
107
|
+
| `google/no-timeless-phrases` | [timeless-documentation](https://developers.google.com/style/timeless-documentation) | "as of this writing, currently, does not yet, eventually, existing, future...latest, new, newer, now, old, older, presently, at present, soon" (full confirmed list) | CONFIRMED, but only 5 of the ~15 confirmed terms are shipped (`as of this writing`, `at present`, `presently`, `does not yet`, `currently`) — the rest are ordinary high-frequency words (`existing`, `future`, `latest`, `new`, `newer`, `now`, `old`, `older`, `soon`, `eventually`, `in the future`) with legitimate everyday uses that would make a blind pattern unusably noisy; see "Author's judgment calls" |
|
|
108
|
+
|
|
109
|
+
### Latinisms, abbreviations, slang — `warn`
|
|
110
|
+
|
|
111
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| `google/no-latinisms` | [word-list](https://developers.google.com/style/word-list) | "Don't use i.e. or e.g."; "Don't use vs. as an abbreviation for versus" | CONFIRMED (i.e./e.g./vs. — independently reconfirmed in verifier C's 3.1 slice). Fix wave A: carries only the 3 period-terminated keys now (see "Fix wave A corrections" below for why `aka`/`vice versa` moved out) |
|
|
114
|
+
| `google/no-latinisms-plain` | [word-list](https://developers.google.com/style/word-list) | "aka: Don't use. Instead, write out also known as"; "vice versa: ...use...the other way around" | CONFIRMED, same verification as `google/no-latinisms` above. Split out in Fix wave A (2026-07-29) so these two non-period keys get full `\b...\b` anchoring instead of the period-terminated group's unanchored match — see "Fix wave A corrections" |
|
|
115
|
+
| `google/no-internet-slang` | [abbreviations](https://developers.google.com/style/abbreviations) | "Don't use internet slang abbreviations such as tl;dr, ymmv, RTFM" | CONFIRMED (each also has its own word-list replacement: "To summarize" / "Your results might vary" / "For more information, see...") |
|
|
116
|
+
| `google/no-via` | [word-list#via](https://developers.google.com/style/word-list#via) | "Don't use." | CONFIRMED, DETECT-ONLY (no replacement given) — this is the exact term the research file's own provenance note flagged a summarizer once inverted; independently reconfirmed by verifier C and the cross-check |
|
|
117
|
+
| `google/abbrev-no-periods` | [abbreviations](https://developers.google.com/style/abbreviations) | "Don't use periods with acronyms or initialisms." | CONFIRMED |
|
|
118
|
+
| `google/us-abbreviation` | [word-list#US](https://developers.google.com/style/word-list#US) | "OK to use as an abbreviation for United States. Don't use U.S. or U.S.A." | CONFIRMED |
|
|
119
|
+
| `google/no-slash-abbrev` | [slashes](https://developers.google.com/style/slashes) | "Slashes with abbreviations... Recommended: care of, with / Not recommended: c/o, w/" | CONFIRMED. Fix wave A: both keys gained a leading-only `\b` (were matching inside "src/output", "www/static", "show/hide", "new/old"); Fix wave C: both also gained a trailing `(?![A-Za-z])` (were matching inside "w/o", "c/oscillator") — see "Fix wave A corrections" / "Fix wave C corrections" |
|
|
120
|
+
|
|
121
|
+
### Numbers, dates, units — `warn`
|
|
122
|
+
|
|
123
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `google/spell-out-ordinals` | [numbers](https://developers.google.com/style/numbers) | "Not recommended: 1st, 5th, 12th, 43rd" | CONFIRMED |
|
|
126
|
+
| `google/number-format` | [numbers](https://developers.google.com/style/numbers) (also [hyphens](https://developers.google.com/style/hyphens) for the "from N-M" token) | "use numerals and the percent sign (%), without a space"; "place a zero in front of the decimal point"; "Recommended: 192x192 / Not recommended: 192 x 192"; "Not recommended: from 8-20 files" | CONFIRMED |
|
|
127
|
+
| `google/date-format` | [dates-times](https://developers.google.com/style/dates-times) | "Not recommended: 12/02/2017" | CONFIRMED |
|
|
128
|
+
| `google/time-format` | [word-list#AM,\_PM](https://developers.google.com/style/word-list#AM,_PM) | "use all caps, no periods, and a space before" (AM/PM); "Remove the minutes from round hours" (dates-times page) | CONFIRMED — citation corrected: the AM/PM quote lives on the word-list page, not dates-times (verifier B row 63) |
|
|
129
|
+
| `google/rfc-spacing` | [word-list#RFC](https://developers.google.com/style/word-list#RFC) | "use a space between RFC and the number (for example, RFC 2318)" | CONFIRMED |
|
|
130
|
+
| `google/data-rate-units` | [word-list#GBps](https://developers.google.com/style/word-list#GBps) | "By convention, we don't use KB/s" (and the other 5 unit pairs) | CONFIRMED — the master research table's "8 pairs" claim was wrong; verified exactly 6 (verifier B row 67, cross-check) |
|
|
131
|
+
|
|
132
|
+
### Punctuation — `warn`
|
|
133
|
+
|
|
134
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
135
|
+
|---|---|---|---|
|
|
136
|
+
| `google/no-ampersand` | [text-formatting](https://developers.google.com/style/text-formatting) | "Don't use ampersands (&) as conjunctions or shorthand for and." | CONFIRMED (UI-element exception preserved: pattern requires spaces on both sides, so `AT&T`/`&` are untouched) |
|
|
137
|
+
| `google/dash-style` | [dashes](https://developers.google.com/style/dashes) | "En dashes...Don't use. Instead, use a hyphen or the word to."; "Don't put a space before or after it [the em dash]." | CONFIRMED |
|
|
138
|
+
| `google/single-space-sentences` | [periods](https://developers.google.com/style/periods) | "Leave only one space between sentences." | CONFIRMED |
|
|
139
|
+
| `google/conjunctive-adverb-comma` | [commas](https://developers.google.com/style/commas) | "put a comma after the conjunctive adverb" | CONFIRMED — the draft's fourth example ("Nonetheless") is not named on the live page; only the three confirmed examples (otherwise/however/therefore) are shipped |
|
|
140
|
+
| `google/comma-before-that` | [pronouns](https://developers.google.com/style/pronouns) | "That introduces a restrictive clause. It isn't preceded by a comma." | CONFIRMED |
|
|
141
|
+
| `google/neither-nor` | [word-list#neither](https://developers.google.com/style/word-list#neither) | "Write neither A nor B, not neither A or B." | CONFIRMED |
|
|
142
|
+
| `google/no-and-or` | [slashes](https://developers.google.com/style/slashes) | "avoid writing and/or except when space is limited, such as in tables" | CONFIRMED — the table exception is not separately carved out in the rule's scope (see "Known simplifications") |
|
|
143
|
+
|
|
144
|
+
### Links — `warn`
|
|
145
|
+
|
|
146
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
147
|
+
|---|---|---|---|
|
|
148
|
+
| `google/vague-link-text` | [cross-references](https://developers.google.com/style/cross-references) | "Don't use phrases such as this document, this article, or click here" | CONFIRMED (page renamed from `link-text`; content unchanged) |
|
|
149
|
+
| `google/no-url-as-link-text` | [cross-references](https://developers.google.com/style/cross-references) | "don't use a URL as link text" | CONFIRMED (legal/ToS exception noted, not separately modeled — see "Known limitations" below) |
|
|
150
|
+
| `google/link-intro-about` | [cross-references](https://developers.google.com/style/cross-references) | "Don't use on instead of about" | CONFIRMED |
|
|
151
|
+
| `google/link-punctuation` | [cross-references](https://developers.google.com/style/cross-references) | "don't put the link text in quotation marks" | CONFIRMED |
|
|
152
|
+
| `google/no-target-blank` | [cross-references](https://developers.google.com/style/cross-references) | "Don't force links to open in a new tab or window" | CONFIRMED |
|
|
153
|
+
| `google/self-reference-terms` | [word-list#documentation](https://developers.google.com/style/word-list#documentation) | "use this document, and not this article, this topic, this doc" | CONFIRMED (general terminology preference, independent of link text — distinct from `vague-link-text` above, which is scoped to the `link` segment) |
|
|
154
|
+
|
|
155
|
+
### Text formatting — `warn`
|
|
156
|
+
|
|
157
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
158
|
+
|---|---|---|---|
|
|
159
|
+
| `google/emphasis-style` | [text-formatting](https://developers.google.com/style/text-formatting) | "we recommend underscores" | CONFIRMED |
|
|
160
|
+
| `google/strong-style` | [text-formatting](https://developers.google.com/style/text-formatting) | "best to use the double asterisk for bold" | CONFIRMED |
|
|
161
|
+
| `google/no-underline` | [text-formatting](https://developers.google.com/style/text-formatting) | "Reserve underlining for link text" | CONFIRMED |
|
|
162
|
+
| `google/no-casing-style-names` | [capitalization](https://developers.google.com/style/capitalization) | "Don't use a casing style name, such as camel case or snake case" | CONFIRMED |
|
|
163
|
+
|
|
164
|
+
### Code in text — `warn`
|
|
165
|
+
|
|
166
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| `google/no-inflected-code` | [code-in-text](https://developers.google.com/style/code-in-text) | "Don't inflect the name of a code element" | CONFIRMED |
|
|
169
|
+
|
|
170
|
+
### UI elements and verbs — `warn`
|
|
171
|
+
|
|
172
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
173
|
+
|---|---|---|---|
|
|
174
|
+
| `google/ui-element-quotes` | [ui-elements](https://developers.google.com/style/ui-elements) | 'click the "Next" button' (Not recommended example) | CONFIRMED |
|
|
175
|
+
| `google/no-click-on` | [word-list#click](https://developers.google.com/style/word-list#click) | "Don't use click on." | CONFIRMED |
|
|
176
|
+
| `google/no-hover` | [word-list#hover](https://developers.google.com/style/word-list#hover) | "Don't use. Instead use hold the pointer over." | CONFIRMED — DETECT-ONLY, not a swap (inflected forms "hovering"/"hovered" don't slot into the replacement phrase) |
|
|
177
|
+
| `google/no-uncheck` | [word-list#uncheck](https://developers.google.com/style/word-list#uncheck) | "use clear for checkboxes" | CONFIRMED. Bare `check` and `deselect` are deliberately NOT shipped — see "Author's judgment calls" |
|
|
178
|
+
| `google/scroll-to` | [word-list#scroll](https://developers.google.com/style/word-list#scroll) | "write go to the section, instead of scroll to the section" | CONFIRMED (preference, not a flat ban — `fix: false`) |
|
|
179
|
+
| `google/no-toggle-verb` | [ui-elements](https://developers.google.com/style/ui-elements) | "Don't use the word toggle as a verb. Describe the action." | CONFIRMED — citation correction: not a word-list entry as the draft implied, but is on the `ui-elements` page (verifier D) |
|
|
180
|
+
| `google/keyboard-keys` | [ui-elements](https://developers.google.com/style/ui-elements) | "Spell out the names of modifier keys"; "use uppercase instead of lowercase" | CONFIRMED |
|
|
181
|
+
| `google/chapter-terminology` | [word-list#chapter](https://developers.google.com/style/word-list#chapter) | "Instead, refer to documents, pages, or sections" | CONFIRMED, DETECT-ONLY |
|
|
182
|
+
|
|
183
|
+
### Plain language and wordiness — `warn`
|
|
184
|
+
|
|
185
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
186
|
+
|---|---|---|---|
|
|
187
|
+
| `google/plain-language-swaps` | [word-list](https://developers.google.com/style/word-list) | "allows_you_to: Don't use. Instead, use lets you"; "enable: Not recommended: ...enables you to..."; "comprise: Don't use. Instead, use consist of..."; "desire: Don't use. Instead, use a word like want or need"; "learnings: Don't use. Instead, refer to knowledge..."; "agnostic: Don't use. Instead, use...platform-independent" | CONFIRMED |
|
|
188
|
+
| `google/in-order-to` | [word-list#in_order_to](https://developers.google.com/style/word-list#in_order_to) | "Avoid in order to; instead, use to. Use in order to when needed to clarify meaning." | CONFIRMED (conditional — `fix: false`) |
|
|
189
|
+
| `google/utilize` | [word-list#utilize](https://developers.google.com/style/word-list#utilize) | "Use with caution. Don't use utilize when you mean use. It's OK to use utilize... when referring to the quantity of a resource being used." | CONFIRMED, DETECT-ONLY given the documented exception |
|
|
190
|
+
| `google/leverage` | [word-list#leverage](https://developers.google.com/style/word-list#leverage) | "Avoid using if you mean use... use, build on, or take advantage of." | CONFIRMED (`fix: false` — three valid alternatives given) |
|
|
191
|
+
| `google/performant` | [word-list#performant](https://developers.google.com/style/word-list#performant) | "Avoid where possible. Instead, use a more precise term." | CONFIRMED, DETECT-ONLY (no fixed replacement) |
|
|
192
|
+
| `google/copy-and-paste` | [word-list#Copy\_and\_paste](https://developers.google.com/style/word-list#Copy_and_paste) | "Avoid using. Instead, explain what to enter into a field and not how." | CONFIRMED |
|
|
193
|
+
| `google/create-a-new` | [word-list#Create\_a\_new](https://developers.google.com/style/word-list#Create_a_new) | "Avoid using unless you need to distinguish... Instead, use Create a ..." | CONFIRMED (exception noted; `fix: false`) |
|
|
194
|
+
| `google/no-run-the-following-command` | [procedures](https://developers.google.com/style/procedures) | "Avoid using run the following command to introduce code. Instead, focus on what the command does." | CONFIRMED |
|
|
195
|
+
| `google/cons-and-pros` | [word-list#pros](https://developers.google.com/style/word-list#pros) | "cons: Don't use. Instead, use a more precise term, such as disadvantages." / "pros: ...such as advantages." | CONFIRMED — only the compound phrase "pros and cons" ships; bare "pros"/"cons" are excluded, see "Author's judgment calls" |
|
|
196
|
+
|
|
197
|
+
### Product and brand names — `warn`
|
|
198
|
+
|
|
199
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
200
|
+
|---|---|---|---|
|
|
201
|
+
| `google/product-names` | [word-list](https://developers.google.com/style/word-list) | "Cloud SDK: Not Google Cloud SDK"; "APIs Explorer: Not API explorer..."; "API key: Not developer key or dev key"; "account name: ...use username"; "curated roles: ...use predefined roles"; "network IP address: ...use internal IP address"; "media type: ...Don't use MIME type"; "curl: Not cURL"; "interconnect type: ...use connection type"; "peering zone: Not peer zone"; "Android-powered device: Not Android device"; "Not...Cloud Platform, or Cloud" (Google Cloud); "Cloud console: Not...Developers Console" | CONFIRMED (each entry individually confirmed in verifier D's §3.4). Fix wave A: `'Cloud console'` gained a `(?<!Google )` lookbehind (self-compounding fix — see "Fix wave A corrections"); `GCP` moved to `google/gcp-name` below. Fix wave C: the lookbehind widened to `(?<![Gg][Oo][Oo][Gg][Ll][Ee]\s+)` (case-insensitive, whitespace-tolerant — see "Fix wave C corrections") |
|
|
202
|
+
| `google/gcp-name` | [word-list](https://developers.google.com/style/word-list) | "Not GCP...(Google Cloud)" | CONFIRMED, same verification as `google/product-names` above. Split out in Fix wave A (2026-07-29), `fix: false` — see "Fix wave A corrections". Fix wave C: `applyMatchCase` fixed at the engine, `fix: false` REMOVED — see "Fix wave C corrections" |
|
|
203
|
+
| `google/brand-capitalization` | [word-list](https://developers.google.com/style/word-list) | "Google Play services: Write services in lowercase."; "Google Account, Google Accounts: Capitalize Account."; "Markdown: Always capitalized."; "Material Design: Capitalize each word."; "Search Console: Capitalize each word." | CONFIRMED |
|
|
204
|
+
|
|
205
|
+
### Compound and one-word forms — `warn`
|
|
206
|
+
|
|
207
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
208
|
+
|---|---|---|---|
|
|
209
|
+
| `google/compound-forms` | [word-list](https://developers.google.com/style/word-list) (webpage via [hyphens](https://developers.google.com/style/hyphens)) | ~68 individual "Not X" / "X: Not Y" entries, e.g. "email: Not e-mail, Email, or E-mail."; "checkbox: Not check box."; "frontend: Not front-end or front end." | CONFIRMED (verifier C's 3.3 slice: ~68/70 confirmed; see "Fabrications"/"Dropped as unverified" for the 2 that didn't make it). Fix wave A: `colo` moved to `google/colo-form` below; `'in line': 'inline'` dropped (see "Dropped in Fix wave A" above) |
|
|
210
|
+
| `google/colo-form` | [word-list](https://developers.google.com/style/word-list) | "colocate: ...Not co-locate or colo." | CONFIRMED, same verification as `google/compound-forms` above. Split out in Fix wave A (2026-07-29), `fix: false` (noun/verb mismatch) — see "Fix wave A corrections" |
|
|
211
|
+
| `google/acronym-forms` | [word-list](https://developers.google.com/style/word-list) | "HTTPS: Not HTTPs."; "IPsec: Not IPSec."; "NoSQL: Not No-SQL or No SQL."; "OAuth 2.0: Not OAuth 2, OAuth2, or Oauth."; "microservices: Not micro-services."; "fintech: ...Don't use FinTech or fin-tech."; "ad tech: ...Don't use adtech or ad-tech." | CONFIRMED. `I-O`/`IO` → `I/O` confirmed individually. Fix wave A: `UNICODE`/`IPSEC` moved to `google/acronym-caps-detect-only` below; `SHA1` moved to `google/sha1-form` below; `Microservices` (capitalized form) dropped (see "Dropped in Fix wave A" above) |
|
|
212
|
+
| `google/acronym-caps-detect-only` | [word-list](https://developers.google.com/style/word-list) | "Unicode: Not UNICODE."; "IPsec: Not...IPSEC." | CONFIRMED, same verification as `google/acronym-forms` above. Split out in Fix wave A (2026-07-29), `fix: false` (case-preservation round-trip made the fix a permanent no-op) — see "Fix wave A corrections" |
|
|
213
|
+
| `google/sha1-form` | [word-list](https://developers.google.com/style/word-list) | "SHA-1: Not SHA1, except in string literals or enum values, and in hyphenated phrases such as HMAC-SHA1." | CONFIRMED (verifier C row 202). Split out in Fix wave A (2026-07-29), `fix: false` per this file's own header policy for rules with a documented guide exception — see "Fix wave A corrections" |
|
|
214
|
+
|
|
215
|
+
### Inclusive language / ableist language / jargon with people references — `warn`
|
|
216
|
+
|
|
217
|
+
| Rule id | Source URL | Quote | Verdict |
|
|
218
|
+
|---|---|---|---|
|
|
219
|
+
| `google/master-slave` | [word-list#slave](https://developers.google.com/style/word-list#slave) | "Don't use. Instead, use alternative terms... such as worker or replica." | CONFIRMED. Only "slave" ships; bare "master" is deliberately excluded — see "Author's judgment calls" |
|
|
220
|
+
| `google/blacklist-whitelist` | [word-list#blacklist](https://developers.google.com/style/word-list#blacklist) | "For the noun blacklist, consider... denylist, excludelist, or blocklist" / "whitelist...consider...allowlist, trustlist, or safelist" | CONFIRMED. Noun forms only — the guide itself says a word-for-word swap isn't the best fix for verb forms |
|
|
221
|
+
| `google/black-white-hat` | [word-list#blackhat](https://developers.google.com/style/word-list#blackhat) | "Don't use. Instead, use precise terms... such as illegal, unethical, or in violation of rules." | CONFIRMED |
|
|
222
|
+
| `google/black-white-box-testing` | [word-list#black-box](https://developers.google.com/style/word-list#black-box) | "For monitoring, use synthetic monitoring. For testing, use opaque-box testing." | CONFIRMED |
|
|
223
|
+
| `google/grayed-out` | [word-list#grayed-out](https://developers.google.com/style/word-list#grayed-out) | "Don't use. Instead, use unavailable." | CONFIRMED |
|
|
224
|
+
| `google/grandfathered` | [word-list#grandfathered](https://developers.google.com/style/word-list#grandfathered) | "Instead, use an adjective like legacy or exempt or a verb like made an exception." | CONFIRMED |
|
|
225
|
+
| `google/gendered-terms` | [word-list#man\_hours](https://developers.google.com/style/word-list#man_hours) | "man hours...Instead use terms like person hours"; "male adapter...use plug"; "he/she...use...they" | CONFIRMED |
|
|
226
|
+
| `google/jargon-with-people-references` | [word-list#ninja](https://developers.google.com/style/word-list#ninja) | "ninja: Don't use to refer to a person. Instead, use a term such as expert."; "DMZ...use...perimeter network"; and others | CONFIRMED |
|
|
227
|
+
| `google/ableist-figurative-terms` | [word-list#crazy](https://developers.google.com/style/word-list#crazy) | "use complicated, complex, baffling, strange, or unexpected...only for inanimate objects" | CONFIRMED. Restricted to the figurative/inanimate-object sense; "mad" and "hang"/"hung" excluded (see "Author's judgment calls") |
|
|
228
|
+
| `google/dummy-variable` | [word-list#dummy-variable](https://developers.google.com/style/word-list#dummy-variable) | "Don't use to refer to placeholders. Instead, use placeholder." | CONFIRMED |
|
|
229
|
+
| `google/blind-figurative` | [word-list#blind](https://developers.google.com/style/word-list#blind) | "blind to, blind eye to...use more precise terms like ignore, unaware of, disregard, avoid, or reject" | CONFIRMED, restricted to the figurative sense only (the SAME entry also covers "blind writes"/"blind change", real technical terms, deliberately not matched) |
|
|
230
|
+
| `google/unsighted-visually-challenged` | [word-list#unsighted](https://developers.google.com/style/word-list#unsighted) | "Don't use. See blind." | CONFIRMED — resolved to the PERSON-REFERENCE sense of "blind" (person who is blind/visually impaired/low-vision), NOT the figurative sense above, per task-9-author-corrections.md's explicit correction |
|
|
231
|
+
| `google/disability-language` | [inclusive-documentation](https://developers.google.com/style/inclusive-documentation) | "avoid terms such as the disabled or a quadriplegic"; "such as victim of, suffering from... instead, use... experiencing, living with" | CONFIRMED |
|
|
232
|
+
| `google/technical-jargon-precision` | [word-list#fat](https://developers.google.com/style/word-list#fat) | "use a precise modifier... high-capacity network connection instead of fat connection" | CONFIRMED — framed as technical-jargon precision, NOT ableist language, per task-9-author-corrections.md: Google's own entries for "chubby"/"fat" never mention people |
|
|
233
|
+
|
|
234
|
+
## Excluded candidates
|
|
235
|
+
|
|
236
|
+
Every candidate below was checked by one of the five verification passes
|
|
237
|
+
(or, where marked, judged independently by this preset's author) and is
|
|
238
|
+
**not** shipped, with the reason. This section exists so "why doesn't
|
|
239
|
+
`recheck/google` check X?" has a documented answer instead of looking like
|
|
240
|
+
an oversight.
|
|
241
|
+
|
|
242
|
+
### Fabrications (found nowhere on the live guide) — never ship
|
|
243
|
+
|
|
244
|
+
| Candidate | Why excluded |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `flesch-reading-ease` metric threshold | No basis anywhere in the guide — zero hits for flesch/reading-ease/readability/grade-level across every fetched page. The guide states only the qualitative principle ("use simpler words and shorter sentences"). Spec §5.6 and spec:215 independently rule out a `metric` rule in the flagship presets; shipping this would attribute an invented numeric mandate to Google under a CC-BY citation. |
|
|
247
|
+
| `respective`/`respectively` → rewrite | No such headword or rule exists anywhere in the word list or any topic page fetched (verifier C, independently re-confirmed by the cross-check). |
|
|
248
|
+
| `makes use of` → `uses` | Zero occurrences anywhere in the fetched pages (verifier C, cross-check). |
|
|
249
|
+
| `query string (not querystring)` | No entry anywhere on the word-list page or any cited topic page; a targeted search of the guide also returns nothing (verifier C, cross-check). |
|
|
250
|
+
| `real time`/`real-time` noun/verb pair | Zero hits in the parsed text or the raw HTML (verifier B, cross-check). |
|
|
251
|
+
| `robust` as a caution term | Does not appear anywhere in the current word list (verifier B, cross-check). |
|
|
252
|
+
|
|
253
|
+
### Dropped as unverified (real principle, no dedicated confirmable entry)
|
|
254
|
+
|
|
255
|
+
| Candidate | Why excluded |
|
|
256
|
+
|---|---|
|
|
257
|
+
| `user name` → `username` | No dedicated word-list entry; only inferable from `account name → username` and the general closed-compound principle. Per the verification contract, unverified means dropped, not shipped at a lower confidence. |
|
|
258
|
+
| N/A first-reference spell-out | The word-list entry only requires spelling out `N/A`/`NA` on FIRST reference, not a blanket ban — Recheck has no reliable way to track "is this the first reference" positionally across a document, so it's excluded rather than shipped as a (wrong) blanket swap. |
|
|
259
|
+
|
|
260
|
+
### TOO-RISKY (guide confirms it, but the "avoid" token is too ordinary/polysemous to blind-match)
|
|
261
|
+
|
|
262
|
+
These are all real, guide-stated preferences; none are shipped because the
|
|
263
|
+
literal string is common enough in unrelated, correct usage that a blind
|
|
264
|
+
`swap`/`pattern` would generate far more false positives than true ones.
|
|
265
|
+
|
|
266
|
+
| Candidate | Why excluded |
|
|
267
|
+
|---|---|
|
|
268
|
+
| `abort`, `kill`, `terminate` → stop/exit/cancel/end | Standard, correct technical vocabulary (process signals, transaction aborts, connection termination) with a guide-documented command-line-syntax carve-out a blind swap can't detect. |
|
|
269
|
+
| `execute` → run; `access` (verb); `possible`/`impossible`; `impact` (verb); `interface` (verb); `exploit`; `scale` (bare); `review` (="first read"); `each` (="all") | Each has a real but conditional/sense-scoped ruling; the bare word is common enough in the OTHER (unflagged) sense that a blind match would misfire constantly. |
|
|
270
|
+
| `simply`/`simple`, `easy`/`easily`, `quick`/`quickly`, `just` | The guide's own "try eliminating this word" framing has documented legitimate uses ("just" is explicitly OK "to convey that one approach is simpler"); a blind delete-swap fights the guide's own exception. |
|
|
271
|
+
| `America`/`American` (=USA sense) | Scoped to the USA-sense only; "American" (American English, American Express, Latin American) has far more legitimate uses than violations. |
|
|
272
|
+
| `Cloud` (bare, capitalized, standing for Google Cloud); `portal`/`dashboard` (meaning the Google Cloud console) | The guide explicitly permits lowercase "the cloud" generically, and "portal"/"dashboard" are ordinary words in enormously common non-Google-Cloud technical writing. |
|
|
273
|
+
| `PostgreSQL`/`Postgres`, `directory`/`folder`, `plain text`/`plaintext` | Context-conditional (match the UI's own wording; CLI vs. GUI; cryptography context only), not a free either-or `consistency` pair — shipping as unconditional would mis-enforce legitimate context-appropriate variation. |
|
|
274
|
+
| `firewalls` → `firewall rules` | Scoped to Compute Engine/networking documentation only; "outside of [that], the term firewalls is acceptable" per the guide's own text — Recheck can't detect document subject matter. |
|
|
275
|
+
| `deselect` (bare, banned) | **Wrong to ship at all**: `deselect` is Google's own correct/recommended term for NON-checkbox UI elements ("use clear for checkboxes, and deselect for other UI elements"). Only `uncheck` (unambiguously checkbox-only in meaning) is shipped. |
|
|
276
|
+
| bare `check` (verb) | Extremely polysemous ("check the logs", "check that X is true") — only the unambiguous `uncheck` ships. |
|
|
277
|
+
| `hit` (UI click synonym) | "hit" is extremely common in unrelated technical senses (cache hit, rate limit hit); the guide's UI-click sense can't be isolated by a blind pattern. |
|
|
278
|
+
| `type` → `enter` | "type" is one of the most common words in technical prose in unrelated senses (data type, type of X); too ambiguous to match blindly. |
|
|
279
|
+
| `menu item`/`choice`/`option` → `command` | "option"/"choice" are common ordinary words far outside the menu-item sense the guide targets. |
|
|
280
|
+
| bare `master` | Google's own quote scopes the objection to the master/slave PAIRING ("Never use in conjunction with slave"), not the standalone word, which has many unrelated legitimate senses (master's degree, master key, master bedroom). Only `slave` ships. |
|
|
281
|
+
| `drag and drop` (as opposed to `click and drag`) | Commonly and correctly used as a noun/adjective ("drag-and-drop interface"); only the unambiguous verb phrase `click and drag` ships. |
|
|
282
|
+
| `hang`/`hung` (of a system) | Extremely polysemous outside the system sense ("hung the picture", "hung jury", "hang up the phone"). |
|
|
283
|
+
| `healthy` (of a system) → responsive | Polysemous even in technical prose ("a healthy amount of caution", "healthy competition"). |
|
|
284
|
+
| `mad` (ableist figurative sense) | At least as commonly used to mean "angry", a sense the guide never objects to. |
|
|
285
|
+
| `abnormal`, `deficient`, `deformed` (of a person) | Explicitly "OK to refer to a condition of a computer system"; unscoped, these would misfire on ordinary error-handling prose ("abnormal termination", "abnormal exit code"). |
|
|
286
|
+
| `gimp`/`gimpy`, `lame` | `gimp` has an explicit carve-out for the GIMP image editor and similarly-named tools; neither has a fixed replacement token, and both are DETECT-ONLY at best. |
|
|
287
|
+
| `native` (of people); `target` (verb, of people) | Both are advisory ("avoid... when possible") and the words themselves are ubiquitous in unrelated, correct senses ("native app", "cloud-native", "target audience"). |
|
|
288
|
+
| `above`/`below`/`higher`/`lower`/`older` (version-range words) | Explicitly OK when non-directional ("below average", describing a hierarchy) and reversed for Android docs; only safe when anchored to an unambiguous version-number context, which a blind pattern can't establish. |
|
|
289
|
+
| `tap`/`click` (touch vs. desktop) | Requires knowing whether the document targets a touch device, which Recheck cannot infer from text alone. |
|
|
290
|
+
|
|
291
|
+
### DETECT-ONLY entries not shipped
|
|
292
|
+
|
|
293
|
+
Real, confirmed guide content with no fixed replacement, excluded here
|
|
294
|
+
because a generic "avoid this" pattern for these specific terms was judged
|
|
295
|
+
lower-value than the DETECT-ONLY rules that did ship (`no-via`, `no-hover`,
|
|
296
|
+
`utilize`, `performant`, `chapter-terminology`, `blind-figurative`):
|
|
297
|
+
|
|
298
|
+
| Candidate | Why excluded |
|
|
299
|
+
|---|---|
|
|
300
|
+
| `persist` (transitive verb) | "Don't use as a transitive verb... best to avoid using as a verb at all" — no fixed replacement token, needs a rewrite. |
|
|
301
|
+
| `comply`/`compliant` | Advisory caution only ("a claim that a product is compliant... is a strong statement"), no replacement at all — not a lint-shaped rule. |
|
|
302
|
+
| `CLI` (bare, generic) | Needs "the specific CLI", which varies by context; no fixed swap target. |
|
|
303
|
+
| `gray-box`/`graybox` testing | "describe exactly what it's doing" — no fixed term, and `translucent-box testing` is only an example, not a mandate. |
|
|
304
|
+
| `tribal knowledge`/`wisdom` | "use a less figurative term" — no fixed replacement. |
|
|
305
|
+
| `anti-pattern`, `canary`/`canarying` (verb), `best effort`, `out of the box` (figurative), `reservation, off the`, `voila` | Each is "avoid"/"don't use" with no fixed replacement token; the underlying content is confirmed but not independently high-value enough to ship as a detection-only pattern rule in this pass. |
|
|
306
|
+
| `physically challenged`, `special`, `differently abled`, `handi-capable` | DETECT-ONLY per `inclusive-documentation`, no replacement offered. |
|
|
307
|
+
| `right-hand side` (directional language, generally) | DETECT-ONLY, no fixed replacement — see also the TOO-RISKY note on `above`/`below` above; directional language generally was judged too broad to ship as its own rule (see "Author's judgment calls"). |
|
|
308
|
+
|
|
309
|
+
### NOISY (verifier-confirmed content, judged too broad to enforce)
|
|
310
|
+
|
|
311
|
+
**Accounting note, so the count below is checkable.** The task-9 corrections
|
|
312
|
+
brief referred to "the 32 NOISY candidates from the research"
|
|
313
|
+
(`research-google-style.md`'s own §4 tally). That figure is a count over a
|
|
314
|
+
*different* population, using a *different* taxonomy, than this file's own
|
|
315
|
+
four-row table below. The research draft numbered 146 candidate "rule
|
|
316
|
+
ideas" and gave each one its own provisional, pre-verification classification
|
|
317
|
+
(CLEAN/NOISY/NOT-ENFORCEABLE); 32 of those 146 rows carried NOISY as their
|
|
318
|
+
first-stated verdict. This preset was not built by re-litigating those 146
|
|
319
|
+
rows one-by-one — the five verification passes instead checked candidate
|
|
320
|
+
content directly against the live guide's word-list and topic pages
|
|
321
|
+
(~380 distinct entries, a finer unit than the 146 rows: e.g. one draft row
|
|
322
|
+
can bundle a dozen word-list headwords). Cross-referencing the specific
|
|
323
|
+
32 research-draft NOISY rows against what this file actually contains:
|
|
324
|
+
|
|
325
|
+
- **6 ended up shipped anyway**, because a narrower scope, `fix: false`,
|
|
326
|
+
or a detection-only rule shape resolved the original noise concern
|
|
327
|
+
instead of requiring exclusion: `heading-sentence-case` (row 1, `fix:
|
|
328
|
+
false` + the `exceptions` mechanism), `no-code-in-heading` (row 9,
|
|
329
|
+
scoped to headings), `second-person` (row 13, detection-only),
|
|
330
|
+
`use-contractions` (row 17, `fix: false`), the timeless-documentation
|
|
331
|
+
words (row 29, 5 of ~15 shipped; see "Author's judgment calls" below for
|
|
332
|
+
the rest), and `copy-and-paste` (row 91, the copy/paste half only — the
|
|
333
|
+
same row's keyboard-shortcut suggestion was not shipped or excluded
|
|
334
|
+
anywhere, see below).
|
|
335
|
+
- **5 correspond exactly to this table's own four rows** below (row 6 →
|
|
336
|
+
`no-gerund-headings`; row 52 → `no-slashes-general`; row 95 → table
|
|
337
|
+
sentence-case; rows 100 and 102 → the shared `no-quotes-around-code` /
|
|
338
|
+
`no-angle-brackets-around-code` row).
|
|
339
|
+
- **2 correspond to NOT-ENFORCEABLE entries** below (row 39 → `oxford-comma`;
|
|
340
|
+
row 123 → gendered pronouns used generically).
|
|
341
|
+
- **1 splits across two other tables**: row 145 ("console"/"CLI"/"UI"/
|
|
342
|
+
"Cloud"/"mobile" used bare) has its "CLI" part in DETECT-ONLY above and
|
|
343
|
+
its "Cloud" part in TOO-RISKY above; the "UI"/"mobile" parts of that same
|
|
344
|
+
row aren't reflected anywhere.
|
|
345
|
+
- **The remaining 18 do not reappear anywhere in this file** — shipped,
|
|
346
|
+
excluded, or otherwise: nonbreaking space before a unit (row 69),
|
|
347
|
+
thousands-separator commas (row 61), avoiding seasons (row 65), SVG over
|
|
348
|
+
PNG (row 113), not forcing line breaks (row 115), inline HTML (row 116),
|
|
349
|
+
comma before "which"/"because" (rows 48-49), a colon instead of a dash to
|
|
350
|
+
introduce a list item (row 44), ambiguous-conjunction swaps like
|
|
351
|
+
since/while/once (row 131), modal-verb guidance (row 132), noun/verb form
|
|
352
|
+
pairs like setup/set up (row 133), spell-checking prose generally (row
|
|
353
|
+
142), foo/bar/baz placeholders (row 144), present tense / avoiding
|
|
354
|
+
will/would (row 16), the screen-reader punctuation caution (row 22), and
|
|
355
|
+
10x-style symbol substitutions (row 37). Their absence here means they
|
|
356
|
+
were never carried into the five verifiers' own ~380-entry check —
|
|
357
|
+
**not** that a verifier confirmed them and this preset silently dropped
|
|
358
|
+
them. Anyone who wants a disposition for one of those 18 specific ideas
|
|
359
|
+
should treat it as unverified against the live guide, not as any of this
|
|
360
|
+
file's excluded categories, and it is not shipped.
|
|
361
|
+
|
|
362
|
+
The four rows below are this preset's own, narrower "NOISY" bucket: guide
|
|
363
|
+
content a verifier independently confirmed as real, but judged too broad to
|
|
364
|
+
enforce as a rule. That is a stricter, verifier-anchored sense of "NOISY"
|
|
365
|
+
than the research draft's own pre-verification tally, which is why the
|
|
366
|
+
counts don't and shouldn't match.
|
|
367
|
+
|
|
368
|
+
| Candidate | Why excluded |
|
|
369
|
+
|---|---|
|
|
370
|
+
| `no-gerund-headings` (heading starting with an -ing word, except Billing/Pricing) | Confirmed principle, but the enforcement shape (first word ends in "-ing") would misfire heavily on common tech-noun headings used as topics, not verb-form imperatives (Networking, Logging, Caching, Monitoring, Testing) — Google names only two exceptions, which is itself evidence the underlying judgment needs more context than a heading's first word. |
|
|
371
|
+
| `no-quotes-around-code`, `no-angle-brackets-around-code` | Confirmed, but the draft itself already flagged these as NOISY; not re-litigated. |
|
|
372
|
+
| table sentence-case (`Use sentence case for all the elements in a table`) | Confirmed, but table cells often legitimately contain short labels, proper nouns, or numeric/code values that don't fit sentence-case cleanly (verifier B row 95, marked NOISY). |
|
|
373
|
+
| `no-slashes-general` (`Avoid using slashes, except in code`) | Too broad — slashes appear constantly in dates, paths, fractions, and URLs; the draft itself marked this NOISY/dropped. |
|
|
374
|
+
|
|
375
|
+
### NOT-ENFORCEABLE (real guide content, requires human judgment)
|
|
376
|
+
|
|
377
|
+
| Candidate | Why excluded |
|
|
378
|
+
|---|---|
|
|
379
|
+
| `optional-prefix` (use "Optional:" prefix in headings) | Requires knowing whether a section is genuinely optional — not something the linter can determine. |
|
|
380
|
+
| `complete-list-intro` (text before a colon must be a complete sentence) | Requires grammatical-completeness judgment beyond regex/AST primitives. |
|
|
381
|
+
| `oxford-comma` (missing comma before the final "and"/"or" in a list) | Confirmed content, but reliably detecting a MISSING Oxford comma without a high false-positive rate on ordinary two-clause sentences needs real list/clause parsing, not regex. |
|
|
382
|
+
| `abbrev-as-verb` (don't use acronyms as verbs, e.g. "ping the server") | Requires knowing a word's grammatical role (verb vs. noun), which the engine's primitives can't determine. |
|
|
383
|
+
| `abbrev-first-use` (spell out an abbreviation on first mention) | Requires positional "is this the first mention" tracking across an arbitrary, unbounded set of abbreviations. |
|
|
384
|
+
| `no-duplicate-link-destinations` (avoid linking one destination from different texts) | The guide states explicit exceptions (linking to a different section, a long page, multiple entry points) that the engine's existing token rule — which fires on same-destination/different-anchor-text — can't evaluate against. (The rule remains available generically via `recheck/markdown` for projects that want it unconditionally; it just isn't part of this style-fidelity preset.) |
|
|
385
|
+
| external link icon (`Don't use an external link icon`) | About a rendered visual icon/CSS class, not markdown text — nothing to match. |
|
|
386
|
+
| `ui-element-ellipsis` (drop the "..." from a UI element name reference) | Requires reliably identifying "this text is quoting a UI element name", which risks both over- and under-firing with a regex. |
|
|
387
|
+
| `no-directional-language` (above/below/right-hand side as spatial UI references) | The guide's objection is to visual/spatial positioning language specifically; a text pattern can't distinguish that from the equally common non-directional uses of the same words (see the TOO-RISKY note above). |
|
|
388
|
+
| `button-for-link` ("a link isn't the same as a button") | Requires knowing whether a referenced UI element is actually a button or a link, which text alone doesn't establish. |
|
|
389
|
+
| gendered pronouns used generically (bare he/him/his/she/her) | Requires knowing whether a pronoun refers to a specific named person or is used generically — text alone can't distinguish. |
|
|
390
|
+
| "introduce a table in the text preceding it"; the large "what belongs in code font" table; "don't pre-announce anything... unless approved by legal counsel"; "don't use metaphors"; passive voice ("make clear who's performing the action") | All require holistic judgment about content/structure/legal status that the engine's regex/AST primitives cannot evaluate. |
|
|
391
|
+
|
|
392
|
+
### Dropped in Fix wave A (confirmed content, but not safely fixable/matchable)
|
|
393
|
+
|
|
394
|
+
An independent review (task 9, fix wave A, 2026-07-29) reproduced four
|
|
395
|
+
demonstrable prose-corruption defects and diagnosed a structural coverage
|
|
396
|
+
gap that let 85 of the preset's 86 swap pairs ship with zero fixture
|
|
397
|
+
coverage. These candidates were CONFIRMED guide content (they were already
|
|
398
|
+
shipping) but are dropped here rather than fixed, because no safe
|
|
399
|
+
detection/fix shape was achievable with the assertions available — see
|
|
400
|
+
`task-9-report.md`'s "Fix wave A" section for the full defect list, every
|
|
401
|
+
fix applied, and the re-run acceptance evidence.
|
|
402
|
+
|
|
403
|
+
| Candidate | Why excluded |
|
|
404
|
+
|---|---|
|
|
405
|
+
| `'in line': 'inline'` (space-separated form, `google/compound-forms`) | Google's own quote ("One word as an adjective, inline, not in line or in-line") only objects to the ADJECTIVAL use, but bare "in line" is at least as commonly the correct idiom "in line with" or the plain verb phrase "wait in line"/"stand in line", neither of which the guide says anything about. Reproduced: `"This change is in line with the platform roadmap."` was being rewritten to `"...is inline with..."`. There's no reliable regex-only way to tell the wrong adjectival use apart from the idiom, so the key is dropped rather than shipped fixable or even detection-only. `'in-line': 'inline'` (the hyphenated form) is KEPT — it doesn't collide with the "in line with"/"wait in line" idioms, which are never written hyphenated. |
|
|
406
|
+
| `'API Console': 'Google Cloud console'` (`google/product-names`) | Verifier B row 125 flagged that it doesn't map cleanly — the guide's own text offers "Google APIs Explorer **or** the Google Cloud console" by context, and which one is meant depends on what the original "API Console" reference meant. Not in verifier C's confirmed-clean list either. |
|
|
407
|
+
| `Microservices: 'microservices'` (`google/acronym-forms`) | Fires on legitimate sentence-initial capitalization ("Microservices deployed on the platform can scale independently...") just as readily as on the actual violation (mid-sentence "the Microservices approach"), and `applyMatchCase` re-capitalizes the replacement to match the (all-caps-adjacent) matched casing, so the "fix" is a permanent no-op — an unsuppressible warning either way. There's no reliable way to detect "sentence-initial" from a `swap` pair alone. The lowercase/hyphenated form `'micro-services': 'microservices'` is KEPT (case-sensitive, so it never matches a legitimately-capitalized sentence start). |
|
|
408
|
+
|
|
409
|
+
## Deliberation and development history
|
|
410
|
+
|
|
411
|
+
Everything from here on records how the shipped and excluded lists above
|
|
412
|
+
were reached: sourcing/hashing methodology, the fabrications an earlier
|
|
413
|
+
draft introduced, the successive fix waves that corrected or excluded
|
|
414
|
+
specific pairs, and the axes a pair must clear before auto-fix is safe.
|
|
415
|
+
**A reader who only wants provenance can stop reading above this point** —
|
|
416
|
+
everything below is for someone auditing or extending this preset.
|
|
417
|
+
|
|
418
|
+
### `sources.json` normalization
|
|
419
|
+
|
|
420
|
+
`sources.json` records one hash per source page as drift detection for a
|
|
421
|
+
future re-check: re-fetch a page later, and a changed digest means the
|
|
422
|
+
guide's content changed. The version of this file that shipped before
|
|
423
|
+
this pass hashed the raw HTML response directly. That does not work as
|
|
424
|
+
drift detection: every `developers.google.com/style/*` page embeds a
|
|
425
|
+
per-request `<script type="application/json" analytics>` blob whose JSON
|
|
426
|
+
keys serialize in non-deterministic order, a CSP `nonce` attribute
|
|
427
|
+
regenerated on every request, and an inline feature-flag/experiment
|
|
428
|
+
bootstrap array whose element order also varies per request. None of that
|
|
429
|
+
reflects the guide's actual content, but it's enough entropy that two
|
|
430
|
+
consecutive fetches of the identical page produce different raw-HTML
|
|
431
|
+
digests every time — confirmed empirically: of the 30 pages listed in
|
|
432
|
+
`sources.json`, fetched twice each a few seconds apart, 16 had a different
|
|
433
|
+
raw byte length on the second fetch even though nothing about the guide's
|
|
434
|
+
content changed. Hashing raw HTML gives a 100% false-positive drift rate,
|
|
435
|
+
which is not drift detection at all — it's noise indistinguishable from
|
|
436
|
+
signal.
|
|
437
|
+
|
|
438
|
+
**Fix**: hash the extracted `<article class="devsite-article">...</article>`
|
|
439
|
+
region instead of the full page. That region is exactly the guide's
|
|
440
|
+
rendered content (headings, paragraphs, lists, tables, the `<dl>`
|
|
441
|
+
definition lists the word-list page is built from) and excludes all of
|
|
442
|
+
the non-deterministic chrome described above. Verified reproducible: two
|
|
443
|
+
consecutive fetches of all 30 pages in `sources.json` (not just a sample)
|
|
444
|
+
produced a byte-identical extracted region, and therefore an identical
|
|
445
|
+
sha256, for every single page — including the 16 whose raw HTML length
|
|
446
|
+
differed between fetches. Reproduction recipe: fetch the page's HTML with
|
|
447
|
+
**`curl`** (Fix wave C / Item 4: a plain Node `fetch()` was confirmed to
|
|
448
|
+
return a materially different HTML variant of the same URL — not just the
|
|
449
|
+
per-request noise above, but a different response shape from the same
|
|
450
|
+
client-vs-client comparison — so a future re-check that fetches with a
|
|
451
|
+
different HTTP client could see a mismatch and misread it as guide drift;
|
|
452
|
+
`sources.json`'s `normalization.fetchMethod` now records this too), take
|
|
453
|
+
the first `<article class="devsite-article">...</article>` match (a
|
|
454
|
+
non-greedy, dot-matches-newline regex scan; every page has exactly one),
|
|
455
|
+
and sha256 the UTF-8 bytes of that substring.
|
|
456
|
+
|
|
457
|
+
Each `sources.json` entry also records `bytes` — the byte length of the
|
|
458
|
+
extracted region, not the raw page — so a future re-check that produces a
|
|
459
|
+
matching `bytes` but a different `sha256` (or vice versa) is a signal to
|
|
460
|
+
check whether the *extraction* shape changed (e.g. Google renamed the
|
|
461
|
+
wrapper class) before treating the result as real guide drift.
|
|
462
|
+
|
|
463
|
+
This normalization has a real, narrow blind spot: a change confined
|
|
464
|
+
entirely to the `<article>` wrapper's own attributes, or to guide content
|
|
465
|
+
that Google renders outside that element, would not be detected. No such
|
|
466
|
+
case was observed across any of the 30 pages while producing this file.
|
|
467
|
+
|
|
468
|
+
### Fix wave A corrections (2026-07-29)
|
|
469
|
+
|
|
470
|
+
Beyond the drops above, several shipped pairs were corrected in place —
|
|
471
|
+
same rule content, safer matching or `fix: false` — rather than dropped,
|
|
472
|
+
because the underlying guide entry is real and worth keeping. Full
|
|
473
|
+
before/after detail, reproduction commands, and gate output live in
|
|
474
|
+
`task-9-report.md`; this is the pointer from provenance to what changed
|
|
475
|
+
and why, so a rule split doesn't read as an unexplained addition.
|
|
476
|
+
|
|
477
|
+
- **`google/no-latinisms` split in two.** The period-terminated keys
|
|
478
|
+
(`i.e.`, `e.g.`, `vs.`) keep `wordBoundary: false` (a trailing `\b`
|
|
479
|
+
right after a period-then-space never matches — both are non-word
|
|
480
|
+
characters) but now carry a LEADING `\b` baked into the regex source via
|
|
481
|
+
`keysAreRegex`, so `vs.` can no longer match inside unrelated words like
|
|
482
|
+
"revs.". `aka` and `vice versa` (no trailing period, so they never
|
|
483
|
+
needed the exemption) moved to a new rule, `google/no-latinisms-plain`,
|
|
484
|
+
with full `wordBoundary: true` anchoring — this is what stops `aka` from
|
|
485
|
+
matching inside "Akamai"/"Osaka".
|
|
486
|
+
- **`google/no-slash-abbrev`** (`c/o`, `w/`) similarly gained a
|
|
487
|
+
leading-only `\b` via `keysAreRegex`, so `w/` no longer matches inside
|
|
488
|
+
"www/static", "show/hide", "new/old", and `c/o` no longer matches inside
|
|
489
|
+
"src/output".
|
|
490
|
+
- **`google/acronym-forms`**: `'OAuth 2'` gained a `(?!\.0)` negative
|
|
491
|
+
lookahead so it can no longer match inside the already-correct "OAuth
|
|
492
|
+
2.0" (which was compounding into "OAuth 2.0.0.0.0.0.0" under
|
|
493
|
+
`runRulesUntilStable`). `SHA1` moved to its own rule
|
|
494
|
+
(`google/sha1-form`, `fix: false`) with a negative lookbehind excluding
|
|
495
|
+
a hyphen-preceded match, matching the guide's own documented
|
|
496
|
+
hyphenated-compound exception (e.g. "HMAC-SHA1"). `UNICODE` and `IPSEC`
|
|
497
|
+
moved to `google/acronym-caps-detect-only` (`fix: false`): both are
|
|
498
|
+
ALL-CAPS matches whose correct replacement (`Unicode`/`IPsec`), when
|
|
499
|
+
`applyMatchCase` re-upper-cases it to match the all-caps input, round-trips
|
|
500
|
+
back to the ORIGINAL wrong spelling byte-for-byte — a permanent,
|
|
501
|
+
silent no-op fix that `--fix` nonetheless reported as "fixed".
|
|
502
|
+
- **`google/product-names`**: `'Cloud console'` gained a `(?<!Google )`
|
|
503
|
+
negative lookbehind — it's a literal substring of its own replacement
|
|
504
|
+
("Google Cloud console"), so it was compounding a "Google " prefix every
|
|
505
|
+
pass, the same failure shape as the OAuth 2 bug above (and it fed the
|
|
506
|
+
same bug via `'Developers Console'`'s own correct output). `GCP` moved
|
|
507
|
+
to its own rule (`google/gcp-name`, `fix: false`): `applyMatchCase`
|
|
508
|
+
upper-cases an all-caps match's ENTIRE multi-word replacement, so
|
|
509
|
+
"GCP" -> "Google Cloud" was being written as "GOOGLE CLOUD".
|
|
510
|
+
- **`google/colo-form`**: split out of `google/compound-forms`, `fix:
|
|
511
|
+
false`. `colo` is a noun ("a colocation facility"); `colocate` is a
|
|
512
|
+
verb — the unconditional swap produced "The colocate hosts the racks."
|
|
513
|
+
- **`google/no-please-note`**: `fix: false` added. Deleting the phrase
|
|
514
|
+
leaves a capitalization/fragment mess behind ("Please note that the
|
|
515
|
+
endpoint is deprecated." -> "that the endpoint is deprecated.").
|
|
516
|
+
- **`google/second-person`**: `ignoreCase: true` replaced with an explicit
|
|
517
|
+
`(?:We|we|Our|our|Us|us)` alternation, so it no longer matches the
|
|
518
|
+
all-caps abbreviation "US" that `google/us-abbreviation` fixes toward —
|
|
519
|
+
previously the two rules fought each other on every occurrence of "US".
|
|
520
|
+
|
|
521
|
+
All of the above were found and fixed by the per-PAIR coverage gate added
|
|
522
|
+
in the same pass (`src/config/__tests__/preset-google.test.ts`'s "per-pair
|
|
523
|
+
coverage" test) plus targeted idempotency/self-match static analysis — see
|
|
524
|
+
`task-9-report.md` for the methodology and the complete list.
|
|
525
|
+
|
|
526
|
+
### Fix wave C corrections (2026-07-29)
|
|
527
|
+
|
|
528
|
+
An independent re-review found this same `applyMatchCase` bug — an
|
|
529
|
+
ALL-CAPS match forcing a multi-word replacement to shout — recurring a
|
|
530
|
+
THIRD time (`AKA` -> `ALSO KNOWN AS`, `VICE VERSA` -> `THE OTHER WAY
|
|
531
|
+
AROUND`, `C/O` -> `CARE OF`, all in rules that shipped with no `fix: false`
|
|
532
|
+
workaround at all), after `GCP` and `UNICODE`/`IPSEC` above had each been
|
|
533
|
+
patched around it per-rule. This wave fixed it at the source instead
|
|
534
|
+
(`src/core/case-preserve.ts`'s `applyMatchCase`): an ALL-CAPS match no
|
|
535
|
+
longer forces a MULTI-WORD replacement to upper-case; single-word
|
|
536
|
+
replacements are unchanged (`WHITELIST` -> `ALLOWLIST` still shouts — that
|
|
537
|
+
remains correct). Two statements above are now stale as a result:
|
|
538
|
+
|
|
539
|
+
- **`GCP` is fixable again.** `google/gcp-name`'s `fix: false` (added
|
|
540
|
+
above specifically because `applyMatchCase` was shouting "GOOGLE CLOUD")
|
|
541
|
+
is REMOVED — the engine fix produces the correctly-cased `"Google
|
|
542
|
+
Cloud"` now, and the result is idempotent. `UNICODE`/`IPSEC`
|
|
543
|
+
(`google/acronym-caps-detect-only`) were re-checked against the same
|
|
544
|
+
engine fix and correctly stay `fix: false`: their replacements
|
|
545
|
+
(`Unicode`, `IPsec`) are each a single word, so the multi-word condition
|
|
546
|
+
never applies and the round-trip no-op is unchanged — a genuinely
|
|
547
|
+
different defect shape (same-word casing round-trip, not a
|
|
548
|
+
multi-word-phrase shout), not something this engine fix was meant to
|
|
549
|
+
reach.
|
|
550
|
+
- **`google/product-names`'s `'Cloud console'` lookbehind widened.** The
|
|
551
|
+
`(?<!Google )` guard above only blocked the exact casing `Google `
|
|
552
|
+
(single space); `(?<![Gg][Oo][Oo][Gg][Ll][Ee]\s+)` now blocks any casing
|
|
553
|
+
of "google" followed by any run of whitespace, closing the same
|
|
554
|
+
self-compounding duplication (`"google Cloud console"` ->
|
|
555
|
+
`"google Google Cloud console"`) the original fix was meant to
|
|
556
|
+
eliminate but didn't fully.
|
|
557
|
+
- **`google/no-slash-abbrev` gained a trailing guard.** The leading-only
|
|
558
|
+
`\b` above fixed matches inside a preceding word (`"src/output"`,
|
|
559
|
+
`"www/static"`) but left the TRAILING side open: `w/` still matched
|
|
560
|
+
inside the common, ordinary abbreviation `w/o` ("without"), and `c/o`
|
|
561
|
+
inside a word immediately following it (`"c/oscillator"`). Both keys now
|
|
562
|
+
carry a trailing `(?![A-Za-z])` negative lookahead blocking a following
|
|
563
|
+
ASCII letter, so `w/o` and `c/oscillator` are left alone entirely (the
|
|
564
|
+
guide's own `slashes` page doesn't list "w/o" as a separate entry),
|
|
565
|
+
while `"w/ headers"` and `"c/o the compliance department"` still match.
|
|
566
|
+
|
|
567
|
+
See `task-9-report.md`'s "Fix wave C" section for the full list of every
|
|
568
|
+
rule whose `--fix` output changed as a result of the engine change (9
|
|
569
|
+
rules / 38 pairs across this preset alone — larger than the three rules
|
|
570
|
+
named above, since the fix is in the shared helper every `swap` rule
|
|
571
|
+
uses), the semantics chosen and why, and the complete acceptance evidence.
|
|
572
|
+
|
|
573
|
+
### CONFIRMED vs. safe-to-fix — a distinction future audits of this preset must also apply
|
|
574
|
+
|
|
575
|
+
Recorded here in mirror of `presets/microsoft/PROVENANCE.md`'s "Fix wave C /
|
|
576
|
+
Step 5" (task 10), per that task's brief: a verifier `CONFIRMED` verdict
|
|
577
|
+
establishes only that the live guide page discusses a term. It does **not**
|
|
578
|
+
establish that a blind textual (`swap`) substitution of that term is safe
|
|
579
|
+
to auto-apply — that is a separate question, and every verification pass
|
|
580
|
+
in task 10 conflated the two. `recheck/microsoft`'s task-10 fix wave C
|
|
581
|
+
found two pairs (`as well as` -> `and`, `or greater`/`or higher`/`or lower`
|
|
582
|
+
-> `or later`/`or earlier`) that were marked plain `CONFIRMED`, with the
|
|
583
|
+
correct quote attached, and still shipped as corrupting unconditional
|
|
584
|
+
swaps: the quotes themselves showed a caution against treating two terms as
|
|
585
|
+
interchangeable ("don't use X as a synonym for Y") or a context scoped
|
|
586
|
+
narrower than what shipped ("when identifying multiple versions..."), not
|
|
587
|
+
an unconditional "use Y instead of X" instruction.
|
|
588
|
+
|
|
589
|
+
This note is a forward-looking record, not a claim that this file's own
|
|
590
|
+
pairs were re-audited against that standard — that re-audit is out of
|
|
591
|
+
scope for task 10 (which targets `recheck/microsoft`) and has not been
|
|
592
|
+
done here. Whoever next adds a candidate pair to this preset, or authors
|
|
593
|
+
either of the two future presets task 10 anticipates, should apply the
|
|
594
|
+
same per-pair check `recheck/microsoft`'s Step 1 table used before marking
|
|
595
|
+
a `CONFIRMED` pair fixable: is the live quote a direct "Use Y, not X"
|
|
596
|
+
instruction, or does it instead read as a synonym-conflation caution, a
|
|
597
|
+
verb/context-scoped rule, a multi-target rule, or a "don't use X" with no
|
|
598
|
+
replacement stated? Only the first shape is safe to ship as an
|
|
599
|
+
unconditional `swap`; the rest need a position anchor, a narrower scope, or
|
|
600
|
+
detection-only, in that preference order. A `CONFIRMED` verdict is
|
|
601
|
+
necessary evidence that a rule belongs in the preset at all — it is not
|
|
602
|
+
sufficient evidence that the rule may safely auto-fix.
|
|
603
|
+
|
|
604
|
+
**This note's own re-audit did eventually happen** — see "Fix-posture
|
|
605
|
+
change" below, which re-audits every fixable pair in THIS preset against a
|
|
606
|
+
second, orthogonal axis the note above doesn't cover, and replaces the
|
|
607
|
+
"CONFIRMED vs. safe-to-fix" framing with a stricter, mechanical posture.
|
|
608
|
+
|
|
609
|
+
### Fix-posture change (2026-07-30)
|
|
610
|
+
|
|
611
|
+
> **RETIRED 2026-07-30 — see "Detection-only" below.** This section's
|
|
612
|
+
> criterion (same-word normalization) no longer determines which pairs are
|
|
613
|
+
> fixable in this preset: none are. Kept as historical record only.
|
|
614
|
+
|
|
615
|
+
Base commit `eb4f8b11dac`, branch `aa/recheck-style-guides`. Brief:
|
|
616
|
+
`.superpowers/sdd/preset-fix-posture-brief.md`. Report:
|
|
617
|
+
`.superpowers/sdd/preset-fix-posture-report.md`. Applied to both flagship
|
|
618
|
+
presets in the same pass — see `presets/microsoft/PROVENANCE.md`'s own
|
|
619
|
+
"Fix-posture change" section for the full two-axis rationale and the six
|
|
620
|
+
named corruption strings that motivated it (three fix waves on
|
|
621
|
+
`recheck/microsoft`, each fixing the pairs a probe found, each followed by
|
|
622
|
+
another probe finding more — 2, then 2, then 6). This preset shipped nine
|
|
623
|
+
of the same defect class across its own three fix waves (`GCP` shouting,
|
|
624
|
+
`OAuth 2` self-compounding, `w/o`/`c/oscillator` corruption, ...) — the
|
|
625
|
+
CONFIRMED-vs-safe-to-fix note above addresses the GUIDANCE-SHAPE axis
|
|
626
|
+
(direct instruction vs. caution/scoped/multi-target); it does not address
|
|
627
|
+
a second, orthogonal axis: whether the avoid-term ALSO has a legitimate,
|
|
628
|
+
unrelated sense a blind substitution corrupts regardless of how clearly
|
|
629
|
+
the guide states its rule.
|
|
630
|
+
|
|
631
|
+
#### The posture
|
|
632
|
+
|
|
633
|
+
Auto-fix is retained only where a replacement cannot be wrong: the same
|
|
634
|
+
word, normalized (spelling, hyphenation, casing, or a non-standard written
|
|
635
|
+
form of the identical word). A pair that substitutes a genuinely different
|
|
636
|
+
word or phrase — even a synonym that looks safe on the page — moves to
|
|
637
|
+
detection-only. Concrete examples found THIS wave, previously shipped
|
|
638
|
+
fixable under a plain `CONFIRMED`/reasonable-looking verdict:
|
|
639
|
+
|
|
640
|
+
- **`agnostic` → `platform-independent`** (`google/plain-language-swaps`):
|
|
641
|
+
"agnostic" very commonly means doubting or noncommittal about religious
|
|
642
|
+
or philosophical claims ("he's agnostic about the existence of an
|
|
643
|
+
afterlife") — a blind fix corrupts that sentence into "...platform-
|
|
644
|
+
independent about the existence of an afterlife." The word-list entry
|
|
645
|
+
is real and the replacement is reasonable for the INTENDED sense; it is
|
|
646
|
+
simply also a different word with an unrelated common sense, the same
|
|
647
|
+
shape as `recheck/microsoft`'s `DMZ`.
|
|
648
|
+
- **`GCP` → `Google Cloud`** (`google/gcp-name`): the same shape as `DMZ` →
|
|
649
|
+
`perimeter network` — an acronym expanded into a DIFFERENT phrase than
|
|
650
|
+
its own literal expansion (`GCP` stands for "Google Cloud Platform", not
|
|
651
|
+
"Google Cloud"), not a respelling, and `GCP` has unrelated expansions in
|
|
652
|
+
other domains ("Good Clinical Practice", "Grade Control Point"). Note
|
|
653
|
+
this reverses Fix wave C's own "GCP is fixable again" call above: that
|
|
654
|
+
wave correctly fixed a real ENGINE bug (the case-preservation shout),
|
|
655
|
+
but engine-correctness and word-choice-safety are different questions,
|
|
656
|
+
and only the first was checked at the time.
|
|
657
|
+
- **`IO` → `I/O`** (`google/acronym-forms`, moved to
|
|
658
|
+
`google/acronym-caps-detect-only`): bare, case-sensitive "IO" is a real
|
|
659
|
+
product/library name in common developer use ("Socket.IO" — the period
|
|
660
|
+
before "IO" is a non-word character, so `\bIO\b` matches inside it) —
|
|
661
|
+
"Socket.IO connects clients" would corrupt to "Socket.I/O connects
|
|
662
|
+
clients."
|
|
663
|
+
|
|
664
|
+
By contrast, `google/compound-forms`'s ~80 remaining pairs (`data store` →
|
|
665
|
+
`datastore`, `e-mail` → `email`, ...) are genuine spacing/hyphenation
|
|
666
|
+
normalizations of the identical two words and stay fixable — this is the
|
|
667
|
+
family the fix-posture brief itself predicted would "largely survive."
|
|
668
|
+
Four pairs did NOT survive despite living in that same rule: `data
|
|
669
|
+
cleansing` → `data cleaning` (different word, "cleansing" vs "cleaning"),
|
|
670
|
+
`transcompile` → `transpile` (two competing compiler-jargon terms, not a
|
|
671
|
+
spelling variant), `autoupdate` → `automatically update` (expands "auto"
|
|
672
|
+
into a different word), and `pre-emptive` → `preemptible` (a different
|
|
673
|
+
adjective — "pre-emptive" describes acting in advance; "preemptible"
|
|
674
|
+
describes being subject to preemption — not a hyphenation of one word).
|
|
675
|
+
Moved to a new sibling rule, `google/compound-forms-word-choice`
|
|
676
|
+
(`fix: false`), since `fix` is a whole-rule flag and this bundle mixed
|
|
677
|
+
both classes.
|
|
678
|
+
|
|
679
|
+
#### Result
|
|
680
|
+
|
|
681
|
+
**Fixable `swap`/`consistency` pairs: 164 → 114**, across 41 rules with a
|
|
682
|
+
`swap`/`consistency` assertion (up from 38 — `google/vs-versus`,
|
|
683
|
+
`google/aka-form`, and `google/compound-forms-word-choice` are new,
|
|
684
|
+
splitting bundles that mixed same-word and different-word pairs).
|
|
685
|
+
`vs.` → `versus` and `aka` → `also known as` both stay fixable: unlike
|
|
686
|
+
`i.e.`/`e.g.` (Latin abbreviations translated into an unrelated English
|
|
687
|
+
phrase) and `vice versa` (a distinct Latin phrase with no letter-derived
|
|
688
|
+
relationship to its replacement), `vs.` and `aka` are literal truncations
|
|
689
|
+
of the identical word/phrase they abbreviate (`aka` is literally the
|
|
690
|
+
initials of "Also Known As"). **Correction (wave 2, see below): this call
|
|
691
|
+
on `aka` was wrong.** Expanding an abbreviation INTO a phrase is a
|
|
692
|
+
substitution, the same shape as `e.g.`/`i.e.` two sentences above, not a
|
|
693
|
+
respelling — "the letters spell out the words" does not make it a
|
|
694
|
+
same-word normalization. `aka` moved to `fix: false` in wave 2. `cURL` →
|
|
695
|
+
`curl` (a pure casing correction)
|
|
696
|
+
moved from `google/product-names` (now fully detection-only) to
|
|
697
|
+
`google/brand-capitalization`, which already ships the same class of
|
|
698
|
+
case-only brand-name fix.
|
|
699
|
+
|
|
700
|
+
Severity is unaffected: this preset's existing policy already puts every
|
|
701
|
+
word-choice/phrasing rule at `warn` regardless of fixability (see "Shipped
|
|
702
|
+
rules" above), so newly-detection-only rules needed no severity change.
|
|
703
|
+
|
|
704
|
+
#### Gates
|
|
705
|
+
|
|
706
|
+
`pnpm build`, `pnpm test` (105 files, 1467 passed / 5 skipped — shared
|
|
707
|
+
suite with `recheck/microsoft`), `pnpm parity --corpus monorepo-docs`
|
|
708
|
+
(unchanged: 27425 = 27425, 0 unexplained — this preset has no bearing on
|
|
709
|
+
the markdownlint-parity corpus), `npx nx run recheck:lint
|
|
710
|
+
--max-warnings=0` (clean). Every one of the 114 pairs that remain fixable
|
|
711
|
+
in this preset (240 combined with `recheck/microsoft`'s 126) was verified
|
|
712
|
+
programmatically: real change, idempotent (second `--fix` pass is a
|
|
713
|
+
no-op), and the original violation regex no longer matches the fixed
|
|
714
|
+
text — not sampled. Full command output and the exhaustive fixable-rule
|
|
715
|
+
table are in `.superpowers/sdd/preset-fix-posture-report.md`.
|
|
716
|
+
|
|
717
|
+
### Fix-posture change, wave 2 — the proper-noun axis (2026-07-30)
|
|
718
|
+
|
|
719
|
+
> **RETIRED 2026-07-30 — see "Detection-only" below.** This section's
|
|
720
|
+
> third axis (proper-noun collision) no longer determines which pairs are
|
|
721
|
+
> fixable in this preset: none are. Kept as historical record only.
|
|
722
|
+
|
|
723
|
+
Base commit `25a62c3d1f1`, branch `aa/recheck-style-guides`. Brief:
|
|
724
|
+
`.superpowers/sdd/preset-posture-fix2-brief.md`. Report:
|
|
725
|
+
`.superpowers/sdd/preset-fix-posture-report.md`'s "Wave 2" section. See
|
|
726
|
+
`presets/microsoft/PROVENANCE.md`'s own "Fix-posture change, wave 2"
|
|
727
|
+
section for the full rationale shared by both presets; this section
|
|
728
|
+
covers this preset's specific findings.
|
|
729
|
+
|
|
730
|
+
#### The third axis
|
|
731
|
+
|
|
732
|
+
A pair keeps `fix: true` only if it is the same word normalized (axis 1,
|
|
733
|
+
guidance-shape), has no unrelated legitimate sense (axis 2, homograph —
|
|
734
|
+
wave 1), **and, new this wave, cannot occur as part of a real
|
|
735
|
+
organization, product, brand, or place name.** Four demonstrated
|
|
736
|
+
corruptions share this cause: `markdown` → `Markdown` (a retail markdown
|
|
737
|
+
sentence gets capitalized into the markup-language name), `FinTech` →
|
|
738
|
+
`fintech` (breaks "FinTech Group AG", a real company), `U.S.` → `US`
|
|
739
|
+
(breaks "U.S. Bank", a real bank), `USA` → `US` (breaks "USA Gymnastics",
|
|
740
|
+
a real governing body — this specific pair lives in
|
|
741
|
+
`microsoft/usa-abbreviation`, not this preset, since `google/us-
|
|
742
|
+
abbreviation` never shipped a bare `USA` key). Acronyms and single
|
|
743
|
+
capitalizable words are the highest-risk shapes: a rule that ignores
|
|
744
|
+
case or normalizes punctuation matches a proper noun's own official
|
|
745
|
+
spelling exactly as readily as ordinary prose.
|
|
746
|
+
|
|
747
|
+
#### Sweep and results
|
|
748
|
+
|
|
749
|
+
Every fixable `swap` pair in this preset (105 pairs after this wave,
|
|
750
|
+
sweeping the full ~114-pair fixable set left by wave 1) was checked
|
|
751
|
+
against question 3.
|
|
752
|
+
|
|
753
|
+
| Rule | Pair(s) flipped | Real proper noun / other reason |
|
|
754
|
+
|---|---|---|
|
|
755
|
+
| `google/aka-form` | `aka` → `also known as` | Not proper-noun — **misclassified in wave 1** (see the correction note above): expanding an abbreviation into a phrase is a substitution, the same shape as `e.g.`/`i.e.`, not a same-word normalization. Also happens to double as a real proper noun ("AKA" is the common abbreviation for the sorority Alpha Kappa Alpha — "She was initiated into AKA her freshman year" is a genuine, independent proper-noun collision on top of the misclassification). |
|
|
756
|
+
| `google/us-abbreviation` | `U.S.A.`/`U.S.` → `US` (both) | "U.S. Bank" (top-10 US bank), "U.S. Steel", "U.S.A. Track and Field" (national governing body) — the named brief case. |
|
|
757
|
+
| `google/acronym-forms` | `FinTech` → `fintech` | "FinTech Group AG" — a real, publicly-traded German company whose name keeps the mixed-case "FinTech" spelling. |
|
|
758
|
+
| `google/acronym-forms` | `I-O` → `I/O` | "I-O DATA DEVICE, INC." — a real, major Japanese PC-peripherals manufacturer ("Japan's undisputed market leader" in that industry) whose brand is written exactly "I-O" (hyphenated, capital letters). `fin-tech`/`adtech`/`ad-tech` (all-lowercase keys, no case change involved) do NOT carry this risk: this rule is case-sensitive, so an all-lowercase key can never match a capitalized brand's own casing in the first place. |
|
|
759
|
+
| `google/brand-capitalization` | `markdown` → `Markdown` | The named brief case — both a retail/finance homograph (axis 2) AND, in the reverse direction, a proper-noun risk: capitalizing every lowercase occurrence assumes it always means the Markdown language. |
|
|
760
|
+
| `google/brand-capitalization` | `material design` → `Material Design` | Same reverse-direction risk as `markdown`: "the material design of the building incorporates local stone" is a plain, unrelated architectural phrase this pair would wrongly capitalize into Google's design-language name. |
|
|
761
|
+
| `google/brand-capitalization` | `search console` → `Search Console` | Same shape, weaker but still real: a generic lowercase phrase for an admin/tuning panel, not exclusively Google's product name. |
|
|
762
|
+
| `google/compound-forms` | `datasource` → `data source` | Collides with `javax.sql.DataSource`/Spring's `DataSource` — a real, load-bearing Java/Spring class and config-property name ("Configure the DataSource bean in the Spring context"), exactly the kind of technical content this preset's own audience writes about. |
|
|
763
|
+
|
|
764
|
+
**9 pairs flipped**, each moved to a new detection-only sibling rather
|
|
765
|
+
than anchored (`google/acronym-forms-proper-noun`, `google/brand-
|
|
766
|
+
capitalization-proper-noun`, `google/compound-forms-proper-noun`;
|
|
767
|
+
`google/aka-form` and `google/us-abbreviation` flip whole-rule since every
|
|
768
|
+
pair in each was reclassified). Severity is unaffected — this preset's
|
|
769
|
+
existing policy already puts every word-choice/phrasing rule at `warn`
|
|
770
|
+
regardless of fixability, so nothing needed adjusting, matching wave 1's
|
|
771
|
+
own note.
|
|
772
|
+
|
|
773
|
+
**Fixable pairs: 114 → 105.**
|
|
774
|
+
|
|
775
|
+
#### Why `fix: false`, not another anchor
|
|
776
|
+
|
|
777
|
+
Same reasoning as `recheck/microsoft`'s wave 2 section: three separate
|
|
778
|
+
waves have each shown an anchor leaking exactly one near-miss beyond
|
|
779
|
+
wherever it was tested. A casing/abbreviation fix is low-value enough
|
|
780
|
+
that detection alone is a fine outcome, so every pair this wave found
|
|
781
|
+
moved straight to `fix: false` rather than growing another exclusion
|
|
782
|
+
list.
|
|
783
|
+
|
|
784
|
+
#### Gates
|
|
785
|
+
|
|
786
|
+
`pnpm build`, `pnpm test` (105 files, 1490 passed / 5 skipped — 23 new
|
|
787
|
+
tests this wave, shared suite with `recheck/microsoft`), `pnpm parity
|
|
788
|
+
--corpus monorepo-docs --profile default` (unchanged: 27425 = 27425, 0
|
|
789
|
+
unexplained), `npx nx run recheck:lint --max-warnings=0` (clean). Every
|
|
790
|
+
sentence in the brief's acceptance set 1 verified unchanged through
|
|
791
|
+
`--fix` twice and still detected against the correct new rule name; every
|
|
792
|
+
rule (including the 3 new ones here) still fires on
|
|
793
|
+
`google-violations.md`. Full output in
|
|
794
|
+
`.superpowers/sdd/preset-fix-posture-report.md`'s "Wave 2" section.
|
|
795
|
+
|
|
796
|
+
### Detection-only (2026-07-30)
|
|
797
|
+
|
|
798
|
+
Base commit `006c026a1f0`, branch `aa/recheck-style-guides`. Brief:
|
|
799
|
+
`.superpowers/sdd/preset-detection-only-brief.md`. Report:
|
|
800
|
+
`.superpowers/sdd/preset-detection-only-report.md`.
|
|
801
|
+
|
|
802
|
+
**This section REPLACES the fixability criterion described in "CONFIRMED
|
|
803
|
+
vs. safe-to-fix," "Fix-posture change," and "Fix-posture change, wave 2"
|
|
804
|
+
above — it does not sit alongside them as a fourth, stricter axis.** Those
|
|
805
|
+
three sections are kept below, unedited, as the historical record of the
|
|
806
|
+
criteria that were tried and superseded; do not read any of them as current
|
|
807
|
+
guidance. As of this section, **`recheck/google` ships zero fixable rules.
|
|
808
|
+
Every rule in this file is `fix: false`, unconditionally** — set
|
|
809
|
+
structurally, once, by a loop at the end of `buildGooglePreset()`
|
|
810
|
+
(`src/config/presets/google.ts`), not by auditing pairs against a sharper
|
|
811
|
+
rule. A dedicated test (`preset-google.test.ts`'s "is detection-only"
|
|
812
|
+
describe block) reads the live preset object and fails if any rule is ever
|
|
813
|
+
fixable again — the same derive-from-the-preset shape the per-pair coverage
|
|
814
|
+
gate already uses, so this cannot regress silently the way three prior
|
|
815
|
+
narrowing passes did.
|
|
816
|
+
|
|
817
|
+
#### Why a fourth axis wasn't the answer
|
|
818
|
+
|
|
819
|
+
Two prior fix-posture changes (above) each replaced "does the guide confirm
|
|
820
|
+
this pair" with a sharper structural test — first "is it the same word
|
|
821
|
+
normalized" (axis 1: guidance-shape, then axis 2: homograph), then "does it
|
|
822
|
+
also collide with a real proper noun" (axis 3). Each pass shipped clean
|
|
823
|
+
against its own criterion and each was then probed again. The fifth
|
|
824
|
+
adversarial probe against this preset and `recheck/microsoft` together (the
|
|
825
|
+
project's fifth in total, after three rounds already narrowed what counted
|
|
826
|
+
as "safe") found **18 of 29 probed pairs (62%) still corrupting correct
|
|
827
|
+
prose** — a RISING hit rate, not a falling one, and the failures spanned
|
|
828
|
+
every category previously believed safe by axes 1-3, including two this
|
|
829
|
+
preset's own criteria treated as clean:
|
|
830
|
+
|
|
831
|
+
- **Spelling**, believed the safest category of all: Hemingway's real,
|
|
832
|
+
correctly spelled published title *A Moveable Feast* is corrected to "A
|
|
833
|
+
Movable Feast" by `microsoft/az-grammar-usage`'s `moveable` → `movable`
|
|
834
|
+
pair (a genuine same-word normalization by every axis above — axis 1
|
|
835
|
+
passes, axis 2 finds no unrelated sense, axis 3 finds no proper-noun
|
|
836
|
+
collision on the WORD "moveable" itself, and the collision is instead
|
|
837
|
+
with a specific, individually unforeseeable literary title).
|
|
838
|
+
- **Hyphenation**, this preset's own `read only` → `read-only` pair
|
|
839
|
+
(`google/compound-forms`): "Please read only the introduction" — an
|
|
840
|
+
adverb ("only") modifying a verb ("read") plus its object — becomes
|
|
841
|
+
"Please read-only the introduction," a nonsense adjective use. Same-word
|
|
842
|
+
by every axis (it is the identical two words, just joined), yet wrong,
|
|
843
|
+
because the axes check the WORDS, not the GRAMMATICAL ROLE those words
|
|
844
|
+
are playing in the sentence being fixed.
|
|
845
|
+
- **Meaning inverted outright**: `google/acronym-forms`'s `No SQL` → `NoSQL`
|
|
846
|
+
turns "No SQL is used here" (a true statement that no NoSQL database is
|
|
847
|
+
in use) into "NoSQL is used here" (a false statement that one is) — same
|
|
848
|
+
word-pair, same axis-1/2/3 clearance, opposite meaning.
|
|
849
|
+
|
|
850
|
+
Full round-5 acceptance evidence (every sentence above, and more, run
|
|
851
|
+
through `--fix` twice and confirmed byte-identical) lives in
|
|
852
|
+
`src/config/__tests__/preset-detection-only-acceptance.test.ts`, plus the
|
|
853
|
+
per-preset regression suites in `preset-google-fix-wave-c.test.ts` and
|
|
854
|
+
`preset-microsoft.test.ts` (both rewritten by this change to assert
|
|
855
|
+
"unchanged" where they used to assert a real rewrite).
|
|
856
|
+
|
|
857
|
+
#### The conclusion this decision rests on
|
|
858
|
+
|
|
859
|
+
A rule's *category* — spelling, hyphenation, casing, word-choice — does not
|
|
860
|
+
predict fix-safety at this scale. A style guide states *intent* ("use X to
|
|
861
|
+
mean Y"); a `swap`/`consistency`/`pattern` rule matches *tokens* (literal
|
|
862
|
+
text, regardless of the grammatical role or referent that text has in a
|
|
863
|
+
given sentence). That gap is not closable by inventing a fourth, fifth, or
|
|
864
|
+
sixth axis: axis 1 (guidance-shape) closed the space of pairs where the
|
|
865
|
+
guide's own wording was ambiguous; axis 2 (homograph) closed the space of
|
|
866
|
+
words with an unrelated common sense; axis 3 (proper-noun) closed the space
|
|
867
|
+
of words that double as real names. Each closure found the NEXT gap, not
|
|
868
|
+
zero gap. The project decision is to stop narrowing and remove fixing
|
|
869
|
+
capability from both style-guide presets entirely: users get every finding
|
|
870
|
+
(detection is completely unaffected — every rule still runs `execute()` and
|
|
871
|
+
reports) and apply the judgment a style guide has always required, same as
|
|
872
|
+
before either preset existed and same as Vale (the tool these presets
|
|
873
|
+
replace), which never shipped an auto-fixer and never had this class of
|
|
874
|
+
bug.
|
|
875
|
+
|
|
876
|
+
#### What did not change
|
|
877
|
+
|
|
878
|
+
Detection. Every rule's `execute()` path, message, severity, and scope are
|
|
879
|
+
untouched — only `fix()` is gated off (`core/runner.ts`'s
|
|
880
|
+
`rule.fix !== false` check). The per-pair and per-rule coverage gates
|
|
881
|
+
(`preset-google.test.ts`) still require every rule to fire on its own clean
|
|
882
|
+
fixture, so a rule that neither fixes nor reports is still caught as dead
|
|
883
|
+
weight, same as before this change.
|
|
884
|
+
|
|
885
|
+
### Known limitations
|
|
886
|
+
|
|
887
|
+
Two verifier-confirmed guide-sanctioned exceptions that the shipped rules
|
|
888
|
+
do not implement. Both are documented here explicitly, not just in the
|
|
889
|
+
Shipped rules table's own one-line notes, because a rule that is stricter
|
|
890
|
+
than its source needs to say so where a reader is actually looking for
|
|
891
|
+
"why did this fire on text the guide allows" — otherwise a user hitting
|
|
892
|
+
either case reasonably concludes the preset misquotes Google.
|
|
893
|
+
|
|
894
|
+
1. **`google/no-emphasis-as-heading` over-fires on one shape of the
|
|
895
|
+
guide's own "run-in heading" pattern (verifier A row 12).** The guide
|
|
896
|
+
permits bold for "run-in headings" — a bolded lead-in term followed by
|
|
897
|
+
its description, most commonly inside a description-list item (`Google's
|
|
898
|
+
own example: <li><b>Emu</b>: the best kind of bird</li>`) or a single
|
|
899
|
+
paragraph ("**Emu:** the best kind of bird."), and instructs authors to
|
|
900
|
+
"end the run-in heading with a period or a colon." The shipped rule
|
|
901
|
+
(ported from markdownlint's MD036) already tolerates the common cases:
|
|
902
|
+
it only examines top-level paragraphs (so a run-in heading inside an
|
|
903
|
+
actual list item is never even considered), a bold lead-in with more
|
|
904
|
+
text in the SAME paragraph is excluded (the paragraph has more than one
|
|
905
|
+
meaningful child), and a bold-only paragraph ending in the guide's own
|
|
906
|
+
required punctuation is excluded by the rule's pre-existing punctuation
|
|
907
|
+
check. Empirically verified still-flagged: a bold/italic-only paragraph
|
|
908
|
+
with NO ending punctuation, whose description follows in a SEPARATE,
|
|
909
|
+
later paragraph (e.g. `**Emu**\n\nThe best kind of bird.`) — reproduced
|
|
910
|
+
directly against the shipped rule. Not fixed in this pass: the rule is
|
|
911
|
+
a markdownlint port shared with `recheck/markdown` (out of scope for
|
|
912
|
+
this wave's provenance/documentation focus, and doing so risks the same
|
|
913
|
+
loosening-vs-noise tradeoff every other TOO-RISKY exclusion in this file
|
|
914
|
+
weighs).
|
|
915
|
+
2. **`google/no-url-as-link-text` does not exempt legal/ToS documents
|
|
916
|
+
(verifier B row 71).** The guide's own text: "Exception: In some legal
|
|
917
|
+
documents (such as some Terms of Service documents), it's okay to use
|
|
918
|
+
URLs as link text." The shipped rule is a plain pattern match on link
|
|
919
|
+
text starting with `http(s)://`, scoped to `link`; it has no way to
|
|
920
|
+
know whether the document containing the link is a legal/ToS document,
|
|
921
|
+
so it will flag a bare URL used as link text there too, against the
|
|
922
|
+
guide's own stated exception. Not enforceable to fix with the engine's
|
|
923
|
+
current primitives (same class of gap as `firewalls` → `firewall
|
|
924
|
+
rules`'s "Compute Engine documentation only" scoping and the
|
|
925
|
+
NOT-ENFORCEABLE table's document-subject-matter entries above) — Recheck
|
|
926
|
+
has no signal for what kind of document a file is.
|
|
927
|
+
3. **`google/gcp-name` is case-sensitive.** The pair (`GCP: 'Google
|
|
928
|
+
Cloud'`) carries no `ignoreCase`, so only the literal all-caps `GCP`
|
|
929
|
+
token is matched or fixed — `gcp` and `Gcp` are neither flagged nor
|
|
930
|
+
fixed by this rule. A reader could reasonably infer broader coverage
|
|
931
|
+
than exists: many OTHER rules in this same file (e.g. `google/
|
|
932
|
+
compound-forms`, `google/use-contractions`) do set `ignoreCase: true`,
|
|
933
|
+
so the absence here is easy to read as an oversight rather than a
|
|
934
|
+
choice. It is a choice, shared with the sibling `google/product-names`
|
|
935
|
+
(also no `ignoreCase`) and `google/brand-capitalization` (explicitly
|
|
936
|
+
documented as "deliberately case-sensitive keys, matching only the
|
|
937
|
+
wrongly-cased literal form" in its own comment) — all three treat
|
|
938
|
+
brand/product-name casing as exact-match by design. Left as-is rather
|
|
939
|
+
than widened here (carried over from a `recheck/microsoft` fix-wave
|
|
940
|
+
audit, flagged as a documentation gap, not a behavior bug): widening to
|
|
941
|
+
`ignoreCase: true` is a scope decision for whoever owns `google.ts`, not
|
|
942
|
+
a documentation fix.
|
|
943
|
+
|
|
944
|
+
### Author's judgment calls
|
|
945
|
+
|
|
946
|
+
Decisions this preset's author made that go beyond a verifier's literal
|
|
947
|
+
verdict, recorded per the task's instruction to flag (not silently
|
|
948
|
+
resolve) anything not settled by the inputs:
|
|
949
|
+
|
|
950
|
+
1. **`google/first-line-h1` and `google/single-h1` share one Google
|
|
951
|
+
quote.** Verifier A's row 4 confirms both rule ids against the same
|
|
952
|
+
sentence ("only use a level-1 heading once on a page"); the research
|
|
953
|
+
draft, not a separate guide statement, is what split them into two rule
|
|
954
|
+
ids. Both ship (both are real markdownlint-ported mechanisms Google's
|
|
955
|
+
principle supports), but see point 2.
|
|
956
|
+
2. **`single-h1` and `first-line-h1` cannot both fire from one document.**
|
|
957
|
+
Empirically verified (not assumed): the underlying token rules faithfully
|
|
958
|
+
port markdownlint's MD025/MD041, which check OPPOSITE preconditions of
|
|
959
|
+
"the document's first heading" — `single-h1` only reports a second h1
|
|
960
|
+
when nothing but comments/frontmatter precede the first one;
|
|
961
|
+
`first-line-h1` only fires when that first real content is NOT a correct
|
|
962
|
+
h1. `google-violations.md` (which starts with a level-2 heading to
|
|
963
|
+
trigger `first-line-h1`) structurally cannot also trigger `single-h1`, so
|
|
964
|
+
a second, tiny fixture (`google-violations-single-h1.md`) isolates it.
|
|
965
|
+
This is a genuine engine/upstream-semantics interaction, not a fixture
|
|
966
|
+
bug or a noisy rule.
|
|
967
|
+
3. **Downgraded `list-length` from the generic "list mechanics = error"
|
|
968
|
+
class to `warn`.** The verifier marked the underlying quote
|
|
969
|
+
NOT-ENFORCEABLE (descriptive, not imperative); only the mechanism
|
|
970
|
+
(`list-length`'s `min: 2` default) is deterministic, so the softer
|
|
971
|
+
severity reflects the guide's own softer confidence.
|
|
972
|
+
4. **Shipped only 5 of ~15 confirmed "timeless documentation" words.** All
|
|
973
|
+
~15 are confirmed content, but 10 of them (`existing`, `future`,
|
|
974
|
+
`latest`, `new`, `newer`, `now`, `old`, `older`, `soon`, `eventually`,
|
|
975
|
+
`in the future`) are ordinary high-frequency English words with
|
|
976
|
+
extensive legitimate everyday use unrelated to documentation staleness.
|
|
977
|
+
Shipping them would make the preset unusably noisy on typical prose —
|
|
978
|
+
the same class of risk the verifiers flagged elsewhere as TOO-RISKY,
|
|
979
|
+
extended here on the same reasoning to entries the verifiers didn't
|
|
980
|
+
individually re-litigate for riskiness (their job was confirming
|
|
981
|
+
content, not judging blind-match safety for every term).
|
|
982
|
+
5. **`google/no-numbered-headings` ships despite some residual risk.**
|
|
983
|
+
Narrowly scoped to `Step N`/`Part N` markers and a bare leading ordinal,
|
|
984
|
+
to keep the false-positive rate low; broader numeric heading patterns
|
|
985
|
+
(e.g. version numbers in a heading) are not matched.
|
|
986
|
+
6. **`google/cons-and-pros` ships only the compound phrase.** Bare `pros`/
|
|
987
|
+
`cons` are excluded even though individually confirmed, because standing
|
|
988
|
+
alone they're closer to ambiguous (conference abbreviations, "con
|
|
989
|
+
artist") than the extremely common, unambiguous two-word phrase.
|
|
990
|
+
7. **The Oxford-comma/no-and-or "except in tables" exception is not
|
|
991
|
+
separately scoped.** `google/no-and-or` runs over the `summary` scope,
|
|
992
|
+
which includes table cells, so it would also (correctly, per the general
|
|
993
|
+
rule, but against the guide's own table exception) flag "and/or" inside
|
|
994
|
+
a table. Judged not worth a bespoke scope array for one rule; a project
|
|
995
|
+
that hits this can override the rule's `scope`.
|
|
996
|
+
|
|
997
|
+
### Engine/registry changes this preset required
|
|
998
|
+
|
|
999
|
+
- **Schema**: `src/config/schema.ts`'s top-level `patternProperties` only
|
|
1000
|
+
accepted `^recheck/[a-z0-9-_]+$` rule keys. Spec §2 ("Composition
|
|
1001
|
+
safety") requires per-preset namespacing (`google/<rule>`,
|
|
1002
|
+
`microsoft/<rule>`, ...) precisely so two flagship presets can be
|
|
1003
|
+
composed without collisions — the pattern is widened to
|
|
1004
|
+
`^[a-z][a-z0-9-]*/[a-z0-9-_]+$` to allow that (existing `recheck/*` keys
|
|
1005
|
+
are unaffected; they're just the `recheck` namespace now).
|
|
1006
|
+
- **`length` moved from opt-in to preset-shipped.** `google/sentence-length`
|
|
1007
|
+
is the first non-prose preset rule to ship a native scope-rule
|
|
1008
|
+
assertion beyond what `recheck/prose` already ships. Per
|
|
1009
|
+
cross-task-constraints.md §C / task-9-10-resolutions.md §5, this trips
|
|
1010
|
+
the registry<->preset completeness guard in
|
|
1011
|
+
`src/config/__tests__/presets.test.ts`: `length` is removed from the
|
|
1012
|
+
documented-opt-in list (now `DOCUMENTED_OPT_IN_ASSERTIONS`, moved from
|
|
1013
|
+
`prose.ts` to `presets/index.ts` since the policy is monorepo-wide, not
|
|
1014
|
+
prose-specific) and the completeness test's "shipped" side is derived
|
|
1015
|
+
dynamically from ALL presets rather than a single prose-named constant.
|
|
1016
|
+
See that test file's own comments for the mechanics.
|
|
1017
|
+
- **`.npmignore` widened to include `presets/**/*`.** The package has no
|
|
1018
|
+
`files` field in `package.json`; publishing is governed entirely by
|
|
1019
|
+
`.npmignore`, which was a blanket `*` deny with only `dist/**/*` and
|
|
1020
|
+
`package.json` allowed back in. A new top-level `presets/<name>/`
|
|
1021
|
+
directory (this file, `sources.json`) would have shipped nowhere without
|
|
1022
|
+
this change — verified with `npm pack --dry-run` before and after.
|