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
package/README_ZH.md CHANGED
@@ -6,34 +6,60 @@
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![Skill](https://img.shields.io/badge/Skill-Claude%20Code%20%7C%20Codex%20%7C%20Cursor%20%7C%20OpenCode-blueviolet)](#快速开始)
8
8
  [![Multi-language](https://img.shields.io/badge/Languages-KO%20%7C%20EN%20%7C%20ZH%20%7C%20JA-green)](https://github.com/devswha/patina)
9
- [![Version](https://img.shields.io/badge/version-3.11.0-blue)](CHANGELOG.md)
9
+ [![Version](https://img.shields.io/badge/version-4.0.0-blue)](CHANGELOG.md)
10
10
 
11
- > **只剥掉 AI 包装,保留原意。**
11
+ <p align="center">
12
+ <img src="assets/demo/patina-demo-en.gif" alt="patina 将带有 AI 味的英文文案改写并显示评分的终端演示 GIF" width="780">
13
+ </p>
12
14
 
13
- patina 会在中文、韩文、英文和日文里找出 AI 味比较重的写作模式,并在不改动原意的前提下重写。它可以作为 [Claude Code](https://docs.anthropic.com/en/docs/claude-code)、[Codex CLI](https://github.com/openai/codex)、[Cursor](https://cursor.sh)、OpenCode 的技能使用,也可以作为独立的 Node.js CLI 运行。
15
+ <p align="center">
16
+ <a href="https://patina.vibetip.help/"><b>用你自己的文本试用 — 无需安装</b></a>
17
+ </p>
14
18
 
15
- 它不是黑盒改写器。patina **基于模式且可审计**:会说明改了什么、为什么改,以及原文的主张是否保留下来。
19
+ > **去掉 AI 味,保留原意。**
20
+
21
+ patina 会在中文、韩文、英文和日文中找出 AI 味较重的表达,并在不改变主张、数字、立场和因果关系的前提下改写。你可以把它装成 [Claude Code](https://docs.anthropic.com/en/docs/claude-code)、[Codex CLI](https://github.com/openai/codex)、[Cursor](https://cursor.sh)、OpenCode 的 agent skill,也可以直接运行独立的 Node.js CLI。
22
+
23
+ 它不是黑盒式改写器,也不是用来绕过 AI 检测器的工具。patina **基于清晰的模式规则,并且可审计**:会说明改了什么、为什么改,以及原文的主张是否保留下来。只要 `codex`、`claude`、`gemini` 任一 CLI 已登录,就可以不填 API 密钥使用。
16
24
 
17
25
  ## 效果展示
18
26
 
19
- **修改前** *(AI 风格)*:
20
- > 咖啡已成为**深刻改变**全球社交互动的**核心文化现象**。这种备受喜爱的饮品充当了社区建设的催化剂,促进了有意义的联结,并推动了跨文化对话。
27
+ **修改前** *(AI 风格;当前 GIF 使用的是英文示例)*:
28
+ > The newly released Notion template pack is an **innovative solution** designed to **transform productivity** for modern teams. It offers 30 templates optimized for diverse workflows, with a user-friendly design that enables anyone to leverage them effortlessly. This product introduces a **new paradigm** for maximizing work efficiency.
29
+
30
+ **修改后** *(`/patina --lang en --tone marketing` — 事实不变,只去掉 AI 味)*:
31
+ > If Notion still starts as a blank page for your team, open this pack first. It includes 30 templates for common workflows. Duplicate one, adjust the fields you need, and use it for a team project or your own planning without starting from scratch.
32
+
33
+ > **Score = 0.0%** · 30 个模板 ✓ · 适配工作流 ✓ · 复制后可调整使用 ✓
34
+
35
+ **更多例子**
36
+
37
+ | 输入类型 | 去掉的 AI 味 | 保留的含义 |
38
+ |---|---|---|
39
+ | 韩语营销文案 | “혁신적인 솔루션”, “새로운 패러다임” | 30 个 Notion 模板、适配工作流、复制后可自行修改 |
40
+ | 学术文本 | “획기적인 성과”, 宽泛的意义宣称 | 60 个 GitHub 项目、72h→10m 设置时间、p<0.01、限制说明 |
41
+ | 技术文档 | “핵심적인 역할”, 未来标准式夸张 | GPU 管理、一条命令完成配置、5× 结果的注意事项 |
42
+
43
+ ## 浏览器直接体验 — 无需安装
44
+
45
+ **[patina.vibetip.help](https://patina.vibetip.help/)** 可以在浏览器里直接检查 KO / EN / ZH / JA 段落中的 AI 写作信号。
21
46
 
22
- **修改后** *(`/patina --lang zh` 处理 同样内容,仅去除 AI 包装)*:
23
- > 咖啡在不知不觉中改变了人们见面的方式。和人坐下来聊久了,关系自然就有了,哪怕文化背景完全不同也能聊到一起。
47
+ > **仅检测。** playground 只在你的浏览器内运行确定性的文体统计分析。它不会改写文本,不会调用外部 LLM,也不会把 API key 发到服务器。需要实际改写时,请使用下面的 CLI 或 skill。
24
48
 
25
- > **MPS = 100** · 社交变革 ✓ · 社区建设 ✓ · 有意义的联结 ✓ · 跨文化对话 ✓
49
+ 完整改写流程见 [30 秒终端演示](docs/DEMO.md)。更多例子见 [Before/After Gallery](docs/EXAMPLES.md)([한국어](docs/EXAMPLES_KR.md))。
50
+ 品牌资源:[logo](assets/brand/patina-logo.svg)、[mark](assets/brand/patina-mark.svg)、[icon](assets/brand/patina-icon.svg)、[social preview](assets/social/patina-og.svg)、[before/after card](assets/social/patina-before-after.svg)。使用指南见 [BRANDING.md](docs/BRANDING.md)。
26
51
 
27
52
  ## 一览
28
53
 
29
54
  | | |
30
55
  |---|---|
31
- | **160 个模式** | 韩文 40 + 英文 40 + 中文 40 + 日文 40 (各含8个仅评分的 viral-hook) — [PATTERNS.md](docs/PATTERNS.md) |
32
- | **编辑热点召回率** | 韩文 91% [84.0–95.4%] (n=100) / 英文 76% [66.783.3%] (n=100), binomial 95% CI |
33
- | **误检率** | 人类文本不同体裁 13–25% 点估计范围 *(不是 CI;百科风格本质局限,[已记录](core/stylometry.md))* |
56
+ | **168 条模式** | 每种语言 33 条可改写模式 + 9 条仅评分的病毒式钩子模式(KO/EN/ZH/JA 42 条) — [PATTERNS.md](docs/PATTERNS.md) |
57
+ | **编辑热点召回率** | 2026-05-22 现代模型重基线:GPT-5.5 / Claude Sonnet 4.6 / Gemini 2.5 Pro 的总体命中率为 67.3% [63.571.0%]n=600,韩文+英文) |
58
+ | **基准报告** | 可复现的 ko/en/zh/ja 可疑区间基准:[overview](docs/benchmarks/README.md) · [latest.md](docs/benchmarks/latest.md) · [latest.json](docs/benchmarks/latest.json) · [2026 rebaseline](docs/benchmarks/rebaseline-latest.md) · [detector comparison](docs/benchmarks/detector-comparison.md) |
59
+ | **误检率** | 2026-05-22 KO+EN 人类对照为 16.0% [11.6–21.7%](n=200);不同文体的边界见 [stylometry.md](core/stylometry.md) — [报告误检](https://github.com/devswha/patina/issues/new?template=false_positive.yml) |
34
60
  | **模式** | rewrite · audit · score · diff · ouroboros |
35
- | **免费层** | 支持 通过 `codex` CLI(无需 API 密钥) |
36
- | **确定性** | 评分公式是确定性的;LLM 严重度判定阶段 ±8–10pt 波动([scoring.md §8](core/scoring.md)) |
61
+ | **免费使用** | 已登录的 `codex`、`claude` `gemini` CLI 可直接运行,无需 API 密钥 |
62
+ | **确定性** | 评分公式是确定性的;LLM 严重度判定阶段会有 ±8–10pt 波动([scoring.md §8](core/scoring.md)) |
37
63
  | **许可证** | MIT |
38
64
 
39
65
  ## 快速开始
@@ -44,7 +70,7 @@ patina 会在中文、韩文、英文和日文里找出 AI 味比较重的写作
44
70
  curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | bash
45
71
  ```
46
72
 
47
- 安装脚本会把 patina 一次性接入 Claude Code、[Codex CLI](https://github.com/openai/codex)、Cursor、OpenCode。它会在 checkout 前把 repository HEAD 解析到具体 commit;如果需要完全固定安装,请设置 `PATINA_REF=<tag-or-full-sha>`。然后:
73
+ 安装脚本会把 patina 一次接入 Claude Code、[Codex CLI](https://github.com/openai/codex)、Cursor OpenCode。安装时会先把远程 HEAD 固定到具体 commit;如果想固定到某个版本,请设置 `PATINA_REF=<tag-or-full-sha>`。然后:
48
74
 
49
75
  ```
50
76
  /patina --lang zh
@@ -52,7 +78,7 @@ curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | ba
52
78
  [在此粘贴你的文本]
53
79
  ```
54
80
 
55
- 以特定语调改写:
81
+ 按指定语气改写:
56
82
 
57
83
  ```
58
84
  /patina --tone narrative
@@ -60,7 +86,7 @@ curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | ba
60
86
  [在此粘贴你的随笔草稿]
61
87
  ```
62
88
 
63
- 自动检测最适合的语调:
89
+ 自动选择合适的语气:
64
90
 
65
91
  ```
66
92
  /patina --tone auto --lang en
@@ -68,11 +94,18 @@ curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | ba
68
94
  [在此粘贴你的文本]
69
95
  ```
70
96
 
71
- > 注意:`--tone`(含 `auto`)在 v1 仅对 ko/en 生效。zh/ja 使用任何语调均会触发警告并回退到 profile-only 模式。
97
+ > 注意:`--tone`(含 `auto`)在 v1 仅对 ko/en 生效。zh/ja 使用任何语气都会触发警告,并回退到 profile-only 模式。
72
98
 
73
99
  ### 作为独立 CLI
74
100
 
75
- 需要 Node.js ≥ 18。
101
+ 需要 Node.js ≥ 18。npm 包已公开,可以直接运行:
102
+
103
+ ```bash
104
+ npx patina-cli doctor
105
+ npx patina-cli --lang zh input.txt
106
+ ```
107
+
108
+ 如果想拉下仓库本地修改再试:
76
109
 
77
110
  ```bash
78
111
  git clone https://github.com/devswha/patina.git
@@ -80,35 +113,59 @@ cd patina && npm install && npm link
80
113
  patina --lang zh input.txt
81
114
  ```
82
115
 
83
- 也可以 link 后通过 stdin 试用:
116
+ `npm link` 后也可以通过 stdin 试用:
84
117
 
85
118
  ```bash
86
119
  printf '%s\n' '咖啡已成为一种关键文化现象,从根本上改变了全球各地的社会互动。' \
87
120
  | patina --lang zh --backend codex-cli
88
121
  ```
89
122
 
90
- > 🆓 **无需 API 密钥** — 只要 [`codex`](https://github.com/openai/codex)、[`claude`](https://docs.anthropic.com/en/docs/claude-code)、[`gemini`](https://github.com/google-gemini/gemini-cli) 任一 CLI 已登录即可。可通过 `--backend codex-cli | claude-cli | gemini-cli` 直接选择,或用 `--model claude-*` / `--model gemini-*` 按模型名路由。完整后端列表见 [AUTHENTICATION.md](docs/AUTHENTICATION.md)。
123
+ > 🆓 **无需 API 密钥** — 只要 [`codex`](https://github.com/openai/codex)、[`claude`](https://docs.anthropic.com/en/docs/claude-code)、[`gemini`](https://github.com/google-gemini/gemini-cli)、[`kimi`](https://moonshotai.github.io/kimi-cli/) 任一 CLI 已登录即可。可以用 `--backend codex-cli | claude-cli | gemini-cli | kimi-cli` 直接选择,也可以用 `--backend claude-cli,codex-cli` 指定后备顺序;还可以交给模型名自动路由(如 `--model claude-*` `--model kimi-*` 对应 CLI)。未传 `--model` 时,patina 会按 backend 传入默认模型:`gpt-5.5`、`claude-sonnet-4-6`、`gemini-2.5-pro` 或 `kimi-code/kimi-for-coding`。完整后端列表见 [AUTHENTICATION.md](docs/AUTHENTICATION.md)。
91
124
 
92
- ### CI integrations
125
+ ### CI 集成
93
126
 
94
- Patina 提供不需要 live model key 的确定性 CI prose review
127
+ Patina 提供确定性的 CI 文档检查,不需要 live model key:
95
128
 
96
129
  ```yaml
97
130
  # .github/workflows/patina.yml
98
- steps:
99
- - uses: actions/checkout@v6
100
- - uses: devswha/patina-action@main # npm 发布并打 Action 标签后改用 @v1
101
- with:
102
- patina-package: github:devswha/patina # patina-cli@latest 发布到 npm 后删除
103
- report-threshold: 30
104
- comment: true
131
+ name: Patina prose score
132
+
133
+ on:
134
+ pull_request:
135
+ paths:
136
+ - '**/*.md'
137
+ - '**/*.mdx'
138
+
139
+ permissions:
140
+ contents: read
141
+ pull-requests: read
142
+ issues: write
143
+
144
+ jobs:
145
+ patina:
146
+ runs-on: ubuntu-latest
147
+ steps:
148
+ - uses: actions/checkout@v6
149
+ - uses: devswha/patina-action@v1
150
+ with:
151
+ score-threshold: 30
152
+ lang: auto
153
+ comment: true
154
+ ```
155
+
156
+ Docker 镜像发布与 npm release 路径分开追踪。GHCR 镜像公开前,需要容器时请先构建本地镜像:
157
+
158
+ ```bash
159
+ docker build -t patina:local .
160
+ printf '%s\n' '咖啡已成为一种关键文化现象。' \
161
+ | docker run --rm -i -e PATINA_API_KEY patina:local --lang zh --provider openai
105
162
  ```
106
163
 
107
164
  Pre-commit、Husky、Lefthook、Docker 和 release workflow 说明见 [docs/integrations/](docs/integrations/)。
108
165
 
109
- ## 预期用途
166
+ ## 正确使用目的
110
167
 
111
- Patina 适合在作者可以使用 AI 辅助时,用来做 AI 后编辑、保留审计轨迹和清理 voice。它不承诺文本“原本由人类写成”,也不应被用于规避学术 honor-code、绕过出版方 disclosure、洗白抄袭,或声称 detector-bypass。见 [ETHICS.md](docs/ETHICS.md)。
168
+ Patina 适合在作者可以使用 AI 辅助起草的场景中,用来编辑草稿、看清改了哪里和为什么改,并让文字读起来更自然。它不保证文本“原本由人类写成”,也不应被用于规避学术 honor code、绕过出版方 disclosure、洗白抄袭,或声称可以 bypass detector。分数只是有误报和漏报的编辑信号,不是作者身份的证明。见 [ETHICS.md](docs/ETHICS.md)。
112
169
 
113
170
  ## 模式
114
171
 
@@ -121,52 +178,47 @@ patina --lang <ko|en|zh|ja> [模式] [--profile <名称>] input.txt
121
178
  | *(默认)* | 改写 |
122
179
  | `--audit` | 仅检测 AI 模式 |
123
180
  | `--score` | 0–100 AI 相似度评分 + 类别细分 |
124
- | `--score --exit-on <n>` | 保持 CI 严格:当 `overall > n` 时以退出码 `3` 结束(`--gate` 保留为 alias) |
181
+ | `--score --exit-on <n>` | 保持 CI 严格:当 `overall > n` 时以退出码 `3` 结束 |
125
182
  | `--diff` | 按模式逐项展示改动 |
126
183
  | `--ouroboros` | 反复改写直到分数收敛(含 MPS 回滚) |
127
184
  | `--lang <ko\|en\|zh\|ja>` | 选择语言(默认:`ko`) |
128
- | `--profile <名称>` | 语气预设:`blog`, `academic`, `technical`, `formal`, `social`, `email`, `legal`, `medical`, `marketing`, `narrative`, `instructional`, `casual-conversation` |
185
+ | `--profile <名称>` | 语气预设:`blog`, `academic`, `technical`, `formal`, `social`, `email`, `legal`, `medical`, `marketing`, `narrative`, `instructional`, `casual-conversation`, `code-comment`, `commit-message`, `release-notes`, `namuwiki` |
129
186
  | `--tone <名称>` | 语调类别:`casual`, `professional`, `academic`, `narrative`, `marketing`, `instructional`, `auto` |
130
187
  | `--batch` | 把位置参数当作文件列表(例:`--batch docs/*.md`) |
131
188
  | `--format json\|text\|markdown` | 选择 JSON、纯文本或默认 Markdown 输出 |
132
- | `--prompt-mode strict\|minimal\|auto` | 选择完整模式包提示、压缩提示,或按后端自动选择 |
133
- | `--variants <1-5>` | 生成多个改写变体,同时保留相同事实和意义锚点 |
134
-
135
- 完整选项请运行 `patina --help`。
136
-
137
- ### 仅评分模式
189
+ | `--quiet` | 隐藏 stderr 中的状态、警告和进度日志 |
138
190
 
139
- `--score` `--audit` 测量的信号范围比 `--rewrite` 略广。viral-hook 包(`ko/en/zh/ja-viral-hook`,每种语言 8 个模式:数字震撼钩子、标题党收尾、跳过来源的权威断言、适合呼吸节奏的短句堆叠、夸张互动词汇、伪统计引用、头衔堆叠、未来自我承诺)为**仅检测**模式。
191
+ 完整选项请运行 `patina --help`。`patina doctor --json` 可在不调用 LLM 的情况下检查 Node/backend/tmux/API-key 状态。项目配置是可选的;一次性运行请用 flags,只有需要固定默认值时再添加 `.patina.yaml`。
140
192
 
141
- 这些信号只会出现在评分和审计中,用来让基准更贴近用户对四种语言 SNS 营销文案的直觉。`--rewrite`/`--diff`/`--ouroboros` 会跳过它们,因为这些信号往往是有意的修辞。实例: [`examples/viral-hook/`](examples/viral-hook/).
193
+ Markdown 较多的工程流程可以使用开发者 profile:`code-comment` 会收紧 inline comments/docstrings,`commit-message` 会把 Git 历史文本改成更强调意图和验证,`release-notes` 会把 changelog bullets 改成面向用户影响的发布说明,并保留迁移风险。`namuwiki` 是仅适用于韩文的 wiki 风格 profile,只包含原创的 license-safe 指南,不复制 NamuWiki 文章文本。
142
194
 
143
- ### 提示模式调优 (v3.11)
144
-
145
- `--prompt-mode strict|minimal|auto` 可在完整模式包(约 34KB 结构化提示)和压缩的轻量指令(约 3KB)之间取舍。`auto` 会按后端选择 — Gemini 在 minimal 下表现更好(长结构化提示会让它过度受限),Claude 能利用完整模式包,Codex 大致不敏感。case-05 记录了 A/B 结果。
195
+ ### 仅评分模式
146
196
 
147
- ### 多个风格变体 (v3.11)
197
+ `--score` `--audit` 测量的信号范围比 `--rewrite` 略广。viral-hook 包(`ko/en/zh/ja-viral-hook`,每种语言 9 个模式:数字震撼钩子、标题党收尾、跳过来源的权威断言、适合呼吸节奏的短句堆叠、夸张互动词汇、伪统计引用、头衔堆叠、未来自我承诺、格言式收束句)为**仅检测**模式。
148
198
 
149
- `--variants <1-5>` 会在一次调用中请求 N 个改写声音变体(例如 V1 casual、V2 direct、V3 measured)— 事实、数字和因果关系在所有变体中保持一致。每个结果会以 `## Variant N` 返回,方便你选择需要的语气。
199
+ 这些信号只会出现在评分和审计中,用来让基准更贴近用户对四种语言 SNS 营销文案的直觉。`--rewrite`/`--diff`/`--ouroboros` 会跳过它们,因为这些表达往往是有意的修辞。实例:[`examples/viral-hook/`](examples/viral-hook/)。
150
200
 
151
201
  ### 短文本评分增强 (v3.11)
152
202
 
153
- 当输入不超过 200 个字符或不超过 3 个段落时,对 register 敏感的类别(`language`、`style`、`viral-hook`)会获得 1.5 倍 severity multiplier,让单段文本里的声音变化也能体现在分数中。case-04 发现这些信号会被长文本公式低估。
203
+ 当输入不超过 200 个字符或不超过 3 个段落时,对语气更敏感的类别(`language`、`style`、`viral-hook`)会获得 1.5 倍权重,让单段文本里的声音变化也能体现在分数中。case-04 发现这些信号会被长文本公式低估。
154
204
 
155
205
  ### 自审隔离 (v3.11)
156
206
 
157
- 在 rewrite 模式中,模型会把自审笔记放在 `[SELF_AUDIT]`/`[/SELF_AUDIT]` 标签内,并包裹一个 `[BODY]`/`[/BODY]` 块(当 `--variants > 1` 时则是 `[VARIANT n]` 块)。patina 会在展示给用户前移除审计内容,因此原始输出保持干净 — 早期版本有时会把 “남아 있는 AI 티” 或 “Phase 3” 之类的前言泄漏到用户可见文本中。
207
+ 在 rewrite 模式中,模型会把自审笔记放在 `[SELF_AUDIT]`/`[/SELF_AUDIT]` 标签内,并包裹一个 `[BODY]`/`[/BODY]` 块。patina 会在展示给用户前移除审计内容,因此原始输出保持干净。早期版本有时会把 “남아 있는 AI 티” 或 “Phase 3” 之类的前言泄漏到用户可见文本中。
158
208
 
159
- ### Machine-readable output and exit codes
209
+ ### 机器可读输出和退出码
160
210
 
161
- `--format json` 会把所有模式包进稳定 envelope,包含 `overall`、`categories[]`、`tone`、`mps`、`gateResult` 和清理后的 `output` 正文。`--format markdown` 是默认值;`--format text` 保留无 YAML tone footer 的用户可见正文。退出码见 [EXIT-CODES.md](docs/EXIT-CODES.md):`0` 成功,`1` runtime/backend,`2` input/usage,`3` score gate 超限,`4` MAX MPS fallback/all-candidates-failed。
211
+ `--format json` 会把所有模式包进稳定的 JSON envelope,包含 `overall`、`categories[]`、`tone`、`mps`、`gateResult` 和清理后的 `output` 正文。`--quiet` 则为只需要 stdout 的脚本隐藏状态、警告和进度日志。`--format markdown` 是默认值;`--format text` 保留无 YAML tone footer 的用户可见正文。退出码见 [EXIT-CODES.md](docs/EXIT-CODES.md):`0` 成功,`1` runtime/backend,`2` input/usage,`3` score gate 超限。
162
212
 
163
213
  ### 分数权重漂移检测 (v3.11)
164
214
 
165
- `--score` 运行会把模型输出的 Weight 列与配置中的 `category-weights` 交叉检查。如果模型凭空创造类别(例如 `discord`)或替换成不同数字,stderr 会出现 `[patina]` 警告 这只用于可观测性,不会改变分数本身。
215
+ `--score` 运行会把模型输出的 Weight 列与配置中的 `category-weights` 对照。如果模型凭空创造类别(例如 `discord`)或替换成不同数字,stderr 会出现 `[patina]` 警告。这只用于可观测性,权重检查本身不会改变分数。确定性 shadow score 也会从 `src/features/*` 记录;当它与 LLM 分数相差超过 20 分时,patina 会警告并使用更保守的分数作为 gate。
216
+
217
+ 使用 `--voice-sample <path>` 或配置中的 `voice-sample: <path>`,可以让 rewrite 参考你写过的 1–3 个段落。Profile 和 tone 仍然决定目标 register;sample 只学习节奏、具体度、视角和句子质感,prompt 会明确禁止引入 sample facts。
166
218
 
167
219
  ## 语调
168
220
 
169
- `--tone` 是叠加在模式改写之上的具名声音轴。优先级:`--tone` CLI > `tone:` 配置 > `profile:` 配置。
221
+ `--tone` 是叠加在模式改写之上的具名语气轴。优先级:`--tone` CLI > `tone:` 配置 > `profile:` 配置。
170
222
 
171
223
  | 语调 | 适用 | 主要特征 |
172
224
  |------|------|----------|
@@ -177,17 +229,7 @@ patina --lang <ko|en|zh|ja> [模式] [--profile <名称>] input.txt
177
229
  | `marketing` | 广告文案、落地页、产品公告 | 短促有力、有说服力、CTA 友好 |
178
230
  | `instructional` | 教程、操作指南、技术文档 | 命令式动词、编号结构、抑制猜测语 |
179
231
 
180
- `--tone auto` 通过启发式(词汇 + 结构信号)自动选择最契合的语调。zh/ja 上使用任何语调(包括 `auto`)均会发出警告并回退到 profile-only 模式 Phase 4.5b 启发式仅覆盖 ko/en。
181
-
182
- ### MAX 模式
183
-
184
- 将同一段文本独立交给 Claude、Codex、Gemini。通过 MPS ≥ 70 门槛后,AI 分数最低(最像人写)的结果胜出:
185
-
186
- ```
187
- /patina-max
188
-
189
- [在此粘贴你的文本]
190
- ```
232
+ `--tone auto` 通过启发式(词汇 + 结构信号)自动选择最契合的语气。zh/ja 上使用任何语气(包括 `auto`)都会发出警告并回退到 profile-only 模式,因为 Phase 4.5b 启发式仅覆盖 ko/en。
191
233
 
192
234
  ## 工作原理
193
235
 
@@ -195,54 +237,69 @@ patina --lang <ko|en|zh|ja> [模式] [--profile <名称>] input.txt
195
237
  输入
196
238
 
197
239
  [步骤 4.5] 语义锚点提取 (主张、极性、因果、数值)
198
- [步骤 4.6] 文体统计预处理 (burstiness CV + MATTR)
199
- [步骤 4.7] AI 词汇重叠 ( ~108 / 102 项)
240
+ [步骤 4.6] 文体统计预处理 (burstiness CV + MATTR; zh/ja 字符 token fallback)
241
+ [步骤 4.7] AI 词汇重叠 (英文 88 / 韩文 102 / 中文 60 / 日文 60 项)
200
242
  [阶段 1] 结构扫描 + 锚点验证
201
243
  [阶段 2] 句子改写 + 锚点验证
202
244
  [阶段 3] 自审 (极性、回归、MPS)
203
245
 
204
- 自然的文本(语义已验证)
246
+ 自然文本(语义已验证)
205
247
  ```
206
248
 
207
- 任一验证阶段语义偏移则重试或回滚。
249
+ 如果任一验证阶段发现语义偏移,patina 会重试或回滚。
208
250
 
209
- **校准** *(500 段语料,可通过 `.omc/research/v3_8_remeasure.py` 复现)*:HC3 ChatGPT (en) 编辑热点召回率 76% [66.7–83.3%],paired ko/AI 语料 91% [84.095.4%](各 n=100,binomial 95% CI)。人类写作误检以不同体裁 1325% 点估计范围单独报告。接受门槛:AI ≥ 75%,最大 FP ≤ 25%。算法见 [stylometry.md](core/stylometry.md)
251
+ **校准** *(2026-05-22 现代模型重基线;方法见 [2026-rebaseline.md](docs/research/2026-rebaseline.md))*:在 GPT-5.5、Claude Sonnet 4.6、Gemini 2.5 Pro CLI 样本上,确定性编辑热点命中率为 67.3% [63.571.0%]n=600,韩文+英文)。人类对照误检率为 16.0% [11.621.7%](n=200)。语言×模型的细分结果见 [rebaseline-latest.md](docs/benchmarks/rebaseline-latest.md)。这只是编辑信号,不是作者判定,也不是绕过检测的承诺。
210
252
 
211
253
  ## 配置
212
254
 
213
255
  ```yaml
214
256
  # .patina.default.yaml
215
- version: "3.11.0"
257
+ version: "4.0.0"
216
258
  language: ko # ko | en | zh | ja
217
259
  profile: default
218
260
  output: rewrite # rewrite | diff | audit | score
219
261
  tone: # casual | professional | academic | narrative | marketing | instructional | auto
220
- max-models: [claude, gemini]
221
262
  ```
222
263
 
223
- 模式包按语言前缀自动发现。工作目录中的 `.patina.yaml` 会覆盖默认值。扩展检测的列表键(`blocklist`、`allowlist`、`skip-patterns`)会在 default/global/project 配置之间追加合并;`max-models` 等 provider 列表会替换原值,便于用户选择精确的后端集合。
264
+ 模式包按语言前缀自动发现。工作目录中的 `.patina.yaml` 会覆盖默认值。用于扩展检测的列表键(`blocklist`、`allowlist`、`skip-patterns`)会在 default/global/project 配置之间追加合并;其他数组键会直接替换,方便用户指定精确值。
224
265
 
225
266
  ## 文档
226
267
 
268
+ - **[Cookbook](docs/COOKBOOK.md)** — 实用配方(Hugo 批量打分、GitHub Actions、误报 triage、自定义 profile、pre-commit)
227
269
  - **[Glossary](docs/GLOSSARY.md)** — MPS、fidelity、burstiness、MATTR、模式等常见术语的简短定义
228
270
  - **[Demo](docs/DEMO.md)** — 终端 transcript 与多种体裁的 before/after 快照
229
- - **[Patterns](docs/PATTERNS.md)** — 160 个模式目录
230
- - **[Authentication](docs/AUTHENTICATION.md)** — 后端、服务商、免费层设置
231
- - **[CLI Contract](docs/CLI.md)** — score gate、退出码,以及适合自动化的接口边界
232
- - **[Flag Parity](docs/FLAG-PARITY.md)** — standalone CLI、`/patina`、`/patina-max` 的选项支持范围
233
- - **[Ethics](docs/ETHICS.md)** — 预期用途、禁止用途和披露立场
234
- - **[FAQ](docs/FAQ.md)** — detector-bypass 疑虑、MPS、误报、贡献起点
271
+ - **[Patterns](docs/PATTERNS.md)** — 168 个模式目录
272
+ - **[Authentication](docs/AUTHENTICATION.md)** ([한국어](docs/AUTHENTICATION_KR.md)) — 后端、服务商、免费层设置
273
+ - **[GitHub Action](docs/integrations/github-action.md)** — 无需 live model key 即可生成 PR hotspot 评论与 README score badge
274
+ - **[Pre-commit](docs/integrations/pre-commit.md)** — pre-commit、Husky 与 Lefthook 的 score-only 配方
275
+ - **[Static-site Stencils](docs/integrations/static-sites.md)** — Hugo、Astro 与 Next.js MDX 构建期打分配方
276
+ - **[Docker](docs/integrations/docker.md)** — GHCR 镜像用法与 release tag
277
+ - **[Release workflow](docs/integrations/release.md)** — npm provenance + GHCR 发布清单
278
+ - **[CLI Contract](docs/CLI.md)** — score gate、JSON/text/Markdown 输出,以及适合自动化的接口边界
279
+ - **[API Reference](docs/API.md)** — 用于编程式导入与打分 helper 的生成 JSDoc 参考
280
+ - **[Flag Parity](docs/FLAG-PARITY.md)** — standalone CLI 与 `/patina` 的选项支持范围
281
+ - **[Exit Codes](docs/EXIT-CODES.md)** — 面向 CI 与编辑器集成的进程退出码约定
282
+ - **[Ethics](docs/ETHICS.md)** — 正确使用目的、禁止用途和披露立场
283
+ - **[FAQ](docs/FAQ.md)** ([한국어](docs/FAQ_KR.md)) — detector-bypass 疑虑、MPS、误报、贡献起点
284
+ - **[False-positive Gallery](docs/FALSE-POSITIVES.md)** — 应被视为编辑提示而非指控的人类文风示例
235
285
  - **[Comparison](docs/COMPARISON.md)** — 与常见 paraphraser/humanizer 工具的事实比较
236
286
  - **[Branding](docs/BRANDING.md)** — canonical logo/social assets 和 OG 设置说明
237
287
  - **[Design](DESIGN.md)** — repo-native SVG 与 README surface 的产品/品牌基准
238
288
  - **[Roadmap](docs/ROADMAP.md)** — 质量、基准、产品、社区和发布优先级
289
+ - **[Docs Platform RFC](docs/RESEARCH-DOCS-PLATFORM.md)** — Docusaurus、Astro Starlight、MkDocs 与 GitHub Pages 调研
290
+ - **[Benchmark Reports](docs/benchmarks/README.md)** — 已签入的基准产物、刷新命令与 public-claim gate
239
291
  - **[Benchmark Report](docs/benchmarks/latest.md)** — 最新可复现 suspect-zone 基准摘要
292
+ - **[Detector Comparison Harness](docs/benchmarks/detector-comparison.md)** — 第三方 detector 的离线/手动对比协议
240
293
  - **[AI/Human Metrics Research](docs/research/ai-human-metrics.md)** — 用于测量 AI-like writing signals 的基准设计说明
241
- - **[Launch Copy](docs/social/patina-launch-copy.md)** — Show HN、Reddit、X、韩国社区草稿
294
+ - **[2026 Modern-model Rebaseline](docs/research/2026-rebaseline.md)** — 带当前日期戳的 KO+EN catch/FP claim
295
+ - **[2025+ Re-baseline Plan](docs/research/2025-rebaseline-plan.md)** — 面向更广 model-era claim 的协议
296
+ - **[zh/ja Lexicon Calibration](docs/research/zh-ja-lexicon-calibration.md)** — starter lexicon gate 与剩余 corpus risk
297
+ - **[Launch Copy](docs/social/patina-launch-copy.md)** — launch sequence、score gate 与 Show HN/Product Hunt/Reddit/X/韩国社区草稿
298
+ - **[Signs of AI Writing](docs/social/signs-of-ai-writing.md)** ([한국어](docs/social/signs-of-ai-writing_KR.md)) — 附带引用示例的可分享编辑 checklist
242
299
  - **[Stylometry](core/stylometry.md)** — burstiness + MATTR + AI 词汇算法
243
300
  - **[Scoring](core/scoring.md)** — AI 相似度 + 忠实度 + MPS
244
301
  - **[Changelog](CHANGELOG.md)** — 发布说明和方法论
245
- - **[Contributing](CONTRIBUTING.md)** — 模式提交、误报 triage、基准 fixture、版本管理
302
+ - **[Contributing](CONTRIBUTING.md)** ([한국어](CONTRIBUTING_KR.md)) — 模式提交、误报 triage、基准 fixture、版本管理
246
303
  - **[Governance](GOVERNANCE.md)** / **[Maintainers](MAINTAINERS.md)** — 轻量级项目决策规则
247
304
 
248
305
  ## 致谢
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: patina
3
- version: 3.11.0
3
+ version: 4.0.0
4
4
  description: Detect and rewrite AI writing patterns in Korean, English, Chinese, and Japanese text so it reads as if a human wrote it. Meaning-preservation (MPS) verified.
5
5
  allowed-tools:
6
6
  - Read
@@ -32,7 +32,6 @@ Glob .patina.default.yaml → Read
32
32
  - `output`: 출력 모드 (`rewrite` | `diff` | `audit` | `score`)
33
33
  - `blocklist`: 추가 감지 어휘
34
34
  - `allowlist`: 감지 제외 어휘
35
- - `prompt-mode`: 프롬프트 로딩 방식 (`strict` | `minimal` | `auto`, 기본: `strict`)
36
35
 
37
36
  `$ARGUMENTS`에서 옵션을 파싱하여 설정을 오버라이드:
38
37
  - `--profile <name>`: 프로필 변경
@@ -42,8 +41,6 @@ Glob .patina.default.yaml → Read
42
41
  - `--ouroboros`: ouroboros 모드 (반복 교정 + 점수 수렴)
43
42
  - `--lang <code>`: 처리 언어 변경 (ko, en, zh, ja). 설정 파일의 `language` 값을 오버라이드한다.
44
43
  - `--tone <name>`: 톤 카테고리 지정. 유효값: `casual | professional | academic | narrative | marketing | instructional | auto`. 알 수 없는 값이면 즉시 오류: "Unknown tone '<name>'. Valid tones: casual, professional, academic, narrative, marketing, instructional, auto"
45
- - `--prompt-mode <strict|minimal|auto>`: 패턴 팩 전체를 쓰는 strict 모드와 압축 지시문 minimal 모드 중 선택한다. `auto`는 백엔드/문맥별로 선택하되, 불확실하면 strict를 사용한다.
46
- - `--variants <1-5>`: rewrite 모드에서 같은 의미 앵커를 보존한 N개의 문체 변형을 요청한다. `--audit`, `--score`, `--diff`에는 적용하지 않는다.
47
44
  - `--batch <files>`: 여러 파일을 한꺼번에 처리 (glob 또는 명시적 경로 목록).
48
45
  - `--in-place`: 원본 파일을 교정된 텍스트로 덮어쓴다.
49
46
  - `--suffix <ext>`: 결과를 `{원본명}{ext}` 파일로 저장한다 (예: `--suffix .humanized`).
@@ -115,7 +112,7 @@ Read profiles/{profile}.md
115
112
  Glob custom/profiles/{profile}.md → Read (사용자 커스텀 프로필 우선 로드)
116
113
  ```
117
114
 
118
- 커스텀 프로필(`custom/profiles/{profile}.md`)이 있으면 우선 사용한다. 없으면 `profiles/{profile}.md`를 사용한다. 둘 다 없으면 `profiles/default.md`를 사용한다.
115
+ 커스텀 프로필(`custom/profiles/{profile}.md`)이 있으면 우선 사용한다. 없으면 `profiles/{profile}.md`를 사용한다. 둘 다 없으면 `profiles/default.md`를 사용한다. `profiles/namuwiki.md`는 한국어 전용이므로 `--lang`이 `ko`가 아니면 기본 프로필로 폴백한다.
119
116
 
120
117
  프로필에 `voice-overrides`와 `pattern-overrides`가 있으면 이를 파싱하여 5단계에서 적용한다.
121
118
  - `voice-overrides`: voice.md 지침의 강도를 프로필별로 조절 (amplify/allow/suppress)
@@ -141,7 +138,7 @@ Read core/voice.md
141
138
 
142
139
  > **주의:** 텍스트가 1개 단락 이하이고 2개 문장 이하이면 추출을 건너뛰고 파이프라인을 정상 실행한다 (오버헤드 불필요).
143
140
  >
144
- > **참고:** 앵커 추출이 건너뛰어지거나 추출된 앵커가 0개이면, MPS는 N/A로 표시되며 ouroboros와 MAX mode의 MPS 게이팅을 면제한다.
141
+ > **참고:** 앵커 추출이 건너뛰어지거나 추출된 앵커가 0개이면, MPS는 N/A로 표시되며 ouroboros의 MPS 게이팅을 면제한다.
145
142
 
146
143
  ### 앵커 유형
147
144
 
@@ -223,13 +220,13 @@ tone_confidence: high
223
220
 
224
221
  > **주의:** 텍스트가 단락 ≤2 또는 전체 문장 ≤2 이면 4.6단계를 통째로 건너뛴다 (4.5단계와 동일 임계).
225
222
  >
226
- > **언어 제한 (v1):** `stylometry.languages` 설정에 포함된 언어에서만 실행한다. 기본값은 `[ko, en]`. 처리 언어가 `zh` 또는 `ja` 인 경우 4.6단계를 skip 하고 파이프라인을 정상 진행한다 (zh/ja 토큰화는 v2 이후 로드맵).
223
+ > **언어 제한:** `stylometry.languages` 설정에 포함된 언어에서만 실행한다. 기본값은 `[ko, en, zh, ja]`. 처리 언어가 `zh` 또는 `ja` 인 경우 whitespace 단어가 아니라 문자 토큰 fallback으로 4.6단계를 실행한다.
227
224
 
228
225
  ### 메트릭 정의
229
226
 
230
227
  전체 알고리즘 정의는 `core/stylometry.md`를 참조한다. 핵심 공식만 인라인으로 제시한다.
231
228
 
232
- **Tokenization** — whitespace 기준 분할 + edge-punctuation strip. ko=어절, en=단어. 형태소 분석기 미사용.
229
+ **Tokenization** — ko/en은 whitespace 기준 분할 + edge-punctuation strip(ko=어절, en=단어)을 사용한다. zh/ja는 Han/Kana 문자와 ASCII run을 토큰으로 삼는 deterministic character-token fallback을 사용한다. 형태소 분석기 미사용.
233
230
 
234
231
  **Burstiness (CV, 문장 길이 변동성)**
235
232
 
@@ -301,7 +298,7 @@ hot 단락 내부에서 인접 문장 토큰 수 차이 < 20% 인 연속 문장
301
298
 
302
299
  > **주의:** 텍스트가 단락 ≤2 또는 전체 문장 ≤2 이면 4.7단계를 통째로 건너뛴다 (4.6단계와 동일 임계).
303
300
  >
304
- > **언어 제한 (v1):** `lexicon.languages` 설정에 포함된 언어에서만 실행한다. 기본값은 `[en, ko]`. 처리 언어가 `zh` 또는 `ja` 인 경우 4.7단계를 skip 하고 파이프라인을 정상 진행한다 (zh/ja lexicon 큐레이션은 v2 이후 로드맵).
301
+ > **언어 제한:** `lexicon.languages` 설정에 포함된 언어에서만 실행한다. 기본값은 `[en, ko, zh, ja]`. zh/ja character-token fallback 특성상 기본 사전을 phrase-only로 유지한다.
305
302
 
306
303
  ### 사전 로드
307
304
 
@@ -311,8 +308,8 @@ Glob custom/lexicon/ai-{lang}.md → Read (사용자 커스텀 우선)
311
308
  ```
312
309
 
313
310
  각 lexicon 파일은 두 섹션으로 구성된다:
314
- - `## Strict matches`: 대소문자 무시 whole-word 매칭 (한국어 어절은 substring 근사)
315
- - `## Multi-word phrases`: 대소문자 무시 substring 매칭. 한국어 `~` placeholder 는 wildcard 로 취급
311
+ - `## Strict matches`: 대소문자 무시 whole-word 매칭 (CJK ko/zh/ja는 substring 근사)
312
+ - `## Multi-word phrases`: 대소문자 무시 substring 매칭. `~` placeholder 는 wildcard 로 취급
316
313
 
317
314
  ### 알고리즘
318
315
 
@@ -505,7 +502,7 @@ FOR each anchor IN anchor_list:
505
502
 
506
503
  0. **Suspect zone 활용** — 4.6단계의 hot 문장 그룹(`P{n}.S{m}-S{k}`)을 우선 재작성 대상으로 처리. meta block 의 sub-flag 정보를 사용해 패턴 스캔 우선순위를 결정한다. 4.7단계의 lexicon hit 인용("AI-lexicon hits: ..." 부분) 도 우선 재작성 신호로 사용 — 인용된 AI 어구가 등장하는 문장을 패턴 스캔 우선순위 상단에 둔다
507
504
  1. **AI 패턴 식별** - 로드된 문장/어휘 패턴 팩의 모든 패턴을 스캔
508
- 2. **문제 구간 다시 쓰기** - AI스러운 표현을 자연스러운 대안으로 교체
505
+ 2. **문제 구간 다시 쓰기** - AI스러운 표현을 토큰 단위로 치환하지 말고, 문맥을 읽은 뒤 절/문장 단위로 자연스럽게 다시 쓴다
509
506
  3. **의미 보존** - 핵심 메시지를 유지
510
507
  4. **어조 맞추기** - 프로필의 어조 지침에 따라 톤 조절
511
508
  5. **개성 불어넣기** - voice.md의 지침에 따라 실제 사람의 목소리를 넣기
@@ -528,6 +525,8 @@ FOR each anchor IN anchor_list:
528
525
 
529
526
  9. **의미 보존 제약 주입** — 의미 위험도가 HIGH인 패턴을 적용할 때, 해당 문단의 앵커를 교정 프롬프트에 포함한다: "다음 주장을 반드시 유지하라: {앵커 목록}". MEDIUM 위험도 패턴은 극성(Polarity) 또는 부정(Negation) 앵커가 있는 문단에서만 제약을 주입한다. LOW 위험도 패턴은 제약 없이 적용한다.
530
527
 
528
+ **CJK 절/문장 단위 교정 가드 (issue #352):** `--lang ko|zh|ja`에서는 구두점이나 단어 1개만 1:1로 바꾸지 않는다. em dash, 콜론, 세미콜론, 슬래시, 쉼표 접속, 괄호식 삽입구처럼 절 관계를 표시하는 구두점이 AI 신호와 함께 보이면, 문장 전체를 읽고 목표 언어의 자연스러운 절 구조·문장 분리·접속 표현으로 다시 짠다. 번역체/직역 명사구가 구두점에 붙어 있으면 둘을 함께 고친다. 한국어 예: `무 TUI` 식 직역은 `TUI 없이 완전 자율로 설치하려면 ...`처럼 풀고, `"끝난 것 같아요"로는 부족한 열린 작업`은 `"끝난 것 같아요"만으로는 부족한, 결과를 끝까지 확인해야 하는 열린 작업`처럼 절 관계를 드러낸다. 교정 중 행위자·극성·조건·숫자·인과는 유지한다.
529
+
531
530
  > **주의:** 5a단계에서 이미 교정한 구간을 5b단계에서 다시 "정돈된 공식문"으로 되돌리지 않도록 주의한다.
532
531
 
533
532
  ---
@@ -582,14 +581,6 @@ tone_confidence: low | medium | high
582
581
 
583
582
  > **주의 (A7):** rewrite 최종본 본문에 tone 정보를 언급하거나 삽입하지 않는다. "이 텍스트는 casual 톤으로 재작성되었습니다" 같은 내러티브 인터젝션 금지.
584
583
 
585
- #### 변형 출력 (`--variants`)
586
-
587
- `--variants N`이 주어지면 최종본을 하나로 고정하지 말고 `## Variant 1` … `## Variant N` 형식으로 반환한다. 각 변형은 같은 의미 앵커(주장, 수치, 인과관계, 고유명사, 극성)를 보존해야 하며, 문체 축만 달라져야 한다.
588
-
589
- - Variant 1: 기본 프로필/톤을 가장 충실히 따른다.
590
- - Variant 2+: 더 직설적, 더 캐주얼, 더 절제된 식으로 리듬과 레지스터를 바꾼다.
591
- - 각 variant마다 `[SELF_AUDIT]` 메모는 내부 검수용으로만 사용하고 사용자-facing 본문에는 남기지 않는다.
592
-
593
584
  ### diff 모드 (`--diff`)
594
585
 
595
586
  변경 사항을 패턴별로 표시한다. 뭘 왜 바꿨는지 보여준다. 끝에 YAML footer 추가.