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.
- package/.patina.default.yaml +29 -29
- package/CHANGELOG.md +53 -0
- package/NOTICE +21 -0
- package/README.md +117 -224
- package/README_JA.md +134 -77
- package/README_KR.md +132 -74
- package/README_ZH.md +137 -80
- package/SKILL.md +11 -20
- package/artifacts/rebaseline-2025/README.md +147 -0
- package/artifacts/rebaseline-2025/human-controls.public.jsonl +250 -0
- package/artifacts/rebaseline-2025/intake.example.jsonl +2 -0
- package/artifacts/rebaseline-2025/intake.local.example.jsonl +25 -0
- package/artifacts/rebaseline-2025/prompts.template.jsonl +7 -0
- package/artifacts/rebaseline-2025/sources.ko-public.jsonl +39 -0
- package/assets/brand/patina-badge.svg +18 -0
- package/assets/brand/patina-mark.svg +8 -0
- package/assets/demo/README.md +79 -0
- package/core/scoring.md +12 -12
- package/core/standalone-prompt.md +3 -1
- package/core/stylometry.md +93 -22
- package/docs/API.md +1554 -0
- package/docs/AUTHENTICATION.md +50 -26
- package/docs/AUTHENTICATION_KR.md +54 -29
- package/docs/BRANDING.md +9 -8
- package/docs/CLI.md +55 -14
- package/docs/COOKBOOK.md +8 -21
- package/docs/DEMO.md +32 -5
- package/docs/EXIT-CODES.md +2 -3
- package/docs/FALSE-POSITIVES.md +63 -0
- package/docs/FAQ.md +9 -1
- package/docs/FAQ_KR.md +3 -1
- package/docs/FLAG-PARITY.md +33 -47
- package/docs/ISSUE-WAVES.md +57 -0
- package/docs/PATTERNS-EN.md +67 -3
- package/docs/PATTERNS-JA.md +68 -2
- package/docs/PATTERNS-KO.md +70 -7
- package/docs/PATTERNS-ZH.md +67 -3
- package/docs/PATTERNS.md +5 -5
- package/docs/RESEARCH-DOCS-PLATFORM.md +54 -0
- package/docs/ROADMAP.md +46 -66
- package/docs/TRANSLATIONESE-KO.md +51 -0
- package/docs/audits/2026-05-deep-research.md +3 -1
- package/docs/benchmarks/README.md +51 -0
- package/docs/benchmarks/detector-comparison.json +69 -9
- package/docs/benchmarks/detector-comparison.md +10 -5
- package/docs/benchmarks/katfish-ko-latest.json +657 -0
- package/docs/benchmarks/katfish-ko-latest.md +77 -0
- package/docs/benchmarks/latest.json +1183 -108
- package/docs/benchmarks/latest.md +84 -60
- package/docs/benchmarks/lexicon-freshness-en-2026-05-22.json +1121 -0
- package/docs/benchmarks/lexicon-freshness-en-2026-05-22.md +136 -0
- package/docs/benchmarks/rebaseline-latest.json +381 -0
- package/docs/benchmarks/rebaseline-latest.md +121 -0
- package/docs/benchmarks/register-stratified-latest.json +164 -0
- package/docs/benchmarks/register-stratified-latest.md +99 -0
- package/docs/benchmarks/register-stratified.md +43 -0
- package/docs/integrations/github-action.md +44 -11
- package/docs/integrations/playground.md +58 -0
- package/docs/integrations/pre-commit.md +5 -5
- package/docs/integrations/release.md +5 -3
- package/docs/integrations/static-sites.md +83 -0
- package/docs/research/2025-rebaseline-plan.md +71 -2
- package/docs/research/2026-rebaseline.md +102 -0
- package/docs/research/adversarial-mps.md +41 -0
- package/docs/research/ai-human-metrics.md +35 -23
- package/docs/research/human-eval-panel.md +42 -0
- package/docs/research/judge-agreement.md +24 -0
- package/docs/research/ko-2025-corpus-sources.md +135 -0
- package/docs/research/lexicon-freshness-audit.md +64 -0
- package/docs/research/zh-ja-lexicon-calibration.md +60 -0
- package/docs/social/patina-launch-copy.md +173 -100
- package/docs/social/patina-launch-execution.md +94 -0
- package/docs/social/patina-launch-korean-first.md +83 -0
- package/docs/social/signs-of-ai-writing.md +26 -0
- package/docs/social/signs-of-ai-writing_KR.md +26 -0
- package/lexicon/ai-en.md +21 -24
- package/lexicon/ai-ja.md +158 -0
- package/lexicon/ai-ko.md +9 -9
- package/lexicon/ai-zh.md +158 -0
- package/lexicon/provenance/ai-en.json +970 -0
- package/lexicon/provenance/ai-ja.json +542 -0
- package/lexicon/provenance/ai-ko.json +866 -0
- package/lexicon/provenance/ai-zh.json +542 -0
- package/package.json +49 -8
- package/patterns/en-communication.md +5 -0
- package/patterns/en-content.md +5 -0
- package/patterns/en-filler.md +5 -0
- package/patterns/en-language.md +29 -1
- package/patterns/en-structure.md +5 -0
- package/patterns/en-style.md +5 -0
- package/patterns/en-viral-hook.md +42 -2
- package/patterns/ja-communication.md +5 -0
- package/patterns/ja-content.md +5 -0
- package/patterns/ja-filler.md +5 -0
- package/patterns/ja-language.md +33 -1
- package/patterns/ja-structure.md +12 -0
- package/patterns/ja-style.md +5 -0
- package/patterns/ja-viral-hook.md +41 -2
- package/patterns/ko-communication.md +5 -0
- package/patterns/ko-content.md +5 -0
- package/patterns/ko-filler.md +5 -0
- package/patterns/ko-language.md +33 -1
- package/patterns/ko-structure.md +25 -6
- package/patterns/ko-style.md +5 -0
- package/patterns/ko-viral-hook.md +38 -2
- package/patterns/zh-communication.md +5 -0
- package/patterns/zh-content.md +5 -0
- package/patterns/zh-filler.md +5 -0
- package/patterns/zh-language.md +37 -1
- package/patterns/zh-structure.md +12 -0
- package/patterns/zh-style.md +5 -0
- package/patterns/zh-viral-hook.md +38 -2
- package/playground/README.md +55 -0
- package/playground/analytics.js +4 -0
- package/playground/analyzer.js +883 -0
- package/playground/app.js +157 -0
- package/playground/data/lexicons.js +343 -0
- package/playground/index.html +138 -0
- package/playground/styles.css +267 -0
- package/profiles/namuwiki.md +111 -0
- package/scripts/adversarial-mps-report.mjs +201 -0
- package/scripts/badge-json.mjs +79 -0
- package/scripts/benchmark-report.mjs +56 -9
- package/scripts/check-release-metadata.mjs +0 -2
- package/scripts/detector-comparison.mjs +7 -7
- package/scripts/generate-playground-data.mjs +77 -0
- package/scripts/katfish-calibration.mjs +464 -0
- package/scripts/lexicon-freshness.mjs +485 -0
- package/scripts/lint.mjs +1 -1
- package/scripts/precommit-score.mjs +4 -3
- package/scripts/prose-score.mjs +81 -5
- package/scripts/rebaseline-intake.mjs +242 -0
- package/scripts/rebaseline-score.mjs +268 -0
- package/scripts/rebaseline-summary.mjs +773 -0
- package/scripts/rebaseline-web-collect.mjs +410 -0
- package/scripts/update-benchmark-ranges.mjs +1 -0
- package/src/api.js +69 -105
- package/src/auth.js +50 -2
- package/src/backends/claude-cli.js +19 -4
- package/src/backends/codex-cli.js +19 -3
- package/src/backends/contract.js +230 -1
- package/src/backends/gemini-cli.js +18 -5
- package/src/backends/index.js +87 -12
- package/src/backends/kimi-cli.js +161 -0
- package/src/cli.js +577 -567
- package/src/commands/doctor.js +2 -2
- package/src/config.js +29 -0
- package/src/errors.js +53 -1
- package/src/features/discourse-tells.js +68 -0
- package/src/features/index.js +82 -8
- package/src/features/lexicon.js +40 -6
- package/src/features/markup-leakage.js +69 -0
- package/src/features/segment.js +41 -0
- package/src/features/signal-strength.js +81 -0
- package/src/features/stylometry.js +231 -1
- package/src/features/translationese.js +127 -0
- package/src/loader.js +76 -0
- package/src/logger.js +22 -23
- package/src/model-defaults.js +55 -0
- package/src/ouroboros.js +31 -0
- package/src/output.js +102 -90
- package/src/prompt-builder.js +103 -68
- package/src/providers.js +51 -4
- package/src/scoring.js +210 -2
- package/src/security.js +75 -0
- package/tests/fixtures/live-quality/en/public-docs-01.md +26 -0
- package/tests/fixtures/live-quality/ko/public-docs-01.md +26 -0
- package/tests/fixtures/suspect-zones/expected-ranges.json +207 -16
- package/tests/fixtures/suspect-zones/ja/ai/ja-ai-04-lexicon.md +11 -0
- package/tests/fixtures/suspect-zones/ja/natural/ja-nat-04-lexicon-cold.md +11 -0
- package/tests/fixtures/suspect-zones/ko/ai/ko-ai-02.md +4 -5
- package/tests/fixtures/suspect-zones/ko/ai/ko-ai-07-ko-diagnostic.md +11 -0
- package/tests/fixtures/suspect-zones/zh/ai/zh-ai-04-lexicon.md +11 -0
- package/tests/fixtures/suspect-zones/zh/natural/zh-nat-04-lexicon-cold.md +11 -0
- package/tests/quality/README.md +188 -11
- package/tests/quality/adversarial-mps/fixtures.jsonl +10 -0
- package/tests/quality/benchmark.mjs +39 -1
- package/tests/quality/dogfood.mjs +5 -3
- package/tests/quality/live-fixtures.jsonl +2 -0
- package/tests/quality/live-quality.mjs +596 -0
- package/tests/quality/ranking-metrics.mjs +136 -0
- package/tests/quality/rebaseline-manifest.example.jsonl +5 -0
- package/vercel.json +53 -0
- package/SKILL-MAX.md +0 -455
- package/docs/internal/HARNESS.md +0 -14
- package/docs/internal/README.md +0 -14
- package/docs/internal/WARP.md +0 -23
- package/patina-max/SKILL.md +0 -523
- package/patina-max/composite.py +0 -457
- package/src/cache.js +0 -106
- package/src/commands/init.js +0 -208
- package/src/manifest.js +0 -162
- package/src/max-mode.js +0 -207
package/.patina.default.yaml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
version: "
|
|
1
|
+
version: "4.0.0"
|
|
2
2
|
language: ko # Korean (default) -- auto-loads all ko-*.md patterns
|
|
3
3
|
# language: en -- English -- auto-loads all en-*.md patterns
|
|
4
4
|
# language: zh -- Chinese -- auto-loads all zh-*.md patterns
|
|
@@ -60,30 +60,8 @@ patterns:
|
|
|
60
60
|
skip-patterns: [] # additive merge across default/global/project configs
|
|
61
61
|
blocklist: [] # additive merge: 추가로 감지할 어휘
|
|
62
62
|
allowlist: [] # additive merge: 감지에서 제외할 어휘
|
|
63
|
-
# Other arrays
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
-
# MAX mode: multi-model humanization
|
|
67
|
-
# claude uses `claude -p`, gemini uses `gemini -p '' --output-format text`,
|
|
68
|
-
# codex uses `codex exec --skip-git-repo-check --output-last-message <file>`
|
|
69
|
-
# Supported models: claude, codex, gemini
|
|
70
|
-
# Override with CLI: --models claude,gemini,codex
|
|
71
|
-
max-models:
|
|
72
|
-
- claude
|
|
73
|
-
- gemini
|
|
74
|
-
|
|
75
|
-
# Dispatch mode for MAX mode CLI execution
|
|
76
|
-
# omc: tmux pane parallel dispatch (recommended, requires oh-my-claudecode + tmux)
|
|
77
|
-
# - Uses a unique temp dir per run
|
|
78
|
-
# - Waits only for selected models and marks timed-out runs as failed
|
|
79
|
-
# - All providers receive the prompt via stdin
|
|
80
|
-
# direct: sequential stdin dispatch (fallback; apply the same per-model timeout)
|
|
81
|
-
# api: HTTP API dispatch (no local CLI needed; requires PATINA_API_KEY env var)
|
|
82
|
-
# - Uses OpenAI-compatible chat completions endpoint
|
|
83
|
-
# - Works with Anthropic, OpenAI, Google AI Studio, OpenRouter, etc.
|
|
84
|
-
# - Requires curl and jq
|
|
85
|
-
# - Model IDs configurable via PATINA_MODEL_* env vars
|
|
86
|
-
dispatch: omc
|
|
63
|
+
# Other arrays are replaced by the higher-precedence config so users can choose
|
|
64
|
+
# an exact value instead of merging by accident.
|
|
87
65
|
|
|
88
66
|
# Scoring: LLM score remains canonical, with a deterministic shadow score
|
|
89
67
|
# from src/features/* for reproducible drift checks.
|
|
@@ -164,6 +142,9 @@ ouroboros:
|
|
|
164
142
|
marketing:
|
|
165
143
|
ai-likeness: 0.65
|
|
166
144
|
fidelity: 0.35
|
|
145
|
+
namuwiki:
|
|
146
|
+
ai-likeness: 0.65
|
|
147
|
+
fidelity: 0.35
|
|
167
148
|
severity-points:
|
|
168
149
|
high: 3
|
|
169
150
|
medium: 2
|
|
@@ -188,6 +169,25 @@ stylometry:
|
|
|
188
169
|
high: 0.70 # MATTR > 0.70 → high
|
|
189
170
|
sentence_zoom:
|
|
190
171
|
similarity_threshold: 0.20 # adjacent sentences within ±20% token count → grouped as sub-flag
|
|
172
|
+
ko_diagnostics:
|
|
173
|
+
enabled: true # conservative ko-only composite; requires all bands below
|
|
174
|
+
bands:
|
|
175
|
+
minSentences: 4
|
|
176
|
+
minEojeols: 20
|
|
177
|
+
spacing:
|
|
178
|
+
maxEojeolLengthCV: 0.38
|
|
179
|
+
comma:
|
|
180
|
+
maxPerSentence: 1
|
|
181
|
+
posProxy:
|
|
182
|
+
minMatchedCount: 10
|
|
183
|
+
maxClassDiversity: 0.26
|
|
184
|
+
spacing:
|
|
185
|
+
metric: eojeol_length_cv # dependency-free Korean spacing regularity proxy
|
|
186
|
+
comma:
|
|
187
|
+
metric: per_sentence_and_per_100_chars
|
|
188
|
+
pos_proxy:
|
|
189
|
+
metric: suffix_class_diversity
|
|
190
|
+
dependency: none # no runtime morphology analyzer
|
|
191
191
|
skip:
|
|
192
192
|
min_paragraphs: 2
|
|
193
193
|
min_sentences: 2
|
|
@@ -200,12 +200,12 @@ stylometry:
|
|
|
200
200
|
# See core/stylometry.md §16 for the full algorithm.
|
|
201
201
|
lexicon:
|
|
202
202
|
enabled: true
|
|
203
|
-
languages: [en, ko
|
|
203
|
+
languages: [en, ko, zh, ja]
|
|
204
204
|
density_threshold: 2.0 # matches per 1000 tokens; > threshold → SUSPECT
|
|
205
|
-
# Lexicon files auto-discovered via Glob lexicon/ai-{lang}.md
|
|
206
|
-
#
|
|
207
|
-
# Calibrated against 400 paragraphs (HC3 + Wikipedia + NamuWiki):
|
|
205
|
+
# Lexicon files auto-discovered via Glob lexicon/ai-{lang}.md.
|
|
206
|
+
# en/ko use the calibrated baseline from HC3 + Wikipedia + NamuWiki:
|
|
208
207
|
# AI catch 66% → 76% with Wikipedia FP staying at 25% boundary.
|
|
208
|
+
# zh/ja are starter, local-gate lexicons; expand only after a larger corpus pass.
|
|
209
209
|
skip:
|
|
210
210
|
min_paragraphs: 2
|
|
211
211
|
min_sentences: 2
|
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,59 @@ All notable changes to patina. Dates are release dates (YYYY-MM-DD).
|
|
|
12
12
|
Semver rationale: patch | minor | major — explain whether this changes patterns, schemas, CLI behavior, or docs only.
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Unreleased
|
|
16
|
+
|
|
17
|
+
## 4.0.0 — 2026-06-04
|
|
18
|
+
|
|
19
|
+
**Surface reset for a smaller, zero-config patina.**
|
|
20
|
+
|
|
21
|
+
Semver rationale: major — removes public CLI commands, flags, and backend surfaces that shipped before the npm 4.x line; users relying on those names must move to the remaining explicit CLI/API surfaces.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Private-asset leak gate** (`scripts/check-no-private-assets.mjs`, `npm run check:no-private-assets`): enumerates `npm pack --dry-run --json` for both `patina-cli` and `packages/patina-humanizer` plus tracked files, and fails if forbidden private-asset paths appear. Wired into `prepublishOnly` and CI.
|
|
26
|
+
- Centralized backend default-model metadata and surfaced it in `--list-backends`: OpenAI/Codex default to `gpt-5.5`, Claude to `claude-sonnet-4-6`, and Gemini to `gemini-2.5-pro`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Reworked the README into a shorter landing page focused on demo, quick start, common commands, CI, and core docs.
|
|
31
|
+
- Expanded `--list-backends` from a name-only listing into backend diagnostics with kind, selector hints, default models, auth status, and setup notes.
|
|
32
|
+
- Kept provider presets on the HTTP backend path so `--provider gemini` uses the Gemini HTTP API instead of being misrouted by local-CLI model heuristics.
|
|
33
|
+
|
|
34
|
+
### Removed
|
|
35
|
+
|
|
36
|
+
- Removed the opt-in `patina-hosted` backend, hosted schema, and ko hosted-compare harness; the public CLI now keeps local CLI and OpenAI-compatible HTTP backends only.
|
|
37
|
+
- Removed standalone MAX mode (`/patina-max`, `--models`, `--max-concurrency`, `--max-timeout`) and its composite scorer.
|
|
38
|
+
- Removed `--variants`, `--save-run`, response cache flags, `--suspected-generator`, user-facing `--prompt-mode`, the `--gate` alias, main CLI `--json` alias, `--json-logs`, and `--list-providers`.
|
|
39
|
+
- Removed share-card SVG output (`--card`), the one-time star nudge, and deprecated inline `--api-key`; use `--api-key-file` or environment variables for HTTP auth.
|
|
40
|
+
- Removed `patina init`; patina remains zero-config, with optional manual `.patina.yaml` only when project defaults are needed.
|
|
41
|
+
|
|
42
|
+
## 3.12.0 — 2026-06-02
|
|
43
|
+
|
|
44
|
+
Semver rationale: minor — adds new deterministic detection signals plus two new pattern-pack detections across ko/en/zh/ja; backward compatible.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **Model-output leakage detection** (#332): a deterministic detector for pasted-LLM artifacts that never appear in human prose — OpenAI citation markup (`:contentReference` / `oaicite` / `oai_citation`), model tool tokens (`turn0search1`, `navlist`, `grok_card`), the U+FFFC object-replacement char, AI-tool tracking params (`utm_source=chatgpt.com`, …), and explicit self-identification (`as an AI language model`, …). A single hit is near-proof-grade, so it forces the document hot and now short-circuits the deterministic and playground score into the 'heavily AI' band (floor 90). New `src/features/markup-leakage.js`, mirrored in the playground.
|
|
49
|
+
- **Em-dash and boldface overuse in the playground** (#333, partial): the browser analyzer now counts document-level em-dash (≥3) and markdown bold (≥5) overuse, mirroring catalog patterns #13/#14. Emoji / title-case / inline-header remain tracked in #333.
|
|
50
|
+
- **Density-gated discourse tells** (#334): fake-candor / manufactured-intimacy openers (`here's the thing`, `the truth is`, …) fire at ≥2 per document; decorative thematic breaks (`---` / `***` / `___`) fire at ≥3. New `src/features/discourse-tells.js`; fake-candor mirrored in the playground.
|
|
51
|
+
- Added language-pack pattern #33 **Definitional-Metaphor Equation ("X is the Y of Z")** (ko/en/zh/ja) — flags copula sentences that assert a grand abstract equivalence ("Cringe is the visible signature of …") to manufacture profundity; disambiguated from #8 Copula Avoidance.
|
|
52
|
+
- Added viral-hook pattern #9 **Aphoristic Punchline (Standalone Declarative)** (score-only, ko/en/zh/ja) — flags short pseudo-profound declaratives given their own line for gravitas ("Symmetry becomes a trap.").
|
|
53
|
+
- Externally sourced from "LLM smells" observations; updated `core/scoring.md` category counts (language 7→8, viral-hook 8→9, total 40→42) and `docs/PATTERNS-*.md` references to match.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- Trimmed the npm tarball from ~10MB to 627KB by excluding non-runtime assets.
|
|
58
|
+
- Reworked the README hero to be text-first and demoted the demo GIF below the static example; added per-language README demos.
|
|
59
|
+
- Added a typewriter terminal animation for the README demo GIF.
|
|
60
|
+
- Added a maintainer-owned launch-execution handoff packet (`docs/social/patina-launch-execution.md`).
|
|
61
|
+
- One-click false-positive report button on the playground (#331).
|
|
62
|
+
|
|
63
|
+
### Evidence
|
|
64
|
+
|
|
65
|
+
- Refreshed modern-model and English/Korean lexicon-lift benchmark evidence; widened Korean false-positive register coverage with positive-side calibration.
|
|
66
|
+
- Aligned the issue-wave map and backlog docs with live GitHub state.
|
|
67
|
+
|
|
15
68
|
## 3.11.0 — 2026-05-20
|
|
16
69
|
|
|
17
70
|
**Launch-readiness polish for trust, benchmarks, and distribution.**
|
package/NOTICE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
patina-cli
|
|
2
|
+
Copyright (c) devswha and patina contributors
|
|
3
|
+
|
|
4
|
+
This repository and its npm packages are distributed under the MIT License. See
|
|
5
|
+
the LICENSE file for the full license text.
|
|
6
|
+
|
|
7
|
+
Open baseline (this repository; npm packages "patina-cli" and "patina-humanizer")
|
|
8
|
+
--------------------------------------------------------------------------------
|
|
9
|
+
The pattern packs, the deterministic stylometry/lexicon analyzer, the scorer,
|
|
10
|
+
and the bundled backends are part of the open baseline and are covered by the
|
|
11
|
+
MIT License.
|
|
12
|
+
|
|
13
|
+
Private assets (NOT included)
|
|
14
|
+
-----------------------------
|
|
15
|
+
No private corpora, reinforced lexicons/patterns, prompts, or hosted-server
|
|
16
|
+
assets are included in this repository or its npm packages.
|
|
17
|
+
|
|
18
|
+
Acknowledgements
|
|
19
|
+
----------------
|
|
20
|
+
Inspired by oh-my-zsh's plugin architecture, Wikipedia's "Signs of AI writing"
|
|
21
|
+
catalog, and blader/humanizer.
|
package/README.md
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
3
|
-
<a href="README_ZH.md"><b>中文</b></a> ·
|
|
4
|
-
<a href="README_JA.md"><b>日本語</b></a> ·
|
|
5
|
-
<b>English</b>
|
|
6
|
-
</p>
|
|
7
|
-
|
|
8
|
-
<p align="center">
|
|
9
|
-
<img src="assets/brand/patina-logo.svg" alt="patina — Strip the AI packaging. Keep the meaning." width="440">
|
|
2
|
+
<img src="assets/brand/patina-mark.svg" alt="patina mark" width="172">
|
|
10
3
|
</p>
|
|
11
4
|
|
|
12
5
|
<h1 align="center">patina</h1>
|
|
@@ -15,305 +8,205 @@
|
|
|
15
8
|
<strong>Strip the AI packaging. Keep the meaning.</strong>
|
|
16
9
|
</p>
|
|
17
10
|
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="README_KR.md"><b>한국어</b></a> ·
|
|
13
|
+
<a href="README_ZH.md"><b>中文</b></a> ·
|
|
14
|
+
<a href="README_JA.md"><b>日本語</b></a> ·
|
|
15
|
+
<b>English</b>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
18
|
<p align="center">
|
|
19
19
|
<a href="https://github.com/devswha/patina/actions/workflows/test.yml"><img alt="Tests" src="https://github.com/devswha/patina/actions/workflows/test.yml/badge.svg"></a>
|
|
20
20
|
<a href="https://opensource.org/licenses/MIT"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
|
|
21
21
|
<a href="#quick-start"><img alt="Skill: Claude Code | Codex | Cursor | OpenCode" src="https://img.shields.io/badge/Skill-Claude%20Code%20%7C%20Codex%20%7C%20Cursor%20%7C%20OpenCode-blueviolet"></a>
|
|
22
22
|
<a href="https://github.com/devswha/patina"><img alt="Languages: KO | EN | ZH | JA" src="https://img.shields.io/badge/Languages-KO%20%7C%20EN%20%7C%20ZH%20%7C%20JA-green"></a>
|
|
23
|
-
<a href="CHANGELOG.md"><img alt="Version
|
|
23
|
+
<a href="CHANGELOG.md"><img alt="Version 4.0.0" src="https://img.shields.io/badge/version-4.0.0-blue"></a>
|
|
24
24
|
</p>
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://patina.vibetip.help/"><b>Try the browser audit — no install</b></a>
|
|
28
|
+
</p>
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
patina is a deterministic, pattern-based humanizer for Korean, English, Chinese, and Japanese. It finds AI-sounding phrasing and rewrites it without changing the claim, numbers, polarity, or causation.
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
It is not a black-box paraphraser, authorship detector, or detector-bypass tool. patina is built for allowed AI-assisted drafting where the author wants cleaner voice, an audit trail, and meaning-preservation checks.
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
> 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.
|
|
34
|
+
## Demo
|
|
34
35
|
|
|
35
|
-
**
|
|
36
|
-
>
|
|
36
|
+
**Before** *(AI-sounding; same fixture used by the GIF)*:
|
|
37
|
+
> 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.
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
**After** *(`/patina --lang en --tone marketing` — same claims, AI packaging removed)*:
|
|
40
|
+
> 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.
|
|
39
41
|
|
|
40
|
-
**
|
|
42
|
+
> **Score = 0.0%** · 30 templates ✓ · workflow fit ✓ · copy-and-edit use ✓
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
| Academic | “획기적인 성과”, broad significance claims | 60 GitHub projects, 72h→10m setup time, p<0.01, limits noted |
|
|
46
|
-
| Technical | “핵심적인 역할”, future-standard hype | GPU management, one-command provisioning, 5× result caveat |
|
|
44
|
+
<p align="center">
|
|
45
|
+
<img src="https://raw.githubusercontent.com/devswha/patina/main/assets/demo/patina-demo-en.gif" alt="Animated terminal demo showing patina rewriting English AI-sounding copy and scoring the cleaned result" width="780">
|
|
46
|
+
</p>
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
Brand assets: [logo](assets/brand/patina-logo.svg), [icon](assets/brand/patina-icon.svg),
|
|
50
|
-
[social preview](assets/social/patina-og.svg), and [before/after card](assets/social/patina-before-after.svg).
|
|
51
|
-
Usage notes: [BRANDING.md](docs/BRANDING.md).
|
|
48
|
+
More examples: [Before/After Gallery](docs/EXAMPLES.md) ([한국어](docs/EXAMPLES_KR.md)) · [30-second terminal demo](docs/DEMO.md).
|
|
52
49
|
|
|
53
|
-
##
|
|
50
|
+
## Quick Start
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
|---|---|
|
|
57
|
-
| **160 patterns** | 40 KO + 40 EN + 40 ZH + 40 JA (each incl. 8 score-only viral-hook) — see [PATTERNS.md](docs/PATTERNS.md) |
|
|
58
|
-
| **Editing hotspot recall** | 91% Korean [84.0–95.4%] (n=100) / 76% English [66.7–83.3%] (n=100), binomial 95% CI |
|
|
59
|
-
| **Benchmark report** | Reproducible ko/en/zh/ja suspect-zone benchmark: [latest.md](docs/benchmarks/latest.md) · [latest.json](docs/benchmarks/latest.json) · [detector comparison](docs/benchmarks/detector-comparison.md) |
|
|
60
|
-
| **False positives** | 13–25% point-estimate range across human registers *(not a CI; boundary intrinsic to encyclopedic register, [documented](core/stylometry.md))* |
|
|
61
|
-
| **Modes** | rewrite · audit · score · diff · ouroboros |
|
|
62
|
-
| **Free tier** | Yes — via `codex` CLI (no API key) |
|
|
63
|
-
| **Determinism** | Scoring formula is deterministic; LLM severity assignment ±8–10 pt per run ([scoring.md §8](core/scoring.md)) |
|
|
64
|
-
| **License** | MIT |
|
|
52
|
+
### Browser audit
|
|
65
53
|
|
|
66
|
-
|
|
54
|
+
Open **[patina.vibetip.help](https://patina.vibetip.help/)** to score KO / EN / ZH / JA text in your browser. The playground is audit-only: it does not rewrite text, call external LLMs, or send API keys to a server.
|
|
67
55
|
|
|
68
|
-
###
|
|
56
|
+
### Agent skill
|
|
69
57
|
|
|
70
58
|
```bash
|
|
71
59
|
curl -fsSL https://raw.githubusercontent.com/devswha/patina/main/install.sh | bash
|
|
72
60
|
```
|
|
73
61
|
|
|
74
|
-
|
|
62
|
+
Then run the skill from Claude Code, Codex CLI, Cursor, or OpenCode:
|
|
75
63
|
|
|
76
|
-
```
|
|
64
|
+
```text
|
|
77
65
|
/patina --lang en
|
|
78
66
|
|
|
79
67
|
[paste your text here]
|
|
80
68
|
```
|
|
81
69
|
|
|
82
|
-
|
|
70
|
+
Useful skill calls:
|
|
83
71
|
|
|
84
|
-
```
|
|
72
|
+
```text
|
|
85
73
|
/patina --tone narrative
|
|
86
|
-
|
|
87
|
-
[paste your essay draft here]
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Auto-detect and apply the best-fit tone:
|
|
91
|
-
|
|
92
|
-
```
|
|
93
74
|
/patina --tone auto --lang en
|
|
94
|
-
|
|
95
|
-
[paste your text here]
|
|
96
75
|
```
|
|
97
76
|
|
|
98
|
-
###
|
|
77
|
+
### Standalone CLI
|
|
99
78
|
|
|
100
|
-
Requires Node.js
|
|
79
|
+
Requires Node.js >= 18.
|
|
101
80
|
|
|
102
81
|
```bash
|
|
103
|
-
npx patina-cli init --defaults
|
|
104
82
|
npx patina-cli doctor
|
|
105
83
|
npx patina-cli --lang en input.txt
|
|
106
84
|
```
|
|
107
85
|
|
|
108
|
-
|
|
86
|
+
Use a logged-in local model CLI without an API key:
|
|
109
87
|
|
|
110
88
|
```bash
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
patina --lang en input.txt
|
|
89
|
+
printf '%s\n' 'Coffee has emerged as a pivotal cultural phenomenon.' \
|
|
90
|
+
| npx patina-cli --lang en --backend codex-cli
|
|
114
91
|
```
|
|
115
92
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```
|
|
93
|
+
Supported local backends: `codex-cli`, `claude-cli`, `gemini-cli`, `kimi-cli`.
|
|
94
|
+
Without `--model`, patina passes the strongest documented default per backend:
|
|
95
|
+
`gpt-5.5` for OpenAI/Codex, `claude-sonnet-4-6` for Claude, `gemini-2.5-pro`
|
|
96
|
+
for Gemini, and `kimi-code/kimi-for-coding` for Kimi Code. See
|
|
97
|
+
[Authentication](docs/AUTHENTICATION.md) ([한국어](docs/AUTHENTICATION_KR.md)).
|
|
122
98
|
|
|
123
|
-
|
|
99
|
+
For large `--batch` rewrites, prefer an OpenAI-compatible HTTP backend. Local
|
|
100
|
+
CLI backends are agent runtimes; patina caps them conservatively, uses compact
|
|
101
|
+
prompts for them, and exposes `--timeout-ms`, `--max-concurrency`,
|
|
102
|
+
`--max-retries`, `--max-failures`, and `--max-failure-rate` for batch safety.
|
|
124
103
|
|
|
125
|
-
|
|
104
|
+
## What You Get
|
|
126
105
|
|
|
127
|
-
|
|
106
|
+
| | |
|
|
107
|
+
|---|---|
|
|
108
|
+
| **168 patterns** | 33 rewrite-capable + 9 score-only viral-hook per language (42 each across KO/EN/ZH/JA) — see the full 168-pattern catalog in [PATTERNS.md](docs/PATTERNS.md) |
|
|
109
|
+
| **Modes** | rewrite · audit · score · diff · ouroboros |
|
|
110
|
+
| **Surfaces** | agent skill · Node CLI · browser audit playground |
|
|
111
|
+
| **Free usage** | logged-in `codex`, `claude`, or `gemini` CLI can run rewrites without `PATINA_API_KEY` |
|
|
112
|
+
| **Calibration** | 67.3% editing-hotspot catch [63.5–71.0%] across GPT-5.5 / Claude Sonnet 4.6 / Gemini 2.5 Pro (n=600, KO+EN); 16.0% false positives [11.6–21.7%] on KO+EN human controls (n=200) |
|
|
113
|
+
| **License** | MIT |
|
|
128
114
|
|
|
129
|
-
|
|
130
|
-
# .github/workflows/patina.yml
|
|
131
|
-
steps:
|
|
132
|
-
- uses: actions/checkout@v6
|
|
133
|
-
- uses: devswha/patina-action@main # use @v1 after npm publish + action tag
|
|
134
|
-
with:
|
|
135
|
-
patina-package: github:devswha/patina # remove after patina-cli@latest is on npm
|
|
136
|
-
report-threshold: 30
|
|
137
|
-
comment: true
|
|
138
|
-
```
|
|
115
|
+
Scores are editing signals with false positives and false negatives, not proof of authorship. See [Ethics](docs/ETHICS.md).
|
|
139
116
|
|
|
140
|
-
|
|
141
|
-
the GHCR image is published, build the local image when you need a container:
|
|
117
|
+
## Common Commands
|
|
142
118
|
|
|
143
119
|
```bash
|
|
144
|
-
docker build -t patina:local .
|
|
145
|
-
printf '%s\n' 'Coffee has emerged as a pivotal cultural phenomenon.' \
|
|
146
|
-
| docker run --rm -i -e PATINA_API_KEY patina:local --lang en --provider openai
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Pre-commit, Husky, Lefthook, Docker, and release workflow notes live in [docs/integrations/](docs/integrations/).
|
|
150
|
-
|
|
151
|
-
## Intended Use
|
|
152
|
-
|
|
153
|
-
Use Patina for post-AI editing, audit trails, and voice cleanup when the author is allowed to use AI assistance. It does not promise that text was “originally human,” and it should not be used for academic honor-code evasion, publisher disclosure circumvention, plagiarism laundering, or detector-bypass claims. See [ETHICS.md](docs/ETHICS.md).
|
|
154
|
-
|
|
155
|
-
## Modes
|
|
156
|
-
|
|
157
|
-
```
|
|
158
120
|
patina --lang <ko|en|zh|ja> [mode] [--profile <name>] input.txt
|
|
159
121
|
```
|
|
160
122
|
|
|
161
|
-
|
|
|
162
|
-
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
169
|
-
|
|
|
170
|
-
|
|
|
171
|
-
|
|
|
172
|
-
| `--batch` | Treat positional args as a list of files (e.g. `--batch docs/*.md`) |
|
|
173
|
-
| `--format json\|text\|markdown` | Select machine-readable JSON, plain text, or default Markdown output |
|
|
174
|
-
| `--quiet` | Suppress status, warning, and progress logs on stderr |
|
|
175
|
-
| `--json-logs` | Emit stderr logs as NDJSON with `level`, `event`, `model`, and `latency_ms` fields |
|
|
176
|
-
| `--prompt-mode strict\|minimal\|auto` | Choose full pattern-pack prompting, compressed prompting, or backend-aware auto |
|
|
177
|
-
| `--variants <1-5>` | Generate multiple rewrite variants with the same facts and meaning anchors |
|
|
178
|
-
|
|
179
|
-
`patina --help` for the full flag list. `patina doctor --json` checks Node/backend/tmux/API-key readiness without making an LLM call, and `patina init` writes a project `.patina.yaml`.
|
|
180
|
-
|
|
181
|
-
Dev-native profile shortcuts are available for Markdown-heavy engineering workflows:
|
|
182
|
-
`code-comment` tightens inline comments/docstrings, `commit-message` rewrites Git history text around intent and verification, and `release-notes` turns changelog bullets into user-impact notes with migration risks visible.
|
|
183
|
-
|
|
184
|
-
### Score-only patterns
|
|
185
|
-
|
|
186
|
-
`--score` and `--audit` measure a slightly broader set of signals than `--rewrite` does. The viral-hook packs (`ko/en/zh/ja-viral-hook`, 8 patterns each: shock-number hooks, clickbait closings, source-skipping authority claims, breath-optimized short-sentence stacking, hyperbolic engagement lexicon, fake-stat citations, stacked credentials, future-self/parasocial promises) are **detection-only**.
|
|
187
|
-
|
|
188
|
-
They appear in score and audit output so the benchmark matches human intuition for SNS-style marketing copy across all four languages. `--rewrite`/`--diff`/`--ouroboros` skip them because those signals are often intentional rhetoric. Real-world demos: [`examples/viral-hook/`](examples/viral-hook/).
|
|
189
|
-
|
|
190
|
-
### Prompt-mode tuning (v3.11)
|
|
191
|
-
|
|
192
|
-
`--prompt-mode strict|minimal|auto` lets you trade off between the full pattern packs (~34KB structured prompt) and a compressed casual instruction (~3KB). `auto` picks per backend — Gemini does better on minimal (it gets over-constrained by long structured prompts), while Claude leverages the full packs and Codex is roughly insensitive. case-05 documents the A/B.
|
|
193
|
-
|
|
194
|
-
### Multiple stylistic variants (v3.11)
|
|
195
|
-
|
|
196
|
-
`--variants <1-5>` asks the model for N voice variants of the rewrite in one call (e.g., V1 casual, V2 direct, V3 measured) — facts, numbers, and causation stay identical across variants. Each comes back as `## Variant N` so you can pick the voice you want.
|
|
197
|
-
|
|
198
|
-
### Short-text scoring boost (v3.11)
|
|
199
|
-
|
|
200
|
-
For inputs ≤200 chars or ≤3 paragraphs, register-sensitive categories (`language`, `style`, `viral-hook`) get a 1.5× severity multiplier so single-paragraph voice shifts surface in the score. case-04 found these were undercounted by the long-text formula.
|
|
201
|
-
|
|
202
|
-
### Self-audit isolation (v3.11)
|
|
203
|
-
|
|
204
|
-
In rewrite mode, the model emits its self-audit notes inside `[SELF_AUDIT]`/`[/SELF_AUDIT]` tags wrapped around a `[BODY]`/`[/BODY]` block (or `[VARIANT n]` blocks when `--variants > 1`). patina strips the audit before showing the user, so raw output is clean — earlier versions sometimes leaked phrases like "남아 있는 AI 티" or "Phase 3" preambles into the user-facing text.
|
|
205
|
-
|
|
206
|
-
### Machine-readable output and exit codes
|
|
207
|
-
|
|
208
|
-
`--format json` wraps every mode in a stable envelope with `overall`, `categories[]`, `tone`, `mps`, `gateResult`, and the cleaned `output` body. `--json-logs` keeps stderr machine-readable as NDJSON, while `--quiet` silences status/warning/progress logs for scripts that only want stdout. `--format markdown` is the default; `--format text` keeps the user-facing body without the YAML tone footer. Exit codes are standardized in [EXIT-CODES.md](docs/EXIT-CODES.md): `0` success, `1` runtime/backend, `2` input/usage, `3` score gate exceeded, `4` MAX MPS fallback/all-candidates-failed.
|
|
209
|
-
|
|
210
|
-
### Score weight drift detection (v3.11)
|
|
211
|
-
|
|
212
|
-
`--score` runs cross-check the Weight column the model emits against your config's `category-weights`. If the model invents a category (e.g., `discord`) or substitutes a different number, `[patina]` warnings hit stderr — observability only, the weight check itself doesn't alter the score. A deterministic shadow score from `src/features/*` is also recorded; when it differs from the LLM score by more than 20 points, patina warns and uses the more pessimistic value for gates.
|
|
213
|
-
|
|
214
|
-
`--save-run <dir>` now writes manifest schema v2: result entries include prompt and response hashes, available input/output token counts, temperature/seed, score details, per-call cost when a provider returns it, and Ouroboros iteration logs.
|
|
215
|
-
|
|
216
|
-
For repeat benchmarks, opt into the HTTP response cache with `--cache <dir>` or `PATINA_CACHE_DIR`. Cache keys include prompt, model, temperature, and API host; `--cache-ttl <sec>` controls expiry and `--no-cache` bypasses it for fresh runs. Patina prints hit/miss/write stats at the end of cached runs.
|
|
217
|
-
|
|
218
|
-
Use `--voice-sample <path>` or `voice-sample: <path>` in config to anchor rewrites to 1–3 paragraphs you wrote. Profile and tone still set the requested register; the sample only teaches cadence, specificity, POV, and sentence texture, and the prompt explicitly forbids importing sample facts.
|
|
219
|
-
|
|
220
|
-
## Tones
|
|
221
|
-
|
|
222
|
-
`--tone` selects a named voice axis applied on top of pattern rewriting. Resolution order: `--tone` CLI > `tone:` config > `profile:` config.
|
|
223
|
-
|
|
224
|
-
| Tone | Intended for | Key behaviors |
|
|
225
|
-
|------|-------------|---------------|
|
|
226
|
-
| `casual` | Blog posts, social content, personal notes | Contractions, first-person, emoticons OK, low formality |
|
|
227
|
-
| `professional` | Work emails, reports, business writing | Clear and concise, formal but not stiff; legal/medical sub-profiles force fidelity floor |
|
|
228
|
-
| `academic` | Papers, research summaries, technical analysis | Objective, evidence-oriented, minimal first-person |
|
|
229
|
-
| `narrative` | Personal essays, memoir, experience-based writing | First-person anchor, scene detail, emotional presence, time flow |
|
|
230
|
-
| `marketing` | Ad copy, landing pages, product announcements | Short impact sentences, persuasive, CTA-friendly |
|
|
231
|
-
| `instructional` | Tutorials, how-to guides, technical docs | Imperative verbs, numbered structure, hedging suppressed |
|
|
232
|
-
|
|
233
|
-
`--tone auto` runs heuristic detection (lexical + structural signals) and selects the best-fit tone. zh/ja with any tone (including `auto`) emits a warning and falls back to profile-only mode — Phase 4.5b heuristics only cover ko/en.
|
|
234
|
-
|
|
235
|
-
### MAX mode
|
|
236
|
-
|
|
237
|
-
Run the same text through Claude, Codex, and Gemini independently. The lowest AI-score result that passes MPS ≥ 70 wins:
|
|
123
|
+
| Command | Purpose |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `patina input.txt` | rewrite with defaults |
|
|
126
|
+
| `patina --audit input.txt` | detect patterns only |
|
|
127
|
+
| `patina --score input.txt` | output a 0-100 AI-likeness score |
|
|
128
|
+
| `patina --score --exit-on 30 input.txt` | CI gate with exit code `3` when `overall > 30` |
|
|
129
|
+
| `patina --diff input.txt` | show pattern-by-pattern changes |
|
|
130
|
+
| `patina --ouroboros input.txt` | iterate with MPS/fidelity rollback |
|
|
131
|
+
| `patina --tone auto --lang en input.txt` | infer and apply a KO/EN tone axis |
|
|
132
|
+
| `patina --format json --quiet input.txt` | script-friendly output |
|
|
133
|
+
| `patina --batch docs/*.md --outdir cleaned/` | batch file processing |
|
|
238
134
|
|
|
239
|
-
|
|
240
|
-
/patina-max
|
|
135
|
+
`patina --help` prints the full flag list. `patina doctor --json` checks Node, backend, tmux, and API-key readiness without making an LLM call.
|
|
241
136
|
|
|
242
|
-
|
|
243
|
-
```
|
|
137
|
+
## CI
|
|
244
138
|
|
|
245
|
-
|
|
139
|
+
For GitHub Actions, the maintained wrapper is shorter than hand-rolled setup:
|
|
246
140
|
|
|
247
|
-
|
|
141
|
+
```yaml
|
|
142
|
+
name: Patina prose score
|
|
143
|
+
on:
|
|
144
|
+
pull_request:
|
|
145
|
+
paths: ['**/*.md', '**/*.mdx']
|
|
146
|
+
permissions:
|
|
147
|
+
contents: read
|
|
148
|
+
pull-requests: read
|
|
149
|
+
issues: write
|
|
150
|
+
jobs:
|
|
151
|
+
patina:
|
|
152
|
+
runs-on: ubuntu-latest
|
|
153
|
+
steps:
|
|
154
|
+
- uses: actions/checkout@v6
|
|
155
|
+
- uses: devswha/patina-action@v1
|
|
156
|
+
with:
|
|
157
|
+
score-threshold: 30
|
|
158
|
+
lang: auto
|
|
159
|
+
comment: true
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Other integrations: [pre-commit](docs/integrations/pre-commit.md), [static sites](docs/integrations/static-sites.md), [Docker](docs/integrations/docker.md), [release workflow](docs/integrations/release.md).
|
|
248
163
|
|
|
249
164
|
## How It Works
|
|
250
165
|
|
|
251
|
-
```
|
|
166
|
+
```text
|
|
252
167
|
Input
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
[Phase 2] Sentence rewrite + anchor verification
|
|
259
|
-
[Phase 3] Self-audit (polarity, regression, MPS)
|
|
260
|
-
↓
|
|
261
|
-
Natural-sounding text (meaning verified)
|
|
168
|
+
-> semantic anchor extraction (claims, polarity, causation, numbers)
|
|
169
|
+
-> stylometry + AI-lexicon scan
|
|
170
|
+
-> pattern-guided rewrite
|
|
171
|
+
-> self-audit and MPS/fidelity checks
|
|
172
|
+
-> cleaned text
|
|
262
173
|
```
|
|
263
174
|
|
|
264
|
-
If meaning drifts
|
|
265
|
-
|
|
266
|
-
**Calibration** *(500-paragraph corpus, reproducible via `.omc/research/v3_8_remeasure.py`)*: 76% editing-hotspot recall on HC3 ChatGPT (en) [66.7–83.3%] and 91% on paired ko/AI corpus [84.0–95.4%], each n=100 with binomial 95% CI. Human-prose false positives are reported separately as a 13–25% point-estimate range across registers, not as a confidence interval. Acceptance gates: AI ≥ 75%, max FP ≤ 25%. See [stylometry.md](core/stylometry.md) for the algorithm.
|
|
175
|
+
If meaning drifts, the change is retried or rolled back. Deterministic analysis lives in `src/features/*`; LLM-backed rewrite and score calls use the selected backend.
|
|
267
176
|
|
|
268
177
|
## Configuration
|
|
269
178
|
|
|
270
179
|
```yaml
|
|
271
180
|
# .patina.default.yaml
|
|
272
|
-
version: "
|
|
181
|
+
version: "4.0.0"
|
|
273
182
|
language: ko # ko | en | zh | ja
|
|
274
183
|
profile: default
|
|
275
184
|
output: rewrite # rewrite | diff | audit | score
|
|
276
185
|
tone: # casual | professional | academic | narrative | marketing | instructional | auto
|
|
277
|
-
max-models: [claude, gemini]
|
|
278
186
|
```
|
|
279
187
|
|
|
280
|
-
Pattern packs are auto-discovered by language prefix.
|
|
188
|
+
Project `.patina.yaml` overrides defaults. Pattern packs are auto-discovered by language prefix. Additive list keys (`blocklist`, `allowlist`, `skip-patterns`) merge; other arrays replace.
|
|
281
189
|
|
|
282
190
|
## Documentation
|
|
283
191
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
-
|
|
287
|
-
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
294
|
-
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
- **[FAQ](docs/FAQ.md)** ([한국어](docs/FAQ_KR.md)) — detector-bypass concerns, MPS, false positives, contribution starting points
|
|
298
|
-
- **[Comparison](docs/COMPARISON.md)** — factual comparison with common paraphraser/humanizer tools
|
|
299
|
-
- **[Branding](docs/BRANDING.md)** — canonical logo/social assets and OG setup notes
|
|
300
|
-
- **[Design](DESIGN.md)** — product/brand source of truth for repo-native SVG and README surfaces
|
|
301
|
-
- **[Roadmap](docs/ROADMAP.md)** — quality, benchmark, product, community, and launch priorities
|
|
302
|
-
- **[Benchmark Report](docs/benchmarks/latest.md)** — latest reproducible suspect-zone benchmark summary
|
|
303
|
-
- **[Detector Comparison Harness](docs/benchmarks/detector-comparison.md)** — offline/manual comparison protocol for third-party detectors
|
|
304
|
-
- **[AI/Human Metrics Research](docs/research/ai-human-metrics.md)** — benchmark design notes for measuring AI-like writing signals
|
|
305
|
-
- **[2025+ Re-baseline Plan](docs/research/2025-rebaseline-plan.md)** — evidence gate before broader model-era claims
|
|
306
|
-
- **[Launch Copy](docs/social/patina-launch-copy.md)** — Show HN, Reddit, X, Korean community drafts
|
|
307
|
-
- **[Stylometry](core/stylometry.md)** — burstiness + MATTR + AI-lexicon algorithm
|
|
308
|
-
- **[Scoring](core/scoring.md)** — AI-likeness + fidelity + MPS
|
|
309
|
-
- **[Changelog](CHANGELOG.md)** — release notes and methodology
|
|
310
|
-
- **[Contributing](CONTRIBUTING.md)** ([한국어](CONTRIBUTING_KR.md)) — pattern submissions, false-positive triage, benchmark fixtures, versioning
|
|
311
|
-
- **[Governance](GOVERNANCE.md)** / **[Maintainers](MAINTAINERS.md)** — lightweight project decision rules
|
|
192
|
+
Start here:
|
|
193
|
+
|
|
194
|
+
- [Cookbook](docs/COOKBOOK.md) — common recipes and workflows
|
|
195
|
+
- [CLI Contract](docs/CLI.md) — flags, formats, score gates, exit behavior
|
|
196
|
+
- [Authentication](docs/AUTHENTICATION.md) — local CLI backends and API providers
|
|
197
|
+
- [Patterns](docs/PATTERNS.md) — full pattern catalog
|
|
198
|
+
- [Benchmarks](docs/benchmarks/README.md) · [latest report](docs/benchmarks/latest.md) · [2026 rebaseline](docs/research/2026-rebaseline.md)
|
|
199
|
+
- [FAQ](docs/FAQ.md) ([한국어](docs/FAQ_KR.md))
|
|
200
|
+
- [Ethics](docs/ETHICS.md)
|
|
201
|
+
- [Contributing](CONTRIBUTING.md) ([한국어](CONTRIBUTING_KR.md))
|
|
202
|
+
- [Changelog](CHANGELOG.md)
|
|
203
|
+
|
|
204
|
+
Brand assets and usage rules live in [Branding](docs/BRANDING.md). Design notes live in [DESIGN.md](DESIGN.md).
|
|
312
205
|
|
|
313
206
|
## Acknowledgements
|
|
314
207
|
|
|
315
|
-
Inspired by [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh)'s plugin architecture
|
|
208
|
+
Inspired by [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh)'s plugin architecture, [Wikipedia's "Signs of AI writing"](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing), and [blader/humanizer](https://github.com/blader/humanizer).
|
|
316
209
|
|
|
317
210
|
## License
|
|
318
211
|
|
|
319
|
-
MIT
|
|
212
|
+
MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|