taste-lint 0.0.1

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.
Files changed (138) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +141 -0
  3. package/data/config.schema.json +123 -0
  4. package/data/corpus/blode-co-review.jsonl +80 -0
  5. package/data/corpus/copywriting.jsonl +139 -0
  6. package/data/corpus/typography.jsonl +53 -0
  7. package/data/rule-drafts/README.md +9 -0
  8. package/data/rule-drafts/interaction/interaction-layout-shift.yaml +54 -0
  9. package/data/rule-drafts/typography/typography-long-content-safety.yaml +60 -0
  10. package/data/rules/authoring/authoring-approval-every-step.yaml +44 -0
  11. package/data/rules/authoring/authoring-fixed-agent-quota.yaml +44 -0
  12. package/data/rules/authoring/authoring-generic-coding-advice.yaml +44 -0
  13. package/data/rules/authoring/authoring-generic-verification.yaml +45 -0
  14. package/data/rules/authoring/authoring-plan-vague-acceptance.yaml +43 -0
  15. package/data/rules/copywriting/copywriting-announced-honesty.yaml +43 -0
  16. package/data/rules/copywriting/copywriting-anthropomorphism.yaml +29 -0
  17. package/data/rules/copywriting/copywriting-artificial-balance.yaml +35 -0
  18. package/data/rules/copywriting/copywriting-bare-confirm-label.yaml +23 -0
  19. package/data/rules/copywriting/copywriting-boilerplate-offer.yaml +38 -0
  20. package/data/rules/copywriting/copywriting-canned-phrasing.yaml +53 -0
  21. package/data/rules/copywriting/copywriting-changed-supplied-facts.yaml +31 -0
  22. package/data/rules/copywriting/copywriting-claim-without-evidence.yaml +59 -0
  23. package/data/rules/copywriting/copywriting-click-here-links.yaml +22 -0
  24. package/data/rules/copywriting/copywriting-conditions-first.yaml +50 -0
  25. package/data/rules/copywriting/copywriting-confirmshaming.yaml +43 -0
  26. package/data/rules/copywriting/copywriting-cta-names-outcome.yaml +54 -0
  27. package/data/rules/copywriting/copywriting-dead-weight-hedges.yaml +58 -0
  28. package/data/rules/copywriting/copywriting-drafting-instruction-echo.yaml +31 -0
  29. package/data/rules/copywriting/copywriting-emoji-in-ui.yaml +20 -0
  30. package/data/rules/copywriting/copywriting-empty-state-no-action.yaml +51 -0
  31. package/data/rules/copywriting/copywriting-error-descriptions.yaml +53 -0
  32. package/data/rules/copywriting/copywriting-excessive-hedging.yaml +48 -0
  33. package/data/rules/copywriting/copywriting-fabricated-specificity.yaml +35 -0
  34. package/data/rules/copywriting/copywriting-filler-words.yaml +55 -0
  35. package/data/rules/copywriting/copywriting-flat-description.yaml +37 -0
  36. package/data/rules/copywriting/copywriting-friction-cta.yaml +53 -0
  37. package/data/rules/copywriting/copywriting-generic-audience.yaml +55 -0
  38. package/data/rules/copywriting/copywriting-generic-framing.yaml +35 -0
  39. package/data/rules/copywriting/copywriting-generic-language.yaml +35 -0
  40. package/data/rules/copywriting/copywriting-generic-validation.yaml +46 -0
  41. package/data/rules/copywriting/copywriting-idea-repetition.yaml +34 -0
  42. package/data/rules/copywriting/copywriting-latinisms.yaml +25 -0
  43. package/data/rules/copywriting/copywriting-leaked-error-message.yaml +23 -0
  44. package/data/rules/copywriting/copywriting-live-region-feedback.yaml +24 -0
  45. package/data/rules/copywriting/copywriting-machine-prose.yaml +73 -0
  46. package/data/rules/copywriting/copywriting-mechanism-over-outcome.yaml +33 -0
  47. package/data/rules/copywriting/copywriting-meta-commentary.yaml +48 -0
  48. package/data/rules/copywriting/copywriting-missing-reasoning-link.yaml +33 -0
  49. package/data/rules/copywriting/copywriting-nominalisations.yaml +45 -0
  50. package/data/rules/copywriting/copywriting-over-explanation.yaml +34 -0
  51. package/data/rules/copywriting/copywriting-passive-voice.yaml +53 -0
  52. package/data/rules/copywriting/copywriting-permission-benefit.yaml +43 -0
  53. package/data/rules/copywriting/copywriting-profile-register-mismatch.yaml +31 -0
  54. package/data/rules/copywriting/copywriting-promotional-docs-voice.yaml +58 -0
  55. package/data/rules/copywriting/copywriting-prompt-restatement.yaml +35 -0
  56. package/data/rules/copywriting/copywriting-punctuation-tics.yaml +35 -0
  57. package/data/rules/copywriting/copywriting-reader-first.yaml +59 -0
  58. package/data/rules/copywriting/copywriting-register-shift.yaml +58 -0
  59. package/data/rules/copywriting/copywriting-repetitive-transitions.yaml +48 -0
  60. package/data/rules/copywriting/copywriting-requirements-language.yaml +50 -0
  61. package/data/rules/copywriting/copywriting-searchable-headings.yaml +52 -0
  62. package/data/rules/copywriting/copywriting-semantic-links.yaml +23 -0
  63. package/data/rules/copywriting/copywriting-structural-symmetry.yaml +35 -0
  64. package/data/rules/copywriting/copywriting-success-state-specific.yaml +43 -0
  65. package/data/rules/copywriting/copywriting-temporal-words.yaml +55 -0
  66. package/data/rules/copywriting/copywriting-toast-successfully.yaml +22 -0
  67. package/data/rules/copywriting/copywriting-unexplained-action.yaml +33 -0
  68. package/data/rules/copywriting/copywriting-unnatural-polish.yaml +48 -0
  69. package/data/rules/copywriting/copywriting-unraised-objection.yaml +43 -0
  70. package/data/rules/copywriting/copywriting-unverifiable-proof.yaml +23 -0
  71. package/data/rules/copywriting/copywriting-vague-error.yaml +58 -0
  72. package/data/rules/copywriting/copywriting-vague-personal-request.yaml +43 -0
  73. package/data/rules/copywriting/copywriting-visual-direction-instruction.yaml +43 -0
  74. package/data/rules/craft/craft-affordance-mismatch.yaml +23 -0
  75. package/data/rules/craft/craft-decoration-no-role.yaml +27 -0
  76. package/data/rules/craft/craft-faux-product-chrome.yaml +22 -0
  77. package/data/rules/craft/craft-hover-only-affordance.yaml +23 -0
  78. package/data/rules/craft/craft-i18n-rtl-untested.yaml +23 -0
  79. package/data/rules/craft/craft-i18n-untested.yaml +28 -0
  80. package/data/rules/craft/craft-image-dimensions-and-priority.yaml +23 -0
  81. package/data/rules/craft/craft-inline-styles.yaml +24 -0
  82. package/data/rules/craft/craft-lazy-load-offscreen.yaml +28 -0
  83. package/data/rules/craft/craft-near-duplicate-scale.yaml +29 -0
  84. package/data/rules/craft/craft-token-drift.yaml +22 -0
  85. package/data/rules/craft/craft-viewport-scaling.yaml +25 -0
  86. package/data/rules/craft/craft-virtualize-large-lists.yaml +24 -0
  87. package/data/rules/interaction/interaction-a11y-color-only-meaning.yaml +23 -0
  88. package/data/rules/interaction/interaction-a11y-data-table-semantics.yaml +24 -0
  89. package/data/rules/interaction/interaction-a11y-disabled-control-tooltip.yaml +23 -0
  90. package/data/rules/interaction/interaction-a11y-document-language.yaml +24 -0
  91. package/data/rules/interaction/interaction-a11y-icon-controls-labeled.yaml +23 -0
  92. package/data/rules/interaction/interaction-a11y-image-alt-text.yaml +24 -0
  93. package/data/rules/interaction/interaction-a11y-media-captions.yaml +24 -0
  94. package/data/rules/interaction/interaction-a11y-semantic-html-first.yaml +23 -0
  95. package/data/rules/interaction/interaction-a11y-skip-link-heading-order.yaml +24 -0
  96. package/data/rules/interaction/interaction-a11y-tooltip-no-interactive.yaml +23 -0
  97. package/data/rules/interaction/interaction-broken-focus-trap.yaml +25 -0
  98. package/data/rules/interaction/interaction-dont-block-paste-ime.yaml +23 -0
  99. package/data/rules/interaction/interaction-error-association.yaml +24 -0
  100. package/data/rules/interaction/interaction-focus-visible.yaml +25 -0
  101. package/data/rules/interaction/interaction-inline-errors-first-focus.yaml +24 -0
  102. package/data/rules/interaction/interaction-input-affix-hit-target.yaml +23 -0
  103. package/data/rules/interaction/interaction-keyboard-operable.yaml +23 -0
  104. package/data/rules/interaction/interaction-labels-and-autocomplete.yaml +23 -0
  105. package/data/rules/interaction/interaction-lost-data-on-error.yaml +23 -0
  106. package/data/rules/interaction/interaction-mobile-input-font-size.yaml +24 -0
  107. package/data/rules/interaction/interaction-no-disable-while-submitting.yaml +23 -0
  108. package/data/rules/interaction/interaction-no-empty-state.yaml +26 -0
  109. package/data/rules/interaction/interaction-no-error-boundary.yaml +27 -0
  110. package/data/rules/interaction/interaction-no-error-state.yaml +26 -0
  111. package/data/rules/interaction/interaction-no-suspense-boundary.yaml +23 -0
  112. package/data/rules/interaction/interaction-not-restored.yaml +25 -0
  113. package/data/rules/interaction/interaction-on-dynamic-content.yaml +25 -0
  114. package/data/rules/interaction/interaction-optimistic-without-rollback.yaml +23 -0
  115. package/data/rules/interaction/interaction-out-of-order-responses.yaml +27 -0
  116. package/data/rules/interaction/interaction-target-size.yaml +26 -0
  117. package/data/rules/interaction/interaction-use-form-status-misuse.yaml +23 -0
  118. package/data/rules/product/product-nested-modals.yaml +26 -0
  119. package/data/rules/product/product-select-for-few-options.yaml +24 -0
  120. package/data/rules/schema/rule.schema.json +262 -0
  121. package/data/rules/tuning.json +1 -0
  122. package/data/rules/typography/typography-dashes.yaml +28 -0
  123. package/data/rules/typography/typography-ellipsis.yaml +27 -0
  124. package/data/rules/typography/typography-hover-weight-shift.yaml +24 -0
  125. package/data/rules/typography/typography-midpoint-separators.yaml +21 -0
  126. package/data/rules/typography/typography-multiplication-sign.yaml +27 -0
  127. package/data/rules/typography/typography-nbsp-value-unit.yaml +27 -0
  128. package/data/rules/typography/typography-readable-scale.yaml +23 -0
  129. package/data/rules/typography/typography-straight-quotes.yaml +37 -0
  130. package/data/rules/typography/typography-title-case-heading.yaml +49 -0
  131. package/dist/cli.d.ts +2 -0
  132. package/dist/cli.js +6317 -0
  133. package/dist/cli.js.map +1 -0
  134. package/dist/index.d.ts +736 -0
  135. package/dist/index.d.ts.map +1 -0
  136. package/dist/index.js +5330 -0
  137. package/dist/index.js.map +1 -0
  138. package/package.json +87 -0
@@ -0,0 +1,35 @@
1
+ # One of the 21 AI-writing checks Every ran with Jev (Mike Taylor, "Jev judged
2
+ # everything I've written in 0.7 seconds", 15 Sep 2026). The question is the
3
+ # published wording; the second sentence says what to ignore.
4
+ # Candidate list from EveryInc/compound-writing skills/cw-ai-check/SKILL.md, lexicon rows on sentence patterns.
5
+ id: copywriting-punctuation-tics
6
+ title: Overuses dashes, colons or parenthetical asides in a patterned way
7
+ categoryId: machine-prose
8
+ source:
9
+ repo: every.to
10
+ path: https://typesafe-parallel-judgment-lab.every-4573.chatgpt.site/downloads/typesafe-lab-source.zip (scripts/run-ai-checker.mjs)
11
+ line: 1
12
+ ruleId: punctuation_tics
13
+ unit: [paragraph]
14
+ question:
15
+ context: [docType]
16
+ instructions: >-
17
+ Does the writing overuse em dashes, colons, or parenthetical asides in a patterned way? Ignore a single aside, and punctuation inside code or quoted material.
18
+ criteria:
19
+ true:
20
+ what: A dash, colon or parenthesis in nearly every sentence, each doing the same job.
21
+ examples:
22
+ - "The plan was simple (or so we thought): ship fast, learn faster (and cheaper), then scale: the usual story."
23
+ - "Design is a conversation: with the user, with the material (and with the budget), with the past."
24
+ false:
25
+ what: Punctuation that varies with the sentence.
26
+ examples:
27
+ - "We planned to ship fast and learn from the first hundred users. It took three months longer than that."
28
+ - "Design is a conversation with the user. The budget joins it later, usually uninvited."
29
+ thresholds: { review: 0.4, act: 0.75 }
30
+ severity: minor
31
+ fix:
32
+ hint: >-
33
+ Rewrite two of the asides as sentences. Keep the one that earns its place.
34
+ status: review-only
35
+ handWritten: [question, fix, thresholds]
@@ -0,0 +1,59 @@
1
+ # Sourced from mblode/taste-training headline-analyzer.tsx (WHAT signals) and the lesson
2
+ # lead-with-the-readers-world.mdx (Why, How, What).
3
+ id: copywriting-reader-first
4
+ title: Headline that leads with what the product is
5
+ categoryId: reader-first-framing
6
+ source:
7
+ {
8
+ repo: mblode/taste-training,
9
+ path: apps/web/components/demos/copywriting/headline-analyzer.tsx,
10
+ line: 58,
11
+ }
12
+ unit: [heading, jsx-text]
13
+ mechanical:
14
+ phrases:
15
+ [
16
+ platform,
17
+ software,
18
+ solution,
19
+ suite,
20
+ all-in-one,
21
+ introducing,
22
+ meet,
23
+ is a,
24
+ is the,
25
+ is an,
26
+ we built,
27
+ we made,
28
+ the tool,
29
+ a tool,
30
+ ]
31
+ question:
32
+ context: [docType, headingAbove]
33
+ instructions: >-
34
+ The TEXT is a headline or hero line on a page selling or introducing a product. Return true when it opens by naming what the product is (a platform, a tool, a solution, "Introducing X") before saying why that matters to the reader. Return false when it leads with the reader's problem or outcome, when the DOC TYPE is documentation, reference or a lesson where naming the thing first is correct, or when it is not a headline.
35
+ criteria:
36
+ true:
37
+ what: What-first headline.
38
+ examples:
39
+ - "Introducing Northwind, the all-in-one platform for modern teams"
40
+ - "A collaboration tool for growing companies"
41
+ false:
42
+ what: Why-first, or a context where What belongs first.
43
+ examples:
44
+ - "Roll any file back to how it was an hour ago"
45
+ - "Stop losing Friday afternoons to merge cleanup"
46
+ - "The systemOne endpoint accepts state and questions"
47
+ thresholds: { review: 0.4, act: 0.75 }
48
+ severity: minor
49
+ fix:
50
+ hint: >-
51
+ Climb the ladder: why this matters to the reader, then how, then what. Let What lead only where the reader already holds the motivation.
52
+ preconditions:
53
+ {
54
+ notInCode: true,
55
+ role: [heading],
56
+ docType: [marketing, ui, unknown, lesson],
57
+ }
58
+ status: review-only
59
+ handWritten: [mechanical, question, fix, thresholds, preconditions]
@@ -0,0 +1,58 @@
1
+ # Sourced from mblode/taste-training sweep-runner.tsx (sweep 2, Voice).
2
+ id: copywriting-register-shift
3
+ title: Formal or slangy register breaking the product voice
4
+ categoryId: machine-prose
5
+ source:
6
+ {
7
+ repo: mblode/taste-training,
8
+ path: apps/web/components/demos/copywriting/sweep-runner.tsx,
9
+ line: 84,
10
+ }
11
+ unit: [paragraph, heading, jsx-text]
12
+ mechanical:
13
+ phrases:
14
+ [
15
+ we are pleased to,
16
+ we're stoked,
17
+ furthermore,
18
+ moreover,
19
+ gonna,
20
+ ain't,
21
+ henceforth,
22
+ thus,
23
+ utilize,
24
+ utilise,
25
+ herein,
26
+ aforementioned,
27
+ kindly,
28
+ per our,
29
+ whilst,
30
+ ]
31
+ question:
32
+ context: []
33
+ instructions: >-
34
+ Read the TEXT as product or documentation copy. Return true when a word or phrase belongs to a clearly different register from plain spoken English: academic connectors (furthermore, moreover, thus), legal or corporate formality (henceforth, we are pleased to, kindly, utilize), or slang (gonna, stoked). Return false when the TEXT is consistently plain, when the formal word is a technical term with no plain equivalent, or when the TEXT quotes or teaches about register.
35
+ criteria:
36
+ true:
37
+ what: A register shift inside otherwise plain copy.
38
+ examples:
39
+ - "Furthermore, we are pleased to announce dark mode."
40
+ - "Utilize the dashboard to facilitate deployment."
41
+ - "We're stoked to have you. Henceforth your data syncs automatically."
42
+ false:
43
+ what: One plain register throughout, or discussion of the words.
44
+ examples:
45
+ - "Dark mode is here. Turn it on in Settings."
46
+ - "Use the dashboard to start your deployment."
47
+ - "Academic connectors like moreover signal a tone shift."
48
+ severity: minor
49
+ fix:
50
+ hint: Rewrite in the voice the rest of the page uses. Use "use" not "utilize", "so" not "thus", and drop the corporate opener.
51
+ preconditions:
52
+ {
53
+ notInCode: true,
54
+ docType:
55
+ [tutorial, howto, reference, explanation, lesson, marketing, ui, unknown],
56
+ }
57
+ status: review-only
58
+ handWritten: [mechanical, question, fix]
@@ -0,0 +1,48 @@
1
+ # One of the 21 AI-writing checks Every ran with Jev (Mike Taylor, "Jev judged
2
+ # everything I've written in 0.7 seconds", 15 Sep 2026). The question is the
3
+ # published wording; the second sentence says what to ignore.
4
+ # Candidate list from EveryInc/compound-writing skills/cw-ai-check/SKILL.md, category 7 (formal transitions).
5
+ id: copywriting-repetitive-transitions
6
+ title: Repeatedly uses formal or formulaic transitions
7
+ categoryId: machine-prose
8
+ source:
9
+ repo: every.to
10
+ path: https://typesafe-parallel-judgment-lab.every-4573.chatgpt.site/downloads/typesafe-lab-source.zip (scripts/run-ai-checker.mjs)
11
+ line: 1
12
+ ruleId: repetitive_transitions
13
+ unit: [paragraph]
14
+ mechanical:
15
+ phrases:
16
+ - moreover
17
+ - furthermore
18
+ - additionally
19
+ - consequently
20
+ - thus
21
+ - hence
22
+ - in addition
23
+ - in conclusion
24
+ - to summarize
25
+ - ultimately
26
+ minMatches: 2
27
+ question:
28
+ context: [docType]
29
+ instructions: >-
30
+ Does the writing repeatedly use formal or formulaic transitions? Ignore a single transition, and a passage whose sentences follow from each other without the connective.
31
+ criteria:
32
+ true:
33
+ what: Transitions doing the work the sentences should.
34
+ examples:
35
+ - "Moreover, the design is consistent. Furthermore, it is accessible. Additionally, it loads quickly. Consequently, users prefer it."
36
+ - "Thus the migration succeeded. Hence the team moved on. Moreover, morale improved."
37
+ false:
38
+ what: Sentences that connect by their content.
39
+ examples:
40
+ - "The design is consistent and loads quickly, which is why users kept choosing it over the old one in the test."
41
+ - "The migration finished a week early. The team spent that week on the flaky test suite instead."
42
+ thresholds: { review: 0.4, act: 0.75 }
43
+ severity: minor
44
+ fix:
45
+ hint: >-
46
+ Cut the connective and let the order of the sentences carry the logic.
47
+ status: review-only
48
+ handWritten: [question, fix, thresholds, mechanical]
@@ -0,0 +1,50 @@
1
+ id: copywriting-requirements-language
2
+ title: A requirement presented as a recommendation
3
+ categoryId: reader-first-framing
4
+ source:
5
+ repo: mblode/agent-skills
6
+ path: skills/docs-writing/rules/voice-requirements-language.md
7
+ line: 7
8
+ ruleId: voice-requirements-language
9
+ unit:
10
+ - paragraph
11
+ mechanical:
12
+ regex: \bshould\b
13
+ flags: giu
14
+ question:
15
+ context:
16
+ - docType
17
+ - headingAbove
18
+ instructions: The TEXT is technical documentation. Return true only when it uses should for a requirement and the supplied text explicitly establishes that skipping it causes failure, rejection, data loss, or an irreversible unsafe operation. Do not infer undocumented requirements from technical knowledge. Return false for optional recommendations, expected behavior, quoted wording, style discussions, or insufficient evidence of necessity.
19
+ criteria:
20
+ "true":
21
+ what: Explicitly mandatory behavior weakened to should.
22
+ examples:
23
+ - You should supply an API key; requests without one are rejected.
24
+ - You should back up the database before upgrading; the upgrade permanently deletes the old tables.
25
+ "false":
26
+ what: A recommendation, expectation, direct requirement, or necessity not established locally.
27
+ examples:
28
+ - You should set a longer timeout on slow networks.
29
+ - The request should finish within a second.
30
+ - You must supply an API key; requests without one are rejected.
31
+ severity: minor
32
+ fix:
33
+ hint: Use must or a direct imperative when the text establishes a requirement. Keep should for recommendations and expectations.
34
+ preconditions:
35
+ notInCode: true
36
+ docType:
37
+ - tutorial
38
+ - howto
39
+ - reference
40
+ - explanation
41
+ - agent-instructions
42
+ status: review-only
43
+ handWritten:
44
+ - title
45
+ - unit
46
+ - mechanical
47
+ - question
48
+ - fix
49
+ - preconditions
50
+ - severity
@@ -0,0 +1,52 @@
1
+ id: copywriting-searchable-headings
2
+ title: A documentation heading names no topic or action
3
+ categoryId: page-structure
4
+ source:
5
+ repo: mblode/agent-skills
6
+ path: skills/docs-writing/rules/nav-searchable-headings.md
7
+ line: 7
8
+ ruleId: nav-searchable-headings
9
+ unit:
10
+ - heading
11
+ mechanical:
12
+ regex: ^(?:common (?:issues|problems)|more (?:info(?:rmation)?|details)|overview|miscellaneous|other)\s*[.:?]?$
13
+ flags: giu
14
+ question:
15
+ context:
16
+ - docType
17
+ - headingAbove
18
+ instructions: The TEXT is a documentation heading. Return true when it is generic and names neither the feature nor the task, such as Common issues or More information. Return false when the supplied heading context gives it a clear specific subject, when it names a concrete topic or action, or when it quotes a heading as an example. Do not assume unseen page context.
19
+ criteria:
20
+ "true":
21
+ what: A generic heading with no specific subject in the supplied context.
22
+ examples:
23
+ - Common issues
24
+ - More information
25
+ "false":
26
+ what: Specific topic or action, or a generic subheading with explicit subject context.
27
+ examples:
28
+ - Troubleshoot authentication errors
29
+ - Configure rate limits
30
+ - |-
31
+ TEXT: Overview
32
+ HEADING: Webhook retries
33
+ severity: minor
34
+ fix:
35
+ hint: Name the feature or reader task, for example Troubleshoot authentication errors. Keep a short subheading when its parent already supplies the subject.
36
+ preconditions:
37
+ notInCode: true
38
+ docType:
39
+ - tutorial
40
+ - howto
41
+ - reference
42
+ - explanation
43
+ - agent-instructions
44
+ status: review-only
45
+ handWritten:
46
+ - title
47
+ - unit
48
+ - mechanical
49
+ - question
50
+ - fix
51
+ - preconditions
52
+ - severity
@@ -0,0 +1,23 @@
1
+ # Ported from mblode/agent-skills skills/ui-design/rules/nav-semantic-links.md by scripts/port-rules.ts.
2
+ # Keys listed in handWritten are preserved on re-run; everything else is regenerated.
3
+ id: copywriting-semantic-links
4
+ title: Use Semantic Links for Navigation
5
+ categoryId: page-structure
6
+ source:
7
+ line: 9
8
+ path: skills/ui-design/rules/nav-semantic-links.md
9
+ repo: mblode/agent-skills
10
+ ruleId: nav-semantic-links
11
+ scope:
12
+ include:
13
+ - "**/*.tsx"
14
+ - "**/*.jsx"
15
+ unit:
16
+ - source
17
+ mechanical:
18
+ flags: gus
19
+ regex: <(div|span|li)\b[^>]*\bonClick=\{[^}]*(router\.push|navigate\(|location\.href)
20
+ severity: minor
21
+ fix:
22
+ hint: Navigation should use `<a>` or framework `<Link>`, not click handlers on generic elements. A click handler on a div loses middle-click, open-in-new-tab, copy-link, and the browser's own back behaviour.
23
+ status: review-only
@@ -0,0 +1,35 @@
1
+ # One of the 21 AI-writing checks Every ran with Jev (Mike Taylor, "Jev judged
2
+ # everything I've written in 0.7 seconds", 15 Sep 2026). The question is the
3
+ # published wording; the second sentence says what to ignore.
4
+ # Candidate list from EveryInc/compound-writing skills/cw-ai-check/SKILL.md, category 9 (formulaic structure).
5
+ id: copywriting-structural-symmetry
6
+ title: Excessive structural symmetry or formulaic organisation
7
+ categoryId: machine-prose
8
+ source:
9
+ repo: every.to
10
+ path: https://typesafe-parallel-judgment-lab.every-4573.chatgpt.site/downloads/typesafe-lab-source.zip (scripts/run-ai-checker.mjs)
11
+ line: 1
12
+ ruleId: structural_symmetry
13
+ unit: [paragraph]
14
+ question:
15
+ context: [docType]
16
+ instructions: >-
17
+ Does the writing exhibit excessive structural symmetry or formulaic organization? Ignore a short list whose items are parallel by nature (steps, options) and any passage under three sentences.
18
+ criteria:
19
+ true:
20
+ what: Sentences or clauses built to the same template, in matched lengths, with a tidy three-part rhythm.
21
+ examples:
22
+ - "First, we gathered the data. Second, we cleaned the data. Third, we analysed the data. Each step mattered, each step took time, each step taught us something."
23
+ - "It is not about speed. It is about trust. It is not about features. It is about outcomes."
24
+ false:
25
+ what: Structure that follows the argument, uneven where the material is uneven.
26
+ examples:
27
+ - "We spent two days cleaning the export because half the dates were in US format; the analysis itself took an afternoon."
28
+ - "The rewrite shipped in March. Support tickets about the settings page fell from 40 a week to 6, and stayed there."
29
+ thresholds: { review: 0.4, act: 0.75 }
30
+ severity: minor
31
+ fix:
32
+ hint: >-
33
+ Let the shape follow the material: one long sentence where the point needs it, one short one where it does not.
34
+ status: review-only
35
+ handWritten: [question, fix, thresholds]
@@ -0,0 +1,43 @@
1
+ id: copywriting-success-state-specific
2
+ title: Success message does not name the completed operation
3
+ categoryId: actionable-microcopy
4
+ source:
5
+ repo: installed/copywriting
6
+ path: skills/copywriting/references/ui-states.md
7
+ line: 1
8
+ unit:
9
+ - paragraph
10
+ - jsx-text
11
+ - attr-string
12
+ mechanical:
13
+ regex: "^(?:success[!.]?|operation completed(?: successfully)?[!.]?|done[!.]?)$"
14
+ flags: giu
15
+ question:
16
+ context:
17
+ - docType
18
+ - headingAbove
19
+ - role
20
+ - element
21
+ instructions: The text is UI copy. Return true if it is a standalone success notification that says nothing about what completed. Return false for a control label, a named state, quoted examples, or when the supplied heading identifies the completed operation. Do not infer the notification role from a single ambiguous word.
22
+ criteria:
23
+ "true":
24
+ what: The stated failure is supported by the supplied text.
25
+ examples:
26
+ - Operation completed successfully!
27
+ "false":
28
+ what: The text is specific, justified, quoted, or outside this rule.
29
+ examples:
30
+ - Changes saved.
31
+ severity: minor
32
+ fix:
33
+ hint: Name what completed, proportional to the action.
34
+ preconditions:
35
+ notInCode: true
36
+ docType:
37
+ - ui
38
+ status: review-only
39
+ handWritten:
40
+ - mechanical
41
+ - question
42
+ - preconditions
43
+ - fix
@@ -0,0 +1,55 @@
1
+ # Ported from mblode/agent-skills skills/docs-writing/rules/hygiene-no-temporal.md and
2
+ # rules/hygiene-update-metadata.md.
3
+ id: copywriting-temporal-words
4
+ title: Wording anchored to the time of writing
5
+ categoryId: reference-reading
6
+ source:
7
+ {
8
+ repo: mblode/agent-skills,
9
+ path: skills/docs-writing/rules/hygiene-no-temporal.md,
10
+ line: 7,
11
+ }
12
+ unit: [paragraph, heading]
13
+ mechanical:
14
+ phrases:
15
+ [
16
+ currently,
17
+ recently,
18
+ at the moment,
19
+ coming soon,
20
+ in the near future,
21
+ as of today,
22
+ latest version,
23
+ the new,
24
+ brand new,
25
+ this year,
26
+ last year,
27
+ next release,
28
+ soon,
29
+ ]
30
+ question:
31
+ context: [docType]
32
+ instructions: >-
33
+ The TEXT is from documentation. Return true when it will read as wrong or stale once time passes because it anchors to the moment of writing ("currently", "recently added", "coming soon", "the new dashboard", "as of today") without a version or date the reader can check. Return false when the TEXT carries a version marker or date, when the temporal word describes the reader's own action ("Now open the file"), or when the TEXT is not documentation.
34
+ criteria:
35
+ true:
36
+ what: Time-anchored wording with no version or date.
37
+ examples:
38
+ - "The dashboard currently supports three providers, with more coming soon."
39
+ - "We recently added dark mode to the new settings page."
40
+ false:
41
+ what: Versioned, dated, or an instruction step.
42
+ examples:
43
+ - "Since v3.2 the dashboard supports three providers."
44
+ - "Now run the migration."
45
+ thresholds: { review: 0.4, act: 0.75 }
46
+ severity: minor
47
+ fix:
48
+ hint: Replace the time word with a version or date the reader can check, or delete it.
49
+ preconditions:
50
+ {
51
+ notInCode: true,
52
+ docType: [tutorial, howto, reference, explanation, agent-instructions],
53
+ }
54
+ status: review-only
55
+ handWritten: [mechanical, question, fix, thresholds, preconditions]
@@ -0,0 +1,22 @@
1
+ # Ported from mblode/agent-skills skills/ui-design/guidelines/copywriting.md (toasts) and
2
+ # product-design rule/success-state-specific.
3
+ id: copywriting-toast-successfully
4
+ title: Success message padded with "successfully"
5
+ categoryId: actionable-microcopy
6
+ source:
7
+ {
8
+ repo: mblode/agent-skills,
9
+ path: skills/ui-design/guidelines/copywriting.md,
10
+ line: 15,
11
+ }
12
+ unit: [jsx-text, attr-string]
13
+ mechanical:
14
+ regex: "\\bsuccessfully\\b"
15
+ flags: giu
16
+ severity: minor
17
+ fix:
18
+ hint: >-
19
+ Name the thing that changed in past tense and stop: "Project deleted", not "Successfully deleted the project."
20
+ preconditions: { notInCode: true, docType: [ui, unknown] }
21
+ status: active
22
+ handWritten: [mechanical, fix, preconditions]
@@ -0,0 +1,33 @@
1
+ # Hand-authored from Every's writing checks (Mike Taylor and Dan Shipper,
2
+ # "Jev judged everything I've written in 0.7 seconds", 15 Sep 2026): the
3
+ # AI-tell questions and the four passage checks named in the article.
4
+ id: copywriting-unexplained-action
5
+ title: Names an action that cannot be pictured
6
+ categoryId: reader-first-framing
7
+ source:
8
+ repo: every.to
9
+ path: https://every.to/also-true-for-humans/mini-vibe-check-typesafe-s-jev-judged-everything-i-ve-written-in-0-7-seconds
10
+ line: 1
11
+ unit: [paragraph]
12
+ question:
13
+ context: [docType]
14
+ instructions: >-
15
+ Read the TEXT. Return true when it asks the reader to do, or describes someone doing, an action whose concrete steps cannot be pictured from the words (teach a calendar, activate the culture, leverage the learnings). Return false when the action names a thing a person could start doing now, or when the TEXT is a heading or label that a following paragraph will explain.
16
+ criteria:
17
+ true:
18
+ what: An action with no picturable steps.
19
+ examples:
20
+ - "A shared appointment calendar that parents and staff teach together."
21
+ - "Activate the community around the launch and operationalise the insights."
22
+ false:
23
+ what: An action a person could begin.
24
+ examples:
25
+ - "A shared appointment calendar that parents and staff both add bookings to."
26
+ - "Post the launch thread in the community channel on Monday and reply to every question that day."
27
+ thresholds: { review: 0.4, act: 0.75 }
28
+ severity: minor
29
+ fix:
30
+ hint: >-
31
+ Replace the abstract verb with the first concrete step a person would take.
32
+ status: review-only
33
+ handWritten: [question, fix, thresholds]
@@ -0,0 +1,48 @@
1
+ # One of the 21 AI-writing checks Every ran with Jev (Mike Taylor, "Jev judged
2
+ # everything I've written in 0.7 seconds", 15 Sep 2026). The question is the
3
+ # published wording; the second sentence says what to ignore.
4
+ # Candidate list from EveryInc/compound-writing skills/cw-ai-check/SKILL.md, category 0 (structural overcompletion, performed voice).
5
+ id: copywriting-unnatural-polish
6
+ title: Polished in a way that suppresses personal texture
7
+ categoryId: machine-prose
8
+ source:
9
+ repo: every.to
10
+ path: https://typesafe-parallel-judgment-lab.every-4573.chatgpt.site/downloads/typesafe-lab-source.zip (scripts/run-ai-checker.mjs)
11
+ line: 1
12
+ ruleId: unnatural_polish
13
+ unit: [paragraph]
14
+ # The question explicitly excludes reference and UI copy. Decide applicability
15
+ # in code rather than paying Jev to rediscover this deterministic exclusion.
16
+ preconditions:
17
+ docType:
18
+ [
19
+ tutorial,
20
+ howto,
21
+ explanation,
22
+ agent-instructions,
23
+ lesson,
24
+ marketing,
25
+ unknown,
26
+ ]
27
+ question:
28
+ context: [docType]
29
+ instructions: >-
30
+ Does the writing feel polished in a way that suppresses personal texture or irregularity? Ignore reference documentation and UI copy, where a neutral register is the point.
31
+ criteria:
32
+ true:
33
+ what: Even, frictionless prose with no person behind it.
34
+ examples:
35
+ - "The initiative delivered meaningful improvements across several dimensions, and stakeholders responded positively to the enhanced experience."
36
+ - "Each component was carefully considered to ensure a cohesive, thoughtful result that balances form and function."
37
+ false:
38
+ what: Prose with a specific person, opinion or rough edge in it.
39
+ examples:
40
+ - "I hated the old settings page. It had 14 toggles and I could never remember which one hid the sidebar."
41
+ - "The first version was ugly and we shipped it anyway, because the two people who needed it were waiting."
42
+ thresholds: { review: 0.4, act: 0.75 }
43
+ severity: minor
44
+ fix:
45
+ hint: >-
46
+ Put one specific, slightly uncomfortable sentence back in: what you thought, what went wrong, what you would not do again.
47
+ status: review-only
48
+ handWritten: [question, fix, thresholds]
@@ -0,0 +1,43 @@
1
+ id: copywriting-unraised-objection
2
+ title: Personal message defends against an unraised objection
3
+ categoryId: actionable-microcopy
4
+ source:
5
+ repo: mblode/ghostwriter
6
+ path: skills/ghostwriter/SKILL.md
7
+ line: 1
8
+ unit:
9
+ - paragraph
10
+ - jsx-text
11
+ - attr-string
12
+ mechanical:
13
+ regex: \b(?:(?:don.t|do not) get me wrong|I(?:.m| am) not saying|some might say)\b
14
+ flags: giu
15
+ question:
16
+ context:
17
+ - docType
18
+ - headingAbove
19
+ - role
20
+ - element
21
+ instructions: Return true when a defensive preface introduces a hypothetical objection without evidence that anyone raised it and adds no constraint. Return false for a real correction, a quoted objection, an explicit boundary, or an important qualification.
22
+ criteria:
23
+ "true":
24
+ what: The stated failure is supported by the supplied text.
25
+ examples:
26
+ - Do not get me wrong, I am not saying collaboration is bad, but we can cancel this meeting.
27
+ "false":
28
+ what: The text is specific, justified, quoted, or outside this rule.
29
+ examples:
30
+ - You asked whether I oppose collaboration. I do not; I oppose this meeting schedule.
31
+ severity: minor
32
+ fix:
33
+ hint: State the concrete claim and preserve any real qualification.
34
+ preconditions:
35
+ notInCode: true
36
+ docType:
37
+ - personal
38
+ status: review-only
39
+ handWritten:
40
+ - mechanical
41
+ - question
42
+ - preconditions
43
+ - fix
@@ -0,0 +1,23 @@
1
+ # Ported from mblode/agent-skills skills/ui-design/rules/slop-unverifiable-proof.md by scripts/port-rules.ts.
2
+ # Keys listed in handWritten are preserved on re-run; everything else is regenerated.
3
+ id: copywriting-unverifiable-proof
4
+ title: Unverifiable proof standing in for real evidence
5
+ categoryId: evidence-over-claims
6
+ source:
7
+ line: 10
8
+ path: skills/ui-design/rules/slop-unverifiable-proof.md
9
+ repo: mblode/agent-skills
10
+ ruleId: slop-unverifiable-proof
11
+ scope:
12
+ include:
13
+ - "**/*.tsx"
14
+ - "**/*.jsx"
15
+ unit:
16
+ - source
17
+ mechanical:
18
+ flags: gui
19
+ regex: logoipsum|placehold\.|placeholder\.com|via\.placeholder|dummyimage|lorem ipsum
20
+ severity: minor
21
+ fix:
22
+ hint: '"99.9% uptime", "10,000+ teams", "3x faster", a testimonial from Jane Doe, CEO at Acme, and a strip of logos nobody has heard of. Every one of these is a claim about the world, and a visitor who cannot check any of them learns that this page''s numbers are decoration. The damage is not aesthetic: it '
23
+ status: review-only