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
27 changes: 27 additions & 0 deletions .github/styles/AIPatterns/AITics.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
extends: existence
message: "'%s' is an AI-like writing pattern. State the point directly."
ignorecase: true
level: error
tokens:
- It's important to note that
- It is important to note that
- It's worth mentioning that
- It is worth mentioning that
- It's worth noting that
- It is worth noting that
- It should be noted that
- It should be mentioned that
- As previously mentioned
- As mentioned earlier
- As noted above
- As discussed earlier
- As we discussed
- As we mentioned
- It bears mentioning
- It bears noting
- you might be wondering
- you may be wondering
- you may be asking yourself
- you might be asking yourself
- and that's okay
- and that's perfectly fine
9 changes: 9 additions & 0 deletions .github/styles/AIPatterns/Antithesis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extends: existence
message: "'%s' is the AI negation-antithesis construction. Keep only if the contrast is earned; otherwise state the point directly."
ignorecase: true
nonword: true
level: suggestion
tokens:
- '(it''s|it is|that''s|that is) not (just |merely |simply |only )?(about )?[^.]{1,45}[—–-] ?(it''s|it is|that''s|they''re|they are)'
- 'not only (does|is|do|are|will|can|did) [^.,]{1,45}, but (also |it also |they also )'
- 'that''s where [^.]{1,40} comes? in'
13 changes: 13 additions & 0 deletions .github/styles/AIPatterns/Flourishes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extends: existence
message: "'%s' is a dramatic flourish AI writing leans on. Fine if it's earned; cut it if it's filler."
ignorecase: true
level: warning
tokens:
- Let that sink in
- Buckle up
- Spoiler alert
- Plot twist
- Here's the kicker
- Here is the kicker
- Here's the catch
- Here is the catch
14 changes: 14 additions & 0 deletions .github/styles/AIPatterns/MetaCommentary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
extends: existence
message: "Avoid meta-commentary like '%s'. Just do it directly."
ignorecase: true
level: error
tokens:
- Let's explore
- Let's dive into
- Let's take a look at
- Let's examine
- Let's consider
- Let's unpack
- Let's break down
- Let us explore
- Let us dive into
16 changes: 16 additions & 0 deletions .github/styles/AIPatterns/PerformativeEnthusiasm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
extends: existence
message: "'%s' sounds like performative enthusiasm. Keep a measured, authentic tone."
ignorecase: true
nonword: true
level: error
tokens:
- Great question!
- Excellent point!
- Excellent question!
- Great point!
- Fantastic approach
- Fantastic question
- Wonderful point
- Brilliant observation
- Absolutely right
- Couldn't agree more
16 changes: 16 additions & 0 deletions .github/styles/AIPatterns/RhetoricalQuestions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
extends: existence
message: "Avoid formulaic rhetorical questions like '%s'. Trust the reader to draw conclusions."
ignorecase: true
nonword: true
level: suggestion
tokens:
- 'So what does this mean\?'
- 'So what does that mean\?'
- 'So why does this matter\?'
- 'Why does this matter\?'
- 'What does this look like in practice\?'
- 'What does that look like in practice\?'
- But what does this mean
- But why does this matter
- So how do we
- So how do you
18 changes: 18 additions & 0 deletions .github/styles/AIPatterns/SetupPhrases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
extends: existence
message: "'%s' is a setup phrase. Get to the point."
ignorecase: true
level: warning
tokens:
- When it comes to
- In terms of
- In the context of
- In today's
- In an era
- In the world of
- In the realm of
- At its core
- At its heart
- In essence
- Gone are the days
- Rest assured
- Look no further
16 changes: 16 additions & 0 deletions .github/styles/AIPatterns/ThisConstructions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
extends: existence
message: "'%s' is a common AI writing pattern. Rephrase for a more natural voice."
ignorecase: true
level: error
tokens:
- This ensures that
- This allows for
- This enables teams
- This enables you
- This enables organizations
- This provides a
- This creates a
- This helps ensure
- This helps to ensure
- This makes it easy
- This makes it possible
17 changes: 17 additions & 0 deletions .github/styles/AIPatterns/Transitions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extends: existence
message: "'%s' is a formulaic transition. Use a natural transition or restructure."
ignorecase: false
nonword: true
level: warning
scope: sentence
tokens:
- Furthermore,
- Moreover,
- Additionally,
- In addition,
- That being said,
- That said,
- In conclusion,
- To summarize,
- In summary,
- Overall,
12 changes: 12 additions & 0 deletions .github/styles/AIPatterns/VagueIntensifiers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extends: existence
message: "'%s' is a vague intensifier. Be specific or provide evidence."
ignorecase: true
level: suggestion
tokens:
- very unique
- truly unique
- truly transformative
- incredibly important
- incredibly valuable
- incredibly powerful
- highly effective
11 changes: 11 additions & 0 deletions .github/styles/AIPatterns/WeakOpenings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extends: existence
message: "'%s' is a weak opening. Start with a stronger, more specific statement."
ignorecase: true
level: suggestion
tokens:
- One of the most important
- One of the biggest
- One of the key
- An important thing to
- An important aspect of
- An important consideration
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Check warning on line 80 in .github/workflows/ci.yml

View workflow job for this annotation

GitHub Actions / Code Tests

80:73 [comments] too few spaces before comment: expected 2

- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6

Check warning on line 83 in .github/workflows/ci.yml

View workflow job for this annotation

GitHub Actions / Code Tests

83:75 [comments] too few spaces before comment: expected 2
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
Expand All @@ -95,6 +95,22 @@
curl -fSL "https://github.com/Automattic/harper/releases/download/${HARPER_VERSION}/harper-cli-x86_64-unknown-linux-gnu.tar.gz" | tar xz
sudo mv harper-cli /usr/local/bin/

- name: Install Vale
env:
VALE_VERSION: 3.14.2
run: |
curl -fSL "https://github.com/errata-ai/vale/releases/download/v${VALE_VERSION}/vale_${VALE_VERSION}_Linux_64-bit.tar.gz" | tar xz vale
sudo mv vale /usr/local/bin/

- name: Cache Vale styles
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5

Check warning on line 106 in .github/workflows/ci.yml

View workflow job for this annotation

GitHub Actions / Code Tests

106:70 [comments] too few spaces before comment: expected 2
with:
path: .github/styles
key: vale-styles-${{ hashFiles('.vale.ini', '.github/styles/AIPatterns/*.yml') }}

- name: Sync Vale packages
run: vale sync

- name: script/cibuild-content
run: script/cibuild-content

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
node_modules
/tmp
.github/styles/*
# Local Vale style is checked in; synced packages above are not
!.github/styles/AIPatterns
.frontmatter
assets/css/style.css
assets/js/bundle.js
Expand Down
41 changes: 37 additions & 4 deletions .vale.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
StylesPath = .github/styles
Packages = Microsoft, alex, proselint, Readability, write-good, https://github.com/benbalter/vale-styles/releases/download/v0.0.1/BenBalter.zip
Packages = Microsoft, alex, proselint, Readability, write-good, https://github.com/benbalter/vale-styles/releases/download/v0.0.2/BenBalter.zip

[*.md]
BasedOnStyles = Vale, Microsoft, alex, proselint, Readability, write-good, BenBalter
[formats]
mdx = md

[*.{md,mdx}]
BasedOnStyles = Vale, Microsoft, alex, proselint, Readability, write-good, BenBalter, AIPatterns
alex.Condescending = warn
Microsoft.Adverbs = NO
Microsoft.Avoid = warn
Expand All @@ -15,4 +18,34 @@ Microsoft.Percentages = NO
Microsoft.Quotes = NO
Microsoft.Units = warn
Microsoft.We = NO
Vale.Spelling = NO
Vale.Spelling = NO

# Stylistic rules demoted to warning so CI (--minAlertLevel=error) gates on
# genuine problems without re-litigating 15 years of conversational posts.
# Where two packages flag the same concept, one source is disabled outright.
proselint.Cliches = warning
proselint.Very = warning
proselint.Skunked = warning
proselint.Uncomparables = warning
proselint.GenderBias = warning
write-good.ThereIs = warning
write-good.So = NO
BenBalter.So = warning
proselint.But = NO
BenBalter.But = warning
proselint.CorporateSpeak = NO
BenBalter.CorporateSpeak = warning
BenBalter.FillerWords = warning
BenBalter.CulturalInclusion = warning
Microsoft.Plurals = warning
proselint.Typography = warning
proselint.Cursing = warning
proselint.Hyperbole = warning
proselint.Jargon = warning
proselint.Hedging = warning
proselint.DateSpacing = warning
Microsoft.Foreign = warning
Microsoft.DateOrder = warning
Microsoft.AMPM = warning
Microsoft.HeadingColons = warning
Microsoft.Auto = warning
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Contributing to Ben.Balter.com
# Contributing to ben.balter.com

Thank you for your interest in contributing to this project! This document provides guidelines and information for contributors.

Expand Down
7 changes: 6 additions & 1 deletion script/vale
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ if ! [ -x "$(command -v vale)" ]; then
echo "Vale provides additional prose style and grammar checking."
else
echo "Running Vale prose linter..."
vale ./*.md src/content/posts/*.md src/content/resume-positions/*.md --minAlertLevel=error
# Sync packages on first run (the local AIPatterns style is checked in)
if [ ! -d ".github/styles/proselint" ]; then
vale sync
fi
# Note: /bin/sh may be dash (no brace expansion) — keep globs explicit
vale ./*.md src/content/posts/*.md src/content/posts/*.mdx src/content/resume-positions/*.md --minAlertLevel=error
fi
2 changes: 2 additions & 0 deletions src/content/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ These make writing feel machine-generated:
**The coffee test**: read aloud — does it sound like something you'd actually say to a colleague?
**The "anyone test"**: could this have been written by literally anyone? If there's no personality, rewrite it.

Many of these patterns are enforced mechanically by the custom `AIPatterns` Vale style (`.github/styles/AIPatterns/`), which runs in CI via `script/vale`. Unambiguous AI tells (hedging openers, meta-commentary, "This ensures…", performative enthusiasm) are errors and block CI; transitions and setup phrases are warnings; patterns that overlap with deliberate stylistic choices (em-dash antithesis, rhetorical questions) are suggestions. Run `vale <file> --minAlertLevel=suggestion` to see everything.

## Grammar and Mechanics

- **Em dashes** (`—`): no spaces — "Remote work—when done right—transforms teams"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Recording of a GW Tech Alumni panel discussion on removing the barr
archived: true
---

*Recorded at the [The George Washington University Tech Alumni Group](http://www.facebook.com/group.php?gid=154839957865223) Federal Executive Round Table, November 4, 2010.*
*Recorded at [The George Washington University Tech Alumni Group](http://www.facebook.com/group.php?gid=154839957865223) Federal Executive Round Table, November 4, 2010.*

<img src="https://ben.balter.com/wp-content/uploads/2010/11/68153_493302469280_603259280_5451391_4928024_n-300x199.jpg" alt="Photo of the panelists at the event" title="Steven Bucci, William Kirkendale, Brian Moran, Mark Rosenfeld, Mariano Tan " class="float-right ml-3 rounded" />

Expand Down
2 changes: 1 addition & 1 deletion src/content/posts/2011-01-04-the-files-in-the-computer.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ Notes:

[^3]: Beyond the obvious (email, phone, contact, calendars), there's [dinner reservations](http://itunes.apple.com/us/app/opentable/id296581815?mt=8), [car rentals](http://www.zipcar.com/iphone/), [TV viewing habits](http://www.engadget.com/2010/11/15/comcast-xfinity-remote-app-for-iphone-ipad-launches-video-stre/), [financial data](http://www.mint.com/features/iphone/), [recent purchases](https://www.amazon.com/your-account), even [desktop browsing history](http://www.mozilla.com/en-US/mobile/home/) — it's like winning the lottery of personal information.

[^4]: It's worth noting that the word "server" is not mentioned once in the opinion, yet the phrase "storage capacity" is used no less than five times — a concept that [even as early as 2007 was considered a thing of the past](http://mashable.com/2007/05/14/yahoo-mail-unlimited/).
[^4]: The word "server" is not mentioned once in the opinion, yet the phrase "storage capacity" is used no less than five times — a concept that [even as early as 2007 was considered a thing of the past](http://mashable.com/2007/05/14/yahoo-mail-unlimited/).

[^5]: A password may only delay the inevitable. *See* Gershowitz, Adam M., [*Password Protected? Can a Password Save Your Cell Phone from the Search Incident to Arrest Doctrine?*](http://ssrn.com/abstract=1669403) (August 31, 2010).
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The law aside, readers want you to digest and put ideas in your own voice. Take

[^1]: Questions asked included: If there's no copyright symbol, is it still copyrighted?; If it's posted online, can I just copy it because its it's in the public domain?; Can I use it if I'm not selling it?; and It's okay to use if I credit the original author, right?.

[^2]: It should be noted that [I'm not an attorney](https://ben.balter.com/fine-print/) and my writing should not be substituted for qualified legal advice.
[^2]: [I'm not an attorney](https://ben.balter.com/fine-print/) and my writing should not be substituted for qualified legal advice.

[^3]: This is a common misconception. While once true, under the [Berne Convention](http://en.wikipedia.org/wiki/Berne_Convention_for_the_Protection_of_Literary_and_Artistic_Works) the author of any content published today is assumed to retain copyright claims.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ Justice Brandeis is famous for noting that "sunlight is the best disinfectant."

[^2]: [twitter.com/BenBalter/status/209356982983999488](https://twitter.com/BenBalter/status/209356982983999488)

[^3]: [coverity.com/library/PDF/coverity-scan-2011-open-source-integrity-report.PDF](http://www.coverity.com/library/pdf/coverity-scan-2011-open-source-integrity-report.pdf)
[^3]: [coverity.com/library/pdf/coverity-scan-2011-open-source-integrity-report.pdf](http://www.coverity.com/library/pdf/coverity-scan-2011-open-source-integrity-report.pdf)
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ At the least, lets expose all WordPress content in a machine readable format. Th

1. Create a new format ("feed" in WordPress parlance) called JSON, and add the necessary rewrite rules such that I can simply add `.json` to any post and retrieve the underlying information in a machine readable format. This should contain not only the content of the post and information that would normally be accessible via HTML, but all the fields of the posts table (for example, date published, date updated, etc.), all the post's metadata (custom, post-specific information), and all the associated term objects (tags, categories, etc.). Sure we'll need to add a filter or two in their to ensure information folks want private stays private, but from a technical standpoint, we're talking a handful of lines of code here.

2. Extend that format to indices (archives in WordPress terms). Again, just as above, every list of posts (by date, by associated term, search results) should have the capability to expose the list in that same machine-readable format. This allows for the programatic discovery of information. A little bit harder than #1, but again, nothing crazy here. Pretty basic stuff.
2. Extend that format to indices (archives in WordPress terms). Again, just as above, every list of posts (by date, by associated term, search results) should have the capability to expose the list in that same machine-readable format, so that information can be discovered programatically. A little bit harder than #1, but again, nothing crazy here. Pretty basic stuff.

## Walk

Expand Down
Loading
Loading