@heyramzi/lint 2.0.0 → 2.1.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/bin/heyramzi-comment-length.js +4 -3
- package/bin/heyramzi-file-tokens.js +2 -2
- package/bin/heyramzi-slop.js +3 -1
- package/config/oxlintrc.json +1 -1
- package/data/slop/artifacts.js +87 -0
- package/data/slop/pattern-parts.js +56 -0
- package/data/slop/patterns/appositives-and-sayings.js +81 -0
- package/data/slop/patterns/comma-clauses.js +106 -0
- package/data/slop/patterns/diagram-and-script-tells.js +71 -0
- package/data/slop/patterns/dropped-elements.js +149 -0
- package/data/slop/patterns/duration-and-openers.js +102 -0
- package/data/slop/patterns/headings-and-laws.js +116 -0
- package/data/slop/patterns/numbers-and-runs.js +94 -0
- package/data/slop/patterns/openers-and-tails.js +90 -0
- package/data/slop/patterns/parallel-shapes.js +100 -0
- package/data/slop/patterns/reveals-and-tallies.js +101 -0
- package/data/slop/patterns/setups-and-closers.js +83 -0
- package/data/slop/patterns/subject-voice.js +67 -0
- package/data/slop/patterns/vague-and-flourish.js +102 -0
- package/data/slop/patterns/wikipedia-signs.js +103 -0
- package/data/slop/patterns.js +62 -0
- package/data/slop/phrases-en-closers.js +66 -0
- package/data/slop/phrases-en-core.js +185 -0
- package/data/slop/phrases-en-wikipedia.js +136 -0
- package/data/slop/phrases-fr.js +152 -0
- package/data/slop/shapes-density.js +81 -0
- package/data/slop/shapes-framing.js +101 -0
- package/data/slop/shapes-reveals.js +88 -0
- package/data/slop/title-tells.js +8 -0
- package/data/slop/words-en.js +178 -0
- package/data/slop/words-fr.js +101 -0
- package/data/slop-words.js +18 -2576
- package/data/vendor/heading-words.js +6 -0
- package/inline-path.js +2 -0
- package/package.json +1 -1
- package/slop.js +4 -2
- package/ui-rules.js +4 -2
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/** The English banned phrases, first half: the workspace bans, throat-clearing, filler and the corpus reads. */
|
|
2
|
+
export const phrasesEnCore = [
|
|
3
|
+
// --- Existing workspace bans ---
|
|
4
|
+
"not only",
|
|
5
|
+
"but also",
|
|
6
|
+
|
|
7
|
+
// --- Negation pivots: the "it is not X, it is Y" reveal --- Substring-matched, so only distinctive multi-word forms belong here.
|
|
8
|
+
|
|
9
|
+
// A bare "is not" is normal English and must never be listed.
|
|
10
|
+
"it's not just",
|
|
11
|
+
"it is not just",
|
|
12
|
+
"not just about",
|
|
13
|
+
"it's not about",
|
|
14
|
+
"it is not about",
|
|
15
|
+
"isn't about",
|
|
16
|
+
"it's not merely",
|
|
17
|
+
"it is not merely",
|
|
18
|
+
"not merely a",
|
|
19
|
+
"this isn't just",
|
|
20
|
+
"this is not just",
|
|
21
|
+
"that's not just",
|
|
22
|
+
"more than just a",
|
|
23
|
+
"ce n'est pas seulement",
|
|
24
|
+
"il ne s'agit pas seulement",
|
|
25
|
+
"non seulement",
|
|
26
|
+
"ever wondered why",
|
|
27
|
+
"reach new heights",
|
|
28
|
+
"in the realm of",
|
|
29
|
+
"think of it as",
|
|
30
|
+
"that's a wrap",
|
|
31
|
+
"it's like",
|
|
32
|
+
"let's dive in",
|
|
33
|
+
"dive in",
|
|
34
|
+
"buckle up",
|
|
35
|
+
"to the next level",
|
|
36
|
+
"in the fast-paced",
|
|
37
|
+
"in today's",
|
|
38
|
+
"hidden gems",
|
|
39
|
+
|
|
40
|
+
// --- Stop-slop: throat-clearing openers ---
|
|
41
|
+
"here's the thing",
|
|
42
|
+
"the uncomfortable truth",
|
|
43
|
+
"it turns out",
|
|
44
|
+
"let me be clear",
|
|
45
|
+
"the truth is",
|
|
46
|
+
"can we talk about",
|
|
47
|
+
"here's what i find",
|
|
48
|
+
"here's the problem",
|
|
49
|
+
"i'll say it again",
|
|
50
|
+
"i'm going to be honest",
|
|
51
|
+
|
|
52
|
+
// --- 2026 corpus: the three "here's the X" openers named alongside the two above by copy and marketing sources.
|
|
53
|
+
|
|
54
|
+
// Same shape, same job, and the copy one was caught in a shipped email arguing against AI writing.
|
|
55
|
+
"here's the fix",
|
|
56
|
+
"here's the kicker",
|
|
57
|
+
"here's the gap",
|
|
58
|
+
|
|
59
|
+
// --- Transition crutches.
|
|
60
|
+
|
|
61
|
+
// Held only in prose until 3 Sep 2026, in a "Transitions to Avoid" list inside seo-copywriting, where nothing checked them: 7 of its 10 entries were already here and 3
|
|
62
|
+
|
|
63
|
+
// were not, so the file was both a duplicate and the only home for the rest. ---
|
|
64
|
+
"that being said",
|
|
65
|
+
"this begs the question",
|
|
66
|
+
"let's delve into",
|
|
67
|
+
"lets delve into",
|
|
68
|
+
|
|
69
|
+
// --- Stop-slop: emphasis crutches ---
|
|
70
|
+
"let that sink in",
|
|
71
|
+
"this matters because",
|
|
72
|
+
"make no mistake",
|
|
73
|
+
"here's why that matters",
|
|
74
|
+
|
|
75
|
+
// --- Stop-slop: business jargon phrases ---
|
|
76
|
+
"lean into",
|
|
77
|
+
"double down",
|
|
78
|
+
"deep dive",
|
|
79
|
+
"take a step back",
|
|
80
|
+
"moving forward",
|
|
81
|
+
"circle back",
|
|
82
|
+
"on the same page",
|
|
83
|
+
"game-changer",
|
|
84
|
+
"game changer",
|
|
85
|
+
"cutting-edge",
|
|
86
|
+
"cutting edge",
|
|
87
|
+
"best-in-class",
|
|
88
|
+
"best in class",
|
|
89
|
+
"next-generation",
|
|
90
|
+
"state-of-the-art",
|
|
91
|
+
"end-to-end",
|
|
92
|
+
|
|
93
|
+
// --- Stop-slop: filler phrases ---
|
|
94
|
+
"no more",
|
|
95
|
+
"say goodbye to",
|
|
96
|
+
"at its core",
|
|
97
|
+
"at the end of the day",
|
|
98
|
+
"in a world where",
|
|
99
|
+
"in conclusion",
|
|
100
|
+
"it's worth noting",
|
|
101
|
+
"rest assured",
|
|
102
|
+
"the reality is",
|
|
103
|
+
"when it comes to",
|
|
104
|
+
|
|
105
|
+
// --- Stylometric markers from guillaumemeyer/watermarks-remover --- Its detector scores 24 weighted markers.
|
|
106
|
+
|
|
107
|
+
// 26 of the 34 surface forms those cover were already banned here; these are the eight that were not, checked against 56,568 words of first-party corpus first so none of
|
|
108
|
+
|
|
109
|
+
// them is his. Read 2026-08-16.
|
|
110
|
+
"it is important to note",
|
|
111
|
+
"it is essential to note",
|
|
112
|
+
"it is crucial to note",
|
|
113
|
+
"it is worth noting",
|
|
114
|
+
"to summarize",
|
|
115
|
+
"plays a crucial role",
|
|
116
|
+
"plays a key role",
|
|
117
|
+
"plays a vital role",
|
|
118
|
+
|
|
119
|
+
// --- Assistant leakage: a chatbot's own turn-taking, left in the copy ---
|
|
120
|
+
"as an ai",
|
|
121
|
+
"i hope this helps",
|
|
122
|
+
|
|
123
|
+
// --- Stop-slop: meta-commentary ---
|
|
124
|
+
"plot twist",
|
|
125
|
+
"you already know this",
|
|
126
|
+
"is a feature, not a bug",
|
|
127
|
+
"let me walk you through",
|
|
128
|
+
"as we'll see",
|
|
129
|
+
|
|
130
|
+
// --- The unfinished list, and the writer narrating his own argument --- Read from a Nicolas Cole newsletter on 26 Aug 2026, a specimen of the creator-newsletter register.
|
|
131
|
+
|
|
132
|
+
// "the list goes on and on" closes two separate lists in it, both times in place of the items the writer did not have.
|
|
133
|
+
|
|
134
|
+
// Zero occurrences in Ramzi's corpus for all of these except "possibilities are endless", which appears once, in a 2025 ClickUp post from the generic marketer era this voice system was
|
|
135
|
+
|
|
136
|
+
// built to end.
|
|
137
|
+
"the list goes on",
|
|
138
|
+
"the list is endless",
|
|
139
|
+
"possibilities are endless",
|
|
140
|
+
"and so much more",
|
|
141
|
+
"my point is",
|
|
142
|
+
"so you see",
|
|
143
|
+
"half the battle",
|
|
144
|
+
"the name of the game",
|
|
145
|
+
|
|
146
|
+
// --- Stop-slop: vague declaratives ---
|
|
147
|
+
"the implications are",
|
|
148
|
+
"the stakes are high",
|
|
149
|
+
"the consequences are",
|
|
150
|
+
"the reasons are structural",
|
|
151
|
+
|
|
152
|
+
// --- petergyang/no-ai-slop, read 2026-08-31 --- Faux-insight setups, weasel attribution, rhetorical setups, reader guidance and dated-world filler.
|
|
153
|
+
|
|
154
|
+
// Every one is a distinctive multi-word form, so it can be substring-matched without firing on ordinary English; the ones that cannot ("in other words",
|
|
155
|
+
|
|
156
|
+
// "literally", "simply", "overall") stay judgement calls in patterns.md 48. Zero occurrences across the first-party corpus.
|
|
157
|
+
"this changes everything",
|
|
158
|
+
"this is huge",
|
|
159
|
+
// "in today's" is listed above; only the curly apostrophe needs its own entry.
|
|
160
|
+
"in today\u2019s",
|
|
161
|
+
"in the age of",
|
|
162
|
+
"in the world of",
|
|
163
|
+
"in this article",
|
|
164
|
+
"going forward",
|
|
165
|
+
"with regard to",
|
|
166
|
+
"in terms of",
|
|
167
|
+
"widely regarded as",
|
|
168
|
+
"experts agree",
|
|
169
|
+
"industry reports suggest",
|
|
170
|
+
"many argue",
|
|
171
|
+
"what if i told you",
|
|
172
|
+
// "think about it" is NOT listed: the slop form is the standalone imperative ("Think about it:"), and a substring ban also catches the ordinary subordinate clause,
|
|
173
|
+
|
|
174
|
+
// which shipped copy uses ("whether you think about it or not"). It stays in patterns.md 33 as a human read.
|
|
175
|
+
|
|
176
|
+
// "as you can see" is NOT listed: voice-measured.md measures it 20 times in his own spoken corpus, tagged "spoken only, needs a screen".
|
|
177
|
+
|
|
178
|
+
// It is his tutorial register pointing at a screen, not reader guidance. patterns.md 48 carries it as a written-copy read.
|
|
179
|
+
"the key point is",
|
|
180
|
+
"this distinction matters",
|
|
181
|
+
"nobody tells you",
|
|
182
|
+
"the part everyone misses",
|
|
183
|
+
"most people get wrong",
|
|
184
|
+
"most people skip",
|
|
185
|
+
];
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/** The English banned phrases from Wikipedia's signs of AI writing, one block per section of that page. */
|
|
2
|
+
export const phrasesEnWikipedia = [
|
|
3
|
+
// --- Wikipedia:Signs of AI writing, read 2026-09-05 --- One block per section of that page, so a reader can trace a ban back to the sign it came from.
|
|
4
|
+
|
|
5
|
+
// Only distinctive multi-word forms are here; the signs that need an anchor are `patterns` in `data/slop/patterns.js`, and the ones that need a whole document are the structural checks in `slop.js`.
|
|
6
|
+
|
|
7
|
+
// WP:AITREND and the Wikipedia section on undue emphasis. Significance asserted instead of stated.
|
|
8
|
+
"a testament to",
|
|
9
|
+
"plays a significant role",
|
|
10
|
+
"plays a pivotal role",
|
|
11
|
+
"a pivotal moment",
|
|
12
|
+
"a key turning point",
|
|
13
|
+
// "serves as a", "stands as a", "marks a shift" and "represents a shift" are not listed here: the `copula-avoidance` pattern in `data/slop/patterns/wikipedia-signs.js` owns that whole family,
|
|
14
|
+
|
|
15
|
+
// and a phrase entry would only report the same sentence twice.
|
|
16
|
+
"reflects a broader",
|
|
17
|
+
"reflects broader",
|
|
18
|
+
"part of a broader",
|
|
19
|
+
"setting the stage for",
|
|
20
|
+
"indelible mark",
|
|
21
|
+
"deeply rooted",
|
|
22
|
+
"evolving landscape",
|
|
23
|
+
"focal point",
|
|
24
|
+
"underscores the importance",
|
|
25
|
+
"highlights the importance",
|
|
26
|
+
"emphasizes the importance",
|
|
27
|
+
"underscoring its significance",
|
|
28
|
+
"contributing to the broader",
|
|
29
|
+
"in the broader context",
|
|
30
|
+
"ongoing efforts to",
|
|
31
|
+
|
|
32
|
+
// WP:OVERATTRIBUTION, WP:AIATTR. Notability asserted instead of shown.
|
|
33
|
+
"independent coverage",
|
|
34
|
+
"media outlets",
|
|
35
|
+
"trade publications",
|
|
36
|
+
"widely read outlets",
|
|
37
|
+
"has been profiled in",
|
|
38
|
+
"has been featured in",
|
|
39
|
+
"active social media presence",
|
|
40
|
+
"significant coverage",
|
|
41
|
+
"substantial coverage",
|
|
42
|
+
"independent and reliable sources",
|
|
43
|
+
|
|
44
|
+
// WP:AIPUFFERY, WP:AIPEACOCK. The travel-guide register.
|
|
45
|
+
"rich cultural heritage",
|
|
46
|
+
"rich history",
|
|
47
|
+
"natural beauty",
|
|
48
|
+
"in the heart of",
|
|
49
|
+
"nestled in",
|
|
50
|
+
"nestled within",
|
|
51
|
+
"diverse array",
|
|
52
|
+
"wide array of",
|
|
53
|
+
"a wide range of",
|
|
54
|
+
"commitment to excellence",
|
|
55
|
+
"a fascinating glimpse",
|
|
56
|
+
"a glimpse into",
|
|
57
|
+
"shed light on",
|
|
58
|
+
"valuable insights",
|
|
59
|
+
"align with",
|
|
60
|
+
"aligns with",
|
|
61
|
+
"resonate with",
|
|
62
|
+
"resonates with",
|
|
63
|
+
"an integral part of",
|
|
64
|
+
|
|
65
|
+
// WP:FACESCHALLENGES. The formulaic closing section.
|
|
66
|
+
"faces several challenges",
|
|
67
|
+
"faces a number of challenges",
|
|
68
|
+
"despite these challenges",
|
|
69
|
+
"despite its challenges",
|
|
70
|
+
"challenges and opportunities",
|
|
71
|
+
"future prospects",
|
|
72
|
+
"future outlook",
|
|
73
|
+
"awards and recognition",
|
|
74
|
+
"recognition and awards",
|
|
75
|
+
|
|
76
|
+
// WP:CONCLUSION, WP:INCONCLUSION. The section summary. "in conclusion" is
|
|
77
|
+
// listed in `phrases-en-core.js` with the filler phrases.
|
|
78
|
+
"in summary",
|
|
79
|
+
"to sum up",
|
|
80
|
+
|
|
81
|
+
// WP:DIDACTIC. The disclaimer aimed at an imagined reader.
|
|
82
|
+
|
|
83
|
+
// The uncontracted "it is important/essential/crucial to note" and "it's worth noting" are listed in `phrases-en-core.js`; these are the forms a substring match on those misses.
|
|
84
|
+
"it's important to note",
|
|
85
|
+
"it's essential to note",
|
|
86
|
+
"it's crucial to note",
|
|
87
|
+
"important to remember",
|
|
88
|
+
"crucial to remember",
|
|
89
|
+
"worth remembering",
|
|
90
|
+
"important to consider",
|
|
91
|
+
"may vary depending",
|
|
92
|
+
|
|
93
|
+
// WP:CERTAINLY, WP:COLLABCOMM. The chatbot's own turn, left in the copy.
|
|
94
|
+
// "as an ai" and "i hope this helps" are listed in `phrases-en-core.js`.
|
|
95
|
+
"as an ai language model",
|
|
96
|
+
"as a large language model",
|
|
97
|
+
"i cannot provide",
|
|
98
|
+
"i'm sorry, but",
|
|
99
|
+
"i am sorry, but",
|
|
100
|
+
"you're absolutely right",
|
|
101
|
+
"you are absolutely right",
|
|
102
|
+
"great question",
|
|
103
|
+
"would you like me to",
|
|
104
|
+
"let me know if you",
|
|
105
|
+
"is there anything else",
|
|
106
|
+
"detailed breakdown",
|
|
107
|
+
"here is a breakdown",
|
|
108
|
+
"here's a breakdown",
|
|
109
|
+
"i hope this message finds you well",
|
|
110
|
+
"i hope this finds you well",
|
|
111
|
+
"feel free to reach out",
|
|
112
|
+
|
|
113
|
+
// WP:AICUTOFF, WP:AIDISCLAIMER. The model speculating about its own gaps.
|
|
114
|
+
"as of my last knowledge update",
|
|
115
|
+
"as of my last training update",
|
|
116
|
+
"up to my last training update",
|
|
117
|
+
"based on available information",
|
|
118
|
+
"based on the available information",
|
|
119
|
+
"while specific details are limited",
|
|
120
|
+
"specific details are scarce",
|
|
121
|
+
"not widely documented",
|
|
122
|
+
"not widely available",
|
|
123
|
+
"not publicly available",
|
|
124
|
+
"in the provided sources",
|
|
125
|
+
"in the available sources",
|
|
126
|
+
"in the search results",
|
|
127
|
+
"maintains a low profile",
|
|
128
|
+
"keeps personal details private",
|
|
129
|
+
|
|
130
|
+
// WP:AICONNECT, WP:AIASSOCIATION. A relationship alluded to, never stated.
|
|
131
|
+
"widely interpreted as",
|
|
132
|
+
"has been associated with",
|
|
133
|
+
"widely associated with",
|
|
134
|
+
"in connection with",
|
|
135
|
+
"in association with",
|
|
136
|
+
];
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/** The French banned phrases. */
|
|
2
|
+
export const phrasesFr = [
|
|
3
|
+
// --- French: throat-clearing openers ---
|
|
4
|
+
"il est important de noter",
|
|
5
|
+
"il convient de souligner",
|
|
6
|
+
"il est essentiel de",
|
|
7
|
+
"force est de constater",
|
|
8
|
+
"il va sans dire",
|
|
9
|
+
"dans un monde où",
|
|
10
|
+
"à l'ère du",
|
|
11
|
+
"à l'heure où",
|
|
12
|
+
"dans le paysage actuel",
|
|
13
|
+
|
|
14
|
+
// --- French: filler phrases ---
|
|
15
|
+
"en fin de compte",
|
|
16
|
+
"au bout du compte",
|
|
17
|
+
"en d'autres termes",
|
|
18
|
+
"il est à noter que",
|
|
19
|
+
"cela étant dit",
|
|
20
|
+
"dans cette optique",
|
|
21
|
+
"à cet égard",
|
|
22
|
+
"en ce qui concerne",
|
|
23
|
+
"dans le cadre de",
|
|
24
|
+
|
|
25
|
+
// --- French: business jargon phrases ---
|
|
26
|
+
"mise en place",
|
|
27
|
+
"montée en compétence",
|
|
28
|
+
"montée en puissance",
|
|
29
|
+
"retour sur investissement",
|
|
30
|
+
"valeur ajoutée",
|
|
31
|
+
"prise en compte",
|
|
32
|
+
"conduite du changement",
|
|
33
|
+
"transformation digitale",
|
|
34
|
+
"transformation numérique",
|
|
35
|
+
"passage à l'échelle",
|
|
36
|
+
"de pointe",
|
|
37
|
+
"clé en main",
|
|
38
|
+
"sur mesure",
|
|
39
|
+
"de bout en bout",
|
|
40
|
+
"à la pointe",
|
|
41
|
+
"état de l'art",
|
|
42
|
+
|
|
43
|
+
// --- French: AI emphasis crutches ---
|
|
44
|
+
"il ne fait aucun doute",
|
|
45
|
+
"sans aucun doute",
|
|
46
|
+
"il est indéniable",
|
|
47
|
+
"de manière significative",
|
|
48
|
+
"de façon significative",
|
|
49
|
+
"tout au long de",
|
|
50
|
+
|
|
51
|
+
// --- French: the same Wikipedia signs, in French --- fr:Aide:Identifier l'usage d'une IA générative, read 2026-09-05, plus the French surface forms of the English blocks in the `phrases-en-*.js` files.
|
|
52
|
+
|
|
53
|
+
// The French page adds no sign the English one lacks except its emphasis on "langue de bois", so the blocks below mirror the English ones section for section.
|
|
54
|
+
|
|
55
|
+
// Significance asserted instead of stated.
|
|
56
|
+
"constitue un témoignage",
|
|
57
|
+
"témoigne de l'importance",
|
|
58
|
+
"s'impose comme",
|
|
59
|
+
"se présente comme",
|
|
60
|
+
"joue un rôle crucial",
|
|
61
|
+
"joue un rôle clé",
|
|
62
|
+
"joue un rôle majeur",
|
|
63
|
+
"joue un rôle central",
|
|
64
|
+
"un tournant décisif",
|
|
65
|
+
"un moment charnière",
|
|
66
|
+
"une étape clé",
|
|
67
|
+
"marque un tournant",
|
|
68
|
+
"reflète une tendance",
|
|
69
|
+
"s'inscrit dans une dynamique",
|
|
70
|
+
"s'inscrit dans un contexte",
|
|
71
|
+
"contribuant ainsi",
|
|
72
|
+
"mettant en lumière",
|
|
73
|
+
"mettant en avant",
|
|
74
|
+
"met en lumière",
|
|
75
|
+
"met en évidence",
|
|
76
|
+
"souligne l'importance",
|
|
77
|
+
"soulignant l'importance",
|
|
78
|
+
|
|
79
|
+
// Notability asserted instead of shown.
|
|
80
|
+
"sources fiables et indépendantes",
|
|
81
|
+
"de nombreux médias",
|
|
82
|
+
"largement relayé",
|
|
83
|
+
"largement médiatisé",
|
|
84
|
+
"présence active sur les réseaux",
|
|
85
|
+
|
|
86
|
+
// The travel-guide register.
|
|
87
|
+
"au cœur de",
|
|
88
|
+
"niché au cœur",
|
|
89
|
+
"riche patrimoine",
|
|
90
|
+
"patrimoine culturel riche",
|
|
91
|
+
"beauté naturelle",
|
|
92
|
+
"un large éventail",
|
|
93
|
+
"une large gamme",
|
|
94
|
+
"un aperçu fascinant",
|
|
95
|
+
"des informations précieuses",
|
|
96
|
+
"en résonance avec",
|
|
97
|
+
|
|
98
|
+
// The formulaic closing section.
|
|
99
|
+
"malgré ces défis",
|
|
100
|
+
"malgré ces obstacles",
|
|
101
|
+
"fait face à plusieurs défis",
|
|
102
|
+
"de nombreux défis",
|
|
103
|
+
"défis et perspectives",
|
|
104
|
+
"perspectives d'avenir",
|
|
105
|
+
"prix et distinctions",
|
|
106
|
+
|
|
107
|
+
// The section summary.
|
|
108
|
+
"en résumé",
|
|
109
|
+
"pour résumer",
|
|
110
|
+
"en somme",
|
|
111
|
+
"pour conclure",
|
|
112
|
+
|
|
113
|
+
// The disclaimer aimed at an imagined reader.
|
|
114
|
+
"il est crucial de",
|
|
115
|
+
"il est primordial de",
|
|
116
|
+
"il est intéressant de noter",
|
|
117
|
+
"il est bon de noter",
|
|
118
|
+
"il convient de noter",
|
|
119
|
+
"il est utile de rappeler",
|
|
120
|
+
"peut varier selon",
|
|
121
|
+
|
|
122
|
+
// The chatbot's own turn, left in the copy.
|
|
123
|
+
"en tant qu'ia",
|
|
124
|
+
"en tant que modèle de langage",
|
|
125
|
+
"je ne peux pas fournir",
|
|
126
|
+
"je suis désolé, mais",
|
|
127
|
+
"vous avez tout à fait raison",
|
|
128
|
+
"excellente question",
|
|
129
|
+
"souhaitez-vous que je",
|
|
130
|
+
"y a-t-il autre chose",
|
|
131
|
+
"voici un aperçu détaillé",
|
|
132
|
+
"voici une version",
|
|
133
|
+
"j'espère que cela vous aidera",
|
|
134
|
+
"n'hésitez pas à me solliciter",
|
|
135
|
+
|
|
136
|
+
// The model speculating about its own gaps.
|
|
137
|
+
"à ma dernière mise à jour",
|
|
138
|
+
"selon les informations disponibles",
|
|
139
|
+
"d'après les informations disponibles",
|
|
140
|
+
"les détails sont limités",
|
|
141
|
+
"peu de sources",
|
|
142
|
+
"n'est pas largement documenté",
|
|
143
|
+
"n'est pas publiquement disponible",
|
|
144
|
+
|
|
145
|
+
// A relationship alluded to, never stated.
|
|
146
|
+
"en lien avec",
|
|
147
|
+
"en association avec",
|
|
148
|
+
"largement associé",
|
|
149
|
+
"étroitement associé",
|
|
150
|
+
"souvent associé",
|
|
151
|
+
"largement interprété comme",
|
|
152
|
+
];
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** Sentence shapes judged by density, so one instance is style and none can be a pattern. */
|
|
2
|
+
export const shapesDensity = [
|
|
3
|
+
// --- 2026 corpus additions. Seven shapes named repeatedly across 31 videos on AI writing, read 6 Sep 2026. Evidence and counts: ai-doc/skills/content/writing/humanizer/references/detection.md.
|
|
4
|
+
|
|
5
|
+
// All seven are density-judged, so none can move into `patterns`: one instance is style.
|
|
6
|
+
{
|
|
7
|
+
id: "semantic-incoherence",
|
|
8
|
+
name: "Semantic incoherence",
|
|
9
|
+
rule: "Words that co-occur in training data joined into a picture that cannot exist. The phrase scans on first read and collapses on second: nothing is overarching and undergirding at once, a slate is not filled the way a container is, an offensive is not nestled. Name the physical picture the sentence asks for and check that it exists. Diagnoses bad writing, never authorship: weak human writers mix metaphors constantly. See patterns.md 53.",
|
|
10
|
+
example:
|
|
11
|
+
'"Two overarching pillars undergird the approach." / "the offensive, nestled amid a year of war" / "silence like a thunderstorm folded into velvet"',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: "figure-stacking",
|
|
15
|
+
name: "Figure stacking",
|
|
16
|
+
rule: "Three or more similes or metaphors laid end to end for one moment, instead of choosing the one that carries it. Each figure passes a line edit on its own; the pile is the tell. Same instinct at the word level produces adjective couplets where one adjective would do. Choose one and delete the rest. See patterns.md 54.",
|
|
17
|
+
example:
|
|
18
|
+
'"It bit like a thousand tiny teeth, a cruel lover, a quiet violence made beautiful." / "brittle and sharp" / "pastel and brittle"',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "base-adjective-recycling",
|
|
22
|
+
name: "Base adjective recycling",
|
|
23
|
+
rule: "The plainest adjectives (soft, quiet, sharp, light, warm, heavy, bright) returning every page, because the passage is not describing anything specific enough to need another word. The inverse of elegant variation. Mechanical check: search the draft for its five commonest adjectives and count. The repair is a specific detail, not a thesaurus. See patterns.md 55.",
|
|
24
|
+
example: '"The room was quiet. Her voice was quiet. A quiet dread settled."',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "emotional-flatlining",
|
|
28
|
+
name: "Emotional flatlining",
|
|
29
|
+
rule: "One heightened register held from the first line to the last, so nothing is emphatic because everything is. Structural rather than local, which is why it survives sentence-level editing. Read the loudest and the quietest passage: if they are the same volume, the draft has no shape. Fix it by taking pressure out of the ordinary passages, not by adding more to the big ones. Correct and expected in technical and reference text. See patterns.md 56.",
|
|
30
|
+
example:
|
|
31
|
+
'"A breakfast scene and a betrayal written at the same pitch." / A case study whose setup, turn and result all land equally hard.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "asserted-transition",
|
|
35
|
+
name: "Asserted transition",
|
|
36
|
+
rule: "Moreover, Furthermore, In addition, However, On the other hand connecting two sentences whose relation is not the one the word claims. Two failures compound: the pile-up, and the assertion of a logic that is not there. Delete the connective and read the pair again; if the relation was real, the sentences still carry it. One however is not a tell. See patterns.md 57.",
|
|
37
|
+
example:
|
|
38
|
+
'"The region gets heavy rainfall. However, agriculture is a major industry." / "The city has 50,000 people. Moreover, it is near the coast."',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "unsupported-opening-claim",
|
|
42
|
+
name: "Unsupported opening claim",
|
|
43
|
+
rule: "An opening sentence placing the subject among the most significant shifts in history, or reshaping how people think, followed by a second sentence on a different subject. The diagnostic is the absence of a follow-up: the claim is made, no evidence is offered, and the next line moves on to another claim. Ask of the opening line: what in the rest of this makes that true? If nothing does, open on what is actually true. See patterns.md 58.",
|
|
44
|
+
example:
|
|
45
|
+
'"The rise of AI is one of the most profound transformations in human history, reshaping industries, societies and our understanding of intelligence."',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "compare-by-restating",
|
|
49
|
+
name: "Compare by restating",
|
|
50
|
+
rule: "Rather than contrasting, the sentence offers a second and third phrasing of what it just said. It reads as precision and adds nothing, and underneath it is a writer who does not trust the reader to have understood the first phrasing. The tell is that deleting every clause after the first costs no meaning. The subtle cousin of the negation pivot. See patterns.md 59.",
|
|
51
|
+
example:
|
|
52
|
+
'"Her lipstick is red, not just red but vivid, the kind of colour that demands attention." / "hoops, the kind that no one second-guesses"',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "named-feeling",
|
|
56
|
+
name: "Named feeling",
|
|
57
|
+
rule: 'The emotion labelled where its cause belongs. A reader told what to feel feels nothing, and the label is the cheapest sentence in the language to produce, which is why a model reaches for it first. Delete the word and write what caused it: "I was frustrated" is "the fourth build failed at 2am and I put the laptop in a drawer". The reader supplies the word. Never invent the cause to replace the label; go and get it. See patterns.md 63.',
|
|
58
|
+
example:
|
|
59
|
+
'"I was frustrated." / "It was exciting." / "I felt proud of what we built." / "It was a humbling experience."',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "clean-resolution",
|
|
63
|
+
name: "Clean resolution",
|
|
64
|
+
rule: "Every thread tied off, every lesson learned, the piece landing complete. Real work leaves loose ends, so a piece where everything resolves was built backwards from its conclusion and the reader feels the reverse-engineering. Leave the thing that is still broken in, and say plainly what you do not know yet. See patterns.md 64.",
|
|
65
|
+
example:
|
|
66
|
+
'"And that is when it all clicked." / "Looking back, I would not change a thing." / "The lesson here is simple."',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "smoothed-figure",
|
|
70
|
+
name: "Smoothed figure",
|
|
71
|
+
rule: 'A hedge in front of a round number, where the number is the evidence. Real measurement produces ugly figures, so "about 50%" and "roughly 3x" tell the reader you estimated or invented it. Write 47%, 2.8x, $9,340, 213 hours. If the real figure is not to hand, say you are estimating rather than smoothing it. A round number nobody is leaning on (5 clients, 10 minutes) is ordinary English, which is why this stays a human read. The vague-magnitude half is lint-enforced. See patterns.md 65.',
|
|
72
|
+
example: '"about 50% faster" / "roughly 3x the output" / "around $10k a month"',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "costless-claim",
|
|
76
|
+
name: "Costless claim",
|
|
77
|
+
rule: "Advice from somebody who risked nothing. Authority comes from having paid for the knowledge, so instruction with no price attached anywhere in the piece reads as compiled rather than lived. Name one real cost, money, hours, a relationship or a reputation, and one moment you were wrong, neither of them softened. A cost that did not happen is a fabrication, so where there is none, cut the claim rather than furnishing it. See patterns.md 66.",
|
|
78
|
+
example:
|
|
79
|
+
'"Always validate before you build." with no account of the thing the writer built and nobody wanted.',
|
|
80
|
+
},
|
|
81
|
+
];
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** Sentence shapes, second third: framing, aphorism and abstraction tells. */
|
|
2
|
+
export const shapesFraming = [
|
|
3
|
+
{
|
|
4
|
+
id: "tells-you-more-than",
|
|
5
|
+
name: "The diagnostic-tell close",
|
|
6
|
+
rule: "Closing by ranking one signal above another as a source of truth. It sounds like earned judgement and is untestable, and it always arrives as the last line so it reads as a moral.",
|
|
7
|
+
example:
|
|
8
|
+
'"How they answer tells you more than the brief does." / "Their reply says more than the contract ever will." / "That one question reveals more than an hour of discovery."',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: "chiastic-reveal",
|
|
12
|
+
name: "Chiastic reveal",
|
|
13
|
+
rule: "Two abstract nouns swapped across a colon or a full stop so the sentence sounds like an insight. It is a rhetorical figure with no content: the reader has to decode the wordplay before reaching the point, and nobody speaks this way. Say the point.",
|
|
14
|
+
example:
|
|
15
|
+
'"Everyone here has the where. The part that took me longest was the what." / "The problem was never the tool. It was the habit." / "You do not need more time. You need less work."',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "appositive-fragment",
|
|
19
|
+
name: "Appositive fragment",
|
|
20
|
+
rule: "A noun phrase, a comma, then a verbless phrase that grades or denies the first half. The second half carries no fact, only the writer's assurance about the tone of the first. A comma in a short sentence is allowed to join a list of three or more real objects, an adverbial opener, or two clauses that each have a subject and a verb. Nothing else. Delete the appositive, or give it a verb.",
|
|
21
|
+
example:
|
|
22
|
+
'"One line, nothing dramatic." / "A single question, no pressure." / "Two fields, nothing fancy."',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "imperative-payoff",
|
|
26
|
+
name: "Imperative with a restated payoff",
|
|
27
|
+
rule: 'An order to the reader whose payoff only restates the order: the reader is told to do something and then told what they would have seen, so the line teaches nothing and orders nothing. Ramzi, 8 Sep 2026, on a shipped course title slide. Write the claim as a plain statement, or make the imperative an instruction somebody can carry out. Stays out of `patterns` because the same shape is right in a tutorial step: "Run pnpm dev and you get a server on 5173".',
|
|
28
|
+
example:
|
|
29
|
+
'"Open 10 agency accounts and you get 10 shapes" / "Fix the shape and the fields can be fixed too" / "Ask 3 people and you get 3 answers"',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "moral-aphorism",
|
|
33
|
+
name: "Moral aphorism",
|
|
34
|
+
rule: "An abstract virtue or vice given a predicate as a general truth about people. It reads as a lesson delivered from above, and it is unfalsifiable, so it adds nothing the surrounding sentence did not already carry. Generalisations take a concrete subject out of the work: a tool, a price, a status, a deadline.",
|
|
35
|
+
example:
|
|
36
|
+
'"Politeness is free, so it gets treated as free." / "Trust is earned in drops." / "Urgency is a choice."',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "definitional-demotion",
|
|
40
|
+
name: "Definitional demotion",
|
|
41
|
+
rule: 'A concrete noun, a relative clause that disqualifies it, then an equals sign to a lesser noun: "A backup nobody has rebuilt from is a folder." The shape reads as a hard-won definition and is a word game. Nothing is measured, nothing is instructed, and the reader cannot act on the verdict. Write the mechanism instead: what the thing fails to do, and what to do about it. It is the positive twin of the negation pivot, so a draft that has had its "it is not X, it is Y" removed often grows this one in its place.',
|
|
42
|
+
example:
|
|
43
|
+
'"A backup nobody has rebuilt from is a folder." / "A process nobody follows is a document." / "A plan without a date is a wish." / "A meeting with no notes is a rumour."',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "hypothetical-law",
|
|
47
|
+
name: "Hypothetical law",
|
|
48
|
+
rule: 'An "if" clause followed by a re-labelling of an abstraction rather than by an instruction or a real consequence. The sentence sounds like a discovered rule and is only a restatement. Follow a conditional with what to do, or with what actually happens.',
|
|
49
|
+
example:
|
|
50
|
+
'"If nothing ever stops, your due date is a suggestion." / "If everything is urgent, nothing is." / "If you never say no, your calendar belongs to somebody else."',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "colon-connector",
|
|
54
|
+
name: "Colon as a connector",
|
|
55
|
+
rule: "A colon used mid-sentence to join two clauses that a full stop would join better. A colon is right before a list or an example and nowhere else. The construction always arrives with comparison framing in front of it, so the fix is to drop both and let the point stand on its own.",
|
|
56
|
+
example:
|
|
57
|
+
'"If you are coming from traditional automation: instead of registering handlers, you describe conditions." / "The rule is simple: write it down." / "Here is the tradeoff: speed against accuracy."',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "abstract-metaphor-noun",
|
|
61
|
+
name: "Abstract metaphor noun",
|
|
62
|
+
rule: "A noun borrowed from physics, chess or engineering to make a plain idea sound technical: substrate, wedge, vector, locus, vantage, nexus, primitive (as a noun), harness (as a metaphor), surface (as in API surface), bedrock, scaffolding (as a metaphor), modality, gold-plating, ratchet, evacuate (for moving code), endgame, north star, flywheel. Each one has a plainer concrete word. Substrate is base, wedge in is add, vector is way or method, gold-plating is more than the job needs, ratchet is the mechanism's real name or a limit that only tightens, evacuate is move out, endgame is the last phase. Pick the concrete word. These stay off the lint list because several are literal in a codebase: a language primitive and a test harness are the real names of real things.",
|
|
63
|
+
example:
|
|
64
|
+
'"The substrate the whole product sits on." / "Use pricing as a wedge into the account." / "Another vector for growth." / "That is the north star for the flywheel."',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "feeling-not-mechanism",
|
|
68
|
+
name: "Feeling instead of mechanism",
|
|
69
|
+
rule: 'A sentence that names how something feels instead of what it does: "the database stays close at hand", "SQL you can read", "types that follow your schema". The fix names the mechanism or a number. Ask what the sentence tells the reader to do or know and write that; if it cannot be restated as an instruction, a fact or a number, cut it. Second test: if the sentence could appear unchanged in another project\'s docs, it says nothing about this one.',
|
|
70
|
+
example:
|
|
71
|
+
'"The database stays close at hand." / "SQL you can actually read." / "Types that follow your schema." / "Built for teams that move fast."',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "applause-line",
|
|
75
|
+
name: "Applause line",
|
|
76
|
+
rule: 'A standalone sentence whose only job is to tell the reader the paragraph above it was impressive. It carries no new fact, no number and no instruction, and it is always short, so it reads as emphasis while adding nothing. The tell is that deleting it costs the passage nothing. Delete it, or replace it with the figure that would have earned the reaction. Not in `patterns` because "This is leverage." and "This is the schema." are the same shape and only one of them is empty.',
|
|
77
|
+
example:
|
|
78
|
+
'"This is leverage." / "This is a huge benefit." / "That\'s a lot of free growth!" / "There is no better marketing than that." / "But their loss is your gain!"',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "propped-adverb",
|
|
82
|
+
name: "Propped adverb",
|
|
83
|
+
rule: "An adverb holding up a verb that is too weak to stand alone. Runs quickly is is fast or the number, significantly improves is the measured delta. An adverb propping a verb means the verb is wrong, so replace the pair with one stronger verb or with the figure.",
|
|
84
|
+
example:
|
|
85
|
+
'"Significantly improves load time." / "Runs quickly on modest hardware." / "Dramatically reduces the number of steps."',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "long-sentence",
|
|
89
|
+
name: "Sentence past 30 words",
|
|
90
|
+
rule: "Ogilvy's third rule is short words, short sentences and short paragraphs, and the sentence half is the one that gets skipped. Past about 30 words the reader reaches the end holding none of the beginning, so they read it twice or they stop. The tell is a sentence with three or more clauses stacked by commas and `and`. Split it at the first `and` that starts a new idea. Not in `patterns` because a regex counting words across a hard-wrapped paragraph cannot tell a sentence from a bullet list; `course-lint.mjs` counts it where the text is structured.",
|
|
91
|
+
example:
|
|
92
|
+
'"It does the typing part of every lesson with you, one module a sitting, on your own site, and it stops at the end of each module because the reading stays yours." (32 words)',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "spelled-out-number",
|
|
96
|
+
name: "Spelled-out number",
|
|
97
|
+
rule: 'A quantity written as words instead of digits. A digit is the one shape in a line of prose the eye cannot skim, so every count, price, duration, percentage, date and measure ships as digits at any size: 15 clients, 3 hours a week, 20%, 60 seconds, $4,000, 2 of 5. Words are correct only where the number is not a quantity: one standing in for a or a single thing ("one page per space"), an idiom ("second nature", "at first hand"), and a number opening a sentence, which is better rewritten so it does not open one.',
|
|
98
|
+
example:
|
|
99
|
+
'"fifteen clients in and nothing is written down" / "three hours a week" / "a sixty second read" / "twenty per cent of the pipeline"',
|
|
100
|
+
},
|
|
101
|
+
];
|