Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
site/public/
site/resources/
site/content/spec/_index.md
site/content/spec/web/
site/build_and_sync

.DS_Store
Expand Down
5 changes: 5 additions & 0 deletions .vale.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
StylesPath = .vale/styles
MinAlertLevel = suggestion

[*.md]
BasedOnStyles = DC
139 changes: 139 additions & 0 deletions .vale/styles/DC/AICompoundPhrases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Adapted from tbhb/vale-ai-tells (MIT). See THIRD_PARTY_NOTICES.md.
extends: existence
message: "AI fingerprint: '%s'. Rewrite with concrete specifics instead of this clichéd phrase."
level: error
ignorecase: true
tokens:
- rich tapestry
- rich tapestries
- tapestry of
- intricate tapestry
- complex and multifaceted
- multifaceted and complex
- intricate interplay
- delicate balance
- delicate interplay
- dynamic interplay
- crucial role
- played a crucial role
- plays a crucial role
- vital role
- pivotal role
- key role
- instrumental role
- cutting-edge
- game-changer
- game-changing
- paradigm shift
- sea change
- tipping point
- watershed moment
- double-edged sword
- slippery slope
- tip of the iceberg
- at the forefront
- on the cutting edge
- paving the way
- laid the groundwork
- lays the groundwork
- sets the stage
- set the stage
- a testament to
- stands as a testament
- serve as a reminder
- serves as a reminder
- it remains to be seen
- only time will tell
- the jury is still out
- takes center stage
- take center stage
- took center stage
- paints a picture of
- paint a picture of
- painted a picture of
- is not without its challenges
- are not without their challenges
- is not without challenges
- whether we like it or not
- whether you like it or not
- a cornerstone of
- the transformative power of
- deeply rooted in
- deeply rooted
- the hallmark of
- a hallmark of
- moving the needle
- moves the needle
- moved the needle
- move the needle
- nudge the needle
- nudges the needle
- nudged the needle
- unlocks new
- unlocked new
- unlocking new
- unlock new
- unlocks the potential
- unlock the potential
- unlocks the power
- unlock the power
- unlocks the value
- unlock the value
- unlocks capabilities
- unlock capabilities
- unlocks possibilities
- unlock possibilities

# "real" as intensifier before an abstract noun.
# AI reaches for "a real choice" / "a real difference" to inflate
# weight where a plain noun would do. Bare "real" is too broad
# (real-time, real estate, real world), so this is enumerated.
- a real choice
- a real option
- a real difference
- a real test
- a real question
- a real chance
- a real problem
- a real shot
- a real risk
- a real cost
- a real benefit
- real value
- real progress
- real flexibility
- real benefits
- real costs
- real impact
- real leverage
- real ownership
- real accountability
- real consequences
- real tradeoffs
- real trade-offs
- real choices
- real options
- real differences

# Investigation-thread metaphors: AI's preferred way to describe
# "open questions" or "loose ends." Tutorial-blog tone.
- threads to pull on
- thread to pull on
- threads to pull
- thread to pull
- loose threads to pull
- loose threads to chase
- another thread to pull
- more threads to pull

# Solidification metaphors: the surface/design/contract "hardens"
# before some deadline. AI reaches for this constantly when
# describing in-progress work or pre-release windows.
# Broad regex catches "before/after X hardens" for any 1-6
# word X.
- (?:before|after) [^.,;:!?]{1,40} hardens
- (?:before|after) [^.,;:!?]{1,40} hardened
- (?:before|after) [^.,;:!?]{1,40} solidifies
- (?:before|after) [^.,;:!?]{1,40} solidified
- (?:before|after) [^.,;:!?]{1,40} ossifies
- (?:before|after) [^.,;:!?]{1,40} ossified
32 changes: 32 additions & 0 deletions .vale/styles/DC/AdverbDensity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Original rule (not from vale-ai-tells). Flags every non-exception '-ly'
# word, but only in files whose '-ly' density exceeds 2% of word count
# (min 100 words). scope: raw keeps positions accurate; the cost is that
# code blocks and frontmatter count toward the word total.
extends: script
message: "Adverb-heavy file (over 2%% '-ly' words). Cut this one or its neighbors."
level: warning
scope: raw
script: |
text := import("text")
matches := []
exceptions := {only: true, family: true, likely: true, early: true,
friendly: true,
assembly: true, apply: true, reply: true, supply: true, july: true,
italy: true, daily: true, weekly: true, monthly: true, ugly: true,
fly: true, rely: true, imply: true, multiply: true, ally: true,
rally: true, tally: true, anomaly: true, belly: true, silly: true}
words := text.re_find(`[A-Za-z]+`, scope, -1)
total := 0
candidates := []
for w in words {
total += 1
lower := text.to_lower(w[0].text)
if text.has_suffix(lower, "ly") && !exceptions[lower] {
candidates = append(candidates, w[0])
}
}
if total >= 100 && len(candidates) * 100 > total * 2 {
for c in candidates {
matches = append(matches, {begin: c.begin, end: c.begin + len(c.text)})
}
}
192 changes: 192 additions & 0 deletions .vale/styles/DC/ContrastiveFormulas.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Adapted from tbhb/vale-ai-tells (MIT). See THIRD_PARTY_NOTICES.md.
extends: existence
message: "AI contrast: '%s'. State the positive claim directly without the 'not X, but Y' formula."
level: error
tokens:
# "It's not just X; it's Y" patterns
- "[Ii]t'?s not just [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t isn'?t just [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s not merely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s not simply [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s not only [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s not purely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s not solely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s not entirely [^;,—:]+[;,—:] it'?s [^.!?]+"

# "It's not about X; it's about Y" patterns
- "[Ii]t'?s not about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t isn'?t about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not really about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not just about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not merely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not simply about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not only about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not purely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not solely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Ii]t'?s not entirely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
# Period-separated versions (two sentences)
- "[Ii]t'?s not about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t isn'?t about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t'?s not really about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t'?s not just about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t'?s not merely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t'?s not purely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t'?s not solely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Ii]t'?s not entirely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"

# "This isn't X; it's Y" patterns
- "[Tt]his isn'?t just [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t merely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t simply [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t only [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t purely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t solely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t entirely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not just [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not merely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not simply [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not only [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not purely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not solely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is not entirely [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his isn'?t merely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t just about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t simply about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t only about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t purely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t solely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t entirely about [^;,—:]+[;,—:] it'?s about [^.!?]+"
- "[Tt]his isn'?t about [^;,—:]+[;,—:] it'?s about [^.!?]+"
# Period-separated versions (two sentences)
- "[Tt]his isn'?t about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t merely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t just about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t simply about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t only about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t purely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t solely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his isn'?t entirely about [^.!?]+\\. [Ii]t'?s about [^.!?]+"
- "[Tt]his is not about [^.!?]+\\. [Ii]t'?s about [^.!?]+"

# "It's more than X; it's Y" patterns
- "[Ii]t'?s more than [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ii]t'?s more than just [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is more than [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]his is more than just [^;,—:]+[;,—:] it'?s [^.!?]+"

# "It's less about X and more about Y" patterns
- "[Ii]t'?s less about [^;,—:]+ and more about [^.!?]+"
- "[Ii]t'?s less about [^;,—:]+, more about [^.!?]+"
- "[Tt]his is less about [^;,—:]+ and more about [^.!?]+"

# "X isn't the point; Y is" patterns
- "[^.!?]+ isn'?t the point[;,—:] [^.!?]+ is"
- "[^.!?]+ is not the point[;,—:] [^.!?]+ is"

# "The real X isn't Y; it's Z" patterns
- "[Tt]he real [^;,—:]+ isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]he true [^;,—:]+ isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"

# "What matters isn't X; it's Y" patterns
- "[Ww]hat matters isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ww]hat matters is not [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Ww]hat'?s important isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"

# "The question isn't X; it's Y" patterns
- "[Tt]he question isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]he question is not [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]he issue isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]he problem isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"
- "[Tt]he challenge isn'?t [^;,—:]+[;,—:] it'?s [^.!?]+"

# "Yes, X, but Y" dismissive acknowledgment
- "[Yy]es, [^,]+, but the real [^.!?]+"
- "[Ss]ure, [^,]+, but what really [^.!?]+"

# "It's not whether X; it's how/why/when Y"
- "[Ii]t'?s not whether [^;,—:]+[;,—:] it'?s (?:how|why|when|what) [^.!?]+"
- "[Ii]t'?s not if [^;,—:]+[;,—:] it'?s (?:how|why|when|what) [^.!?]+"

# "[Noun] isn't X. It's Y." pattern (any subject)
- "[A-Z][a-z]+ isn'?t [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "[A-Z][a-z]+ is not [^.!?]+\\. [Ii]t'?s [^.!?]+"

# "a Y, not a Z" bare appositive: the categorical assertion with
# preemptive correction, verb optional ("a refinement, not a rivalry").
# Verbless, so it also fires in headings, where the clause-shaped tokens
# above never match. Subsumes the older single-word-subject
# "X is a Y, not a Z" token.
- "\\b[Aa]n? [^,.;:!?\\n]{2,}, [Nn]ot [Aa]n? [^.!?;:,\\n]+"
- "[A-Z][a-z]+ are [^,]+, not [^.]+"

# "Not only X but also Y" patterns
- "[Nn]ot only [^,;—:]+,? but (?:also )?[^.!?]+"

# "Not because X, but because Y" causal variant
- "[Nn]ot because [^,;—:]+,? but because [^.!?]+"

# === Plural subject negation-correction ===

# "These aren't X. They're Y." — period-separated
- "[Tt]hese aren'?t [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[Tt]hose aren'?t [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[Tt]hese are not [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[Tt]hose are not [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[Tt]hese are not [^.!?]+\\. [Tt]hey are [^.!?]+"
- "[Tt]hose are not [^.!?]+\\. [Tt]hey are [^.!?]+"

# With modifiers
- "[Tt]hese aren'?t just [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[Tt]hese aren'?t merely [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[Tt]hese aren'?t simply [^.!?]+\\. [Tt]hey'?re [^.!?]+"

# Semicolon/em-dash-joined
- "[Tt]hese aren'?t [^;,—:]+[;,—:] they'?re [^.!?]+"
- "[Tt]hose aren'?t [^;,—:]+[;,—:] they'?re [^.!?]+"
- "[Tt]hese are not [^;,—:]+[;,—:] they'?re [^.!?]+"
- "[Tt]hose are not [^;,—:]+[;,—:] they'?re [^.!?]+"

# Generic "[Noun] aren't X. They're Y." catch-all
- "[A-Z][a-z]+ aren'?t [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[A-Z][a-z]+ are not [^.!?]+\\. [Tt]hey'?re [^.!?]+"
- "[A-Z][a-z]+ are not [^.!?]+\\. [Tt]hey are [^.!?]+"

# === "Doesn't mean X. It means Y." ===

# Period-separated
- "[Tt]his doesn'?t mean [^.!?]+\\. [Ii]t means [^.!?]+"
- "[Tt]hat doesn'?t mean [^.!?]+\\. [Ii]t means [^.!?]+"
- "[Tt]his does not mean [^.!?]+\\. [Ii]t means [^.!?]+"
- "[Tt]hat does not mean [^.!?]+\\. [Ii]t means [^.!?]+"

# Semicolon/em-dash-joined
- "[Tt]his doesn'?t mean [^;,—:]+[;,—:] it means [^.!?]+"
- "[Tt]hat doesn'?t mean [^;,—:]+[;,—:] it means [^.!?]+"

# Generic "[Noun] doesn't mean X. It means Y."
- "[A-Z][a-z]+ doesn'?t mean [^.!?]+\\. [Ii]t means [^.!?]+"
- "[A-Z][a-z]+ does not mean [^.!?]+\\. [Ii]t means [^.!?]+"

# === Multi-word subject "isn't X. It's Y." ===
# Catches "The colophon isn't a disclaimer. It's a feature."
# The single-word "[Noun] isn't X. It's Y." patterns above only match
# single capitalized-word subjects.

# "The [noun] isn't X. It's Y."
- "[Tt]he [a-z]+ isn'?t [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "[Tt]he [a-z]+ is not [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "[Tt]he [a-z]+ isn'?t [^.!?]+\\. [Ii]t is [^.!?]+"

# "A/An [noun] isn't X. It's Y."
- "[Aa]n? [a-z]+ isn'?t [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "[Aa]n? [a-z]+ is not [^.!?]+\\. [Ii]t'?s [^.!?]+"

# "Our/Your/Their [noun] isn't X. It's Y."
- "(?:Our|Your|Their|Its) [a-z]+ isn'?t [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "(?:Our|Your|Their|Its) [a-z]+ is not [^.!?]+\\. [Ii]t'?s [^.!?]+"

# Multi-word/acronym subjects — catch-all with "isn't...It's" anchor
# "WCAG 2.1 AA isn't a checkbox. It's a constraint."
- "[^.!?]+ isn'?t [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "[^.!?]+ is not [^.!?]+\\. [Ii]t'?s [^.!?]+"
- "[^.!?]+ isn'?t [^.!?]+\\. [Ii]t is [^.!?]+"
6 changes: 6 additions & 0 deletions .vale/styles/DC/EmDash.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extends: existence
message: "Em dash used — vary punctuation (parens, colon, semicolon, period, comma) instead. A few per article are fine; heavy use reads as LLM-generated."
level: error
nonword: true
tokens:
- '—'
Loading