promptdojo_

The voice pack is data — on-voice copy at batch volume — step 2 of 8

The linter: fifteen lines that replace an argument

You know the review meeting where someone says "this doesn't sound like us" and someone else says "it sounds fine to me" and twenty minutes evaporate? A linter ends that meeting. Either the draft contains "best-in-class" or it doesn't. Either the sentence runs 27 words or it doesn't. The conversation moves from taste to fact, and fact takes four seconds.

Run the code on the right. The whole check is:

  1. Lowercase the draft once. Banned phrases are stored lowercase; "Revolutionary" and "revolutionary" are the same sin. Case-insensitive matching costs one .lower() call.
  2. Loop the banned list, substring match. phrase in text — Python's in on strings is a substring check. Each hit appends a labeled violation, banned: revolutionary, so the report says what broke, not just that something did.
  3. Word-count check. len(draft.split()) > PACK["max_words"]. Crude twice over — split() counts tokens, not typographer's words, and it measures the whole draft against what the pack states as a per-sentence rule. That's fine here because this draft is one sentence; body copy would need a split into sentences first. But crude and consistent beats precise and manual. Same yardstick every draft, every time.

Note what the violations are: strings, in a list. Not print statements buried in the loop, not a boolean looks_ok. A list of labeled problems is something the pipeline can count (len(problems) == 0 means pass), forward (attach them to the variant that failed, send it back for a redraft), and log (which rules fail most tells Dana which rules the prompt needs to state harder).

What the linter doesn't catch — on purpose

"One idea per line" is in the pack but not in this script. Some rules stay human: the linter can't tell whether a sentence carries one idea or three. That's fine. The point was never full automation — it's that every mechanically checkable rule gets checked mechanically, so the human reviewer spends her attention on the rules that actually need a human. Dana shouldn't burn her review pass counting words. She should burn it on "is this true, and is it us?"

The division of labor, explicitly: the script catches banned phrases and length. Dana catches meaning. The model catches nothing — it's the thing being checked.

Next step: a draft goes through this exact linter, and you call the output before Python does.