patina-cli 3.11.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 (180) hide show
  1. package/.patina.default.yaml +211 -0
  2. package/CHANGELOG.md +265 -0
  3. package/LICENSE +21 -0
  4. package/README.md +319 -0
  5. package/README_JA.md +254 -0
  6. package/README_KR.md +253 -0
  7. package/README_ZH.md +254 -0
  8. package/SKILL-MAX.md +455 -0
  9. package/SKILL.md +730 -0
  10. package/assets/brand/patina-icon.svg +9 -0
  11. package/assets/brand/patina-logo.svg +17 -0
  12. package/assets/social/patina-before-after.svg +46 -0
  13. package/assets/social/patina-og.svg +31 -0
  14. package/bin/patina.js +9 -0
  15. package/core/scoring.md +657 -0
  16. package/core/standalone-prompt.md +364 -0
  17. package/core/stylometry.md +754 -0
  18. package/core/voice.md +163 -0
  19. package/docs/AUTHENTICATION.md +105 -0
  20. package/docs/AUTHENTICATION_KR.md +105 -0
  21. package/docs/BRANDING.md +37 -0
  22. package/docs/CLI.md +80 -0
  23. package/docs/COMPARISON.md +38 -0
  24. package/docs/COOKBOOK.md +173 -0
  25. package/docs/DEMO.md +40 -0
  26. package/docs/ETHICS.md +27 -0
  27. package/docs/EXAMPLES.md +130 -0
  28. package/docs/EXAMPLES_KR.md +130 -0
  29. package/docs/EXIT-CODES.md +25 -0
  30. package/docs/FAQ.md +67 -0
  31. package/docs/FAQ_KR.md +65 -0
  32. package/docs/FLAG-PARITY.md +53 -0
  33. package/docs/GLOSSARY.md +123 -0
  34. package/docs/PATTERNS-EN.md +718 -0
  35. package/docs/PATTERNS-JA.md +706 -0
  36. package/docs/PATTERNS-KO.md +707 -0
  37. package/docs/PATTERNS-ZH.md +706 -0
  38. package/docs/PATTERNS.md +22 -0
  39. package/docs/ROADMAP.md +315 -0
  40. package/docs/audits/2026-05-deep-research.md +290 -0
  41. package/docs/benchmarks/detector-comparison.json +442 -0
  42. package/docs/benchmarks/detector-comparison.md +65 -0
  43. package/docs/benchmarks/latest.json +988 -0
  44. package/docs/benchmarks/latest.md +112 -0
  45. package/docs/integrations/docker.md +19 -0
  46. package/docs/integrations/github-action.md +59 -0
  47. package/docs/integrations/pre-commit.md +77 -0
  48. package/docs/integrations/release.md +43 -0
  49. package/docs/internal/HARNESS.md +14 -0
  50. package/docs/internal/README.md +14 -0
  51. package/docs/internal/WARP.md +23 -0
  52. package/docs/research/2025-rebaseline-plan.md +89 -0
  53. package/docs/research/ai-human-metrics.md +380 -0
  54. package/docs/social/gstack-cardnews.html +236 -0
  55. package/docs/social/gstack-cardnews.md +88 -0
  56. package/docs/social/gstack-thread.md +106 -0
  57. package/docs/social/patina-launch-copy.md +227 -0
  58. package/docs/superpowers/specs/2026-04-03-meaning-preservation-design.md +299 -0
  59. package/lexicon/ai-en.md +162 -0
  60. package/lexicon/ai-ko.md +159 -0
  61. package/package.json +100 -0
  62. package/patina-max/SKILL.md +523 -0
  63. package/patina-max/composite.py +457 -0
  64. package/patterns/en-communication.md +89 -0
  65. package/patterns/en-content.md +133 -0
  66. package/patterns/en-filler.md +113 -0
  67. package/patterns/en-language.md +163 -0
  68. package/patterns/en-structure.md +173 -0
  69. package/patterns/en-style.md +139 -0
  70. package/patterns/en-viral-hook.md +211 -0
  71. package/patterns/ja-communication.md +101 -0
  72. package/patterns/ja-content.md +153 -0
  73. package/patterns/ja-filler.md +123 -0
  74. package/patterns/ja-language.md +190 -0
  75. package/patterns/ja-structure.md +142 -0
  76. package/patterns/ja-style.md +147 -0
  77. package/patterns/ja-viral-hook.md +216 -0
  78. package/patterns/ko-communication.md +98 -0
  79. package/patterns/ko-content.md +154 -0
  80. package/patterns/ko-filler.md +105 -0
  81. package/patterns/ko-language.md +182 -0
  82. package/patterns/ko-structure.md +147 -0
  83. package/patterns/ko-style.md +146 -0
  84. package/patterns/ko-viral-hook.md +211 -0
  85. package/patterns/zh-communication.md +101 -0
  86. package/patterns/zh-content.md +153 -0
  87. package/patterns/zh-filler.md +118 -0
  88. package/patterns/zh-language.md +173 -0
  89. package/patterns/zh-structure.md +145 -0
  90. package/patterns/zh-style.md +159 -0
  91. package/patterns/zh-viral-hook.md +216 -0
  92. package/profiles/academic.md +53 -0
  93. package/profiles/blog.md +81 -0
  94. package/profiles/casual-conversation.md +105 -0
  95. package/profiles/code-comment.md +104 -0
  96. package/profiles/commit-message.md +99 -0
  97. package/profiles/default.md +62 -0
  98. package/profiles/email.md +52 -0
  99. package/profiles/formal.md +98 -0
  100. package/profiles/instructional.md +80 -0
  101. package/profiles/legal.md +57 -0
  102. package/profiles/marketing.md +56 -0
  103. package/profiles/medical.md +53 -0
  104. package/profiles/narrative.md +79 -0
  105. package/profiles/release-notes.md +98 -0
  106. package/profiles/social.md +56 -0
  107. package/profiles/technical.md +53 -0
  108. package/scripts/benchmark-report.mjs +252 -0
  109. package/scripts/check-release-metadata.mjs +48 -0
  110. package/scripts/detector-comparison.mjs +267 -0
  111. package/scripts/lint.mjs +40 -0
  112. package/scripts/precommit-score.mjs +31 -0
  113. package/scripts/prose-score.mjs +186 -0
  114. package/scripts/update-benchmark-ranges.mjs +108 -0
  115. package/src/api.js +330 -0
  116. package/src/auth.js +105 -0
  117. package/src/backends/claude-cli.js +112 -0
  118. package/src/backends/codex-cli.js +121 -0
  119. package/src/backends/contract.js +21 -0
  120. package/src/backends/gemini-cli.js +135 -0
  121. package/src/backends/index.js +159 -0
  122. package/src/cache.js +106 -0
  123. package/src/cli.js +1280 -0
  124. package/src/commands/doctor.js +229 -0
  125. package/src/commands/init.js +208 -0
  126. package/src/config.js +126 -0
  127. package/src/errors.js +53 -0
  128. package/src/features/index.js +96 -0
  129. package/src/features/lexicon.js +90 -0
  130. package/src/features/segment.js +49 -0
  131. package/src/features/stylometry.js +50 -0
  132. package/src/loader.js +103 -0
  133. package/src/logger.js +70 -0
  134. package/src/manifest.js +162 -0
  135. package/src/max-mode.js +207 -0
  136. package/src/ouroboros.js +233 -0
  137. package/src/output.js +480 -0
  138. package/src/prompt-builder.js +409 -0
  139. package/src/providers.js +100 -0
  140. package/src/scoring.js +531 -0
  141. package/src/security.js +133 -0
  142. package/tests/fixtures/suspect-zones/en/ai/en-ai-01.md +16 -0
  143. package/tests/fixtures/suspect-zones/en/ai/en-ai-02.md +16 -0
  144. package/tests/fixtures/suspect-zones/en/ai/en-ai-03.md +17 -0
  145. package/tests/fixtures/suspect-zones/en/ai/en-ai-04.md +15 -0
  146. package/tests/fixtures/suspect-zones/en/ai/en-ai-05.md +16 -0
  147. package/tests/fixtures/suspect-zones/en/ai/en-ai-06-chat-register.md +16 -0
  148. package/tests/fixtures/suspect-zones/en/natural/en-nat-01.md +15 -0
  149. package/tests/fixtures/suspect-zones/en/natural/en-nat-02.md +15 -0
  150. package/tests/fixtures/suspect-zones/en/natural/en-nat-03.md +15 -0
  151. package/tests/fixtures/suspect-zones/en/natural/en-nat-04.md +15 -0
  152. package/tests/fixtures/suspect-zones/en/natural/en-nat-05.md +15 -0
  153. package/tests/fixtures/suspect-zones/expected-ranges.json +939 -0
  154. package/tests/fixtures/suspect-zones/ja/ai/ja-ai-01.md +11 -0
  155. package/tests/fixtures/suspect-zones/ja/ai/ja-ai-02.md +11 -0
  156. package/tests/fixtures/suspect-zones/ja/ai/ja-ai-03.md +11 -0
  157. package/tests/fixtures/suspect-zones/ja/natural/ja-nat-01.md +11 -0
  158. package/tests/fixtures/suspect-zones/ja/natural/ja-nat-02.md +11 -0
  159. package/tests/fixtures/suspect-zones/ja/natural/ja-nat-03.md +11 -0
  160. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-01.md +14 -0
  161. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-02.md +16 -0
  162. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-03.md +15 -0
  163. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-04.md +15 -0
  164. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-05.md +16 -0
  165. package/tests/fixtures/suspect-zones/ko/ai/ko-ai-06-chat-register.md +16 -0
  166. package/tests/fixtures/suspect-zones/ko/natural/ko-nat-01.md +15 -0
  167. package/tests/fixtures/suspect-zones/ko/natural/ko-nat-02.md +15 -0
  168. package/tests/fixtures/suspect-zones/ko/natural/ko-nat-03.md +15 -0
  169. package/tests/fixtures/suspect-zones/ko/natural/ko-nat-04.md +14 -0
  170. package/tests/fixtures/suspect-zones/ko/natural/ko-nat-05.md +15 -0
  171. package/tests/fixtures/suspect-zones/zh/ai/zh-ai-01.md +11 -0
  172. package/tests/fixtures/suspect-zones/zh/ai/zh-ai-02.md +11 -0
  173. package/tests/fixtures/suspect-zones/zh/ai/zh-ai-03.md +11 -0
  174. package/tests/fixtures/suspect-zones/zh/natural/zh-nat-01.md +11 -0
  175. package/tests/fixtures/suspect-zones/zh/natural/zh-nat-02.md +11 -0
  176. package/tests/fixtures/suspect-zones/zh/natural/zh-nat-03.md +11 -0
  177. package/tests/quality/README.md +121 -0
  178. package/tests/quality/benchmark.mjs +306 -0
  179. package/tests/quality/detectors.manual.example.json +31 -0
  180. package/tests/quality/dogfood.mjs +44 -0
@@ -0,0 +1,112 @@
1
+ # Benchmark Report
2
+
3
+ This is the latest checked-in report for patina's deterministic suspect-zone benchmark.
4
+
5
+ > Scope: this benchmark measures whether patina's stylometry layer flags fixture paragraphs as AI-like editing hotspots. It does **not** prove whether a real document was written by a human or by AI.
6
+
7
+ ## Current result
8
+
9
+ - Status: **passing**
10
+ - Generated at: 2026-05-20T11:14:22.284Z
11
+ - Node: v22.17.1
12
+ - Fixture schema: v1
13
+ - Fixtures: 34
14
+ - Languages: 4 (en, ja, ko, zh)
15
+ - Overall accuracy: **100.0%** [89.8%–100.0%] (n=34, Wilson score interval, 95%)
16
+ - Source fixtures: `tests/fixtures/suspect-zones/**`
17
+ - Regression ranges: `tests/fixtures/suspect-zones/expected-ranges.json` (refresh with `npm run benchmark:ranges`)
18
+ - Reproduce: `npm run benchmark:report`
19
+ - Raw JSON: [latest.json](latest.json)
20
+ - Detector comparison harness: [detector-comparison.md](detector-comparison.md)
21
+ - 2025+ re-baseline plan: [docs/research/2025-rebaseline-plan.md](../research/2025-rebaseline-plan.md)
22
+
23
+ ## Language breakdown
24
+
25
+ | lang | fixtures | accuracy | 95% CI | precision | recall | f1 | TP | FP | FN | TN |
26
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
27
+ | en | 11 | 100.0% | 74.1%–100.0% | 100.0% | 100.0% | 1 | 6 | 0 | 0 | 5 |
28
+ | ja | 6 | 100.0% | 61.0%–100.0% | 100.0% | 100.0% | 1 | 3 | 0 | 0 | 3 |
29
+ | ko | 11 | 100.0% | 74.1%–100.0% | 100.0% | 100.0% | 1 | 6 | 0 | 0 | 5 |
30
+ | zh | 6 | 100.0% | 61.0%–100.0% | 100.0% | 100.0% | 1 | 3 | 0 | 0 | 3 |
31
+
32
+ ## Detector breakdown
33
+
34
+ | lang | detector | fixtures | accuracy | 95% CI | precision | recall | f1 | TP | FP | FN | TN |
35
+ |---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
36
+ | en | burstiness | 11 | 100.0% | 74.1%–100.0% | 100.0% | 100.0% | 1 | 6 | 0 | 0 | 5 |
37
+ | en | lexicon | 11 | 45.5% | 21.3%–72.0% | 0.0% | 0.0% | 0 | 0 | 0 | 6 | 5 |
38
+ | en | mattr | 11 | 45.5% | 21.3%–72.0% | 0.0% | 0.0% | 0 | 0 | 0 | 6 | 5 |
39
+ | ja | burstiness | 6 | 100.0% | 61.0%–100.0% | 100.0% | 100.0% | 1 | 3 | 0 | 0 | 3 |
40
+ | ja | lexicon | 6 | 50.0% | 18.8%–81.2% | 0.0% | 0.0% | 0 | 0 | 0 | 3 | 3 |
41
+ | ja | mattr | 6 | 50.0% | 18.8%–81.2% | 0.0% | 0.0% | 0 | 0 | 0 | 3 | 3 |
42
+ | ko | burstiness | 11 | 100.0% | 74.1%–100.0% | 100.0% | 100.0% | 1 | 6 | 0 | 0 | 5 |
43
+ | ko | lexicon | 11 | 81.8% | 52.3%–94.9% | 100.0% | 66.7% | 0.8 | 4 | 0 | 2 | 5 |
44
+ | ko | mattr | 11 | 45.5% | 21.3%–72.0% | 0.0% | 0.0% | 0 | 0 | 0 | 6 | 5 |
45
+ | zh | burstiness | 6 | 100.0% | 61.0%–100.0% | 100.0% | 100.0% | 1 | 3 | 0 | 0 | 3 |
46
+ | zh | lexicon | 6 | 50.0% | 18.8%–81.2% | 0.0% | 0.0% | 0 | 0 | 0 | 3 | 3 |
47
+ | zh | mattr | 6 | 50.0% | 18.8%–81.2% | 0.0% | 0.0% | 0 | 0 | 0 | 3 | 3 |
48
+
49
+ ## Sample sizes
50
+
51
+ | lang | class | fixtures |
52
+ |---|---|---:|
53
+ | en | ai | 6 |
54
+ | en | natural | 5 |
55
+ | ja | ai | 3 |
56
+ | ja | natural | 3 |
57
+ | ko | ai | 6 |
58
+ | ko | natural | 5 |
59
+ | zh | ai | 3 |
60
+ | zh | natural | 3 |
61
+
62
+ ## Misclassifications
63
+
64
+ All fixtures classified correctly.
65
+
66
+ ## Fixture log
67
+
68
+ | fixture | lang | class | expected | predicted | ok | CV band | MATTR band | lexicon/1k | sample lexicon hits |
69
+ |---|---|---|---|---|---:|---:|---:|---:|---|
70
+ | en-ai-01 | en | ai | hot | hot | ✓ | 0.058 low | 0.928 high | 0 | — |
71
+ | en-ai-02 | en | ai | hot | hot | ✓ | 0.09 low | 0.841 high | 0 | — |
72
+ | en-ai-03 | en | ai | hot | hot | ✓ | 0.065 low | 0.828 high | 0 | — |
73
+ | en-ai-04 | en | ai | hot | hot | ✓ | 0.07 low | 0.84 high | 0 | — |
74
+ | en-ai-05 | en | ai | hot | hot | ✓ | 0.093 low | 0.879 high | 0 | — |
75
+ | en-ai-06-chat-register | en | ai | hot | hot | ✓ | 0.034 low | 0.814 high | 0 | — |
76
+ | en-nat-01 | en | natural | cold | cold | ✓ | 0.881 high | 0.898 high | 0 | — |
77
+ | en-nat-02 | en | natural | cold | cold | ✓ | 0.886 high | 0.884 high | 0 | — |
78
+ | en-nat-03 | en | natural | cold | cold | ✓ | 0.914 high | 0.882 high | 0 | — |
79
+ | en-nat-04 | en | natural | cold | cold | ✓ | 0.494 mid | 0.854 high | 0 | — |
80
+ | en-nat-05 | en | natural | cold | cold | ✓ | 0.853 high | 0.875 high | 0 | — |
81
+ | ja-ai-01 | ja | ai | hot | hot | ✓ | 0.045 low | 0.833 high | 0 | — |
82
+ | ja-ai-02 | ja | ai | hot | hot | ✓ | 0.23 low | 0.785 high | 0 | — |
83
+ | ja-ai-03 | ja | ai | hot | hot | ✓ | 0.063 low | 0.795 high | 0 | — |
84
+ | ja-nat-01 | ja | natural | cold | cold | ✓ | 0.487 mid | 0.719 high | 0 | — |
85
+ | ja-nat-02 | ja | natural | cold | cold | ✓ | 0.65 high | 0.796 high | 0 | — |
86
+ | ja-nat-03 | ja | natural | cold | cold | ✓ | 0.395 mid | 0.807 high | 0 | — |
87
+ | ko-ai-01 | ko | ai | hot | hot | ✓ | 0.093 low | 0.977 high | 23.256 | 추세 |
88
+ | ko-ai-02 | ko | ai | hot | hot | ✓ | 0.073 low | 0.82 high | 19.608 | 환경 |
89
+ | ko-ai-03 | ko | ai | hot | hot | ✓ | 0.073 low | 0.79 high | 19.608 | 추세 |
90
+ | ko-ai-04 | ko | ai | hot | hot | ✓ | 0.098 low | 0.853 high | 0 | — |
91
+ | ko-ai-05 | ko | ai | hot | hot | ✓ | 0.098 low | 0.853 high | 0 | — |
92
+ | ko-ai-06-chat-register | ko | ai | hot | hot | ✓ | 0.081 low | 1 high | 21.739 | 흐름 |
93
+ | ko-nat-01 | ko | natural | cold | cold | ✓ | 0.717 high | 1 high | 0 | — |
94
+ | ko-nat-02 | ko | natural | cold | cold | ✓ | 0.552 high | 1 high | 0 | — |
95
+ | ko-nat-03 | ko | natural | cold | cold | ✓ | 0.68 high | 1 high | 0 | — |
96
+ | ko-nat-04 | ko | natural | cold | cold | ✓ | 0.771 high | 0.975 high | 0 | — |
97
+ | ko-nat-05 | ko | natural | cold | cold | ✓ | 0.996 high | 0.998 high | 0 | — |
98
+ | zh-ai-01 | zh | ai | hot | hot | ✓ | 0.062 low | 0.902 high | 0 | — |
99
+ | zh-ai-02 | zh | ai | hot | hot | ✓ | 0.28 low | 0.734 high | 0 | — |
100
+ | zh-ai-03 | zh | ai | hot | hot | ✓ | 0.083 low | 0.933 high | 0 | — |
101
+ | zh-nat-01 | zh | natural | cold | cold | ✓ | 0.506 high | 0.875 high | 0 | — |
102
+ | zh-nat-02 | zh | natural | cold | cold | ✓ | 0.528 high | 0.936 high | 0 | — |
103
+ | zh-nat-03 | zh | natural | cold | cold | ✓ | 0.58 high | 0.907 high | 0 | — |
104
+
105
+ ## How to read this
106
+
107
+ - **Hot** means at least one deterministic signal crossed the benchmark threshold: low burstiness CV, low MATTR, or AI-lexicon density.
108
+ - **Cold** means the fixture did not cross those thresholds.
109
+ - The report is meant for regression tracking and contributor discussion, not for authorship accusation.
110
+ - This deterministic corpus is intentionally small (34 fixtures across en, ja, ko, zh); do not treat 100% fixture accuracy as generalization to new models, genres, or edited AI text.
111
+ - Confidence intervals use Wilson score intervals for the checked-in fixture set; external threshold sweeps and 2025+ model rebaselines are separate research follow-ups tracked in [2025+ Re-baseline Plan](../research/2025-rebaseline-plan.md).
112
+ - Broader methodology notes live in [AI/Human Metrics Research](../research/ai-human-metrics.md) and [Quality Checks](../../tests/quality/README.md).
@@ -0,0 +1,19 @@
1
+ # Docker image
2
+
3
+ The npm release job does not publish Docker images automatically. GHCR
4
+ publishing is tracked separately so the first npm release can stay npm-only.
5
+
6
+ Until the image is published, build the local image:
7
+
8
+ ```bash
9
+ docker build -t patina:local .
10
+ printf '%s\n' 'Coffee has emerged as a pivotal cultural phenomenon.' \
11
+ | docker run --rm -i -e PATINA_API_KEY patina:local --lang en --provider openai
12
+ ```
13
+
14
+ Planned tags after the GHCR publishing issue is closed:
15
+
16
+ - `ghcr.io/devswha/patina:<version>` — version tag from `v<version>`.
17
+ - `ghcr.io/devswha/patina:latest` — latest release tag.
18
+
19
+ The image uses `node:18-alpine`. It does **not** include codex, claude, or gemini CLI binaries, and it never carries local login state. For container runs, use an API-backed provider or mount your own authenticated tools explicitly.
@@ -0,0 +1,59 @@
1
+ # GitHub Action
2
+
3
+ Patina's standalone Action repository is [`devswha/patina-action`](https://github.com/devswha/patina-action). It runs pull request prose review without a live model call, leaves a sticky comment with file-level hotspot scores, and can fail above an optional score threshold.
4
+
5
+ > The Action defaults to `patina-cli@latest`, so the `@v1` tag should be cut after the npm publish in #203. Until then, pre-release workflows can use `@main` with `patina-package: github:devswha/patina`.
6
+
7
+ ```yaml
8
+ name: Patina prose score
9
+
10
+ on:
11
+ pull_request:
12
+ paths:
13
+ - '**/*.md'
14
+ - '**/*.mdx'
15
+
16
+ permissions:
17
+ contents: read
18
+ pull-requests: read
19
+ issues: write
20
+
21
+ jobs:
22
+ patina:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v6
26
+ - uses: devswha/patina-action@main # replace with @v1 after npm publish + action tag
27
+ with:
28
+ patina-package: github:devswha/patina # remove after patina-cli@latest is on npm
29
+ report-threshold: 30
30
+ lang: auto
31
+ comment: true
32
+ ```
33
+
34
+ Once `patina-cli` is on npm and `devswha/patina-action@v1` is tagged, the stable form is:
35
+
36
+ ```yaml
37
+ - uses: actions/checkout@v6
38
+ - uses: devswha/patina-action@v1
39
+ with:
40
+ score-threshold: 30
41
+ comment: true
42
+ ```
43
+
44
+ ## Inputs
45
+
46
+ | Input | Default | Meaning |
47
+ |---|---:|---|
48
+ | `github-token` | `${{ github.token }}` | Token for changed-file detection and comments. |
49
+ | `files` | changed PR Markdown | Optional newline/comma/JSON file list; overrides paths-filter. |
50
+ | `lang` | `auto` | `auto`, `ko`, `en`, `zh`, or `ja`. |
51
+ | `score-threshold` | unset | If set, fail when any file score is above this percentage. |
52
+ | `report-threshold` | `30` | Advisory report gate when `score-threshold` is unset. |
53
+ | `max-files` | `50` | Maximum Markdown files to score. |
54
+ | `comment` | `true` | Create/update a sticky PR comment. |
55
+ | `patina-package` | `patina-cli@latest` | npm package spec used by `npx`. |
56
+
57
+ ## What it measures
58
+
59
+ The Action uses `dorny/paths-filter@v4` to find changed Markdown files, runs Patina's deterministic `patina-score` command through `npx`, and updates a sticky comment with `peter-evans/create-or-update-comment@v5`. Read the table as a review queue. Open the highest row, check the surrounding paragraph, and decide whether the prose actually needs editing for your audience. It reports **editing hotspots**, not proof that text was AI-written.
@@ -0,0 +1,77 @@
1
+ # Pre-commit integrations
2
+
3
+ Use these recipes when you want Patina to flag AI-sounding prose before Markdown changes land in a docs or blog repository.
4
+
5
+ The hook is **score-only**: it never rewrites files during commit. It uses Patina's deterministic stylometry/lexicon layer, so it does not need an API key and it does not claim authorship provenance.
6
+
7
+ ## pre-commit framework
8
+
9
+ ```yaml
10
+ # .pre-commit-config.yaml
11
+ repos:
12
+ - repo: https://github.com/devswha/patina
13
+ rev: main # replace with a release tag after v1 is cut
14
+ hooks:
15
+ - id: patina-score
16
+ args: [--gate, "30", --lang, auto]
17
+ ```
18
+
19
+ Run it locally:
20
+
21
+ ```bash
22
+ pre-commit run patina-score --all-files
23
+ ```
24
+
25
+ ## Husky + lint-staged
26
+
27
+ ```bash
28
+ npm install --save-dev husky lint-staged patina-cli
29
+ npx husky init
30
+ ```
31
+
32
+ ```jsonc
33
+ // package.json
34
+ {
35
+ "lint-staged": {
36
+ "*.{md,mdx}": "patina-score --gate 30 --lang auto"
37
+ }
38
+ }
39
+ ```
40
+
41
+ ```bash
42
+ # .husky/pre-commit
43
+ npx lint-staged
44
+ ```
45
+
46
+ ## Lefthook
47
+
48
+ Install the package in the repository first:
49
+
50
+ ```bash
51
+ npm install --save-dev patina-cli
52
+ ```
53
+
54
+ ```yaml
55
+ # lefthook.yml
56
+ pre-commit:
57
+ commands:
58
+ patina-score:
59
+ glob: "*.{md,mdx}"
60
+ run: npx patina-score --gate 30 --lang auto {staged_files}
61
+ ```
62
+
63
+ A repo-local Lefthook command if this repository is vendored or checked out:
64
+
65
+ ```yaml
66
+ pre-commit:
67
+ commands:
68
+ patina-score:
69
+ glob: "*.{md,mdx}"
70
+ run: node scripts/precommit-score.mjs --gate 30 --lang auto {staged_files}
71
+ ```
72
+
73
+ ## Tuning
74
+
75
+ - `--gate 30` means fail when more than 30% of prose paragraphs in a file trip a hot signal.
76
+ - `--lang auto` infers language from filename and Unicode ranges; pass `ko`, `en`, `zh`, or `ja` when a repo is single-language.
77
+ - Use this as a discussion prompt, not as an accusation. See [ETHICS.md](../ETHICS.md).
@@ -0,0 +1,43 @@
1
+ # Release
2
+
3
+ `release.yml` is the maintainer path for npm distribution artifacts.
4
+
5
+ ## Dry run
6
+
7
+ ```bash
8
+ gh workflow run release.yml -f publish=false -f publish_ghcr=false
9
+ ```
10
+
11
+ The dry run verifies:
12
+
13
+ - version metadata across `package.json`, skill files, `.patina.default.yaml`, README, and CHANGELOG;
14
+ - unit/e2e tests;
15
+ - benchmark report schema;
16
+ - dogfood docs score;
17
+ - `npm pack --dry-run` for both `patina-cli` and the `patina-humanizer` alias package.
18
+
19
+ ## Publish
20
+
21
+ Publishing the npm packages is intended for `v*.*.*` tags:
22
+
23
+ ```bash
24
+ git tag v3.11.0
25
+ git push origin v3.11.0
26
+ ```
27
+
28
+ Required secret:
29
+
30
+ - `NPM_TOKEN` for npm provenance publishing.
31
+
32
+ The publish job uploads:
33
+
34
+ - `patina-cli` to npm;
35
+ - `patina-humanizer` alias to npm.
36
+
37
+ Docker / GHCR publishing is intentionally decoupled from npm releases while
38
+ the container distribution issue is still open. Maintainers can run the
39
+ experimental image path manually after npm verification:
40
+
41
+ ```bash
42
+ gh workflow run release.yml --ref v3.11.0 -f publish=false -f publish_ghcr=true
43
+ ```
@@ -0,0 +1,14 @@
1
+ # Harness Notes
2
+
3
+ Status: internal maintainer note. This is not public installation guidance.
4
+
5
+ ## Current stance
6
+
7
+ - Patina is primarily a Markdown skill plus a Node.js CLI.
8
+ - Use specification-first review for changes that touch pattern definitions, scoring logic, or meaning-preservation behavior.
9
+ - Keep the core skill pipeline stable unless the change explicitly targets pipeline behavior.
10
+ - For docs-only waves, prefer `docs-review` evidence and the standard npm verification gates.
11
+
12
+ ## Historical context
13
+
14
+ Older agent notes referenced an OMC/Ouroboros harness as the primary working lane. The current workspace uses the repo's active Codex/OMX runtime instructions from `AGENTS.md` and the bootstrap files instead. Treat older harness-specific routing as historical unless it is reintroduced in active automation.
@@ -0,0 +1,14 @@
1
+ # Internal Maintainer Notes
2
+
3
+ These files are maintainer/agent context, not public user documentation. Public docs stay in the root README files and `docs/`; internal notes should not be treated as installation or API contracts.
4
+
5
+ ## Triage of legacy top-level Markdown
6
+
7
+ | File | Decision | Rationale |
8
+ |---|---|---|
9
+ | `DESIGN.md` | keep public | Active product/brand source of truth; linked from the README docs list. |
10
+ | `HARNESS.md` | moved here | Agent/harness notes are useful for maintainers but not user-facing. |
11
+ | `WARP.md` | moved here | Warp-specific agent context is useful for maintainers but was stale as public root docs. |
12
+ | `AGENTS.md`, `BOOTSTRAP.md`, `USER.md`, `IDENTITY.md`, `SOUL.md`, `MEMORY.md`, `HEARTBEAT.md`, `TOOLS.md` | not tracked in this branch | Runtime/local agent files are intentionally outside the public docs set when absent from git. |
13
+
14
+ If a future internal note becomes a user-facing contract, move it back into `docs/` or the root and link it from `README.md` with a clear audience.
@@ -0,0 +1,23 @@
1
+ # WARP Notes
2
+
3
+ Status: internal maintainer note for Warp/agent users. Public usage remains in `README.md`, localized READMEs, and `docs/`.
4
+
5
+ ## What this repo is
6
+
7
+ Patina is a Claude Code / Codex / Cursor / OpenCode skill plus a standalone Node.js CLI. It detects and rewrites AI writing patterns in Korean, English, Chinese, and Japanese while checking meaning preservation.
8
+
9
+ ## Current architecture reminders
10
+
11
+ - `SKILL.md`: prompt-based `/patina` orchestrator.
12
+ - `src/cli.js` and `bin/patina.js`: standalone CLI surface.
13
+ - `patterns/{ko,en,zh,ja}-*.md`: language-specific pattern packs, auto-discovered by prefix.
14
+ - `docs/PATTERNS.md` and `docs/PATTERNS-{KO,EN,ZH,JA}.md`: generated/manual references for the pattern packs.
15
+ - `core/voice.md`, `profiles/*.md`, and `core/scoring.md`: voice, profile, and scoring references.
16
+ - `SKILL-MAX.md` and `patina-max/SKILL.md`: MAX-mode references and installable entrypoint.
17
+
18
+ ## Safe-change rules
19
+
20
+ - Do not change the core skill pipeline unless explicitly asked.
21
+ - When editing patterns, include before/after examples.
22
+ - Version-sync changes must update all five version-bearing files named in `AGENTS.md`.
23
+ - Run the relevant npm gates before claiming completion.
@@ -0,0 +1,89 @@
1
+ # 2025+ Re-baseline Plan
2
+
3
+ Status: protocol template, no external detector/vendor claims yet.
4
+ Owner: maintainers.
5
+ Related issues: #155, #163, #170, #172, #213.
6
+
7
+ Patina's checked-in benchmark is a deterministic regression corpus. It is useful
8
+ for catching tokenizer, threshold, lexicon, and fixture drift. It is not enough
9
+ to claim performance against current LLM output. This plan defines the evidence
10
+ needed before making broader README or launch-page claims.
11
+
12
+ ## Scope
13
+
14
+ Measure whether Patina flags **AI-like writing signals** and preserves meaning
15
+ after rewriting. Do not frame the result as authorship proof.
16
+
17
+ Minimum matrix:
18
+
19
+ | axis | minimum coverage |
20
+ |---|---:|
21
+ | languages | ko, en, zh, ja |
22
+ | classes | AI-like, natural/human, lightly edited AI, heavily edited AI |
23
+ | registers | blog, academic-summary, product-doc, chat/update, technical how-to |
24
+ | generators | at least one GPT-family, Claude-family, Gemini-family, and open-weight model |
25
+ | sample size | start at 25 paragraphs per language × class × register cell before publishing claims |
26
+
27
+ ## Data rules
28
+
29
+ - Use redistributable prompts and generated text; do not check private user text into the repo.
30
+ - Store full text only when redistribution is allowed. Otherwise store hashes, metadata, and metrics.
31
+ - Keep generation metadata: model, provider, date, prompt id, decoding params, language, register, and any editing pass.
32
+ - Separate detector-facing evaluation from rewrite-quality evaluation.
33
+
34
+ ## Metrics
35
+
36
+ For deterministic suspect-zone detection:
37
+
38
+ - accuracy, precision, recall, F1
39
+ - Wilson 95% confidence interval per language and register
40
+ - detector sub-signal breakdown: burstiness, MATTR, lexicon
41
+ - expected metric ranges for checked-in fixtures
42
+
43
+ For rewrite quality:
44
+
45
+ - before/after AI-likeness score
46
+ - MPS or manual meaning-preservation notes
47
+ - named entity, number, negation, and causality preservation
48
+ - human reviewer preference where available
49
+
50
+ For external detector comparison:
51
+
52
+ - use `npm run benchmark:compare` for the in-tree analyzer
53
+ - add third-party rows manually through `scripts/detector-comparison.mjs --input <json>`
54
+ - record detector id, date, plan/version if visible, score, and hot/cold label
55
+ - avoid scraping and avoid automated vendor calls unless a service explicitly permits it
56
+
57
+ ## Artifact layout
58
+
59
+ Recommended local/private layout before publishing sanitized summaries:
60
+
61
+ ```text
62
+ artifacts/rebaseline-2025/
63
+ ├── prompts.jsonl
64
+ ├── generations.jsonl # only redistributable text
65
+ ├── generations.private.jsonl # gitignored/private text if needed
66
+ ├── patina-scores.jsonl
67
+ ├── third-party.manual.json
68
+ ├── reviewer-notes.jsonl
69
+ └── summary.md
70
+ ```
71
+
72
+ Checked-in public summaries should live under `docs/benchmarks/` after review.
73
+
74
+ ## Publication gate
75
+
76
+ Do not publish competitive claims until the report includes:
77
+
78
+ 1. sample sizes by language, class, register, and generator
79
+ 2. confidence intervals, not just point estimates
80
+ 3. false-positive notes for human/natural prose
81
+ 4. clear statement that Patina measures AI-like writing signals, not authorship provenance
82
+ 5. reproducible commands or a manual collection protocol
83
+ 6. issue/PR links for corpus additions and threshold changes
84
+
85
+ ## Current baseline
86
+
87
+ The current checked-in report is `docs/benchmarks/latest.md`. It covers a small
88
+ curated suspect-zone corpus across ko/en/zh/ja and pins deterministic feature
89
+ ranges in `tests/fixtures/suspect-zones/expected-ranges.json`.