@heyramzi/lint 1.34.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/README.md +52 -5
- package/bin/heyramzi-comment-length.js +5 -6
- package/bin/heyramzi-file-tokens.js +2 -2
- package/bin/heyramzi-old-names.js +72 -0
- package/bin/heyramzi-push-diff.js +16 -5
- package/bin/heyramzi-slop.js +3 -1
- package/bin/heyramzi-ui-rules.js +18 -9
- package/comment-length.js +18 -12
- package/config/oxlintrc.json +3 -4
- package/data/jev-code-bench.js +5 -5
- 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/file-tokens.js +26 -13
- package/index.js +4 -6
- package/inline-path.js +2 -0
- package/jev-code.js +1 -1
- package/old-names-mask.js +206 -0
- package/old-names.js +145 -0
- package/package.json +8 -2
- package/push-diff.js +2 -2
- package/repo-rules/packages.js +5 -5
- package/repo-rules.js +2 -2
- package/rules/convex-index-name.js +3 -1
- package/rules/convex-internal-only.js +2 -1
- package/rules/{convex-no-deprecated-crons.js → convex-no-hourly-daily-crons.js} +8 -7
- package/rules/convex-runtime-imports.js +2 -1
- package/rules/{no-legacy-compat.js → no-underscore-reexport.js} +1 -1
- package/slop.js +4 -2
- package/ui-rules-css.js +221 -0
- package/ui-rules-markup.js +130 -0
- package/ui-rules.js +98 -25
- package/vendor/old-names-words.js +9 -0
- package/rules/no-relative-type-imports.js +0 -40
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Patterns for spelled-out numbers, numbered labels and comma-run lists. */
|
|
2
|
+
export const patternsNumbersAndRuns = [
|
|
3
|
+
{
|
|
4
|
+
id: "spelled-out-quantity",
|
|
5
|
+
name: "Spelled-out quantity",
|
|
6
|
+
// The lintable half of the `spelled-out-number` shape. A cardinal word followed by the thing it counts is always a quantity, so it always wants digits.
|
|
7
|
+
|
|
8
|
+
// `one` is left out because it doubles as an article, and a bare cardinal with no noun after it ("two of the three") is left out because the shape entry
|
|
9
|
+
|
|
10
|
+
// still covers it for the human read.
|
|
11
|
+
|
|
12
|
+
// The lookbehind added 31 Aug 2026: `hundred|thousand|million` are on the list for "three thousand euros", and without it they also fired on a figure that is already correct,
|
|
13
|
+
|
|
14
|
+
// so "17 million last year" failed the gate it passes by construction. Caught auditing the 45 planned posts.
|
|
15
|
+
|
|
16
|
+
// The `Sigma` exclusion added 6 Sep 2026: Six Sigma is the name of a methodology, so the number is not counting anything and no digit belongs there.
|
|
17
|
+
|
|
18
|
+
// It fired 8 times across the UpSys blog, in both languages.
|
|
19
|
+
|
|
20
|
+
// `Factor` joined it 7 Sep 2026 for the same reason: Two-Factor Authentication is a feature name, and a screenshot's alt text has to quote the label the screenshot shows.
|
|
21
|
+
|
|
22
|
+
// `way` joined 9 Sep 2026: two-way sync is a feature name on the Airtable to Sheets pricing page and in the add-on UI.
|
|
23
|
+
|
|
24
|
+
// The singular is always an adjective, and `\b` keeps "two ways" caught, which is a real quantity.
|
|
25
|
+
|
|
26
|
+
// A relative pronoun or `of` after the cardinal means it counts no noun ("the one or two that carry weight"), 15 Oct 2026.
|
|
27
|
+
test: /(?<!\d[\s-])\b(?:two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety|hundred|thousand|million)[\s-]+(?!(?:Sigma|Factor|way|that|which|who|whom|whose|of)\b)[a-z]{3,}/i,
|
|
28
|
+
rule: "A quantity written as words. A digit is the one shape in a line of prose the eye cannot skim, so every count, duration, price and measure ships as digits: 40 pages, 19 minutes, 3 channels, 20%. See the `spelled-out-number` shape for the exceptions.",
|
|
29
|
+
example:
|
|
30
|
+
'"forty pages" / "nineteen minutes beat twenty-nine" / "twenty per cent of the pipeline"',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "spelled-out-label",
|
|
34
|
+
name: "Numbered label in words",
|
|
35
|
+
// The other half of `spelled-out-quantity`, which cannot see this one: a label is followed by a colon or a heading break rather than by the noun it counts,
|
|
36
|
+
|
|
37
|
+
// so "Lesson two:" never reaches that test. The noun list is closed and every entry is an index into a set the writer made.
|
|
38
|
+
|
|
39
|
+
// `day` is deliberately absent, because "from day one" is an idiom rather than a count, and `point` is absent because "point five" is a decimal.
|
|
40
|
+
test: /\b(?:lesson|step|part|phase|chapter|module|rule|tip|slide|stage|round|week|version|level)\s+(?:one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve)\b/i,
|
|
41
|
+
rule: "A label that counts, written as a word. It is the same rule as any other quantity: a digit is the one shape in a line the eye cannot skim, and a label is read at a glance more than any other line on the page. Write Lesson 3, Step 2, Part 4.",
|
|
42
|
+
example: '"Lesson one: stop selling the tool" / "Step three" / "Part two of the build"',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "ring-label",
|
|
46
|
+
name: "Ring as a numbered label",
|
|
47
|
+
// Ramzi, 19 Sep 2026, on a board that labelled its four cards RING 1 to RING 4: the ring is the drawing, not the thing.
|
|
48
|
+
|
|
49
|
+
// A number is allowed to follow the real noun (Load 2, Step 3), never the shape it was drawn as.
|
|
50
|
+
|
|
51
|
+
// Restricted to a following number so "ring the bell" and a phone ringing stay ordinary English.
|
|
52
|
+
test: /(?:^|[.!?]["'’”)\]]?\s+|\n)\s*(?:#{1,6}[ \t]+)?(?:[-*•]\s*)?ring\s+(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten)\b/i,
|
|
53
|
+
rule: "A label naming the picture instead of the thing. The reader has to hold your diagram in their head before the line means anything, and the real noun was available. Write Load 2, Step 3, the schedule.",
|
|
54
|
+
example: '"RING 2" / "Ring one: your business" / "Ring 4, the schedule"',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "comma-run",
|
|
58
|
+
name: "Comma-run list",
|
|
59
|
+
// 3+ fragments strung on commas with no conjunction anywhere, all short.
|
|
60
|
+
|
|
61
|
+
// Ramzi, 19 Sep 2026, on "One connector, read the permission screen, 12 slides back": *"For AI, the sequence of commas is AI slop."* A written list has "and" in it,
|
|
62
|
+
|
|
63
|
+
// or it is 2 items, or it is bullets.
|
|
64
|
+
view: "prose",
|
|
65
|
+
test: /(?:^|[.!?:\n]\s*)(?![^.!?\n]*(?:\b(?:and|or|but|nor|then|so|plus|et|ou|mais|ni|puis|donc)\b|=>))[^.!?\n,]{4,40},\s[^.!?\n,]{4,40},\s[^.!?\n,]{4,40}(?=[.!?\n]|$)/i,
|
|
66
|
+
rule: "Three or more fragments hung on commas with no conjunction. It reads as a machine emptying a list rather than a person making a point: nothing in it is subordinate to anything else, so the reader has no idea which part matters. Use two items and a conjunction, or write bullets.",
|
|
67
|
+
example:
|
|
68
|
+
'"One connector, read the permission screen, 12 slides back." / "Fast, cheap, reliable." / "The brief, the offer, the tone."',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "nobody-opener",
|
|
72
|
+
name: "Nobody opener",
|
|
73
|
+
// Sentence-initial only. Mid-sentence "and nobody reads it" is an ordinary
|
|
74
|
+
// clause; the tell is the crowd taking the first position, where the
|
|
75
|
+
// reader's own problem belongs.
|
|
76
|
+
test: /(?:^|[.!?]["'’”)\]]?\s+|\n)\s*(?:#{1,6}[ \t]+)?(?:nobody|no one|no-one)\s+[a-zà-ÿ]/i,
|
|
77
|
+
rule: "A sentence opening on what an unnamed crowd does not do. It spends the strongest position in the line on an absence nobody can check, and the claim after it needs the crowd to be wrong before it means anything. Write what the reader in front of you wants.",
|
|
78
|
+
example:
|
|
79
|
+
'"Nobody wakes up wanting an app." / "No one reads the second page." / "Nobody has time for this."',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "reassurance-relative",
|
|
83
|
+
name: "Reassurance relative clause",
|
|
84
|
+
// The verb set is deliberately short: comprehension and ease only.
|
|
85
|
+
|
|
86
|
+
// "a form you can fill in on your phone" carries a fact about the form and passes; "a report you can read" carries only the promise that it is not
|
|
87
|
+
|
|
88
|
+
// bad.
|
|
89
|
+
test: /\b(?:a|an|the)\s+(?:[a-zà-ÿ-]+\s+){0,3}[a-zà-ÿ-]+\s+(?:you\s+can\s+(?:actually\s+)?(?:read|use|understand|trust|follow|act\s+on)|that\s+(?:actually|just)\s+works|that\s+makes\s+sense)\b/i,
|
|
90
|
+
rule: "A noun, then a relative clause whose only content is that the noun is not bad. It defends the thing against a complaint the reader never made, and it concedes that the usual version of the thing is unreadable. Say what is in it: 4 numbers, one page, the 3 jobs it lists.",
|
|
91
|
+
example:
|
|
92
|
+
'"A monthly report you can read" / "a dashboard you can actually use" / "a process that makes sense" / "a tool that just works"',
|
|
93
|
+
},
|
|
94
|
+
];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { PARTICIPLE_LIST } from "#lint/data/slop/pattern-parts.js";
|
|
2
|
+
|
|
3
|
+
/** Patterns for sentence openers and the benefit tails hung on the end. */
|
|
4
|
+
export const patternsOpenersAndTails = [
|
|
5
|
+
// The next 6 were read off Batch 2's clean reads the same day. At most 1 hit in 45,574 words of his own speech.
|
|
6
|
+
{
|
|
7
|
+
id: "and-escalation",
|
|
8
|
+
name: "And most of them are",
|
|
9
|
+
test: /, and (?:most|all|half|none|many) of (?:them|these|those) (?:are|were|have|go)\b|\b(?:there is|there's) and (?:it'?s|it is) the (?:weakest|worst|best|least|most)\b|, and everything else is\b/i,
|
|
10
|
+
rule: 'A claim, then a bigger claim bolted on with ", and most of them". The second clause inflates the first instead of adding a fact. Split it and give the second its own evidence, or cut it.',
|
|
11
|
+
example:
|
|
12
|
+
'"Every one of these tells turns up in good human writing, and most of them are centuries old." / "That\'s the most cited tell there is and it\'s the weakest one."',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "which-is-why",
|
|
16
|
+
name: "Which is exactly why",
|
|
17
|
+
test: /, which is (?:exactly |precisely )?(?:why|what|how)\b/i,
|
|
18
|
+
rule: "A tidy causal tail that closes the loop for the viewer. Say the cause as its own sentence, or let them reach it.",
|
|
19
|
+
example:
|
|
20
|
+
'"The service still making you money is the one keeping you stuck, which is exactly why you haven\'t touched it."',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "labelled-turn",
|
|
24
|
+
name: "The awkward part is that",
|
|
25
|
+
test: /\bthe (?:awkward|uncomfortable|hard|tricky|funny|scary|annoying|ugly|brutal|interesting|surprising|real) (?:part|bit|thing|truth)(?: here)? is that\b/i,
|
|
26
|
+
rule: "A label announcing that the next sentence matters. Delete the label and start on the fact.",
|
|
27
|
+
example:
|
|
28
|
+
'"The awkward part is that this list keeps rotting." / "The uncomfortable bit is that the branch you cut is still alive."',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "there-is-only",
|
|
32
|
+
name: "There's no X. There's only Y.",
|
|
33
|
+
test: /\bthere'?s no [^.!?]+[.!?]\s+there'?s only\b/i,
|
|
34
|
+
rule: "A negation pivot split over 2 sentences to sound final. State the Y.",
|
|
35
|
+
example: "\"There's no detector for this. There's only a list.\"",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "nobody-ever",
|
|
39
|
+
name: "Nobody has ever",
|
|
40
|
+
test: /\b(?:nobody|no one|no-one) (?:has |had )?ever\b/i,
|
|
41
|
+
rule: 'An absolute nobody measured. Say what you saw, with its count: "none of the 12 people I onboarded learned it from the doc."',
|
|
42
|
+
example: '"Nobody has ever learned a process from a paragraph."',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "is-where-people",
|
|
46
|
+
name: "Is where people stop",
|
|
47
|
+
test: /\bis where (?:people|you|most|everyone|teams?|clients?|readers?) (?:stop|quit|leave|give up|lose|drop)\b/i,
|
|
48
|
+
rule: 'A place standing in for a behaviour. Say what people do and when: "people stop reading after the first paragraph."',
|
|
49
|
+
example: '"A wall of paragraphs is where people stop reading."',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "every-opener",
|
|
53
|
+
// Case-sensitive so the lookahead spares Sitehub's plan names, which are proper nouns.
|
|
54
|
+
test: /(?:^|[.!?]["'’”)\]]?\s+|\n|["'`])\s*(?:#{1,6}[ \t]+)?(?:EVERY|[Ee]very|EACH|Each)\s(?!(?:Town|Search|Service|other|of)\b)/,
|
|
55
|
+
name: "Every or Each opener",
|
|
56
|
+
rule: 'A sentence that opens with Every or Each. It asserts a total in place of describing the thing, and swapping one for the other keeps the tell: Ramzi, 17 Sep 2026, on "Each workflow arrives named, grouped and explained": "each is also slop". Start the sentence on who does what: "We name, group and document your workflows."',
|
|
57
|
+
example:
|
|
58
|
+
'"Every number names its source article." / "Each workflow arrives named, grouped and explained."',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "participle-stack",
|
|
62
|
+
name: "Named, grouped and explained",
|
|
63
|
+
// 3 past participles in one list, tags allowed between. 0 hits on 190 of his posts, 3 on the website.
|
|
64
|
+
test: new RegExp(
|
|
65
|
+
`\\b${PARTICIPLE_LIST},\\s+(?:<[^>]+>\\s*)?${PARTICIPLE_LIST},?\\s+(?:and|or)\\s+${PARTICIPLE_LIST}\\b`,
|
|
66
|
+
),
|
|
67
|
+
rule: 'Three past participles stacked as the result ("named, grouped and explained", "built, tested and documented"). Nobody does anything in it, and the list sounds thorough while saying nothing about how. Ramzi, 17 Sep 2026: "something that does not use passive words like named, grouped and explained." Give it a doer and active verbs: "We name, group and document your workflows."',
|
|
68
|
+
example:
|
|
69
|
+
'"Each workflow arrives named, grouped and explained." / "each one built, tested and documented"',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "participle-opener",
|
|
73
|
+
// Put, Cut, Set, Read and Run open imperatives as often as participles, so they're out.
|
|
74
|
+
// "Done when" names a step's finish line, the house shape since 4 Oct 2026.
|
|
75
|
+
test: /(?:^|[.!?]["'’”)\]]?\s+|\n|["'`])\s*(?:#{1,6}[ \t]+)?(?:(?!(?:Need|Seed|Speed|Feed|Bed|Red|Shed|Indeed|Breed|Weed|Deed|Greed|Embed|Proceed|Exceed|Succeed)\b)[A-Z][a-z]{2,}ed|Built|Made|Done(?!\s+when\b)|Kept|Written|Found|Taken|Shown|Grown|Known|Seen|Given|Chosen|Driven|Sold|Told|Held|Brought|Bought|Caught|Taught|Sent|Spent|Meant|Lost|Paid|Drawn|Worn|Named)\b,?\s+(?:in|for|by|with|to|from|on|around|into|once|before|after|at|off|out|up|over|under|through|across|and|like|as|when|while|where|the|your|our|their|a|an)\b/,
|
|
76
|
+
name: "Participle opener",
|
|
77
|
+
rule: "A sentence, heading or label that opens on a past participle (Built for, Found when, Measured once, Made to measure) with no subject. It is passive and nobody in it does anything. Say who does what: We built it for a phone. People find you when they search your town.",
|
|
78
|
+
example:
|
|
79
|
+
'"Built in your own colours" / "Found when your town searches" / "Named when somebody asks ChatGPT"',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "reader-benefit-tail",
|
|
83
|
+
// A conjunction or wh-word before `you` makes it a real clause (so your team can rest), not this.
|
|
84
|
+
test: /\b(?!(?:and|but|or|nor|so|yet|if|when|whenever|until|till|unless|because|before|after|once|now|then|here|there|where|what|whatever|how|why|who|whom|as|than|while|since|though|although|also|too|are|is|was|were|do|does|did|have|has|had|sure|think|suggest|guess|hope|bet)\b)[A-Za-z]{3,}\s+(?:(?:that|which)\s+)?(?:you|your\s+[a-z]+)(?:\s+(?:can(?:'t|’t|not)?|will|won't|won’t|could|would|should|actually)|['’]ll)\s+(?:(?:actually|really|finally|still|all)\s+)?[a-z]+[.!](?=["'’”<)\]]|\s|$)/i,
|
|
85
|
+
name: "Reader-benefit tail",
|
|
86
|
+
rule: "A sentence that ends on a noun plus a clipped relative clause about the reader: a capacity number your team can hold, a price your CFO will love, a system you can trust. The that is dropped and the verb's object is the noun before it, so the sentence closes on a bare modal verb that promises a feeling instead of stating a fact. Ramzi, 23 Sep 2026. Say what the thing does, with a number: a cap of 30 points per person a week.",
|
|
87
|
+
example:
|
|
88
|
+
'"and a capacity number your team can hold." / "A price your CFO will love." / "Systems that your team can actually maintain." / "A board you can trust."',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { SUBJECT_STOP, PARTICIPLE, NOUN_PHRASE_STOP, INTRANSITIVE_PAST, PREPOSITION, FINITE_AUXILIARY, CLAUSE_SUBJECT, PRESENT_VERB, OBJECT_DETERMINER } from "#lint/data/slop/pattern-parts.js";
|
|
2
|
+
|
|
3
|
+
/** Patterns for parallel, paired and countdown sentence shapes. */
|
|
4
|
+
export const patternsParallelShapes = [
|
|
5
|
+
{
|
|
6
|
+
id: "before-it-happens-countdown",
|
|
7
|
+
name: "Before it happens again",
|
|
8
|
+
// A closing imperative racing a recurrence: "before it happens again" or "before it happens a 4th time".
|
|
9
|
+
|
|
10
|
+
// The ordinal or "again" is required, so an ordinary "finish it before it happens" (a real deadline, no recurrence) does not match.
|
|
11
|
+
test: /\bbefore\s+it\s+happens\s+(?:again|(?:a\s+)?(?:\d+(?:st|nd|rd|th)|another)(?:\s+time)?)\b/i,
|
|
12
|
+
rule: 'A closing line staged as a countdown to a recurrence nobody was tracking, for tension rather than fact. Ramzi, 14 Sep 2026, on "Write each one down before it happens a 4th time": "Same thing here. XXX before it happens or whatever." Say when to do the thing: "Write it down the next time it comes up."',
|
|
13
|
+
example:
|
|
14
|
+
'"Write each one down before it happens a 4th time." / "Fix the root cause before it happens again."',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: "universal-so-payoff",
|
|
18
|
+
name: "Every X, so Y",
|
|
19
|
+
// A universal quantifier ("Every"/"All") stating a generalization, then a
|
|
20
|
+
// comma-"so" clause delivering a tidy payoff. Bounded to one sentence so
|
|
21
|
+
// it cannot cross a paragraph and pair two unrelated claims.
|
|
22
|
+
test: /\b(?:Every|All)\s+[^.!?\n]{3,60},\s+so\s+[^.!?\n]{3,60}[.!?]/i,
|
|
23
|
+
rule: 'A generalization capped with a neat "so" consequence in the same breath, reads as a thesis statement rather than something said. Ramzi, 14 Sep 2026, on "Every agency meets the same 7, so nobody improvises the 5th ask": flagged as the same anti-pattern, on a run of feedback he said he has repeated for weeks. Split it: state the fact, then the consequence as its own plain sentence.',
|
|
24
|
+
example:
|
|
25
|
+
'"Every agency meets the same 7, so nobody improvises the 5th ask." / "All 6 templates ship the same way, so nobody argues about the steps."',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "how-adj-subject-verb-final",
|
|
29
|
+
name: "How busy the day is",
|
|
30
|
+
// "no matter how [adjective] [noun phrase] is/are/was/were": the adjective fronts for the "how" question shape and strands the subject and its verb at the very end of the clause,
|
|
31
|
+
|
|
32
|
+
// which is not how the sentence would be said out loud. Scoped to "no matter how" so an ordinary question ("how busy is the day?") does not match.
|
|
33
|
+
test: /\bno matter how\s+\w+\s+(?:the|a|an|this|that|your|my|our|his|her|their)\s+[\w'-]+(?:\s+[\w'-]+){0,2}\s+(?:is|are|was|were|gets)\b/i,
|
|
34
|
+
rule: 'The adjective fronts to ask "how", and the subject and its verb end up stranded as the last words of the sentence instead of leading it. Ramzi, 14 Sep 2026, on "no matter how busy the day is": "You have put the subject and the verb as the last word of the sentence." Put the subject first: "even on a busy day" or "however busy the day gets" restructured so the verb is not the clause\'s last word.',
|
|
35
|
+
example:
|
|
36
|
+
'"no matter how busy the day is" / "no matter how tight the deadline was" / "no matter how loud the room gets"',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "paired-copula",
|
|
40
|
+
name: "X is the A, Y is the B",
|
|
41
|
+
// Two "is the" clauses on ONE line, the second riding on the first.
|
|
42
|
+
|
|
43
|
+
// The second subject is at most two words and cannot open on a conjunction, which is what separates the aphorism from an ordinary joined sentence:
|
|
44
|
+
|
|
45
|
+
// "the rate is the cost, and the volume is the driver" reads as speech and does not match. Same line only, so two unrelated paragraphs cannot pair.
|
|
46
|
+
test: /\b(?:is|are)[ \t]+the[ \t]+[a-zà-ÿ-]+[ \t]*[.;,][ \t]+(?!(?:and|but|so|or|yet|while|because|when|if|which|that|then)\b)(?:the[ \t]+|a[ \t]+|an[ \t]+)?[a-zà-ÿ-]+(?:[ \t]+[a-zà-ÿ-]+)?[ \t]+(?:is|are)[ \t]+the\b/i,
|
|
47
|
+
rule: "Two copulas in a row, each assigning one noun to another, written for the balance rather than to say a second thing. Ramzi, 15 Sep 2026, on the CBAM news page. Keep the clause that carries the fact and delete the one that mirrors it.",
|
|
48
|
+
example:
|
|
49
|
+
'"News is the signal. The dataset is the answer." / "The diff is the product, the version is the receipt."',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "elided-passive",
|
|
53
|
+
name: "X built for Y",
|
|
54
|
+
// Headline grammar: subject, participle, preposition, no auxiliary. Measured 17 Sep 2026: 0 hits on 190 of his posts, 27 on the website and app strings.
|
|
55
|
+
test: new RegExp(
|
|
56
|
+
`(?:^|["'\`]|#{1,6}[ \\t])[ \\t]*${SUBJECT_STOP}[A-Z0-9][\\w&'’.-]*(?:[ \\t]+${NOUN_PHRASE_STOP}(?!${PARTICIPLE}\\b)[\\w&'’-]+){0,3}[ \\t]+${INTRANSITIVE_PAST}${PARTICIPLE}[ \\t]+${PREPOSITION}\\b(?:(?!\\b${FINITE_AUXILIARY}\\b)[^.!?\\n"'\`<>]){0,60}[.!]?(?=[ \\t]*(?:["'\`]|$(?![\\r\\n][ \\t]*[a-z])))`,
|
|
57
|
+
"m",
|
|
58
|
+
),
|
|
59
|
+
rule: 'A subject, then a past participle standing in for the verb, then a preposition, with the auxiliary dropped. It is newspaper headline grammar: nothing happens in it and nobody does it. Ramzi, 17 Sep 2026, on a deck cover that passed the gate: "ClickUp rebuilt around your cases". Write the sentence with a doer and a finite verb: "We rebuild ClickUp around your cases."',
|
|
60
|
+
example:
|
|
61
|
+
'"ClickUp rebuilt around your cases" / "Scenarios built on your own stack" / "4 hours saved on each"',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "parallel-clauses",
|
|
65
|
+
name: "X does the A, Y does the B",
|
|
66
|
+
// Isocolon: two clauses cut to one build (subject, present verb, object) side by side. Widens `paired-copula` past "is the".
|
|
67
|
+
test: new RegExp(
|
|
68
|
+
`(?:^|[.!?:]["'’”)]?[ \\t]+|["'\`\\n])[ \\t]*${CLAUSE_SUBJECT}[ \\t]+${PRESENT_VERB}[ \\t]+${OBJECT_DETERMINER}(?:[ \\t]+[\\w'’-]+){0,2}[ \\t]*[,;.][ \\t]+(?:and[ \\t]+)?${CLAUSE_SUBJECT}[ \\t]+${PRESENT_VERB}[ \\t]+${OBJECT_DETERMINER}\\b`,
|
|
69
|
+
"m",
|
|
70
|
+
),
|
|
71
|
+
rule: 'Two or more clauses built the same way (subject, present verb, object) and set side by side for the balance. The symmetry carries the message, each clause says less than it would alone, and a third member usually arrives longer as a crescendo. Ramzi, 17 Sep 2026, on "Clio keeps the record, ClickUp runs the work, and Maz reads it all on one dashboard." Keep the clause that carries the new fact and fold the others into it.',
|
|
72
|
+
example:
|
|
73
|
+
'"Clio keeps the record, ClickUp runs the work, and Maz reads it all on one dashboard." / "One builds the workspace, the other runs the week inside it." / "The diff shows the change. The version keeps the receipt."',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "for-any-tail",
|
|
77
|
+
name: "..., for any X",
|
|
78
|
+
// A question or an inquisitive imperative, then a comma and a universal scope bolted on as a closer.
|
|
79
|
+
|
|
80
|
+
// The opener set is closed and the tail is `for` plus a quantifier, so "it is priced in euros, for each importer" (no opener),
|
|
81
|
+
|
|
82
|
+
// "know what it costs for any code" (no comma) and "what the calendar says, in one line" (a count, not a scope) all read clean.
|
|
83
|
+
test: /\b(?:know|see|find out|learn|discover|check|understand|what|which|how)\b[^.!?\n]{2,60},[ \t]*for[ \t]+(?:any|every|each|one)\b/i,
|
|
84
|
+
rule: "A headline that asks something, then hangs a scope claim off a comma to cover the whole catalogue. The scope is a specification, not a clause. Ramzi, 15 Sep 2026, on the CBAM home and calculator headlines. Fold it into the sentence or make it its own line.",
|
|
85
|
+
example:
|
|
86
|
+
'"Know what CBAM costs you, for any CN code." / "What CBAM costs you, for one CN code."',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "before-you-verb-it",
|
|
90
|
+
name: "X before you Y it",
|
|
91
|
+
// A whole line that is a noun, then a second-person clause telling the reader when they are allowed to act.
|
|
92
|
+
|
|
93
|
+
// Anchored per line and to the line's end, so an ordinary "read the terms before you sign it" inside a paragraph is left alone:
|
|
94
|
+
|
|
95
|
+
// this only fires on the heading shape.
|
|
96
|
+
test: /^[ \t]*(?:#{1,6}[ \t]+)?[A-Z][^.!?\n]{0,40}[ \t]+before[ \t]+you[ \t]+[a-zà-ÿ]{2,12}[ \t]+(?:it|them|one)[ \t]*[.!?]?[ \t]*$/m,
|
|
97
|
+
rule: "A heading that stages the reader's own action as a gate, in the second person, so the section reads as permission rather than as what it holds. Ramzi, 15 Sep 2026, on the CBAM FAQ heading. Name what is in the section.",
|
|
98
|
+
example: '"Questions before you use it" / "What to check before you ship it"',
|
|
99
|
+
},
|
|
100
|
+
];
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** Patterns for flat reveals, stock pivots and counted claims. */
|
|
2
|
+
export const patternsRevealsAndTallies = [
|
|
3
|
+
{
|
|
4
|
+
id: "tool-does-the-job",
|
|
5
|
+
name: "13 skills do the writing",
|
|
6
|
+
test: /\b(?:skills?|prompts?|plugins?|tools?|agents?|templates?|files?|automations?|workflows?|models?|AI|bots?|courses?|lessons?|systems?)\s+(?:(?:that|which|will|can|then|now)\s+)?(?:do|does|did|handles?|takes?\s+care\s+of)\s+(?:all\s+)?(?:of\s+)?(?:the|your)\s+(?:heavy\s+lifting|hard\s+part|legwork|grunt\s+work|work|job|writing|reading|reads|thinking|research|selling|planning|editing|drafting|talking|analysis|rest)\b/i,
|
|
7
|
+
rule: 'A skill or a tool doing the person\'s work: skills do the writing, the agent does the research. It\'s an aphorism, and nobody learns what runs. Make the person the subject and name the tool as the thing they use: "Claude writes the page with the SEO skill", "You run the skill and it drafts the meta fields". Ramzi, 23 Sep 2026: "A skill does not do the writing, it\'s not a human."',
|
|
8
|
+
example:
|
|
9
|
+
'"13 public skills do the writing, the meta fields and the reads" / "the agent does the research"',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "free-as-figure",
|
|
13
|
+
name: "The moment capture is free",
|
|
14
|
+
test: /\bmoments?\s+(?:where\s+|when\s+)?(?:\w+\s+)?(?:is|are)\s+free\b|\b(?:capture|capturing|recording|context|clarity|feedback)\s+(?:is|are)\s+free\b|\bcosts?\s+nothing\s+to\s+(?:capture|record|write|ask|fix|say|check)\b|\bwhile\s+\w+ing\s+it\s+is\s+(?:still\s+)?free\b/i,
|
|
15
|
+
rule: 'A price put on something nobody pays for: a moment is free, capture costs nothing. It reads as an aphorism and says nothing the reader can act on. Say who does what, and when: "Capture each answer when it\'s first said, on the call or in the form". Ramzi, 23 Sep 2026.',
|
|
16
|
+
example:
|
|
17
|
+
'"The moment capture is free" / "One moment in every process costs nothing to capture"',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "ends-on-verb",
|
|
21
|
+
name: "A page the market asked for",
|
|
22
|
+
test: /\b(?!(?:\w*thing|during|morning|evening|ceiling|string|spring|wing|king|ring|bring|sing)\b)(?:[a-z]+(?:ed|ing)|paid|made|built|sold|bought|meant|said|sent|ask|asks|pay|pays|call|calls|look|looks|wait|waits|care|cares|account|accounts|search|searches|hope|hopes|vote|votes|apply|applies|reach|reaches|settle|settles|up)\s+(?:for|about|with|from)(?=\s*(?:[.!?;:,)"'”’\n]|$))|\b(?:it's|it is|is|was|are|were|been|being|gets|got|get)\s+(?:(?:first|1st|already|still|never|not|just|finally|actually|really|\w+ly)\s+)?(?:said|asked|written|made|sent|built|shipped|captured|heard|given|taken|seen|known|told|paid|read|shown|found|decided|agreed|signed|recorded|typed|spoken|answered|called|raised|mentioned|promised|approved|needed|wanted)(?=\s*(?:[.!?,;:)"'”’\n]|$))/i,
|
|
23
|
+
rule: 'A sentence that ends on its verb: "a page the market asked for", "when it\'s first said". The object is missing and the reader has to supply it. Name who does it and to what: "a page for a query that has impressions and no page", "when the client first says it". Ramzi, 23 Sep 2026.',
|
|
24
|
+
example:
|
|
25
|
+
'"Impressions with no page behind them is a page the market asked for" / "Capture the answer when it\'s first said"',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "count-of-total",
|
|
29
|
+
name: "62 of 99 agency owners",
|
|
30
|
+
test: /\b\d+\s+of\s+(?:the\s+)?\d{2,}\s+(?:[a-z-]+\s+)?(?:agenc(?:y|ies)|compan(?:y|ies)|founders?|owners?|clients?|orgs?|organi[sz]ations?|businesses|people|teams?|calls?)\b/i,
|
|
31
|
+
rule: 'A raw count out of a total reads like a spreadsheet and makes the reader do the division. Give the share, and who said it: "62% of the agency owners I\'ve met told me work goes missing". Ramzi, 23 Sep 2026: "This is way too specific. 62 of 99."',
|
|
32
|
+
example:
|
|
33
|
+
'"62 of 99 agency owners describe work going missing" / "73 of the 99 agencies I have worked with"',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "paired-backref",
|
|
37
|
+
name: "The first X, and the second Y in it",
|
|
38
|
+
test: /\bthe (?:first|former)\b[^.!?\n]{0,80}[,;.]\s+(?:and\s+)?the (?:second|other|latter)\b|, and\s+(?:the|your|a|an)\s+[^,.!?\n]{2,50}\b(?:inside|into|in|on|onto|under)\s+it\b/i,
|
|
39
|
+
rule: 'Two halves where the second only makes sense by pointing back at the first: "the first..., the second...", or ", and the week runs inside it". The reader has to hold the first half to parse the second, and it reads as an aphorism. Name each thing and give the reader the order: "Set up your ClickUp with this course. And use The Project Manager skill to plan your week in it." Ramzi, 23 Sep 2026.',
|
|
40
|
+
example:
|
|
41
|
+
'"The first builds the workspace, and the week runs inside it on the second." / "The first course sets it up. The second runs it."',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "you-injunctive",
|
|
45
|
+
name: "You put, you add",
|
|
46
|
+
test: /(?:^|(?<=[.!?:]\s)|(?<=\n))[ \t]*(?:[-*][ \t]+|\d+\.[ \t]+)?You (?:put|add|keep(?! \w+ing)|write|give|make|move|set|use|build|pick|name|delete|open|run|paste|end|create|turn|check|send|start|cut)\b/,
|
|
47
|
+
rule: 'An instruction dressed as a description of the reader: "You keep the numbers in 1 file". It reads as a model narrating the reader\'s day. Drop the "You" and give the order: "Keep the numbers in 1 file".',
|
|
48
|
+
example: '"You keep all the numbers in 1 file" / "You end each lesson with something built"',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "you-now-know",
|
|
52
|
+
name: "You now know",
|
|
53
|
+
test: /\bYou now know\b/,
|
|
54
|
+
rule: 'A recap that tells the reader what they learned before handing over the next thing. It opened 5 course finales in the same words. Cut it and start on the next thing: "Here\'s 1 prompt that runs the loop."',
|
|
55
|
+
example: '"You now know the loop and why each step is there."',
|
|
56
|
+
},
|
|
57
|
+
// The next 6 were read off the A20 Short on 23 Sep 2026, which passed the gate and was one tell per sentence. 0 hits on his own transcripts.
|
|
58
|
+
{
|
|
59
|
+
id: "stock-half-pivot",
|
|
60
|
+
name: "The easy half",
|
|
61
|
+
test: /\b(?:easy|easier|hard|harder|simple|tricky) half\b/i,
|
|
62
|
+
rule: 'A pivot off the shelf: "X is the easy half. The harder half is Y." It announces a turn instead of making one, and it repeats across scripts because a template taught it. Say what breaks: "It cuts the shouting. It keeps your rules."',
|
|
63
|
+
example: '"Deleting is the easy half." / "The counting is the easy half."',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "because-parallel",
|
|
67
|
+
name: "Same verb, because, twice",
|
|
68
|
+
test: /\b(\w+), because\b[^.!?]*[.!?]["'”’]?\s+[^.!?]*?\b\1, because\b/i,
|
|
69
|
+
rule: 'Two sentences in a row built on one frame, "X goes, because Y. Z goes, because W." A list pretending to be speech. Count the items out loud instead: "Number one: think step by step. Gone."',
|
|
70
|
+
example:
|
|
71
|
+
'"The old line goes, because it always thinks. The next one goes, because it already is."',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "called-splice",
|
|
75
|
+
name: "It's called X, and",
|
|
76
|
+
test: /, (?:it'?s|it is|this is|that'?s) called [^,.;]{1,60}, and\b/i,
|
|
77
|
+
rule: 'The name buried mid-sentence between 2 commas, then a second clause bolted on. Give the name its own sentence: "It\'s called prompt-audit."',
|
|
78
|
+
example: '"Anthropic shipped the fix, it\'s called prompt-audit, and it reads your files."',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "shipped-the-fix",
|
|
82
|
+
name: "Shipped the fix",
|
|
83
|
+
test: /\b(?:shipped|released|built|put out|dropped|rolled out) (?:the|a) fix\b/i,
|
|
84
|
+
rule: 'Launch-announcement voice. "The fix" presumes a problem the viewer never agreed to. Name the thing and show it running.',
|
|
85
|
+
example: '"Anthropic shipped the fix inside Claude Code."',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "never-meant",
|
|
89
|
+
name: "Places you never meant",
|
|
90
|
+
test: /\b(?:places|ways|things|spots) you never (?:meant|intended|expected|wanted)\b/i,
|
|
91
|
+
rule: "A vague consequence standing in for a real one. Name the place: which task, which output, what went wrong.",
|
|
92
|
+
example: '"A rule in capitals gets applied in places you never meant it to go."',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "made-sense-ago",
|
|
96
|
+
name: "Made sense a year ago",
|
|
97
|
+
test: /\bmade (?:perfect |total )?sense (?:back then|(?:a|one|two|three|\d+) (?:year|month|week)s? ago)\b/i,
|
|
98
|
+
rule: "A backstory with a date nobody measured. Either give the real date and source, or cut the history and state the current fact.",
|
|
99
|
+
example: '"All the MUSTs in there made sense a year ago."',
|
|
100
|
+
},
|
|
101
|
+
];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Patterns for the setup line before a point and the closer after it. */
|
|
2
|
+
export const patternsSetupsAndClosers = [
|
|
3
|
+
{
|
|
4
|
+
id: "stop-start",
|
|
5
|
+
name: "Stop this, start that",
|
|
6
|
+
// `stop`/`don't` and its answering `start`, across a stop, a comma, an `and`, or a line break. Bounded so it cannot reach across a paragraph and pair two unrelated sentences.
|
|
7
|
+
|
|
8
|
+
// The past tense and the `and` joiner were added 24 Aug 2026, after "So I stopped putting lessons in the room and started putting playbooks in it" shipped into a
|
|
9
|
+
|
|
10
|
+
// scheduled campaign and read clean here: `\bstop\b` does not match `stopped`, and the original required sentence punctuation between the halves. The narrative form is the same slogan wearing a story.
|
|
11
|
+
test: /\b(?:stop(?:ped)?|quit|don'?t|do not)\b[^.!?\n]{0,80}(?:[.!?,;\n]+|\s+and\s+)\s*(?:instead[, ]+)?(?:start(?:ed)?|begin|began)\b/i,
|
|
12
|
+
rule: "A negative imperative answered by its mirror, in either the imperative or the past tense. It is the negation pivot wearing a verb: the first half exists only to set up the swap, and the reader gets a slogan where an instruction or a fact was due. Write the instruction. The thing that stopped is implied by the thing that happens now.",
|
|
13
|
+
example:
|
|
14
|
+
'"stop adding tools. start taking them away." / "don\'t chase people, start building systems." / "I stopped shipping lessons and started shipping playbooks."',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: "imperative-then-watch",
|
|
18
|
+
name: "Do this, watch that",
|
|
19
|
+
// Two imperatives back to back, the second one a spectator verb.
|
|
20
|
+
|
|
21
|
+
// Bounded to one sentence each side so it cannot reach across a paragraph, and the second verb list stays short: "See the reference" is documentation.
|
|
22
|
+
test: /(?:^|[.!?]["'’”)\]]?\s+|\n)(?:#{1,6}[ \t]+)?(?:Ask|Try|Take|Give|Tell|Show|Send|Pull|Type|Paste|Write|Read|Open|Run|Click|Drop|Post|Push|Put|Buy|Hire)\b[^.!?\n]{2,70}[.!?]\s+(?:Now\s+|Then\s+)?(?:[Ww]atch|[Nn]otice|[Oo]bserve)\b[^.!?\n]{2,70}[.!?]/,
|
|
23
|
+
rule: "An order to the reader followed by an order to admire the result. The second sentence states no fact: it tells the reader what to feel about the first, and the pair reads as a trailer for the thing instead of the thing. Write what happens, in one sentence, with a subject.",
|
|
24
|
+
example:
|
|
25
|
+
'"Ask a model for one line. Watch what it pays out instead." / "Run the import. Watch the duplicates disappear."',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "numeric-anaphora",
|
|
29
|
+
name: "Number, number, number",
|
|
30
|
+
// Two or more number-led noun phrases in a row, comma separated.
|
|
31
|
+
|
|
32
|
+
// Bounded to three words a phrase so it cannot reach across a clause and pair two unrelated counts, and to 3 digits a number,
|
|
33
|
+
|
|
34
|
+
// because "15 rue des Halles, 75001 Paris" is a postal address and failed 3 legal pages on the CBAM site, 15 Sep 2026.
|
|
35
|
+
test: /\b(?:one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|\d{1,3})\s+(?:[a-z][a-z-]{2,}\s+){0,2}[a-z][a-z-]{2,},\s+(?:and\s+)?(?:one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|\d{1,3})\s+(?:[a-z][a-z-]{2,}\s+){0,2}[a-z][a-z-]{2,}\b/i,
|
|
36
|
+
rule: "A run of counted noun phrases standing in for a sentence. The numbers make it feel measured while the line states nothing, and the cadence is doing the work a verb should. Write the sentence, or set the counts as a list where the reader can actually scan them.",
|
|
37
|
+
example:
|
|
38
|
+
'"one form, five fields, and the routing behind it." / "three jobs, four questions, twelve answers."',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "faux-insight-setup",
|
|
42
|
+
name: "What nobody tells you",
|
|
43
|
+
// A setup noun ("what", "the part", "the math") handed to an ignorant crowd and a verb of telling.
|
|
44
|
+
|
|
45
|
+
// One-directional: an ordinary "nobody tells me what to do" has no setup noun in front of it and does not match.
|
|
46
|
+
|
|
47
|
+
// `skips` is deliberately absent, because "the pass everyone skips" is a real course term rather than a flourish.
|
|
48
|
+
test: /\b(?:what|the\s+[a-zà-ÿ]+)\s+(?:nobody|no one|hardly anyone|most people|everyone|everybody)\s+(?:tells|warns|shows|mentions|misses|runs|talks about|leaves out|gets wrong)\b/i,
|
|
49
|
+
rule: "A setup clause that casts the writer as the one person who sees it, then delivers an ordinary claim. It needs an implied crowd to be wrong, and it opens on the writer's vantage rather than on the reader's problem. Cut the setup and let the claim carry itself; if the claim cannot stand without the crowd, it was not worth the sentence.",
|
|
50
|
+
example:
|
|
51
|
+
'"Here is what nobody tells you before you upgrade." / "Here is the math nobody runs." / "The part everyone misses: distribution is the moat."',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "removal-closer",
|
|
55
|
+
name: "That is the part we took out",
|
|
56
|
+
// The decidable half of the `deadpan-closer` shape: a demonstrative, a setup noun and a past-tense removal verb.
|
|
57
|
+
|
|
58
|
+
// Ramzi, 11 Sep 2026, on this exact line shipping to the Sitesmiths page: "that is the part we is AI slop".
|
|
59
|
+
test: /\bthat(?:'s|\s+is)\s+the\s+(?:part|bit|piece|step|thing)\s+(?:we|i|they)\s+(?:took|cut|removed|dropped|deleted|killed|skipped)\b/i,
|
|
60
|
+
rule: 'A flat demonstrative parked after a list, pointing back at it instead of stating the new thing. The reader has to hold the list in their head to decode `that`, and the sentence adds no fact. Name what you do: "So we build yours before we ask you for anything."',
|
|
61
|
+
example:
|
|
62
|
+
'"That is the part we took out." / "That\'s the bit we cut." / "That is the step we removed."',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: "where-it-came-from",
|
|
66
|
+
name: "Where the X came from",
|
|
67
|
+
// Heading and topic-sentence shape. `Where` plus a subject plus `came from`
|
|
68
|
+
// or `comes from`, inside one clause.
|
|
69
|
+
test: /\bwhere\s+[^.!?\n]{2,60}\b(?:came|comes|come)\s+from\b/i,
|
|
70
|
+
rule: 'A heading that promises an origin story and then delivers the fact plainly anyway. It buys a beat of suspense the reader did not ask for. Name the fact: "the 104 hours" rather than "where the 104 hours came from".',
|
|
71
|
+
example: '"Where the 104 hours came from" / "Where the gap comes from"',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "hollow-actually",
|
|
75
|
+
name: "That actually",
|
|
76
|
+
// `actually` inside a relative clause, or standing in a heading. Both are pure intensifier: the word is doing the work the noun should.
|
|
77
|
+
|
|
78
|
+
// Bare `actually` elsewhere can be load-bearing (a measured result against a predicted one), so it is deliberately not matched.
|
|
79
|
+
test: /\b(?:that|who|which|people|nobody|somebody)\s+actually\b|^#{1,6}\s+[^\n]*\bactually\b/im,
|
|
80
|
+
rule: "`actually` in a relative clause is the writer insisting rather than the noun earning it. Traffic that actually sells is just traffic that sells, and if the contrast matters, name the thing it beats. In a heading it is always filler.",
|
|
81
|
+
example: '"get traffic that actually sells" / "a thumbnail people actually click"',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Patterns where the wrong thing is the subject: the seller, a page, a tool or a place doing a person's job. */
|
|
2
|
+
export const patternsSubjectVoice = [
|
|
3
|
+
{
|
|
4
|
+
id: "seller-as-proof",
|
|
5
|
+
name: "The same agents we run our agency on",
|
|
6
|
+
test: /\bthe\s+same\s+(?:[\w-]+\s+){1,2}(?:that\s+)?(?:we|I)\s+(?:run|use|built|build)\b|\b(?:we|I)\s+run\s+(?:our|my|[A-Z][\w-]+)\s+(?:own\s+)?(?:[\w-]+\s+)?on\b|\b(?:our|my)\s+own\s+[\w-]+\s+(?:runs?|relies|is\s+built)\s+on\b|\bbuilt\s+(?:them|it)\s+for\s+(?:ourselves|us|[A-Z][\w-]+)\s+first\b|\bqui\s+font\s+tourner\s+notre\b|\bles\s+mêmes\s+(?:[\w'’-]+\s+){1,2}qui\s+font\s+tourner\b|\bconstruits?\s+d'abord\s+pour\b/i,
|
|
7
|
+
rule: 'Copy about the seller where the reader wanted their own result: "the agents we run our agency on" makes us the subject and the proof. Lead with what the client gets, in their numbers, and keep "we use it too" for a proof section, if anywhere. Ramzi, 30 Sep 2026, on his own agency\'s hero: "do not be focused about us, be focused on the client."',
|
|
8
|
+
example:
|
|
9
|
+
'"The same agents we run Acme on." / "The AI agents we run our agency on." / "the AI agents our own agency runs on" / "We built them for Acme first" / "Les mêmes agents qui font tourner Acme"',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "unasked-reassurance",
|
|
13
|
+
name: "The studio's own interface never changes",
|
|
14
|
+
test: /\b(?:its|our|the\s+[\w-]+'s|the\s+(?:tool|app|studio|page|site))\s+own\s+(?:interface|ui|chrome|look|design|styles?|colou?rs?)\s+(?:never|doesn't|does\s+not|won't|will\s+not|stays?|remains?)\b|\b(?:never|doesn't|does\s+not|won't|will\s+not)\s+(?:changes?|moves?|restyles?|touch(?:es)?|affects?)\s+(?:with|along\s+with)\s+(?:it|them|this|that|yours?)\b/i,
|
|
15
|
+
rule: 'A line spent on what does NOT happen, answering a worry the reader never had. It costs a sentence and plants the doubt it denies. Cut it, or say what the thing does. Ramzi, 28 Sep 2026, on the Editor OS brand page: "This is slop."',
|
|
16
|
+
example:
|
|
17
|
+
'"The palette your videos are drawn in. The studio\'s own interface never changes with it." / "It never changes with your brand"',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "the-one-x-everyone-y",
|
|
21
|
+
name: "The one map every agent reads",
|
|
22
|
+
test: /\bone\s+(?:[a-z./-]+\s+){1,2}(?:that\s+)?(?:every|each)\s+[a-z-]+\s+(?:reads?|uses?|needs?|looks?(?:\s+(?:at|up))?|checks?|knows?|shares?|sees?|opens?|follows?|runs?|works?\s+from|starts?\s+from)\b/i,
|
|
23
|
+
rule: 'The superlative-plus-universal line: "the one X every Y reads". It sounds like a definition and says nothing a reader can check, and it is the shape a diagram label takes when nobody stopped to say what the thing is. Say what it holds or what it does: "the file that lists your lists and statuses". Ramzi, 29 Sep 2026, on the ClickUp Agent Kit board: "the one xxx every xxx is AI slop."',
|
|
24
|
+
example:
|
|
25
|
+
'"the one map every agent reads" / "one file every tool reads" / "the one thing every founder needs"',
|
|
26
|
+
},
|
|
27
|
+
// The next 2 are Ramzi's, 23 Sep 2026, on course copy that passed this gate.
|
|
28
|
+
{
|
|
29
|
+
id: "object-as-agent",
|
|
30
|
+
name: "The page carries a fact",
|
|
31
|
+
test: /\b(?:page|row|file|task|field|lesson|card|list|slide|number|course|post|step|folder|doc|document|template|space|view|bucket|section)s?\s+(?:all\s+)?(?:carries|carry|holds|hold|owns|own|earns|earn|hands|gives|(?:lives|live|sits|sit)\s+(?:in|on|under|inside))\b|\bgive\s+(?:each|every|the|a)\s+(?:page|row|file|task|card|slide|post)\s+(?:one|a|1)\s+(?:fact|number|thing|claim|proof)\b/i,
|
|
32
|
+
rule: 'A thing doing what only a person does: a page carries, a number lives, a task sits, a row owns. It is a metaphor passed off as a statement, and it hides who acts. Say who does what, as a bare imperative: "Put one thing on each page that only you know", "Put every task in a BATCH bucket".',
|
|
33
|
+
example:
|
|
34
|
+
'"Every page carries one fact only you can supply" / "All the numbers live in 1 file" / "Open tasks all sit in a BATCH bucket" / "Give each page one fact only you can supply"',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "abstract-as-agent",
|
|
38
|
+
name: "This course gets ClickUp set up",
|
|
39
|
+
test: /\b(?:the|this|that|these|your|our|each|every|one|1)\s+(?:[a-z-]+\s+)?(?:course|lesson|module|prompt|guide|video|workshop|skill|playbook|framework|method|system|workspace|week|first|second|latter|former)s?\s+(?:(?:that|which)\s+)?(?:shows|teaches|walks|builds|reads|writes|plans|picks|finds|sets up|hands|helps|lets|runs|makes|turns|keeps|tells|does|handles|delivers|gets (?:you|your|it|them)|takes (?:you|them|your))\b/i,
|
|
40
|
+
rule: 'An abstract thing doing the reader\'s job: the course sets it up, the week runs, the prompt builds. The reader does the work, so make them the subject, as an order: "Set up your ClickUp with this course", "Use The Project Manager skill to plan your week in it". Ramzi, 23 Sep 2026.',
|
|
41
|
+
example:
|
|
42
|
+
'"This course gets your ClickUp set up" / "the week runs inside it" / "This lesson hands you 1 prompt"',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "place-as-person",
|
|
46
|
+
name: "See what the room is working on",
|
|
47
|
+
test: /\b(?:the|this|that|your|our|my)\s+(?:room|community|group|classroom|channel|space|school|newsletter|forum|list)\s+(?:is\s+|are\s+|was\s+|has\s+been\s+)?(?:working on|thinking|building|doing|talking about|discussing|saying|asking|wants|needs|shipping|learning|feels|believes|knows|decides)\b/i,
|
|
48
|
+
rule: 'A place doing a person\'s job: a room does not work, a community does not think. Name the people and what they did: "Read what members posted this week". Ramzi, 23 Sep 2026: "A room does not work. It\'s not a person."',
|
|
49
|
+
example: '"See what the room is working on" / "what the community is building"',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "thing-as-person",
|
|
53
|
+
name: "Automations that save you the afternoon",
|
|
54
|
+
// After "of a", the noun belongs to the one before it: "a review of an app complains" has the review complaining.
|
|
55
|
+
test: /(?<!\bof\s+(?:an?|the|this|that|its|their|your|our)\s+)\b(?:automations?|tools?|apps?|software|agents?|AI|bots?|dashboards?|systems?|process(?:es)?|templates?|workflows?|integrations?|boards?|scripts?|platforms?|CRMs?|inbox(?:es)?|calendars?|method|structure|views?)\s+(?:that\s+|which\s+|will\s+|can\s+|should\s+|finally\s+)?(?:saves?|gives?\s+(?:you|your|them|back)|frees\b|free\s+(?:you|up)|buys?\s+(?:you|back)|remembers?|notices?|decides?|thinks?|knows?|cares?|wants?|worr(?:y|ies)|forgets?|looks?\s+after|takes?\s+care\s+of|understands?|chases?|nags?|complains?|whines?|screams?|yells?|shouts?|begs?|sulks?|panics?|fears?|hates?|loves?)\b/i,
|
|
56
|
+
rule: 'A tool doing a person\'s job: an automation saves an afternoon, a dashboard knows, a system cares. It is a slogan, not a fact. Say what the tool does mechanically, or make the reader the subject: "Each one removes a decision somebody made by hand", "Get the afternoon back". Ramzi, 23 Sep 2026: "automations cannot save an afternoon. They are not a person."',
|
|
57
|
+
example: '"Automations that save you the afternoon" / "the dashboard knows who is late"',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "best-is-the-one",
|
|
61
|
+
name: "The best automation is the one that complains",
|
|
62
|
+
test: /\b[Tt]he\s+(?:best|worst|only|safest|cheapest|fastest|strongest|smartest|(?:most|least)\s+[a-z]+)\s+[a-z][\w'’-]*(?:\s+[\w'’-]+){0,5}?\s+(?:is|are|was)\s+the\s+ones?\s+(?:that|who|which|you|nobody|no\s+one)\b/,
|
|
63
|
+
rule: 'A superlative that crowns "the one that": the best automation is the one that complains, the best client is the one who leaves. It\'s a fortune cookie. The reader nods, then learns nothing they can check, and it often hides a tool acting like a person. Say the fact under it: "Set the automation to email you when a run fails, so a silent stop shows up the same day." Ramzi, 6 Oct 2026, on a LinkedIn draft graded A+: "using an automation as a human... it\'s an anti-pattern."',
|
|
64
|
+
example:
|
|
65
|
+
'"The best automation you own is the one that complains" / "The best client is the one who says no"',
|
|
66
|
+
},
|
|
67
|
+
];
|