mirror of
https://github.com/conorbronsdon/avoid-ai-writing.git
synced 2026-09-19 01:32:11 +08:00
d8c235186f
* Add detector trio from #108: launch intros, crowd contrast, fake-casual props Three regex-detectable patterns from the welttowelt merged-system diff, each with a must-fire and a must-not-fire fixture: - launch-intro: sentence-initial imperative product introductions ("Enter X.", "Meet X, your new...", "Think X meets Y"). "Say hello to X" stays judgment-only ("Say hello to Grandma." is ordinary prose). - crowd-contrast: the trailing "while everyone else..." clause, gated on a dismissive verb so literal simultaneity never fires. - fake-casual-prop: stage directions, wink asides, and "because of course it does". Verdict closers and label-prefix openers stay LLM-judgment per the precision-over-recall policy. Catalog 62 -> 65, engine 48 -> 51, word table unchanged at 112. * Apply review fixes to the #128 detector trio Addresses the three detector-surface items in the CHANGES_REQUESTED review, plus the prose-scoping follow-up comment. Each item was reproduced against the PR head before being changed. 1. `launch-intro`: the bare `Enter X.` surface is judgment-only. It matched "Enter Password." and "Enter Amount." verbatim, and "Enter Username — your work email." through the dash terminator; neither a terminator change nor a field-name denylist reaches the period-terminated class. The `Meet X, your new favorite…` and `Think X meets Y` surfaces stay. The three UI forms and "Enter Flowdesk." are pinned as must-not-fire. 2. `crowd-contrast`: the progressive branch is restricted to `-ing` forms. `(?:e|es|ed|ing)` let the adjective ("was still deliberate about"), the passive ("was still debated by pundits") and the bare present through; all three are now must-not-fire fixtures. 3. `fake-casual-prop`: `because of course …` is judgment-only. The present tense plus `did` gate does not hold — "The build failed because of course it did." is the ordinary human grumble in the same form. Two grumbles are pinned as must-not-fire. Also scopes the prose claim: the "was still" marker gates the debate/speculation branch only, and the two stereotyped variants ("wrote think-pieces", "played catch-up") match on their own wording. SKILL.md, detector/CATEGORIES.md and the CHANGELOG say the same thing, and the generated plugin/cursor copies are regenerated from SKILL.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Disclose the crowd-contrast residue that was measured, not assumed Beyond the review. A fresh-eyes pass turned up sentences that fire and that the entry's disclosure did not cover; every one was reproduced against this branch before being written down. - Branch one fires on any literal progressive use of its verbs, not only on "was still debating": "while the market was still speculating about the price" and "while others were still arguing about procedure" are ordinary wire copy and both fire. - Branches two and three fire on literal contrasts of their own: "while everyone else wrote think-pieces from Washington" (a real reporting contrast) and "while everyone else played catch-up in the spring" (sports and classroom narrative). - The wink-aside regex accepts all four of (yes|no) x (really|seriously); the entry named two. No regex changes: these are accepted under precision-over-recall, and narrowing them is the maintainer's call, not a review item. The prose now states what the engine does instead of a tighter gate it does not enforce. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Tighten two surfaces and make every entry state what its regex does Cross-family review (Codex / GPT-5.6). Each item was reproduced against `land-pr-128` before the change and re-measured after. Regex changes, both false positives on ordinary prose: 1. `fake-casual-prop`: `chef['’]?s\s+kiss` made the apostrophe optional, so "At midnight, *chefs kiss* their spouses goodbye" fired. The apostrophe is now required, straight or curly. 2. `launch-intro`: `the\s+new\s+(?:standard|way|home)\b` let the head noun swallow the first word of a compound noun — "Meet Rosa, the new home secretary" and "Meet Emma, the new way station manager" both fired. Each head now needs the tail launch copy actually has (`home of`, `way to`, `standard in|for`) or an end of clause. "Meet Riverside, the new home of our Saturday farmers market." still fires. Not changed, disclosed instead: "Meet Alice, your new favorite aunt" and "Think Alice meets Bob at noon" fire. They are person-name variants of the two surfaces the maintainer asked to keep, so narrowing them would cost the surfaces themselves. Test change: the `(yes, really)` positive shared a fixture with `*checks notes*` and only asserted that some `fake-casual-prop` existed, so replacing the wink regex with a never-match left it green. It is now an independent case asserting the matched text. Prose: the three entries and the CATEGORIES rows now state the actual gates — the four `Meet` heads and the one-token 2-30 character name; the `was|were|is|are` + `still` + `-ing` branch, the `writing|wrote` branch and the `play|plays|played|playing` branch; the six stage directions and four parentheticals — plus the measured misses that follow from closed lists: two-token names ("Meet North Star", "Think Google Docs meets Microsoft Word"), crowds outside the list ("every competitor", "our rivals"), and register neighbours ("*checks calendar*", "(yes, honestly)"). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: welttowelt <welttowelt@users.noreply.github.com> Co-authored-by: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
28 lines
981 B
JSON
28 lines
981 B
JSON
{
|
|
"name": "avoid-ai-writing-detector",
|
|
"version": "3.29.0",
|
|
"description": "Deterministic detection engine for the Avoid AI Writing skill \u2014 pattern + stylometric analysis of AI-generated text.",
|
|
"license": "MIT",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "https://github.com/conorbronsdon/avoid-ai-writing.git"
|
|
},
|
|
"main": "detector/patterns.js",
|
|
"files": [
|
|
"detector/patterns.js",
|
|
"detector/validate.js"
|
|
],
|
|
"engines": {
|
|
"node": ">=18"
|
|
},
|
|
"scripts": {
|
|
"test": "node detector/patterns.test.js && node detector/categories.test.js && node detector/validate.test.js && node scripts/corpus.test.js && node scripts/check-style.test.js",
|
|
"self-scan": "node scripts/self-scan.js",
|
|
"self-scan:check": "node scripts/self-scan.js --check",
|
|
"corpus": "node scripts/corpus.js list",
|
|
"corpus:fetch": "node scripts/corpus.js fetch",
|
|
"corpus:verify": "node scripts/corpus.js verify",
|
|
"fp": "node scripts/fp-measure.js"
|
|
}
|
|
}
|