patina-cli 3.11.0 → 4.0.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.
Files changed (193) hide show
  1. package/.patina.default.yaml +29 -29
  2. package/CHANGELOG.md +53 -0
  3. package/NOTICE +21 -0
  4. package/README.md +117 -224
  5. package/README_JA.md +134 -77
  6. package/README_KR.md +132 -74
  7. package/README_ZH.md +137 -80
  8. package/SKILL.md +11 -20
  9. package/artifacts/rebaseline-2025/README.md +147 -0
  10. package/artifacts/rebaseline-2025/human-controls.public.jsonl +250 -0
  11. package/artifacts/rebaseline-2025/intake.example.jsonl +2 -0
  12. package/artifacts/rebaseline-2025/intake.local.example.jsonl +25 -0
  13. package/artifacts/rebaseline-2025/prompts.template.jsonl +7 -0
  14. package/artifacts/rebaseline-2025/sources.ko-public.jsonl +39 -0
  15. package/assets/brand/patina-badge.svg +18 -0
  16. package/assets/brand/patina-mark.svg +8 -0
  17. package/assets/demo/README.md +79 -0
  18. package/core/scoring.md +12 -12
  19. package/core/standalone-prompt.md +3 -1
  20. package/core/stylometry.md +93 -22
  21. package/docs/API.md +1554 -0
  22. package/docs/AUTHENTICATION.md +50 -26
  23. package/docs/AUTHENTICATION_KR.md +54 -29
  24. package/docs/BRANDING.md +9 -8
  25. package/docs/CLI.md +55 -14
  26. package/docs/COOKBOOK.md +8 -21
  27. package/docs/DEMO.md +32 -5
  28. package/docs/EXIT-CODES.md +2 -3
  29. package/docs/FALSE-POSITIVES.md +63 -0
  30. package/docs/FAQ.md +9 -1
  31. package/docs/FAQ_KR.md +3 -1
  32. package/docs/FLAG-PARITY.md +33 -47
  33. package/docs/ISSUE-WAVES.md +57 -0
  34. package/docs/PATTERNS-EN.md +67 -3
  35. package/docs/PATTERNS-JA.md +68 -2
  36. package/docs/PATTERNS-KO.md +70 -7
  37. package/docs/PATTERNS-ZH.md +67 -3
  38. package/docs/PATTERNS.md +5 -5
  39. package/docs/RESEARCH-DOCS-PLATFORM.md +54 -0
  40. package/docs/ROADMAP.md +46 -66
  41. package/docs/TRANSLATIONESE-KO.md +51 -0
  42. package/docs/audits/2026-05-deep-research.md +3 -1
  43. package/docs/benchmarks/README.md +51 -0
  44. package/docs/benchmarks/detector-comparison.json +69 -9
  45. package/docs/benchmarks/detector-comparison.md +10 -5
  46. package/docs/benchmarks/katfish-ko-latest.json +657 -0
  47. package/docs/benchmarks/katfish-ko-latest.md +77 -0
  48. package/docs/benchmarks/latest.json +1183 -108
  49. package/docs/benchmarks/latest.md +84 -60
  50. package/docs/benchmarks/lexicon-freshness-en-2026-05-22.json +1121 -0
  51. package/docs/benchmarks/lexicon-freshness-en-2026-05-22.md +136 -0
  52. package/docs/benchmarks/rebaseline-latest.json +381 -0
  53. package/docs/benchmarks/rebaseline-latest.md +121 -0
  54. package/docs/benchmarks/register-stratified-latest.json +164 -0
  55. package/docs/benchmarks/register-stratified-latest.md +99 -0
  56. package/docs/benchmarks/register-stratified.md +43 -0
  57. package/docs/integrations/github-action.md +44 -11
  58. package/docs/integrations/playground.md +58 -0
  59. package/docs/integrations/pre-commit.md +5 -5
  60. package/docs/integrations/release.md +5 -3
  61. package/docs/integrations/static-sites.md +83 -0
  62. package/docs/research/2025-rebaseline-plan.md +71 -2
  63. package/docs/research/2026-rebaseline.md +102 -0
  64. package/docs/research/adversarial-mps.md +41 -0
  65. package/docs/research/ai-human-metrics.md +35 -23
  66. package/docs/research/human-eval-panel.md +42 -0
  67. package/docs/research/judge-agreement.md +24 -0
  68. package/docs/research/ko-2025-corpus-sources.md +135 -0
  69. package/docs/research/lexicon-freshness-audit.md +64 -0
  70. package/docs/research/zh-ja-lexicon-calibration.md +60 -0
  71. package/docs/social/patina-launch-copy.md +173 -100
  72. package/docs/social/patina-launch-execution.md +94 -0
  73. package/docs/social/patina-launch-korean-first.md +83 -0
  74. package/docs/social/signs-of-ai-writing.md +26 -0
  75. package/docs/social/signs-of-ai-writing_KR.md +26 -0
  76. package/lexicon/ai-en.md +21 -24
  77. package/lexicon/ai-ja.md +158 -0
  78. package/lexicon/ai-ko.md +9 -9
  79. package/lexicon/ai-zh.md +158 -0
  80. package/lexicon/provenance/ai-en.json +970 -0
  81. package/lexicon/provenance/ai-ja.json +542 -0
  82. package/lexicon/provenance/ai-ko.json +866 -0
  83. package/lexicon/provenance/ai-zh.json +542 -0
  84. package/package.json +49 -8
  85. package/patterns/en-communication.md +5 -0
  86. package/patterns/en-content.md +5 -0
  87. package/patterns/en-filler.md +5 -0
  88. package/patterns/en-language.md +29 -1
  89. package/patterns/en-structure.md +5 -0
  90. package/patterns/en-style.md +5 -0
  91. package/patterns/en-viral-hook.md +42 -2
  92. package/patterns/ja-communication.md +5 -0
  93. package/patterns/ja-content.md +5 -0
  94. package/patterns/ja-filler.md +5 -0
  95. package/patterns/ja-language.md +33 -1
  96. package/patterns/ja-structure.md +12 -0
  97. package/patterns/ja-style.md +5 -0
  98. package/patterns/ja-viral-hook.md +41 -2
  99. package/patterns/ko-communication.md +5 -0
  100. package/patterns/ko-content.md +5 -0
  101. package/patterns/ko-filler.md +5 -0
  102. package/patterns/ko-language.md +33 -1
  103. package/patterns/ko-structure.md +25 -6
  104. package/patterns/ko-style.md +5 -0
  105. package/patterns/ko-viral-hook.md +38 -2
  106. package/patterns/zh-communication.md +5 -0
  107. package/patterns/zh-content.md +5 -0
  108. package/patterns/zh-filler.md +5 -0
  109. package/patterns/zh-language.md +37 -1
  110. package/patterns/zh-structure.md +12 -0
  111. package/patterns/zh-style.md +5 -0
  112. package/patterns/zh-viral-hook.md +38 -2
  113. package/playground/README.md +55 -0
  114. package/playground/analytics.js +4 -0
  115. package/playground/analyzer.js +883 -0
  116. package/playground/app.js +157 -0
  117. package/playground/data/lexicons.js +343 -0
  118. package/playground/index.html +138 -0
  119. package/playground/styles.css +267 -0
  120. package/profiles/namuwiki.md +111 -0
  121. package/scripts/adversarial-mps-report.mjs +201 -0
  122. package/scripts/badge-json.mjs +79 -0
  123. package/scripts/benchmark-report.mjs +56 -9
  124. package/scripts/check-release-metadata.mjs +0 -2
  125. package/scripts/detector-comparison.mjs +7 -7
  126. package/scripts/generate-playground-data.mjs +77 -0
  127. package/scripts/katfish-calibration.mjs +464 -0
  128. package/scripts/lexicon-freshness.mjs +485 -0
  129. package/scripts/lint.mjs +1 -1
  130. package/scripts/precommit-score.mjs +4 -3
  131. package/scripts/prose-score.mjs +81 -5
  132. package/scripts/rebaseline-intake.mjs +242 -0
  133. package/scripts/rebaseline-score.mjs +268 -0
  134. package/scripts/rebaseline-summary.mjs +773 -0
  135. package/scripts/rebaseline-web-collect.mjs +410 -0
  136. package/scripts/update-benchmark-ranges.mjs +1 -0
  137. package/src/api.js +69 -105
  138. package/src/auth.js +50 -2
  139. package/src/backends/claude-cli.js +19 -4
  140. package/src/backends/codex-cli.js +19 -3
  141. package/src/backends/contract.js +230 -1
  142. package/src/backends/gemini-cli.js +18 -5
  143. package/src/backends/index.js +87 -12
  144. package/src/backends/kimi-cli.js +161 -0
  145. package/src/cli.js +577 -567
  146. package/src/commands/doctor.js +2 -2
  147. package/src/config.js +29 -0
  148. package/src/errors.js +53 -1
  149. package/src/features/discourse-tells.js +68 -0
  150. package/src/features/index.js +82 -8
  151. package/src/features/lexicon.js +40 -6
  152. package/src/features/markup-leakage.js +69 -0
  153. package/src/features/segment.js +41 -0
  154. package/src/features/signal-strength.js +81 -0
  155. package/src/features/stylometry.js +231 -1
  156. package/src/features/translationese.js +127 -0
  157. package/src/loader.js +76 -0
  158. package/src/logger.js +22 -23
  159. package/src/model-defaults.js +55 -0
  160. package/src/ouroboros.js +31 -0
  161. package/src/output.js +102 -90
  162. package/src/prompt-builder.js +103 -68
  163. package/src/providers.js +51 -4
  164. package/src/scoring.js +210 -2
  165. package/src/security.js +75 -0
  166. package/tests/fixtures/live-quality/en/public-docs-01.md +26 -0
  167. package/tests/fixtures/live-quality/ko/public-docs-01.md +26 -0
  168. package/tests/fixtures/suspect-zones/expected-ranges.json +207 -16
  169. package/tests/fixtures/suspect-zones/ja/ai/ja-ai-04-lexicon.md +11 -0
  170. package/tests/fixtures/suspect-zones/ja/natural/ja-nat-04-lexicon-cold.md +11 -0
  171. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-02.md +4 -5
  172. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-07-ko-diagnostic.md +11 -0
  173. package/tests/fixtures/suspect-zones/zh/ai/zh-ai-04-lexicon.md +11 -0
  174. package/tests/fixtures/suspect-zones/zh/natural/zh-nat-04-lexicon-cold.md +11 -0
  175. package/tests/quality/README.md +188 -11
  176. package/tests/quality/adversarial-mps/fixtures.jsonl +10 -0
  177. package/tests/quality/benchmark.mjs +39 -1
  178. package/tests/quality/dogfood.mjs +5 -3
  179. package/tests/quality/live-fixtures.jsonl +2 -0
  180. package/tests/quality/live-quality.mjs +596 -0
  181. package/tests/quality/ranking-metrics.mjs +136 -0
  182. package/tests/quality/rebaseline-manifest.example.jsonl +5 -0
  183. package/vercel.json +53 -0
  184. package/SKILL-MAX.md +0 -455
  185. package/docs/internal/HARNESS.md +0 -14
  186. package/docs/internal/README.md +0 -14
  187. package/docs/internal/WARP.md +0 -23
  188. package/patina-max/SKILL.md +0 -523
  189. package/patina-max/composite.py +0 -457
  190. package/src/cache.js +0 -106
  191. package/src/commands/init.js +0 -208
  192. package/src/manifest.js +0 -162
  193. package/src/max-mode.js +0 -207
@@ -0,0 +1,64 @@
1
+ # Lexicon freshness audit
2
+
3
+ Status: English remine complete; multilingual provenance sidecars complete with honest legacy/null fields.
4
+ Related issue: #160.
5
+
6
+ Patina lexicons are detection hypotheses. They should not be described as fresh model-era evidence unless each entry has a corpus source and a false-positive check.
7
+
8
+ ## Current frontmatter status
9
+
10
+ | file | entries | current snapshot status | provenance | action |
11
+ |---|---:|---|---|---|
12
+ | `lexicon/ai-en.md` | 88 | `current` | `lexicon/provenance/ai-en.json` | keep; recheck at the next quarterly HAP-E or 2025+ paired refresh |
13
+ | `lexicon/ai-ko.md` | 96 | `partial` | `lexicon/provenance/ai-ko.json` | keep; rerun against 2026 KO positive + human-control pairs before threshold changes |
14
+ | `lexicon/ai-zh.md` | 60 | `needs-external-calibration` | `lexicon/provenance/ai-zh.json` | calibrate before broad claims |
15
+ | `lexicon/ai-ja.md` | 60 | `needs-external-calibration` | `lexicon/provenance/ai-ja.json` | calibrate before broad claims |
16
+
17
+ English was re-mined on 2026-05-22 against the HAP-E English paired corpus:
18
+ 8,290 GPT-4o continuations versus 8,290 paired human `chunk_2` controls across
19
+ academic, blog, fiction, news, spoken, and TV/movie registers. Raw corpus text
20
+ stays in `artifacts/rebaseline-2025/private/`; only the aggregate report is
21
+ tracked.
22
+
23
+ Evidence:
24
+
25
+ - aggregate report: `docs/benchmarks/lexicon-freshness-en-2026-05-22.md`
26
+ - aggregate JSON: `docs/benchmarks/lexicon-freshness-en-2026-05-22.json`
27
+ - validation command: `npm run lexicon:freshness`
28
+
29
+ ## English remine result
30
+
31
+ | decision | entries | rule |
32
+ |---|---:|---|
33
+ | kept | 88 | ≥4× hot-vs-cold document-frequency lift, at least one hot hit, cold document-frequency ≤5% |
34
+ | dropped | 20 | below the lift floor or zero hot hits |
35
+
36
+ Dropped English entries:
37
+
38
+ - strict: `state-of-the-art`, `enable`, `workflow`, `framework`, `dimensions`, `unleash`, `elevated`
39
+ - phrases: `a wide range of`, `a host of`, `in the age of`, `gain a deeper understanding`, `key drivers`, `driving force`, `play a key role`, `close the gap`, `end-to-end`, `to ensure that`, `it is essential to`, `under the hood`, `on the other hand`
40
+
41
+ ## Per-entry remine gate
42
+
43
+ A refreshed entry needs:
44
+
45
+ ```yaml
46
+ added: YYYY-MM-DD or null when the legacy add date is unknown
47
+ source: <snapshot id or corpus manifest path>
48
+ last_validated: YYYY-MM-DD or null when not yet externally validated
49
+ lift: <hot/cold document-frequency ratio or null>
50
+ ```
51
+
52
+ Promotion floor from `process/pattern-freshness.md`:
53
+
54
+ - ≥4× hot-vs-cold document-frequency lift;
55
+ - cold document-frequency ≤5%, unless the entry is register-scoped;
56
+ - no severe false positives in matched controls;
57
+ - no private text checked into the repo.
58
+
59
+ ## Next action
60
+
61
+ Do not re-add dropped English entries without a newer paired-corpus lift report.
62
+ For KO/ZH/JA, the sidecar fields exist but some `added`, `last_validated`, or
63
+ `lift` values remain `null` instead of invented. Treat those languages as
64
+ partial or calibration-pending until their own paired hot/cold reports land.
@@ -0,0 +1,60 @@
1
+ # zh/ja AI-Lexicon Calibration Notes
2
+
3
+ This note documents the first checked-in zh/ja AI-lexicon pass for issue #104.
4
+ The goal is high precision: the lexicon should add signal when AI-style
5
+ scaffolding is dense, without turning ordinary Chinese or Japanese prose hot on
6
+ one phrase.
7
+
8
+ ## Shipped packs
9
+
10
+ | file | entries | shape | matching note |
11
+ |---|---:|---|---|
12
+ | `lexicon/ai-zh.md` | 60 | phrase-only | substring + `~` wildcard |
13
+ | `lexicon/ai-ja.md` | 60 | phrase-only | substring + `~` wildcard |
14
+
15
+ Both packs avoid strict entries by default because zh/ja tokenization uses the
16
+ character fallback. Custom strict entries still work through the CJK substring
17
+ fallback added in `src/features/lexicon.js`.
18
+
19
+ ## Regression corpus
20
+
21
+ The committed regression corpus now has 39 fixtures overall. The zh/ja slice in
22
+ this note remains:
23
+
24
+ | language | AI | natural | expected FP |
25
+ |---|---:|---:|---:|
26
+ | zh | 4 | 4 | 0 |
27
+ | ja | 4 | 4 | 0 |
28
+
29
+ The new lexicon-specific fixtures are:
30
+
31
+ - `tests/fixtures/suspect-zones/zh/ai/zh-ai-04-lexicon.md`
32
+ - `tests/fixtures/suspect-zones/zh/natural/zh-nat-04-lexicon-cold.md`
33
+ - `tests/fixtures/suspect-zones/ja/ai/ja-ai-04-lexicon.md`
34
+ - `tests/fixtures/suspect-zones/ja/natural/ja-nat-04-lexicon-cold.md`
35
+
36
+ `npm run benchmark` reports 100% fixture accuracy with zh/ja precision and
37
+ recall at 4/4 each. The lexicon-specific AI fixtures are lexicon-only hot: their
38
+ burstiness and MATTR detectors stay cold while lexicon density crosses the
39
+ threshold.
40
+
41
+ ## Expansion rule
42
+
43
+ Before adding more entries, test candidates against at least these classes:
44
+
45
+ 1. AI/guidance prose that uses broad summary scaffolds.
46
+ 2. Wikipedia/news-style human prose.
47
+ 3. Personal narrative or sensory prose.
48
+ 4. Domain-heavy technical prose where repeated nouns are normal.
49
+
50
+ Drop any candidate that appears at similar frequency in class 2 or 4. A phrase
51
+ that is common in human explanatory writing should move to the pattern catalog
52
+ only if it has a rewrite strategy; otherwise it should stay out of the lexicon.
53
+
54
+ ## Remaining calibration risk
55
+
56
+ The committed fixture set is a regression gate, not a full 200-paragraph external
57
+ corpus. The original #104 acceptance target called for HC3 zh and curated ja
58
+ AI-vs-human calibration. This PR adds the lexicon packs and local gates so the
59
+ feature can be exercised safely, but future expansion should still run the larger
60
+ external corpus before raising entry counts or lowering the density threshold.
@@ -1,10 +1,56 @@
1
- # patina Launch Copy
1
+ # patina Launch Copy and Playbook
2
2
 
3
- Use this file as the source of truth for public launch posts. The positioning is deliberately "auditable cleanup / editing tool", not detector bypass.
3
+ Use this file as the source of truth for public launch posts. The positioning is deliberately **auditable cleanup / editing tool**, not detector bypass.
4
4
 
5
- ## Positioning
5
+ Execution checklist:
6
+ [`docs/social/patina-launch-execution.md`](patina-launch-execution.md).
7
+
8
+ ## Launch sequence
9
+
10
+ Run the launch in this order. Do not skip the Korean-first pass: it is the wedge that makes patina different from generic English humanizers.
11
+
12
+ | Order | Surface | Primary angle | Launch state |
13
+ |---:|---|---|---|
14
+ | 1 | Korean communities: GeekNews, Velog, Clien | Korean AI tells plus auditable edits | Ready after final score pass |
15
+ | 2 | Show HN | Local, auditable, benchmarked prose cleanup | Ready after final score pass |
16
+ | 3 | Product Hunt | Visual demo plus “keep the meaning” | Ready after final score pass |
17
+ | 4 | Reddit / X / Threads / LinkedIn | Local/no-key angle or editing/voice angle | Reuse the channel drafts below |
18
+
19
+ ## Prerequisite checklist
20
+
21
+ | Item | Status | Launch impact |
22
+ |---|---|---|
23
+ | npm package live (#203) | Done | Use `npx patina-cli` in posts. |
24
+ | GitHub Action v1 (#204) | Done | Mention PR comments and README score badge. |
25
+ | README score badge (#282) | Done | Use as adoption/social proof. |
26
+ | Ethics framing (#164, [`docs/ETHICS.md`](../ETHICS.md)) | Done | Never imply detector evasion. |
27
+ | Comparison page (#213, [`docs/COMPARISON.md`](../COMPARISON.md)) | Done | Cite only factual comparisons. |
28
+ | Web playground (#208) | Ready | Use <https://patina.vibetip.help/> as the try-it-now URL. |
29
+ | Shareable card generator (#283) | Helpful | Product Hunt and X work better with it. |
30
+ | “Signs of AI writing” guide (#285) | Helpful | Use as top-of-funnel content. |
31
+
32
+ ## Non-negotiable rules
33
+
34
+ - Score every final post before publishing. Target `<= 30`.
35
+ - Attach the score screenshot or CLI output to the internal launch thread.
36
+ - Lead with the writing problem. Mention the tool after the reader recognizes the problem.
37
+ - Do not use “bypass,” “undetectable,” or “beats detectors.”
38
+ - Avoid hype vocabulary, emoji-bullet stacks, and tidy three-item slogans.
39
+ - Link the playground from every broad-launch post: <https://patina.vibetip.help/>. Keep the repo link nearby for source, install, and issues.
6
40
 
7
- patina detects recurring AI-writing patterns, rewrites the affected passages, and checks whether the original claims were preserved.
41
+ Score command:
42
+
43
+ ```bash
44
+ node scripts/precommit-score.mjs docs/social/patina-launch-copy.md
45
+ ```
46
+
47
+ Last local score check: 2026-05-23, `docs/social/patina-launch-copy.md` scored 6.3% (`node scripts/precommit-score.mjs docs/social/patina-launch-copy.md`).
48
+
49
+ Korean-first launch drafts are now split out for exact channel copying:
50
+ [`docs/social/patina-launch-korean-first.md`](patina-launch-korean-first.md).
51
+ Last score check on 2026-05-23: Korean-first drafts 0.0%, this file 6.3%.
52
+
53
+ ## Positioning
8
54
 
9
55
  Short tagline:
10
56
 
@@ -14,38 +60,54 @@ Long tagline:
14
60
 
15
61
  > A pattern-based cleanup tool for AI-sounding text. It shows what changed, why it changed, and whether the original claims survived.
16
62
 
17
- ## Before posting
63
+ One-sentence description:
64
+
65
+ > patina finds recurring AI-writing habits in Korean, English, Chinese, and Japanese, rewrites the affected passages, and keeps the edit auditable.
18
66
 
19
- - Run `npm run benchmark:report && npm test`.
20
- - Check the current benchmark: [`docs/benchmarks/latest.md`](../benchmarks/latest.md).
21
- - If comparing tools, link the factual comparison page: [`docs/COMPARISON.md`](../COMPARISON.md).
22
- - Use the launch social preview when the surface supports images: [`assets/social/patina-og.svg`](../../assets/social/patina-og.svg).
23
- - Keep claims to "editing signal" and "suspect-zone benchmark"; do not imply authorship proof.
24
- - Link issues for useful feedback: false positives, missing patterns, benchmark fixtures.
67
+ ## Assets to attach
25
68
 
26
- ## Avoid
69
+ - Social preview: [`assets/social/patina-og.svg`](../../assets/social/patina-og.svg)
70
+ - Before/after card: [`assets/social/patina-before-after.svg`](../../assets/social/patina-before-after.svg)
71
+ - Static badge fallback: [`assets/brand/patina-badge.svg`](../../assets/brand/patina-badge.svg)
72
+ - Benchmark report: [`docs/benchmarks/latest.md`](../benchmarks/latest.md)
73
+ - Comparison page: [`docs/COMPARISON.md`](../COMPARISON.md)
27
74
 
28
- Do not frame patina as:
75
+ ## Korean communities
29
76
 
30
- - an AI detector bypass tool
31
- - a way to fake authorship
32
- - proof that text is human-written
33
- - a universal paraphraser
77
+ Title options:
34
78
 
35
- Use these instead:
79
+ ```text
80
+ patina — 한국어·영어 AI 글의 “AI 티”를 찾아서 지워주는 오픈소스
81
+ AI가 쓴 티 나는 문장, 패턴으로 잡아서 고쳐주는 도구를 만들었습니다
82
+ ```
83
+
84
+ Post body:
85
+
86
+ ```text
87
+ GPT한테 글을 맡기면 어딘가 티가 납니다. “~적인”, “~하고 있다”, 갑자기 늘어나는 한자어, 너무 반듯한 목록 같은 것들요.
88
+
89
+ patina는 그런 패턴을 찾아서 고칩니다. 한국어, 영어, 중국어, 일본어를 지원하고, Claude Code / Codex / Cursor / OpenCode 스킬이나 Node CLI로 쓸 수 있습니다.
90
+
91
+ 핵심은 AI detector 우회가 아니라 편집입니다. 어떤 표현을 잡았는지, 왜 바꿨는지, 원래 주장과 의미가 보존됐는지를 audit / diff / score로 확인할 수 있게 만들었습니다.
36
92
 
37
- - auditable editing
38
- - pattern-based cleanup
39
- - meaning preservation
40
- - false-positive-aware scoring
41
- - diff/audit/score modes
93
+ API 없이도 쓸 수 있습니다. codex, claude, gemini CLI 중 하나에 로그인돼 있으면 됩니다.
94
+
95
+ 웹에서 먼저:
96
+ https://patina.vibetip.help/
97
+
98
+ 레포:
99
+ https://github.com/devswha/patina
100
+
101
+ 특히 한국어 오탐 사례가 궁금합니다. 사람이 쓴 글인데 patina가 AI 티로 잡는 문장이 있으면 이 글 댓글로 편하게 붙여주셔도 됩니다.
102
+ 웹에서 바로 신고: 플레이그라운드(https://patina.vibetip.help/)에서 '오탐 신고' 버튼을 누르면 걸린 문장이 자동으로 채워진 GitHub 폼이 열립니다.
103
+ ```
42
104
 
43
105
  ## Show HN
44
106
 
45
107
  Title:
46
108
 
47
109
  ```text
48
- Show HN: patinaStrip the AI packaging, keep the meaning
110
+ Show HN: Patinarewrite AI text patterns in Korean/English/Chinese/Japanese
49
111
  ```
50
112
 
51
113
  Post body:
@@ -53,141 +115,144 @@ Post body:
53
115
  ```text
54
116
  Hi HN,
55
117
 
56
- I built patina, a pattern-based cleanup tool for AI-sounding text.
118
+ I built Patina because I kept editing the same LLM tells out of drafts: inflated adjectives, neat three-part lists, hedging on hedging, and in Korean, suffixes like “~적”, progressive “~고 있다”, and needless Sino-Korean phrasing.
57
119
 
58
- It detects recurring LLM writing habits, rewrites the affected passages, and checks whether the original claims were preserved. It supports Korean, English, Chinese, and Japanese, and runs as a skill for Claude Code, Codex CLI, Cursor, and OpenCode, or as a standalone Node.js CLI.
120
+ Patina turns those habits into a pattern catalog for Korean, English, Chinese, and Japanese. It can rewrite the affected passages, but it is not a black-box paraphraser. It shows what changed, why it changed, and whether claims, numbers, polarity, causation, and negation survived the edit.
59
121
 
60
- The main difference from a generic paraphraser is auditability: patina can show what pattern it found, what it changed, and whether semantic anchors such as claims, polarity, causation, numbers, and negation survived the rewrite.
122
+ It runs as a skill in Claude Code, Codex CLI, Cursor, and OpenCode, or as a standalone Node CLI:
61
123
 
62
- Example:
124
+ npx patina-cli --lang en draft.md
63
125
 
64
- Before:
65
- "Coffee has emerged as a pivotal cultural phenomenon that has fundamentally transformed social interactions across the globe. This beloved beverage serves as a catalyst for community building, fosters meaningful connections, and facilitates cross-cultural dialogue."
126
+ If you are already logged into codex, claude, or gemini CLI, you can use it without adding an API key.
66
127
 
67
- After:
68
- "Coffee has quietly changed how people meet. Sit across from someone long enough, and something like a real connection tends to form — even between people from very different cultures."
128
+ This is not meant as a detector-bypass tool. I treat the score as an editing signal, not proof of authorship. False positives are documented because the useful output is the audit and diff, not a verdict.
69
129
 
70
- This is not meant as an AI-detector bypass tool. Detectors are noisy. I treat the score as an editing signal, and the diff/audit output as the useful artifact.
130
+ Try:
131
+ https://patina.vibetip.help/
71
132
 
72
133
  Repo:
73
134
  https://github.com/devswha/patina
74
135
 
75
- I would especially like feedback on false positives, missing pattern families, and whether the MPS / diff / audit modes are useful for real writing workflows.
136
+ The feedback I want most: human text that Patina wrongly flags, missing pattern families, and examples where the rewrite preserved the wrong thing.
76
137
  ```
77
138
 
78
- ## Reddit / ClaudeAI Megathread
139
+ ## Product Hunt
140
+
141
+ Tagline:
79
142
 
80
143
  ```text
81
- I built patina, a Claude Code skill / CLI for cleaning up AI-sounding text.
144
+ Strip the AI packaging. Keep the meaning.
145
+ ```
82
146
 
83
- It detects recurring AI writing patterns, rewrites them, and checks that the original meaning is preserved. It supports Korean, English, Chinese, and Japanese, and also works with Codex CLI, Cursor, OpenCode, and standalone Node.js.
147
+ Description:
84
148
 
85
- Quick before/after:
149
+ ```text
150
+ Patina finds the habits that make text read as AI-written — in Korean, English, Chinese, and Japanese — and rewrites them out. It is not a black-box paraphraser: it shows what changed, why it changed, and whether your claims survived. Use it in Claude Code, Codex, Cursor, OpenCode, or as a Node CLI.
151
+ ```
86
152
 
87
- Before:
88
- “Coffee has emerged as a pivotal cultural phenomenon that has fundamentally transformed social interactions across the globe. This beloved beverage serves as a catalyst for community building, fosters meaningful connections, and facilitates cross-cultural dialogue.”
153
+ Maker comment:
89
154
 
90
- After:
91
- “Coffee has quietly changed how people meet. Sit across from someone long enough, and something like a real connection tends to form, even between people from very different cultures.”
155
+ ```text
156
+ I built Patina because I was tired of removing the same AI tells from drafts by hand. Two details matter to me: it works on Korean, where most English-first humanizers miss the obvious tells, and it is auditable. Every edit should have a reason and a meaning-preservation check.
92
157
 
93
- Repo:
94
- https://github.com/devswha/patina
158
+ I do not want this framed as “make text undetectable.” Detectors are noisy. Patina is an editing pass: find the synthetic packaging, remove it, and keep the claim intact.
95
159
 
96
- I’d especially like feedback on false positives, missing AI-writing patterns, and whether the audit/score/diff modes make sense for real Claude output.
160
+ Try it on something you wrote at https://patina.vibetip.help/ and tell me where it is wrong. False positives are the most useful reports.
97
161
  ```
98
162
 
99
- ## X launch thread
163
+ ## Reddit
100
164
 
101
- ### 1
165
+ ### r/LocalLLaMA
102
166
 
103
167
  ```text
104
- I built patina: a pattern-based cleanup tool for AI-sounding text.
168
+ I built Patina, a local-friendly tool for cleaning up AI-sounding prose.
169
+
170
+ It runs through the CLI you already use. If you are logged into codex, claude, or gemini, you can run Patina without adding a separate API key. It also works as a Claude Code / Codex / Cursor / OpenCode skill.
171
+
172
+ The tool finds recurring LLM writing habits, rewrites the affected text, and checks whether the original claims survived. It supports Korean, English, Chinese, and Japanese.
105
173
 
106
- It strips the AI packaging while keeping the meaning.
174
+ This is not an “undetectable text” project. The score is an editing signal. The useful artifact is the audit: what pattern fired, what changed, and whether meaning drifted.
107
175
 
108
- Claude Code / Codex CLI / Cursor / OpenCode / Node CLI
109
- KO / EN / ZH / JA
176
+ Try:
177
+ https://patina.vibetip.help/
110
178
 
179
+ Repo:
111
180
  https://github.com/devswha/patina
181
+
182
+ I am looking for false positives and missing pattern families, especially outside English.
112
183
  ```
113
184
 
114
- ### 2
185
+ ### r/writing or r/Korean
115
186
 
116
187
  ```text
117
- The goal is not detector bypass.
188
+ I built a tool that spots and rewrites AI-sounding patterns in writing, including Korean.
118
189
 
119
- AI detectors are noisy. patina treats the score as an editing signal, not proof of authorship.
190
+ The goal is not to hide authorship. It is to make AI-assisted drafts easier to edit. Patina points out habits like inflated phrasing, tidy generic structure, and Korean AI tells such as “~적인”, “~하고 있다”, and needless formal nouns.
120
191
 
121
- The useful parts are audit, diff, and meaning-preservation checks: what changed, why it changed, and whether the original claims survived.
122
- ```
192
+ It then rewrites the affected passages and checks that the original meaning survived. You can see the audit and diff instead of trusting a black-box paraphrase.
123
193
 
124
- ### 3
194
+ Try:
195
+ https://patina.vibetip.help/
125
196
 
126
- ```text
127
- Example before:
128
-
129
- “Coffee has emerged as a pivotal cultural phenomenon that has fundamentally transformed social interactions across the globe...”
197
+ Repo:
198
+ https://github.com/devswha/patina
130
199
 
131
- This is the kind of AI packaging patina looks for: inflated stakes, vague abstraction, and generic benefit stacking.
200
+ If you have human-written text that gets flagged, I would love to see it. Those examples are the best way to reduce false positives.
132
201
  ```
133
202
 
134
- ### 4
203
+ ## X / Threads
135
204
 
136
- ```text
137
- After:
205
+ ### Korean thread
138
206
 
139
- “Coffee has quietly changed how people meet. Sit across from someone long enough, and something like a real connection tends to form — even between people from very different cultures.”
207
+ ```text
208
+ 1/ AI가 쓴 글은 티가 납니다. “~적인”, 너무 반듯한 목록, 갑자기 늘어나는 한자어 같은 것들요.
140
209
 
141
- Same claims. Less model voice.
210
+ patina는 그런 패턴을 찾아서 고칩니다. KO / EN / ZH / JA.
142
211
  ```
143
212
 
144
- ### 5
145
-
146
213
  ```text
147
- Under the hood, patina tracks semantic anchors: claims, polarity, causation, numbers, and negation.
148
-
149
- If a rewrite drops or flips an anchor, it retries or rolls back the change.
214
+ 2/ 그냥 다시 써주는 도구는 많습니다.
150
215
 
151
- That is the part I care about most: editable output with a safety rail.
216
+ patina는 바꿨는지, 원래 의미가 보존됐는지까지 보여주는 편집 도구에 가깝습니다.
152
217
  ```
153
218
 
154
- ### 6
219
+ ```text
220
+ 3/ API 키 없이도 쓸 수 있습니다.
221
+
222
+ codex / claude / gemini CLI 중 하나만 로그인돼 있으면 Node CLI나 에디터 스킬로 바로 돌릴 수 있습니다.
223
+ ```
155
224
 
156
225
  ```text
157
- Current calibration:
226
+ 4/ 목표는 detector 우회가 아닙니다.
158
227
 
159
- - 146 pattern catalog
160
- - 91% Korean editing-hotspot recall [84.0-95.4%], n=100
161
- - 76% English HC3 editing-hotspot recall [66.7-83.3%], n=100
162
- - 13-25% human-prose false-positive point-estimate range across registers
163
- - Latest fixture benchmark: https://github.com/devswha/patina/blob/main/docs/benchmarks/latest.md
228
+ 점수는 편집 신호일 뿐이고, 중요한 건 audit / diff / meaning check입니다.
164
229
 
165
- False positives are documented because this should be used as an editor, not a judge.
230
+ https://github.com/devswha/patina
166
231
  ```
167
232
 
168
- ### 7
233
+ ### English single post
169
234
 
170
235
  ```text
171
- If you write with LLMs and hate the default polished-but-empty voice, try it and tell me where it fails.
236
+ I built Patina: an AI-writing cleanup tool that works on Korean, shows its edits, and checks whether the meaning survived.
172
237
 
173
- I’m especially looking for missing patterns, false positives, and better before/after examples.
238
+ Not detector bypass. Just auditable editing for text that sounds too packaged.
174
239
 
240
+ Claude Code / Codex / Cursor / OpenCode / Node CLI.
175
241
  https://github.com/devswha/patina
176
242
  ```
177
243
 
178
- ## Short Korean community post
244
+ ## LinkedIn
179
245
 
180
246
  ```text
181
- patina라는 오픈소스 도구를 만들고 있습니다.
247
+ Every team ships AI-assisted writing now: docs, release notes, support replies, launch posts. The problem is not that the writing is AI-assisted. The problem is that it often reads like it.
182
248
 
183
- AI가 글에서 자주 보이는 표현 패턴을 잡아서, 의미는 유지한 자연스럽게 고치는 도구입니다. Claude Code 스킬로 있고, Codex CLI / Cursor / OpenCode / Node CLI에서도 동작합니다. 한국어, 영어, 중국어, 일본어 패턴을 지원합니다.
249
+ I built Patina for the editing pass after generation. It finds the habits that make prose feel machine-written, rewrites the affected passages, and checks whether the original claims survived.
184
250
 
185
- 핵심은 “AI detector 우회”가 아니라 편집입니다. 어떤 패턴을 잡았는지, 바꿨는지, 원래 주장과 의미가 보존됐는지를 audit / diff / score 모드로 확인할 수 있게 만드는 쪽에 집중했습니다.
251
+ The important part for work is auditability. You can see what changed and why instead of trusting a black-box paraphrase.
186
252
 
187
- 레포:
188
- https://github.com/devswha/patina
253
+ It supports Korean, English, Chinese, and Japanese, and runs as an editor skill or Node CLI.
189
254
 
190
- 특히 한국어 false positive, 빠진 AI 문체 패턴, before/after 예시 피드백을 받고 싶습니다.
255
+ https://github.com/devswha/patina
191
256
  ```
192
257
 
193
258
  ## Maintainer reply templates
@@ -195,33 +260,41 @@ https://github.com/devswha/patina
195
260
  ### Detector-bypass concern
196
261
 
197
262
  ```text
198
- Fair concern. I do not think of patina as a detector-bypass tool. AI detectors are noisy anyway.
263
+ Fair concern. I do not think of Patina as a detector-bypass tool. AI detectors are noisy anyway.
199
264
 
200
- The goal is editing: find repeated writing habits that make LLM output feel synthetic, rewrite those parts, and keep the meaning checkable through audit/diff/score modes.
265
+ The goal is editing: find repeated writing habits that make LLM output feel synthetic, rewrite those parts, and keep the meaning checkable through audit, diff, and score modes.
201
266
  ```
202
267
 
203
268
  ### False positives
204
269
 
205
270
  ```text
206
- False positives are real. Human prose can trigger patina, especially encyclopedic, corporate, academic, or heavily edited writing.
271
+ False positives are real. Human prose can trigger Patina, especially encyclopedic, corporate, academic, or heavily edited writing.
207
272
 
208
- That is why I treat the score as a rough editing signal, not a truth machine. The diff and the highlighted patterns matter more than the exact number.
273
+ That is why I treat the score as a rough editing signal, not a truth machine. The diff and highlighted patterns matter more than the exact number.
209
274
  ```
210
275
 
211
276
  ### Install help
212
277
 
213
278
  ```text
214
- Install:
279
+ Install (standalone CLI, nothing to trust beyond npm):
215
280
 
216
- curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | bash
281
+ npx patina-cli --lang en input.txt
217
282
 
218
- Then in Claude Code:
283
+ Or inside Claude Code:
219
284
 
220
285
  /patina --lang en
221
286
 
222
287
  [paste text]
223
288
 
224
- Or as a standalone CLI:
289
+ Prefer a one-line installer? Review the script first, then:
225
290
 
226
- patina --lang en input.txt
291
+ curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | bash
227
292
  ```
293
+
294
+ ## Post-launch triage
295
+
296
+ - Collect false-positive reports under the `false-positive` label.
297
+ - Use <https://github.com/devswha/patina/issues/new?template=false_positive.yml> for public false-positive reports.
298
+ - Turn repeated missing patterns into pattern issues with examples.
299
+ - Add strong before/after examples to `docs/EXAMPLES.md` or `examples/`.
300
+ - Re-score public copy after edits; keep the launch thread evidence attached.
@@ -0,0 +1,94 @@
1
+ # patina Launch Execution Packet
2
+
3
+ Last prepared: 2026-05-23.
4
+
5
+ Use this packet when the maintainer is ready to post. Agents may prepare copy,
6
+ score proof, and follow-up notes, but should not publish from maintainer-owned
7
+ accounts.
8
+
9
+ ## Current source files
10
+
11
+ | Purpose | File |
12
+ |---|---|
13
+ | Broad channel copy | [`patina-launch-copy.md`](patina-launch-copy.md) |
14
+ | Korean-first copy | [`patina-launch-korean-first.md`](patina-launch-korean-first.md) |
15
+ | Top-of-funnel English guide | [`signs-of-ai-writing.md`](signs-of-ai-writing.md) |
16
+ | Top-of-funnel Korean guide | [`signs-of-ai-writing_KR.md`](signs-of-ai-writing_KR.md) |
17
+
18
+ ## Pre-post checklist
19
+
20
+ Run these before copying any post into a public channel:
21
+
22
+ ```bash
23
+ node scripts/precommit-score.mjs \
24
+ docs/social/patina-launch-copy.md \
25
+ docs/social/patina-launch-korean-first.md \
26
+ docs/social/signs-of-ai-writing.md \
27
+ docs/social/signs-of-ai-writing_KR.md
28
+ ```
29
+
30
+ Latest local result:
31
+
32
+ | File | Score | Status |
33
+ |---|---:|---|
34
+ | `docs/social/patina-launch-copy.md` | 6.3% | pass |
35
+ | `docs/social/patina-launch-korean-first.md` | 0.0% | pass |
36
+ | `docs/social/signs-of-ai-writing.md` | 0.0% | pass |
37
+ | `docs/social/signs-of-ai-writing_KR.md` | 20.0% | pass |
38
+
39
+ Confirm the links used in broad posts:
40
+
41
+ - Playground: <https://patina.vibetip.help/>
42
+ - Repository: <https://github.com/devswha/patina>
43
+ - False-positive form: <https://github.com/devswha/patina/issues/new?template=false_positive.yml>
44
+ - Benchmark report: [`docs/benchmarks/latest.md`](../benchmarks/latest.md)
45
+
46
+ ## Posting order
47
+
48
+ | Order | Channel | Copy source | Maintainer action |
49
+ |---:|---|---|---|
50
+ | 1 | GeekNews | `patina-launch-korean-first.md` → GeekNews | Post or mark deferred in the maintainer launch note. |
51
+ | 2 | Velog | `patina-launch-korean-first.md` → Velog | Post or mark deferred in the maintainer launch note. |
52
+ | 3 | Clien-style short post | `patina-launch-korean-first.md` → Clien-style short post | Post or mark deferred in the maintainer launch note. |
53
+ | 4 | Show HN | `patina-launch-copy.md` → Show HN | Post with playground + repo links. |
54
+ | 5 | Product Hunt | `patina-launch-copy.md` → Product Hunt | Use brand/social assets and maker comment. |
55
+ | 6 | Reddit | `patina-launch-copy.md` → Reddit | Pick LocalLLaMA or writing/Korean angle. |
56
+ | 7 | X / Threads / LinkedIn | `patina-launch-copy.md` → X / Threads | Use short copy and link playground first. |
57
+
58
+ ## Maintainer update template
59
+
60
+ After each channel action, add a short entry to the maintainer launch note:
61
+
62
+ ```text
63
+ Channel:
64
+ Status: posted | queued | deferred
65
+ URL:
66
+ Copy source:
67
+ Score command:
68
+ Score result:
69
+ Notes / feedback:
70
+ ```
71
+
72
+ If a post is deferred, record the reason instead of leaving the checkbox
73
+ ambiguous.
74
+
75
+ ## Feedback triage
76
+
77
+ Capture useful launch feedback with enough detail to reproduce it:
78
+
79
+ - language and register,
80
+ - copied paragraph or a private/non-redistributable note,
81
+ - score output,
82
+ - expected behavior,
83
+ - whether the reporter allows the text to be used as a fixture.
84
+
85
+ Public false-positive reports should use:
86
+ <https://github.com/devswha/patina/issues/new?template=false_positive.yml>.
87
+
88
+ ## Close criteria for the launch note
89
+
90
+ Keep the maintainer launch note open until each channel is either:
91
+
92
+ - posted with URL and score proof,
93
+ - queued with owner/date,
94
+ - or explicitly deferred with reason.