zero-slop 2.8.10 → 2.9.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/.mcp.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "zero-slop": {
4
+ "type": "http",
5
+ "url": "https://mcp.zero-slop.ai/mcp"
6
+ }
7
+ }
8
+ }
package/README.md CHANGED
@@ -1,54 +1,62 @@
1
- # Zero Slop
1
+ <p align="center">
2
+ <a href="https://zero-slop.ai">
3
+ <img src="assets/logo/studio/zero-slop-mark-300-transparent.png" width="112" alt="Zero Slop">
4
+ </a>
5
+ </p>
6
+
7
+ Zero Slop crossed 100 GitHub stars and 2,000 npm downloads in its first 12 days.
8
+
9
+ <h1 align="center">Zero Slop</h1>
10
+
11
+ <p align="center"><strong>Find AI-sounding writing. Keep the source intact.</strong></p>
2
12
 
3
13
  <p align="center">
4
- <img alt="MIT" src="https://img.shields.io/badge/license-MIT-202521">
5
- <img alt="tests" src="https://img.shields.io/badge/tests-passing-227B5B">
6
- <img alt="dependencies" src="https://img.shields.io/badge/runtime%20dependencies-0-227B5B">
7
- <img alt="privacy" src="https://img.shields.io/badge/learning-private-227B5B">
8
- <img alt="version" src="https://img.shields.io/badge/version-2.8.10-72528F">
9
- <a href="https://hol.org/guard/plugins"><img alt="Listed in the HOL plugin registry" src="https://img.shields.io/badge/HOL%20registry-listed-2C6E8F"></a>
10
- <a href="https://github.com/hashgraph-online/awesome-ai-plugins#tools--integrations"><img alt="Listed in awesome-ai-plugins" src="https://img.shields.io/badge/awesome--ai--plugins-listed-2C6E8F"></a>
11
- <a href="https://zero-slop.ai/try/"><img alt="This README scores 11.6 out of 100 on the slop score, inside the human range" src="https://img.shields.io/badge/slop%20score-11.6%2F100-0f7d55"></a>
14
+ Zero Slop finds stock phrasing, mechanical rhythm, vague claims, and canned formatting.<br>
15
+ Your existing AI assistant edits the draft; local checks guard its names, numbers, links, quotations, code, tables, and paths.
12
16
  </p>
13
17
 
14
- Less slop, more pop in your writing.
18
+ <p align="center">
19
+ <a href="https://zero-slop.ai/try/"><strong>Try it in your browser</strong></a>
20
+ ·
21
+ <a href="#install">Install the skill</a>
22
+ ·
23
+ <a href="#evidence-and-limits">See the evidence</a>
24
+ ·
25
+ <a href="https://github.com/manavmishra/ZeroSlop/releases/latest">Latest release</a>
26
+ </p>
15
27
 
16
- Zero Slop finds stock phrasing, mechanical rhythm, vague claims, and canned
17
- formatting. Local checks run offline; your existing AI assistant does the editing.
18
- Score a draft at [zero-slop.ai/try](https://zero-slop.ai/try/); benchmark at
19
- [zero-slop.ai](https://zero-slop.ai).
28
+ <p align="center">
29
+ <a href="https://github.com/manavmishra/ZeroSlop/actions/workflows/validate.yml"><img alt="Validate" src="https://github.com/manavmishra/ZeroSlop/actions/workflows/validate.yml/badge.svg"></a>
30
+ <img alt="Version 2.9.0" src="https://img.shields.io/badge/version-2.9.0-72528F">
31
+ <a href="https://www.npmjs.com/package/zero-slop"><img alt="npm version" src="https://img.shields.io/npm/v/zero-slop?color=72528F"></a>
32
+ <a href="https://www.npmjs.com/package/zero-slop"><img alt="npm downloads" src="https://img.shields.io/npm/dm/zero-slop?color=227B5B"></a>
33
+ <a href="https://github.com/manavmishra/ZeroSlop/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/manavmishra/ZeroSlop?style=flat&color=b0442a"></a>
34
+ <a href="LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-202521"></a>
35
+ <a href="https://hol.org/guard/plugins"><img alt="Listed in the HOL plugin registry" src="https://img.shields.io/badge/HOL%20registry-listed-2C6E8F"></a>
36
+ </p>
20
37
 
21
38
  ```sh
22
- npx zero-slop install
39
+ npx skills add manavmishra/ZeroSlop --global
23
40
  ```
24
41
 
25
- ![Scoring a launch post at 100.0, rewriting it to 9.5, with the 40% figure held by the fact gate](assets/zero-slop-demo.gif)
42
+ <a href="assets/zero-slop-demo.mp4?v=dark-shell-restored-20260906">
43
+ <picture>
44
+ <source media="(prefers-reduced-motion: reduce)" srcset="assets/zero-slop-demo-poster.png?v=dark-shell-restored-20260906">
45
+ <source type="image/webp" srcset="assets/zero-slop-demo.webp?v=dark-shell-restored-20260906">
46
+ <img src="assets/zero-slop-demo.gif?v=dark-shell-restored-20260906" width="900" alt="Dark-shell demo: install Zero Slop, edit with your assistant, and check scores while preserving 40%.">
47
+ </picture>
48
+ </a>
26
49
 
27
- ### What it does, on a real draft
50
+ <p align="center"><a href="assets/zero-slop-demo.mp4?v=dark-shell-restored-20260906">Watch the 15-second shell demo</a> · <sub>The original demo uses a longer sample than the example below.</sub></p>
28
51
 
29
- A launch post, as AI wrote it:
52
+ ## Before and after
30
53
 
31
- > We're thrilled to announce that our team has leveraged cutting-edge AI to deliver a seamless onboarding experience. It's not just a redesign, it's a fundamental reimagining of how users engage with our platform. In today's fast-paced landscape, the ability to iterate quickly is crucial. By harnessing the power of machine learning, we've been able to reduce setup time by 40%. Here's the thing nobody tells you: onboarding is where most products lose their users. We're excited to continue this journey with you.
54
+ A launch post, as AI wrote it:
32
55
 
33
- `slopscore.py --explain` on that paragraph, unedited:
56
+ > We're thrilled to announce that our team has leveraged cutting-edge machine learning to deliver a seamless onboarding experience, reducing setup time by 40%.
34
57
 
35
- ```text
36
- Writing score: 100.0/100 [major rewrite]
37
- Flagged phrases : 11 across 83 words
38
- Sentence variety: too even
39
- Main issues : canned LinkedIn phrase, promotional language, manufactured
40
- stakes, two-part contrast used as a formula, performed
41
- writer's voice, buzzword used as promotion
42
-
43
- Flagged phrases (11), strongest first:
44
- "In today's fast-paced" manufactured stakes; start where the reader needs to start
45
- "We're thrilled to" canned LinkedIn phrase; say what happened without the stock opening
46
- "It's not just a redesign, it's"
47
- two-part contrast used as a formula; state the claim once, plainly
48
- "Here's the thing" performed writer's voice; say the thing plainly
49
- 'cutting-edge' promotional language; name what it does; cut the adjectives
50
- 'leveraged' buzzword used as promotion; use the plain word
51
- ```
58
+ The scorer rates that draft 99.3/100 and flags four phrases: “We're thrilled
59
+ to,” “leveraged,” “cutting-edge,” and “seamless.”
52
60
 
53
61
  The rewrite, limited to the draft's stated claims:
54
62
 
@@ -59,213 +67,171 @@ Writing score: 9.5/100 [clear]
59
67
  Flagged phrases : 0 across 10 words
60
68
  ```
61
69
 
62
- ## Problem
70
+ The rewrite retains the draft's stated result. See four complete, reproducible pairs in [`examples/`](examples/).
71
+
72
+ ## What can I use it for?
63
73
 
64
- AI-assisted writing often converges on the same constructions: "It's not X. It's Y."
65
- "Here's the thing nobody tells you." Repeated wording, uniform rhythm, and
66
- overworked formatting can have the same effect.
74
+ - Tighten a launch post without losing the release details.
75
+ - Turn a padded product update into a useful changelog.
76
+ - Clean up an email while preserving names, dates, and numbers.
77
+ - Edit a research summary without flattening its qualifications.
78
+ - Gate a folder of generated copy before it ships.
67
79
 
68
- Zero Slop is an Agent Skill and ships no model. Claude, GPT, or another compatible
69
- model edits; local tools protect names, numbers, quotations, links, code, tables,
70
- and paths. Your AI compares meaning that word matching cannot judge.
80
+ Zero Slop is a writing tool. It does not detect authorship; its score describes the text.
71
81
 
72
- ## How to install Zero Slop
82
+ ## Install
73
83
 
74
- Paste this into Claude Code, Codex, Cursor, OpenCode, Warp, or Zed:
84
+ To try Zero Slop first, paste a draft into [zero-slop.ai/try](https://zero-slop.ai/try/). The free editor returns the edit, the before-and-after scores, and the exact phrases that triggered the scorer.
85
+
86
+ | Environment | Fastest route |
87
+ |---|---|
88
+ | Claude Code, Codex, Cursor, OpenCode, Warp, Zed | `npx skills add manavmishra/ZeroSlop --global` |
89
+ | Gemini CLI | `gemini extensions install https://github.com/manavmishra/ZeroSlop --auto-update` |
90
+ | Claude Code plugin | `/plugin marketplace add manavmishra/ZeroSlop`, then `/plugin install zero-slop@zero-slop` |
91
+ | Any assistant with file uploads | Download the [single-file bundle](https://github.com/manavmishra/ZeroSlop/releases/latest/download/zero-slop-single-file.md) |
92
+ | Claude.ai | Upload the [latest skill ZIP](https://github.com/manavmishra/ZeroSlop/releases/latest/download/zero-slop.zip) |
93
+ | ChatGPT, Claude, Grok, Gemini, Cursor, or another MCP client | Connect the optional [hosted MCP server](mcp/README.md) |
94
+
95
+ Once installed, ask your AI assistant to edit a draft:
75
96
 
76
97
  ```text
77
- Install the Zero Slop skill globally from https://github.com/manavmishra/ZeroSlop
98
+ /zero-slop (your writing)
78
99
  ```
79
100
 
80
- Or install it with `npx`:
101
+ Inspect a draft without changing it:
81
102
 
82
- ```sh
83
- npx skills add manavmishra/ZeroSlop --global
103
+ ```text
104
+ /zero-slop inspect (your writing)
84
105
  ```
85
106
 
86
- Or install from npm, which also adds the scoring command:
107
+ Score a file locally:
87
108
 
88
109
  ```sh
89
- npx zero-slop install # add --harness codex|cursor|opencode|zed
90
- npx zero-slop score draft.md # score without installing anything
110
+ npx zero-slop score draft.md
91
111
  ```
92
112
 
93
- ChatGPT users can download [`dist/zero-slop-single-file.md`](dist/zero-slop-single-file.md).
94
- Claude.ai users can upload the [release ZIP](https://github.com/manavmishra/ZeroSlop/releases/latest/download/zero-slop.zip).
113
+ From a cloned checkout, gate a folder:
95
114
 
96
- ## How to use Zero Slop
97
-
98
- ```text
99
- /zero-slop (your writing)
115
+ ```sh
116
+ python3 scripts/slopscore.py --batch drafts/ --gate 25
100
117
  ```
101
118
 
102
- You get the edited draft, before-and-after scores, and quoted flagged phrases.
103
- `/zero-slop inspect (your writing)` reviews without rewriting. For a folder,
104
- `slopscore.py --batch drafts/ --gate 25` fails above the threshold.
119
+ Installed checks run locally; editing follows your AI assistant's privacy settings. The optional hosted MCP processes drafts remotely. See its [privacy details](mcp/README.md).
105
120
 
106
- ## Show your score
121
+ ### Prefer one hosted connection? Use the MCP
107
122
 
108
- The badge above is this README's own, from `npx zero-slop score README.md`.
109
- Put yours up the same way:
123
+ Connect the [Zero Slop MCP](https://zero-slop.ai/#mcp) once to edit drafts inside your MCP client. Its `deslop` tool returns the edit, before-and-after scores, and review status. Zero Slop requires no account or API key; server updates are managed for you.
110
124
 
111
- ```md
112
- [![Slop score](https://img.shields.io/badge/slop%20score-11.6%2F100-0f7d55)](https://zero-slop.ai/try/)
125
+ ```text
126
+ https://mcp.zero-slop.ai/mcp
113
127
  ```
114
128
 
115
- Colours are the scorer's bands: `0f7d55` under 25, `b8860b` under 60, `b0502c`
116
- above.
129
+ See [`DISTRIBUTION.md`](DISTRIBUTION.md) for direct connector commands and directory status.
117
130
 
118
- ## The slop that Zero Slop catches
131
+ ## What the workflow adds
119
132
 
120
- 294 weighted patterns and a 96-term lexicon, including:
133
+ | A prompt alone | Zero Slop |
134
+ |---|---|
135
+ | “Make this sound human” leaves the target vague. | A 0–100 meter points to exact phrases and structural problems. |
136
+ | One rewrite can quietly alter source details. | A local fact gate checks protected strings before the edit is returned. |
137
+ | The model tends to overcorrect into fragments or forced casualness. | An overcorrection pass checks readability, rhythm, grammar, and voice. |
138
+ | Each session starts from scratch. | Optional, reason-labelled preferences can be learned privately. |
121
139
 
122
- 1. Binary contrasts: "It's not X. It's Y."
123
- 2. Throat-clearing openers: "Here's the thing," "Let me be clear"
124
- 3. Faux-insight setups: "What nobody tells you," "The part everyone misses"
125
- 4. Colon reveals: "The best part: it learns."
126
- 5. Dramatic fragments: "That's it. That's the whole thing."
127
- 6. Superficial analysis: "highlighting the team's commitment to innovation"
128
- 7. Importance puffery: "marks a pivotal moment," "a testament to"
129
- 8. Weasel attribution: "experts agree," "studies show"
130
- 9. Synonym cycling: the agent, the assistant, the tool, all one thing.
131
- 10. Marketing riders: "robust" and "leverage" score only beside a marketing trigger, so a runbook stays quiet.
140
+ Zero Slop ships no model. Your AI assistant reads and edits the draft in context,
141
+ using Claude, GPT, or another compatible model. The repository supplies the
142
+ workflow and local tools for scoring and source checks.
132
143
 
133
- A reading pass covers repeated shapes, crowded statistics, and paragraphs that
134
- shuffle without loss. [`references/eval.md`](references/eval.md) has all 80 checks.
144
+ ## What it catches
135
145
 
136
- Human writing scored 9 to 21 in [`data/corpus/must-not-flag/`](data/corpus/must-not-flag/);
137
- unedited AI drafts averaged 77 across [`bench/examples.json`](bench/examples.json).
146
+ The current scorer combines 294 weighted patterns with a 96-term lexicon. Examples include:
138
147
 
148
+ - binary contrast formulas: “It's not X. It's Y.”
149
+ - canned openers: “We're thrilled to…” and “Here's the thing…”
150
+ - vague attribution: “experts agree” and “studies show”
151
+ - significance inflation: “marks a pivotal moment” and “a testament to”
152
+ - promotional riders: “robust,” “seamless,” and “leverage” when used as hype
153
+ - repeated sentence shapes, crowded statistics, and overworked formatting
139
154
 
140
- ## How it works
155
+ Marketing terms are scored in context, so an ordinary technical use of a word need not trigger the same penalty. [`references/eval.md`](references/eval.md) documents all 80 checks.
141
156
 
142
- ![Eight editorial roles, a private learning loop, and a separate release review](assets/engine.svg)
143
-
144
- Eight responsibilities form one workflow. They are jobs, not separate models. An
145
- installed assistant can isolate them.
146
- The free web editor combines
147
- the five AI responsibilities into one model response, then runs the scorer and source
148
- checks locally. It makes at most one live model call and never describes that response
149
- as independent review. The research supports the checks, not the number eight, which
150
- is an engineering choice.
151
-
152
- | Role | Who does it | What happens |
153
- |---|---|---|
154
- | 1. Scorer | Local tools | Finds the exact phrases behind the writing score, then checks pacing and readability. It also catches overworked formatting. |
155
- | 2. Interpreter | Your AI assistant | Reads the claims, purpose, audience, structure, and voice before changing anything. |
156
- | 3. Rewriter | Your AI assistant | Removes stock language and rebuilds order, rhythm, and tone without inventing detail. |
157
- | 4. Fact gate | Local tools | Rejects any version that changes names, numbers, quotations, links, code, tables, paths, or structure. |
158
- | 5. Copy desk | Your AI assistant | Corrects grammar, spelling, usage, and consistency in the actual deliverable. |
159
- | 6. Read-aloud editor | Your AI assistant | Fixes stumbles, repetition, weak transitions, and awkward flow. |
160
- | 7. Verifier | Local tools and your AI assistant | Compares text with source for facts, meaning, qualifiers, voice, format, structure. In the web editor, source safety is checked locally. |
161
- | 8. Fresh-eyes finalizer | Your AI assistant | Reads the finished text as a first-time reader and applies only safe polish. Any change receives one final local recheck. |
162
-
163
- Missed editorial targets do not erase a useful edit or start an open-ended loop. Zero
164
- Slop permits one targeted repair and one local recheck, then returns the safest
165
- source-preserving edit with a plain warning. On the website, a failed model call falls
166
- back to the same conservative local editor shipped with the installed skill instead of
167
- retrying through more providers. Shared fixtures require the browser and local command
168
- to return the same fallback edit, character for character.
169
-
170
- Studies find
171
- [predictable wording](https://arxiv.org/abs/2301.11305) and
172
- [overused vocabulary](https://arxiv.org/abs/2406.07016) in machine text, and authorship
173
- detectors can [misclassify non-native English](https://arxiv.org/abs/2304.02819). Local
174
- tools use only Python's standard library.
175
-
176
- ## Private learning from your edits
177
-
178
- Learning starts only when you provide the original output and your edited version.
179
- Zero Slop does not monitor files, browsers, or publishing tools.
180
-
181
- Private data stays under `$ZERO_SLOP_HOME`.
182
-
183
- This human-in-the-loop learning never retrains the model. A profile selected by name
184
- can exempt existing watchlist words; it does not learn cadence, tone, or a complete
185
- style.
186
-
187
- ## What's inside
188
-
189
- [`SKILL.md`](SKILL.md) has the workflow and [`references/eval.md`](references/eval.md) the
190
- 80 checks. [`scripts/slopscore.py`](scripts/slopscore.py) is the meter and fact gate,
191
- with [`scripts/register.py`](scripts/register.py) running the reading pass.
192
- [`bench/README.md`](bench/README.md) documents every benchmark with its limits.
193
- [zero-slop.ai](https://zero-slop.ai) has the same reference as browsable pages, plus the [benchmark in full](https://zero-slop.ai/benchmark/).
194
-
195
- ## Testing and limits
196
-
197
- ### Against other tools, same model, same drafts
198
-
199
- The saved replay ran Zero Slop, [avoid-ai-writing](https://github.com/conorbronsdon/avoid-ai-writing),
200
- [no-ai-slop](https://github.com/petergyang/no-ai-slop) and
201
- [humanizer](https://github.com/blader/humanizer) over 18 drafts with GPT-5.4, high
202
- reasoning, and pinned instructions. Zero Slop's outputs came from v2.5.9; later
203
- releases only rescore those frozen outputs.
204
-
205
- | Method | Mean writing score ↓ | Passed Zero Slop's local gates | Source check passed | Average length change |
206
- |---|---:|---:|---:|---:|
207
- | Original drafts | 76.3 | 0/18 | — | — |
208
- | Zero Slop | 12.8 | 18/18 | 18/18 | -8.9% |
209
- | avoid-ai-writing | 23.3 | 15/18 | 18/18 | -14.6% |
210
- | no-ai-slop | 28.4 | 12/18 | 17/18 | -13.7% |
211
- | humanizer | 35.4 | 9/18 | 17/18 | -7.2% |
157
+ Unedited AI drafts averaged 77 in [`bench/examples.json`](bench/examples.json).
158
+ Human writing scored 9 to 21 in
159
+ [`data/corpus/must-not-flag/`](data/corpus/must-not-flag/). These are reference
160
+ points for the scorer, not authorship boundaries.
212
161
 
213
- ![Fresh same-model editing replay on 18 drafts](assets/bench-search-rewrites.png)
162
+ ## How it works
214
163
 
164
+ ![Zero Slop's eight editorial responsibilities, private learning loop, and separate release review](assets/engine.svg)
215
165
 
166
+ Eight responsibilities form one workflow. They are jobs, not separate models.
167
+ Research supports the checks, not the number eight, which is an engineering
168
+ choice.
216
169
 
217
- ![Method-hidden editorial preference on 18 drafts](assets/bench-incumbent-hidden.png)
170
+ | Stage | Job |
171
+ |---|---|
172
+ | 1. Scorer | Find exact phrases, pacing problems, readability issues, and overworked formatting. |
173
+ | 2. Interpreter | Read the claims, audience, structure, and voice before editing. |
174
+ | 3. Rewriter | Remove stock language without inventing detail. |
175
+ | 4. Fact gate | Check names, numbers, quotations, links, code, tables, paths, and structure locally. |
176
+ | 5. Copy desk | Fix grammar, usage, spelling, and consistency. |
177
+ | 6. Read-aloud editor | Catch stumbles, repetition, and awkward transitions. |
178
+ | 7. Verifier | Compare the edit with the source for meaning, qualifiers, voice, and format. |
179
+ | 8. Fresh-eyes finalizer | Apply only safe final polish, then run one last local check. |
218
180
 
219
- Two cross-checks: AIStoryHub clean rates and a method-hidden quality ranking.
181
+ The free web editor combines the five AI responsibilities into one response and
182
+ makes at most one live model call. A single response does not provide independent review.
183
+ Any final change receives one final local recheck.
220
184
 
221
- ![External checker clean rates per method](assets/bench-external-checker.png)
185
+ If a repair still misses the target, Zero Slop returns the safest source-preserving edit with a plain warning. It does not enter an open-ended rewrite loop.
222
186
 
223
- ![Method-hidden quality ranking, lower is better](assets/bench-blind-quality.png)
187
+ ## Evidence and limits
224
188
 
225
- This small LLM-reviewed regression study measures neither field accuracy nor a
226
- universal ranking. Drafts, hashes, and limits are in [`bench/README.md`](bench/README.md).
227
- The separate two-way replay used Zero Slop v2.6.0 and is preserved in
228
- [`bench/incumbent-blind-replay/`](bench/incumbent-blind-replay/).
189
+ ### Same model, same 18 drafts
229
190
 
230
- For the 38-item editorial panel, the current scorer matched the prior 84.2% result.
231
- All frozen scores stayed unchanged, all 18 human controls remained below the gate,
232
- and all 18 obvious search cases remained above it. These fixed-sample checks are not
233
- proof of general accuracy.
191
+ A saved replay ran Zero Slop and three comparable open-source instruction sets over the same drafts with GPT-5.4, high reasoning, and pinned instructions. The outputs are frozen and reproducible.
234
192
 
235
- ### Speed
193
+ | Method | Mean writing score ↓ | Passed local gates | Source check passed | Mean length change |
194
+ |---|---:|---:|---:|---:|
195
+ | Original drafts | 76.3 | 0/18 | — | — |
196
+ | **Zero Slop** | **12.8** | **18/18** | **18/18** | -8.9% |
197
+ | avoid-ai-writing | 23.3 | 15/18 | 18/18 | -14.6% |
198
+ | no-ai-slop | 28.4 | 12/18 | 17/18 | -13.7% |
199
+ | humanizer | 35.4 | 9/18 | 17/18 | -7.2% |
236
200
 
237
- One Apple silicon Mac: the meter scored 1,000 documents in 1.9929 seconds
238
- (501.8 per second), 15,201 words in 0.3223 seconds, and the worst stress case in 2.2932
239
- seconds. The reading pass handled the same 1,000 in 0.7823 seconds (1278.3/second);
240
- learning on 8,000 words took 0.1592 seconds. Across 24 interleaved runs against 2.7.7,
241
- median throughput was 0.26% lower, effectively no difference. Editing is excluded.
201
+ ![Fresh same-model editing replay on 18 drafts, with lower scores better](assets/bench-search-rewrites.png)
242
202
 
243
- ### Reading-pass accuracy
203
+ This small LLM-reviewed regression study measures repeatable behavior; it does not establish universal writing quality. The drafts, hashes, method versions, prompts, and limitations are in [`bench/README.md`](bench/README.md).
244
204
 
245
- The reading pass budgets antithesis pairs by frequency, so the count has to be right
246
- before the budget means anything. On 75 labelled pairs in
247
- [`bench/antithesis/`](bench/antithesis/):
205
+ Zero Slop's frozen outputs came from v2.5.9; newer versions only rescore those
206
+ saved outputs. The current scorer matched the prior 84.2% result on the fixed
207
+ 38-item editorial panel. These fixed-sample checks are not field accuracy.
248
208
 
249
- | Reading pass | 2.8.0 | now |
250
- |---|---:|---:|
251
- | Recall, all shapes | 40.0% | 91.2% |
252
- | Recall, shapes in reach | 44.4% | 100% |
253
- | Precision | 80.0% | 100% |
254
- | False positives | 3 | 0 |
209
+ <details>
210
+ <summary>More validation</summary>
255
211
 
256
- 2.8.3 added the families the 58-pair corpus never tested, where 2.8.2 scores 67.5%
257
- precision.
212
+ - A method-hidden editorial preference replay: [`bench/incumbent-blind-replay/`](bench/incumbent-blind-replay/)
213
+ - External-checker clean rates: [`assets/bench-external-checker.png`](assets/bench-external-checker.png)
214
+ - Method-hidden quality ranking: [`assets/bench-blind-quality.png`](assets/bench-blind-quality.png)
215
+ - Current-model corpus measurements: [`assets/bench-raid-plus.png`](assets/bench-raid-plus.png)
216
+ - Antithesis regression set: [`assets/bench-antithesis.png`](assets/bench-antithesis.png)
258
217
 
259
- ![Antithesis detection before and after, on 75 labelled pairs](assets/bench-antithesis.png)
218
+ On the 75 labelled antithesis pairs, the current reading pass reached 91.2% recall across the full set, 100% recall on shapes in reach, and 100% precision. The labels are maintainer-authored and the pairs are constructed, so this is a regression floor rather than field accuracy.
260
219
 
261
- Bare subject swap and the weak isocolon stay out of reach and count against recall: both
262
- are identical to ordinary prose on every lexical statistic. Maintainer labels on
263
- constructed pairs, so this is a regression floor, not field accuracy.
220
+ Local speed measurements cover the checks, with editing time excluded. On one
221
+ Apple silicon Mac, the scorer processed 1,000 documents in a median of 1.9929
222
+ seconds (501.8 per second); the five runs ranged from 1.9614 to 2.0945 seconds.
223
+ It scored a 15,201-word document in a median of 0.3223 seconds. The slowest
224
+ stress case took 2.2932 seconds, and learning from an 8,000-word edit took
225
+ 0.1592 seconds. The measurements and machine details are in
226
+ [`bench/performance-results.json`](bench/performance-results.json).
264
227
 
265
- ### Current models
228
+ Across 12 interleaved runs against 2.7.7, we measured 0.02% lower median throughput,
229
+ which is effectively unchanged. The separate two-way replay used
230
+ Zero Slop v2.6.0.
266
231
 
267
- The pinned [RAID+](https://huggingface.co/datasets/markstanl/RAID-Plus) sample yielded
268
- 7,627 usable generations:
232
+ The [RAID+ audit](bench/raid-plus-corpus/README.md) checks how the scorer responds
233
+ to output from different models. Its pinned sample contains 7,627 usable
234
+ generations:
269
235
 
270
236
  | Model | Texts scored | Mean writing score ↓ | At or above 25 |
271
237
  |---|---:|---:|---:|
@@ -274,27 +240,53 @@ The pinned [RAID+](https://huggingface.co/datasets/markstanl/RAID-Plus) sample y
274
240
  | Gemma 3 27B | 1,634 | 21.6 | 30.4% |
275
241
  | Llama 3.3 70B | 2,000 | 25.5 | 41.7% |
276
242
 
277
- RAID+ labels capture which model produced a text, not how well it reads. In
278
- Beemo, raw responses averaged
279
- 30.2, expert edits 25.3, human answers 20.0. Neither dataset has quality labels.
243
+ RAID+ labels record which model produced each text; they do not grade writing
244
+ quality. The [Beemo paired-edit audit](bench/beemo-corpus/README.md) checks how
245
+ scores change after human editing: raw responses averaged 30.2, expert edits
246
+ 25.3, and human answers 20.0. Beemo also lacks writing-quality labels.
280
247
 
281
- ## Where Zero Slop came from
248
+ </details>
282
249
 
283
- Zero Slop builds on work by no-ai-slop, humanizer, de-slop, stop-slop, unslop-text,
284
- and avoid-ai-writing. It adds a writing score, source protection, separate editorial
285
- passes, private learning, portfolio analysis, and release tests.
250
+ ### Documented capability audit
286
251
 
287
252
  ![Documented capabilities at pinned repository versions](assets/competitor-capabilities.png)
288
253
 
289
- The chart says nothing about writing quality. Reproduce it with:
254
+ This chart says nothing about writing quality or which tool writes better. It
255
+ records documented features at pinned commits; the data and reproduction notes
256
+ are in [`bench/README.md`](bench/README.md).
290
257
 
291
- ```sh
292
- python3 tests/test_all.py
293
- python3 scripts/calibrate.py --selftest
294
- python3 scripts/register.py --selftest
295
- python3 bench/make_charts.py --check
296
- ```
258
+ The design follows research on [predictable wording in machine text](https://arxiv.org/abs/2301.11305) and [overused vocabulary](https://arxiv.org/abs/2406.07016). It deliberately avoids authorship claims because detectors can [misclassify non-native English](https://arxiv.org/abs/2304.02819).
259
+
260
+ ## Private learning
261
+
262
+ Learning begins only when you provide an original output and your reason-labelled edit. Zero Slop does not monitor files, browsers, or publishing tools. Private data stays under `$ZERO_SLOP_HOME`; it is not committed to this repository and does not retrain the model.
263
+
264
+ A profile selected by name can exempt existing watchlist words. It does not
265
+ learn cadence, tone, or a complete writing style.
266
+
267
+ ## Repository map
268
+
269
+ | Path | Purpose |
270
+ |---|---|
271
+ | [`SKILL.md`](SKILL.md) | The complete detect, rewrite, verify, and learn workflow |
272
+ | [`scripts/slopscore.py`](scripts/slopscore.py) | Offline meter and source-detail gate |
273
+ | [`scripts/register.py`](scripts/register.py) | Performed-register and reading pass |
274
+ | [`references/`](references/) | Genre guidance, tells, safeguards, and evaluation rules |
275
+ | [`examples/`](examples/) | Reproducible before-and-after edits |
276
+ | [`bench/`](bench/) | Frozen benchmarks, provenance, and limitations |
277
+ | [`mcp/`](mcp/) | Optional hosted MCP server documentation |
278
+ | [`DISTRIBUTION.md`](DISTRIBUTION.md) | Direct installs, marketplace submissions, and release synchronization |
279
+
280
+ ## Contributing and support
281
+
282
+ Bug reports, false positives, examples, and carefully tested pattern improvements are welcome. Read [`CONTRIBUTING.md`](CONTRIBUTING.md) before opening a pull request, use the structured [issue forms](https://github.com/manavmishra/ZeroSlop/issues/new/choose), or start a [Discussion](https://github.com/manavmishra/ZeroSlop/discussions).
283
+
284
+ For setup help and responsible disclosure, see [`SUPPORT.md`](SUPPORT.md) and [`SECURITY.md`](SECURITY.md).
285
+
286
+ ## Credits
287
+
288
+ Zero Slop builds on ideas from [no-ai-slop](https://github.com/petergyang/no-ai-slop), [humanizer](https://github.com/blader/humanizer), [de-slop](https://github.com/isatimur/de-slop), [stop-slop](https://github.com/hardikpandya/stop-slop), [unslop-text](https://github.com/JCarterJohnson/vibecoded-design-tells/tree/main/unslop-ai-text), and [avoid-ai-writing](https://github.com/conorbronsdon/avoid-ai-writing).
297
289
 
298
290
  ## License
299
291
 
300
- MIT
292
+ [MIT](LICENSE)
package/SKILL.md CHANGED
@@ -2,7 +2,7 @@
2
2
  name: zero-slop
3
3
  license: MIT
4
4
  metadata:
5
- version: "2.8.10"
5
+ version: "2.9.0"
6
6
  author: manavmishra
7
7
  description: Turn drafts into sharp, natural prose or inspect them without rewriting. Zero Slop runs inside the user's existing AI assistant; Claude, GPT, or another compatible model reads and edits in context while local tools point to exact phrases and protect the source. Use when the user asks to humanize or de-slop writing, inspect AI-sounding patterns, fix text that reads like ChatGPT, polish outward-facing prose, draft social or LinkedIn content, or apply a final quality check to prose the agent generated. The workflow preserves facts, voice, and format and learns privately from repeated, reason-labelled human edits.
8
8
  ---
@@ -80,7 +80,22 @@ not eight models or services. In an installed assistant, use role-isolated passe
80
80
  the harness can do that without extra network calls. When a service has a one-request
81
81
  budget, combine the AI responsibilities into one structured editorial response and
82
82
  run the local checks before and after it. Name that consolidation honestly; one model
83
- response is not independent review. Keep local and AI responsibilities distinct:
83
+ response is not independent review.
84
+
85
+ Preserve source material rather than sentence count. Delete before rewriting: keep
86
+ a sentence when it adds a fact, position, reason, example, instruction, or necessary
87
+ connection. Delete empty sentences instead of replacing their flagged words with
88
+ milder synonyms. Do not add a takeaway or benefit summary that repeats a nearby
89
+ point. For example, delete “Efficiency is paramount” instead of changing it to
90
+ “Efficiency is crucial.” After a measured improvement in setup time, do not append
91
+ that the change “makes it easier to get started.” Preserve substantive opinions,
92
+ emotion, and useful transitions even when they contain flagged wording. Leave clear
93
+ factual statements and qualifications unchanged where possible. Missing knowledge
94
+ stays missing: “not measured beyond the first month” does not establish that the
95
+ first month was measured, and a missing feature in a new product does not establish
96
+ that the old product had it.
97
+
98
+ Keep local and AI responsibilities distinct:
84
99
 
85
100
  1. **Scorer — local tools.** Point to exact phrases and problems with rhythm,
86
101
  readability, formatting, and register; explain the writing score.
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "zero-slop",
3
+ "version": "2.9.0",
4
+ "description": "Find and fix canned AI writing while preserving the facts, voice, and format.",
5
+ "mcpServers": {
6
+ "zero-slop": {
7
+ "httpUrl": "https://mcp.zero-slop.ai/mcp",
8
+ "includeTools": ["deslop"],
9
+ "timeout": 45000
10
+ }
11
+ }
12
+ }
package/mcp.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
3
+ "mcpServers": {
4
+ "zero-slop": {
5
+ "type": "streamable-http",
6
+ "url": "https://mcp.zero-slop.ai/mcp"
7
+ }
8
+ }
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zero-slop",
3
- "version": "2.8.10",
3
+ "version": "2.9.0",
4
4
  "description": "An Agent Skill that scores AI-sounding prose locally, guides the host AI through an editorial rewrite, and checks changed source details. The local tools run offline with zero dependencies.",
5
5
  "bin": {
6
6
  "zero-slop": "bin/zero-slop.mjs"
@@ -42,11 +42,17 @@
42
42
  "data/",
43
43
  "README.md",
44
44
  "LICENSE",
45
+ "plugin.json",
46
+ "mcp.json",
47
+ ".mcp.json",
48
+ "gemini-extension.json",
45
49
  "!scripts/build_bundle.py",
46
50
  "!scripts/build_onepager_pdf.py",
47
51
  "!scripts/build_plugin.py",
48
52
  "!scripts/build_skill_zip.py",
49
53
  "!scripts/check_svg.py",
54
+ "!scripts/check_distribution_manifests.py",
55
+ "!scripts/check_release_version.py",
50
56
  "!scripts/check_release_surfaces.py",
51
57
  "!scripts/contextual.py",
52
58
  "!scripts/contextual-signals.md",
package/plugin.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
+ "name": "zero-slop",
4
+ "version": "2.9.0",
5
+ "description": "Find and fix canned AI writing while preserving the facts, voice, and format.",
6
+ "author": {
7
+ "name": "Manav Mishra",
8
+ "url": "https://github.com/manavmishra"
9
+ },
10
+ "homepage": "https://zero-slop.ai/",
11
+ "repository": "https://github.com/manavmishra/ZeroSlop",
12
+ "license": "MIT",
13
+ "keywords": ["writing", "editing", "ai-slop", "agent-skill", "mcp"]
14
+ }
@@ -155,7 +155,10 @@ the report even when they are zero.
155
155
 
156
156
  ## B. Substance
157
157
 
158
- 31. **Removal test.** Does every paragraph lose something real when deleted?
158
+ 31. **Removal test.** Does every paragraph lose something real when deleted? Check
159
+ individual sentences too. Replacing “Efficiency is paramount” with “Efficiency
160
+ is crucial” fails when the whole sentence is empty. Cut sentences that merely
161
+ restate a nearby benefit; preserve substantive opinions and useful transitions.
159
162
  32. **Relevance test.** Does every paragraph serve the brief, audience, and argument?
160
163
  33. **Front-loading, applied selectively.** Conclusions arrive early where that helps
161
164
  the reader, without forcing every section into the same point-then-detail shape.
package/scripts/rescue.py CHANGED
@@ -24,12 +24,13 @@ PROTECTED = re.compile(
24
24
  TOKEN = re.compile(r"\ue000(\d+)\ue001")
25
25
 
26
26
 
27
- def _sentence_pair(match: re.Match[str], *, past: bool) -> str:
28
- first, second = match.group(1), match.group(2)
29
- lead = first[:1].upper() + first[1:]
30
- return f"{lead} {'mattered' if past else 'matters'}. " + (
31
- f"More important was {second}." if past else f"The larger gain is {second}."
32
- )
27
+ def _without_wrapper(match: re.Match[str]) -> str:
28
+ prefix, word = match.group(1), match.group(2)
29
+ # Capitalize the exposed sentence, but leave names such as iOS and eBay
30
+ # byte-for-byte. This applies only where a sentence wrapper was removed.
31
+ if word.islower():
32
+ word = word[:1].upper() + word[1:]
33
+ return prefix + word
33
34
 
34
35
 
35
36
  def rescue_text(text: str) -> str:
@@ -43,6 +44,11 @@ def rescue_text(text: str) -> str:
43
44
 
44
45
  masked = PROTECTED.sub(mask, original)
45
46
  out = re.sub(r"[\u00a0\u202f]", " ", masked)
47
+ out = re.sub(
48
+ r"(^|[.!?][ \t]+|\n[ \t]*)(?:it is important to note that|it is worth noting that)"
49
+ r"[ \t]+([A-Za-z][A-Za-z0-9_-]*)",
50
+ _without_wrapper, out, flags=re.IGNORECASE,
51
+ )
46
52
  rules: list[tuple[str, str | object]] = [
47
53
  (
48
54
  r"\bwe are thrilled to unveil ([^,\n]+),\s+a transformative release that "
@@ -69,8 +75,8 @@ def rescue_text(text: str) -> str:
69
75
  (r"\bour journey\b", "our work"),
70
76
  (r"\bour transformative journey\b", "our work"),
71
77
  (r"\bin today'?s rapidly evolving (?:landscape|world)\b", "Today"),
72
- (r"\bit is important to note that\b", ""),
73
- (r"\bit is worth noting that\b", ""),
78
+ (r"\bit is important to note that\b[ \t]*", ""),
79
+ (r"\bit is worth noting that\b[ \t]*", ""),
74
80
  (r"\bwhat we did not realize was just how deeply it impacted everything downstream\.",
75
81
  "We underestimated its effect on the work that followed."),
76
82
  (r"\bonboarding is not a checklist\.\s*it is a promise\.",
@@ -78,7 +84,8 @@ def rescue_text(text: str) -> str:
78
84
  (r"\bonboarding isn['’]t a checklist\s*[-—]\s*it['’]s a promise\.",
79
85
  "We see onboarding as a promise."),
80
86
  (r"\bthe insights were game[-\u2011]changing\.",
81
- "Those conversations changed our approach."),
87
+ lambda m: ("Those" if m.group(0)[0].isupper() else "those")
88
+ + " conversations changed our approach."),
82
89
  (r"\bthe insights were (?:transformative|clear|significant):\s*",
83
90
  "Those conversations showed that "),
84
91
  (r"\ba platform that leverages intelligent automation to streamline the entire "
@@ -87,34 +94,33 @@ def rescue_text(text: str) -> str:
87
94
  lambda m: m.group(1).upper()),
88
95
  (r"\bthe results speak for themselves\.\s*", ""),
89
96
  (r"\bbut here is the thing nobody talks about\.\s*", ""),
90
- (r"\bthe real win was not ([^.]+)\.\s*it was ([^.]+)\.",
91
- lambda m: _sentence_pair(m, past=True)),
92
- (r"\bthe real win isn['’]t just ([^.]+)\.\s*it['’]s ([^.]+)\.",
93
- lambda m: _sentence_pair(m, past=False)),
97
+ # A contrast may carry a substantive position. A local rule cannot
98
+ # infer that the thing rejected in the source nevertheless mattered.
94
99
  (r"\bthat is the kind of impact that keeps us going\b", "That result keeps us going"),
95
- (r"\bunlock(?:ing)? the full potential of\b", "use"),
96
- (r"\bseamlessly integrates?\b", "integrates"),
100
+ (r"\bseamlessly (integrates?)\b",
101
+ lambda m: m.group(1).capitalize() if m.group(0)[0].isupper() else m.group(1)),
97
102
  (r"\bjust how deeply\b", "how much"),
98
103
  (r"\bgame[-\u2011]changing\b", "useful"),
99
104
  (r"\bcutting[-\u2010\u2011 ]edge\b", "current"),
100
105
  (r"\bredefines what(?:['’]s| is) possible in\b", "updates"),
101
106
  (r"\bin order to\b", "to"),
102
107
  (r"\bat the end of the day\b", "ultimately"),
103
- (r"\bwe are\b", "we're"),
104
- (r"\bwe did not\b", "we didn't"),
105
- (r"\bwe do not\b", "we don't"),
106
- (r"\bi am\b", "I'm"),
107
- (r"\bit is\b", "it's"),
108
- (r"\bthey are\b", "they're"),
109
- (r"\byou are\b", "you're"),
110
- (r"\bthere is\b", "there's"),
111
- (r"\bdoes not\b", "doesn't"),
112
- (r"\bis not\b", "isn't"),
113
- (r"\bare not\b", "aren't"),
114
- (r"\bcannot\b", "can't"),
108
+ # Contractions alone are not evidence of better writing. Leave clean
109
+ # source sentences unchanged instead of manufacturing an edit.
115
110
  ]
116
111
  for pattern, replacement in rules:
117
- out = re.sub(pattern, replacement, out, flags=re.IGNORECASE)
112
+ def replace(match: re.Match[str]) -> str:
113
+ if callable(replacement):
114
+ return replacement(match)
115
+ value = replacement
116
+ if not value:
117
+ return value
118
+ if match.group(0)[0].isupper():
119
+ return value[:1].upper() + value[1:]
120
+ if not value.startswith("I'"):
121
+ return value[:1].lower() + value[1:]
122
+ return value
123
+ out = re.sub(pattern, replace, out, flags=re.IGNORECASE)
118
124
  out = re.sub(r"[ \t]+\n", "\n", out)
119
125
  out = re.sub(r" {2,}", " ", out).strip()
120
126
 
@@ -1156,6 +1156,18 @@ are artificial bookmark despite hey modern please researchers save unpopular wel
1156
1156
  """.split())
1157
1157
  NOT_NAME_WORDS = {word.lower() for word in NOT_NAMES} | COMMON_WORDS
1158
1158
 
1159
+ # These ordinary subjects are capitalised by sentence position. Exempt only
1160
+ # the generic construction, not the word everywhere: "Efficiency raised $4M"
1161
+ # and "Efficiency Labs" still contain protected names. A quoted construction
1162
+ # remains protected by the independent quotation check.
1163
+ _ABSTRACT_SUBJECT = re.compile(
1164
+ r"(?:^|(?<=[.!?])\s+|\n[ \t]*)"
1165
+ r"(?P<subject>Efficiency|Productivity|Innovation|Quality|Reliability|Success|Customer)"
1166
+ r"(?: (?:(?:experience|service|support|satisfaction)))?"
1167
+ r" is (?:paramount|crucial|essential|important|key|everything)\b",
1168
+ re.M,
1169
+ )
1170
+
1159
1171
 
1160
1172
  def _peel_entity(run, prose, other):
1161
1173
  """The entity inside a title-case run, or None if the run holds no name.
@@ -1217,6 +1229,7 @@ def facts(text, _other=""):
1217
1229
  prose = re.sub(r"(?m)^\s*\d+[.)]\s+", "", prose)
1218
1230
  other = _spell_to_digits(_other)
1219
1231
  other = re.sub(r"(?m)^\s*\d+[.)]\s+", "", other)
1232
+ ordinary_subject_positions = {m.start("subject") for m in _ABSTRACT_SUBJECT.finditer(prose)}
1220
1233
  out = {}
1221
1234
  for kind, rx in FACT_RX:
1222
1235
  found = set()
@@ -1224,6 +1237,8 @@ def facts(text, _other=""):
1224
1237
  for m in re.finditer(rx, urls if kind == "url" else prose, flags):
1225
1238
  v = (m.group(1) if m.lastindex else m.group(0)).strip()
1226
1239
  if kind == "name":
1240
+ if m.start() in ordinary_subject_positions:
1241
+ continue
1227
1242
  v = _peel_entity(v, prose, other)
1228
1243
  if not v:
1229
1244
  continue