Documentation
- Document paste-field limits and current file-size measurement. Recommend a directory install for Windsurf and the native plugin or an activated Knowledge upload for ChatGPT (#219).
Packaging
- The six ChatGPT/Codex Skills that lacked them now carry
versionandlicensein their frontmatter, so a bug report or vendored copy can name its version.validate-openai-plugin.pyfails when any Skill's version is missing or differs from the plugin manifest, both in PR checks and release preflight before tagging or publishing (#246).
Fixed
- Fix empty-result stats and non-string input handling (#234).
- Cyrillic and Greek prose no longer reads as a homoglyph bypass. Script dominance is decided per sentence, and only mixed-script or fully substituted words surrounded by non-Russian text are swapped; limits are documented in
detector/patterns.js(#352). - Narrow the false-concession rule to require a vague close in the following clause, allow multi-word subjects, and drop the bare "despite challenges" opener (#211).
Added
-
Add advisory residual checks and separate mechanical preservation results from pattern diagnostics (#204).
-
The bundled
ai-writing-detectorscript accepts--source-mode <plain|rendered-markdown>, so the published plugin can reach rendered-Markdown scoring instead of flagging YAML frontmatter as the author's prose. It also accepts themarketingandpersonalcontexts the root CLI and the detector already support, which it previously rejected. Blank input reports the selected context and source mode instead of an emptystatsobject, matching the root CLI. A bad argument now prints the usage message and exits 2 instead of throwing an uncaught stack trace (#244). -
The detector flags negative parallelism with a new
negative-parallelismtype. "It's not just a search index, it's a foundation for trust." flags on its own. The plain "isn't X, it's Y" frame and the split-sentence "isn't just X. It's Y." flag only when another frame starts within three sentences in the same paragraph, so one real correction stays clean and two unrelated ones far apart do too. "Not only X but also Y" and "not X but Y" are not matched: they are ordinary correlatives and showed up more often in the human control corpus than in the machine one. The engine now has 54 types (#351). -
Ignore markers: text between
<!-- avoid-ai-writing:ignore-start -->and<!-- avoid-ai-writing:ignore-end -->is excluded from scoring in every source mode, so a page can quote an AI specimen on purpose. Markers act only on their own line, and starts nest.stats.ignoredRegionscounts the regions (#351).
Changed
- The low vocabulary diversity flag (
low-ttr) now averages the type-token ratio over 200-token windows instead of taking it across the whole text. Whole-text TTR falls with length, so in the human control corpus the flag fired on all 13 documents longer than 1,900 tokens, including every 6,000-word public-domain slice, and it now fires on none of them. A text of exactly 200 tokens gets the same value as before (#361). - Word joiners (U+2060) next to URLs, spaces, or punctuation no longer raise the bypass-character flag. Show-notes editors insert them to control line breaks, and four of them pushed a plain paragraph of links to
AI_ONLY. They are still stripped before matching, and a word joiner that splits a word still counts (#351). - A word joiner between two letters outside the Basic Multilingual Plane now counts as a bypass character (#353).
- The negative-parallelism proximity gate now counts distinct reported frames. Repeating an identical plain contrast no longer produces one finding from a gate that counted two raw matches (#353).
- The Cursor rule and the portable paste file now state the manual marks-pass convention once. The paragraph no longer tells the model to run normalizer flags (
--write,--quotes,--reference) that those standalone files cannot use (#218). - Check how a destination renders single newlines before delivering prose; unwrap hard-wrapped paragraphs only where the breaks remain visible, while preserving intentional line breaks and fixed-width Markdown source layout (#122).
- Performed-insight phrases now cover staged discoveries: a judgment framed as a twist the writer found ("the recording turned out to be the least interesting part", "the real story was"). The detector keeps the superlative-plus-insight-noun form and reveal-style "real story" continuations narrow, so literal uses such as "turned out to be the most expensive option" and "the real story was covered" stay clean. Nested emotional-flatline wording and sentence-initial "Turns out" count once when contained in a staged discovery. In short social copy, one staged discovery carrying the payoff is enough to fix. The fabricated-speaker-perspective guardrail now also covers drafting new copy in someone else's voice. No new category.
- The detector now skips quoted material, as the skill's self-reference escape hatch describes. Words inside a double-quoted span (straight or curly) and single-line blockquotes, including nested
>>lines, lists inside a quote and the compact>textform, no longer count against the writer, so quoting AI output to criticise it stops scoring its vocabulary. Bypass characters inside a quotation no longer raise the normalization flag.stats.maskedQuotesreports how many spans were skipped. Single quotes still count, because apostrophes would pair up across ordinary prose. Issue and highlight offsets still point at the original text (#238). - Cover two phrasings flagged in #325 as judgment-only examples: cold-outreach flattery asks ("I'd value your take on this") under sycophantic tone, and the teaser form of the crowd contrast ("the call most leaders still won't make"). No detector change and no new category.