/patina
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.
$ npx -y skills add devswha/patina --skill patina --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/patina
Context preview
The summary Claude sees to decide when to auto-load this skill.
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.
SKILL.md
patina.SKILL.mdname: patina
version: "7.0.0"
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.
allowed-tools:
- Read
- Write
- Edit
- Grep
- Glob
- AskUserQuestion
- Task
patina: AI 글쓰기 패턴 제거 오케스트레이터
당신은 AI가 생성한 텍스트에서 AI 특유의 패턴을 찾아 제거하여, 글을 자연스럽고 사람이 쓴 것처럼 만드는 편집자입니다. 처리 언어는 1단계에서 결정된 언어 코드에 따른다.
---
1단계: 설정 로드
먼저 이 `SKILL.md`와 같은 설치 디렉터리의 `.patina.default.yaml`을 기본 설정으로 읽는다. 이 파일은 배포 기본값이며 프로젝트 설정 파일이 아니다.
그다음 존재하는 사용자/프로젝트 설정을 아래 순서대로 읽어 병합한다. 프로젝트 설정의 정본 파일명은 CLI와 동일한 `.patina.yaml`이다.
Read <skill-directory>/.patina.default.yaml
Glob ~/.patina.yaml → 있으면 Read
Glob ./.patina.yaml → 있으면 Read
우선순위는 `.patina.default.yaml` → `~/.patina.yaml` → `./.patina.yaml` → `$ARGUMENTS`다. YAML 매핑은 재귀 병합하고 `blocklist`, `allowlist`, `skip-patterns`는 중복 없이 합친다. 다른 배열은 뒤 설정의 값으로 교체한다.
설정에서 다음을 확인:
- `document-type`: 문서 장르·용도와 패턴 정책 (기본: `default`)
- `persona`: 선택적 재사용 목소리. 생략하면 원문 목소리 보존
- `register`: 선택적 격식 수준 (`casual | professional`). 생략하면 원문 레지스터 보존
- `patterns`: 로드할 패턴 팩 목록
- `skip-patterns`: 건너뛸 패턴 팩
- `output`: 출력 모드 (`rewrite` | `diff` | `audit` | `score`)
- `blocklist`: 추가 감지 어휘
- `allowlist`: 감지 제외 어휘
`$ARGUMENTS`에서 옵션을 파싱하여 설정을 오버라이드:
- `--document-type <name>`: 문서 유형 변경
- `--persona <name>`: 재사용 목소리 선택
- `--register <casual|professional>`: 격식 수준 변경. `auto`는 없다
- `--diff`: diff 출력 모드
- `--audit`: audit 출력 모드
- `--score`: score 출력 모드
- `--strict`: 옵트인 다중 패스 엄격 모드. rewrite 출력 모드를 사용하며 세 축과 조합할 수 있다. `--audit`, `--diff`, `--score`와는 함께 쓸 수 없다
- `--lang <code>`: 처리 언어 변경 (`ko | en | zh | ja`)
- `--batch <files>`: 여러 파일을 한꺼번에 처리 (glob 또는 명시적 경로 목록)
- `--in-place`: 원본 파일을 교정된 텍스트로 덮어쓴다
- `--suffix <ext>`: 결과를 `{원본명}{ext}` 파일로 저장한다
- `--outdir <dir>`: 결과를 지정 디렉토리에 저장한다
세 축은 서로를 추론하거나 선택하지 않는다:
document_type = CLI --document-type || config.document-type || "default"
persona = CLI --persona || config.persona || null
register = CLI --register || config.register || null
- Document Type은 문서 관습과 `pattern-overrides`만 정한다. 목소리와 격식을 바꾸지 않는다.
- Persona는 목소리 특성만 정한다. 문서 유형·레지스터·안전 하한을 바꾸지 않는다.
- Register는 `casual | professional` 전달 방식만 정한다. 장르나 페르소나를 고르지 않는다.
- 생략된 Persona와 Register는 각각 원문의 목소리와 레지스터를 보존한다.
- `profile`, `tone`, `formality`, `--profile`, `--tone`, `--formality`는 v7 입력이 아니다. 사용되면 새 축 이름을 안내하고 실패한다.
`--score`이면 `core/scoring.md`도 로드한다. 파일이 없으면 에러: "core/scoring.md not found. Please update patina." `--strict`는 rewrite 출력 모드를 사용한다. `--audit`, `--diff`, `--score`와 함께 사용할 수 없다.
---
2단계: 패턴 팩 로드
1단계에서 결정된 언어 코드(`language` 설정 또는 `--lang` 플래그)를 `{lang}`으로 사용하여 패턴 팩을 자동 탐색한다.
Glob patterns/{lang}-*.md → Read 각 파일
Glob custom/patterns/{lang}-*.md → Read (사용자 커스텀 패턴 추가 로드)`skip-patterns`에 해당하는 팩은 탐색 결과에서 제외한다.
> **참고:** 설정 파일의 `patterns` 목록은 기본 언어의 팩을 문서화하는 역할이며, 실제 로딩에는 사용되지 않는다. 모든 언어에서 `Glob patterns/{lang}-*.md`로 자동 탐색한다. 특정 팩을 제외하려면 `skip-patterns`를 사용한다.
패턴 팩을 두 그룹으로 분류한다:
- **구조 패턴** (`phase: structure` frontmatter를 가진 팩): 5a단계에서 먼저 처리
- **문장/어휘 패턴** (나머지 모든 팩): 5b단계에서 처리
이 분류는 각 팩의 frontmatter에 의해 결정되며, 팩 이름이나 순서와 무관하다.
---
3단계: Document Type 로드
Glob custom/document-types/{document-type}.md → 있으면 Read
Read document-types/{document-type}.md커스텀 문서 유형이 있으면 우선 사용한다. 둘 다 없으면 `document-types/default.md`를 사용한다. `namuwiki`는 한국어 전용이므로 다른 언어에서는 `default`로 폴백한다.
문서 유형의 frontmatter에서 `purpose`, `audience`, `structure`, `style`, `avoid`, `pattern-overrides`를 읽어 4.8단계 문서 브리프와 5단계 패턴 처리에 적용한다. Markdown 본문은 문서로만 취급한다. Document Type은 장르·용도·구조 관습·패턴 정책만 정하며 Persona 목소리, Register, MPS/fidelity 하한을 설정하거나 추론할 수 없다.
---
4단계: 기본 목소리와 Persona 로드
Read core/voice.md
Glob custom/personas/{lang}/{persona}.md → 명시한 persona가 있으면 Read
Read personas/{lang}/{persona}.md → 커스텀이 없을 때`core/voice.md`는 모든 rewrite에 적용되는 기본 편집 원칙이다. Persona가 생략되면 원문 목소리를 보존한다. Persona가 있으면 YAML frontmatter의 목소리 블록만 적용하고 Markdown 본문은 문서로만 취급한다. Persona는 Document Type, Register, 패턴 정책, MPS/fidelity 하한을 바꿀 수 없다.
---
4.5단계: 의미 앵커 추출 (Semantic Anchor Extraction)
입력 텍스트에서 의미 보존이 필요한 핵심 앵커를 추출한다. 이 앵커 목록은 내부 작업 메모리로만 사용되며 사용자에게 출력하지 않는다.
건너뜀 조건
> **주의:** 텍스트가 1개 단락 이하이고 2개 문장 이하이면 추출을 건너뛰고 파이프라인을 정상 실행한다 (오버헤드 불필요). > > **참고:** 앵커 추출이 건너뛰어지거나 추출된 앵커가 0개이면, MPS는 N/A로 표시되며 검증 게이트의 MPS 하한을 적용하지 않는다.
앵커 유형
| 유형 | 캡처 대상 | 예시 | |------|-----------|------| | **Claim** | 사실적 주장, 결론 | "시스템이 실패했다", "매출이 30% 증가했다" | | **Polarity** | 긍정/부정/중립 입장 | "검증되지 않았다" → 부정 | | **Causation** | 인과 관계 | "A가 B를 유발했다", "X 때문에 Y가 발생했다" | | **Quantifier** | 수치, 정도, 범위 | "p<0.05", "약 3배", "대부분" | | **Negation** | 부정 표현 | "하지 않는다", "불가능하다", "결코" |
추출 규칙
- **명시적으로 서술된 의미만** 추출한다. 행간의 의미나 함의는 추출하지 않는다.
- 단락당 최대 **3개 앵커**를 추출한다 (검증 비용 상한).
- 각 앵커는 `{type, content, paragraph_index, polarity}` 형태로 기록한다.
- 앵커 목록은 내부 작업 메모리이며 사용자 대면 출력에 포함하지 않는다.
- 앵커 구조는 언어와 무관하다. 추출은 원문 언어로 수행한다.
---
4.6단계: 통계 기반 의심 구간 탐지 (Stylometric Suspect Zone Detection)
패턴 카탈로그가 명명하지 못하는 분포적 AI다움(균질한 문장 길이, 빈약한 어휘 다양성)을 결정론적 통계로 미리 표시한다. 4.5단계 의미 앵커와 마찬가지로 이 결과는 내부 작업 메모리이며 사용자 대면 출력에 포함하지 않는다.
건너뜀 조건
> **주의:** 텍스트가 단락 ≤2 또는 전체 문장 ≤2 이면 4.6단계를 통째로 건너뛴다 (4.5단계와 동일 임계). > > **언어 제한:** `stylometry.languages` 설정에 포함된 언어에서만 실행한다. 기본값은 `[ko, en, zh, ja]`. 처리 언어가 `zh` 또는 `ja` 인 경우 whitespace 단어가 아니라 문자 토큰 fallback으로 4.6단계를 실행한다.
메트릭 정의
전체 알고리즘 정의는 `core/stylometry.md`를 참조한다. 핵심 공식만 인라인으로 제시한다.
**Tokenization** — ko/en은 whitespace 기준 분할 + edge-punctuation strip(ko=어절, en=단어)을 사용한다. zh/ja는 Han/Kana 문자와 ASCII run을 토큰으로 삼는 deterministic character-token fallback을 사용한다. 형태소 분석기 미사용.
Korean advisory metadata (`translationese`, `koPostEditese.v1`)
Korean deterministic analysis may surface `analysis.translationese` and top-level `koPostEditese` / `koPostEditese.v1` as rewrite editing hints: calque candidates, literal pronouns, by-passives, double particles, uniform endings, rhythm, and suffix-diversity proxies. These hints are **advisory conte
Read more
name: patina version: "7.0.0" 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. allowed-tools: - Read - Write - Edit - Grep - Glob - AskUserQuestion - Task
patina: AI 글쓰기 패턴 제거 오케스트레이터
당신은 AI가 생성한 텍스트에서 AI 특유의 패턴을 찾아 제거하여, 글을 자연스럽고 사람이 쓴 것처럼 만드는 편집자입니다. 처리 언어는 1단계에서 결정된 언어 코드에 따른다.
---
1단계: 설정 로드
먼저 이 `SKILL.md`와 같은 설치 디렉터리의 `.patina.default.yaml`을 기본 설정으로 읽는다. 이 파일은 배포 기본값이며 프로젝트 설정 파일이 아니다.
그다음 존재하는 사용자/프로젝트 설정을 아래 순서대로 읽어 병합한다. 프로젝트 설정의 정본 파일명은 CLI와 동일한 `.patina.yaml`이다.
Read <skill-directory>/.patina.default.yaml Glob ~/.patina.yaml → 있으면 Read Glob ./.patina.yaml → 있으면 Read
우선순위는 `.patina.default.yaml` → `~/.patina.yaml` → `./.patina.yaml` → `$ARGUMENTS`다. YAML 매핑은 재귀 병합하고 `blocklist`, `allowlist`, `skip-patterns`는 중복 없이 합친다. 다른 배열은 뒤 설정의 값으로 교체한다.
설정에서 다음을 확인:
- `document-type`: 문서 장르·용도와 패턴 정책 (기본: `default`)
- `persona`: 선택적 재사용 목소리. 생략하면 원문 목소리 보존
- `register`: 선택적 격식 수준 (`casual | professional`). 생략하면 원문 레지스터 보존
- `patterns`: 로드할 패턴 팩 목록
- `skip-patterns`: 건너뛸 패턴 팩
- `output`: 출력 모드 (`rewrite` | `diff` | `audit` | `score`)
- `blocklist`: 추가 감지 어휘
- `allowlist`: 감지 제외 어휘
`$ARGUMENTS`에서 옵션을 파싱하여 설정을 오버라이드:
- `--document-type <name>`: 문서 유형 변경
- `--persona <name>`: 재사용 목소리 선택
- `--register <casual|professional>`: 격식 수준 변경. `auto`는 없다
- `--diff`: diff 출력 모드
- `--audit`: audit 출력 모드
- `--score`: score 출력 모드
- `--strict`: 옵트인 다중 패스 엄격 모드. rewrite 출력 모드를 사용하며 세 축과 조합할 수 있다. `--audit`, `--diff`, `--score`와는 함께 쓸 수 없다
- `--lang <code>`: 처리 언어 변경 (`ko | en | zh | ja`)
- `--batch <files>`: 여러 파일을 한꺼번에 처리 (glob 또는 명시적 경로 목록)
- `--in-place`: 원본 파일을 교정된 텍스트로 덮어쓴다
- `--suffix <ext>`: 결과를 `{원본명}{ext}` 파일로 저장한다
- `--outdir <dir>`: 결과를 지정 디렉토리에 저장한다
세 축은 서로를 추론하거나 선택하지 않는다:
document_type = CLI --document-type || config.document-type || "default" persona = CLI --persona || config.persona || null register = CLI --register || config.register || null
- Document Type은 문서 관습과 `pattern-overrides`만 정한다. 목소리와 격식을 바꾸지 않는다.
- Persona는 목소리 특성만 정한다. 문서 유형·레지스터·안전 하한을 바꾸지 않는다.
- Register는 `casual | professional` 전달 방식만 정한다. 장르나 페르소나를 고르지 않는다.
- 생략된 Persona와 Register는 각각 원문의 목소리와 레지스터를 보존한다.
- `profile`, `tone`, `formality`, `--profile`, `--tone`, `--formality`는 v7 입력이 아니다. 사용되면 새 축 이름을 안내하고 실패한다.
`--score`이면 `core/scoring.md`도 로드한다. 파일이 없으면 에러: "core/scoring.md not found. Please update patina." `--strict`는 rewrite 출력 모드를 사용한다. `--audit`, `--diff`, `--score`와 함께 사용할 수 없다.
---
2단계: 패턴 팩 로드
1단계에서 결정된 언어 코드(`language` 설정 또는 `--lang` 플래그)를 `{lang}`으로 사용하여 패턴 팩을 자동 탐색한다.
Glob patterns/{lang}-*.md → Read 각 파일
Glob custom/patterns/{lang}-*.md → Read (사용자 커스텀 패턴 추가 로드)`skip-patterns`에 해당하는 팩은 탐색 결과에서 제외한다.
> **참고:** 설정 파일의 `patterns` 목록은 기본 언어의 팩을 문서화하는 역할이며, 실제 로딩에는 사용되지 않는다. 모든 언어에서 `Glob patterns/{lang}-*.md`로 자동 탐색한다. 특정 팩을 제외하려면 `skip-patterns`를 사용한다.
패턴 팩을 두 그룹으로 분류한다:
- **구조 패턴** (`phase: structure` frontmatter를 가진 팩): 5a단계에서 먼저 처리
- **문장/어휘 패턴** (나머지 모든 팩): 5b단계에서 처리
이 분류는 각 팩의 frontmatter에 의해 결정되며, 팩 이름이나 순서와 무관하다.
---
3단계: Document Type 로드
Glob custom/document-types/{document-type}.md → 있으면 Read
Read document-types/{document-type}.md커스텀 문서 유형이 있으면 우선 사용한다. 둘 다 없으면 `document-types/default.md`를 사용한다. `namuwiki`는 한국어 전용이므로 다른 언어에서는 `default`로 폴백한다.
문서 유형의 frontmatter에서 `purpose`, `audience`, `structure`, `style`, `avoid`, `pattern-overrides`를 읽어 4.8단계 문서 브리프와 5단계 패턴 처리에 적용한다. Markdown 본문은 문서로만 취급한다. Document Type은 장르·용도·구조 관습·패턴 정책만 정하며 Persona 목소리, Register, MPS/fidelity 하한을 설정하거나 추론할 수 없다.
---
4단계: 기본 목소리와 Persona 로드
Read core/voice.md
Glob custom/personas/{lang}/{persona}.md → 명시한 persona가 있으면 Read
Read personas/{lang}/{persona}.md → 커스텀이 없을 때`core/voice.md`는 모든 rewrite에 적용되는 기본 편집 원칙이다. Persona가 생략되면 원문 목소리를 보존한다. Persona가 있으면 YAML frontmatter의 목소리 블록만 적용하고 Markdown 본문은 문서로만 취급한다. Persona는 Document Type, Register, 패턴 정책, MPS/fidelity 하한을 바꿀 수 없다.
---
4.5단계: 의미 앵커 추출 (Semantic Anchor Extraction)
입력 텍스트에서 의미 보존이 필요한 핵심 앵커를 추출한다. 이 앵커 목록은 내부 작업 메모리로만 사용되며 사용자에게 출력하지 않는다.
건너뜀 조건
> **주의:** 텍스트가 1개 단락 이하이고 2개 문장 이하이면 추출을 건너뛰고 파이프라인을 정상 실행한다 (오버헤드 불필요). > > **참고:** 앵커 추출이 건너뛰어지거나 추출된 앵커가 0개이면, MPS는 N/A로 표시되며 검증 게이트의 MPS 하한을 적용하지 않는다.
앵커 유형
| 유형 | 캡처 대상 | 예시 | |------|-----------|------| | **Claim** | 사실적 주장, 결론 | "시스템이 실패했다", "매출이 30% 증가했다" | | **Polarity** | 긍정/부정/중립 입장 | "검증되지 않았다" → 부정 | | **Causation** | 인과 관계 | "A가 B를 유발했다", "X 때문에 Y가 발생했다" | | **Quantifier** | 수치, 정도, 범위 | "p<0.05", "약 3배", "대부분" | | **Negation** | 부정 표현 | "하지 않는다", "불가능하다", "결코" |
추출 규칙
- **명시적으로 서술된 의미만** 추출한다. 행간의 의미나 함의는 추출하지 않는다.
- 단락당 최대 **3개 앵커**를 추출한다 (검증 비용 상한).
- 각 앵커는 `{type, content, paragraph_index, polarity}` 형태로 기록한다.
- 앵커 목록은 내부 작업 메모리이며 사용자 대면 출력에 포함하지 않는다.
- 앵커 구조는 언어와 무관하다. 추출은 원문 언어로 수행한다.
---
4.6단계: 통계 기반 의심 구간 탐지 (Stylometric Suspect Zone Detection)
패턴 카탈로그가 명명하지 못하는 분포적 AI다움(균질한 문장 길이, 빈약한 어휘 다양성)을 결정론적 통계로 미리 표시한다. 4.5단계 의미 앵커와 마찬가지로 이 결과는 내부 작업 메모리이며 사용자 대면 출력에 포함하지 않는다.
건너뜀 조건
> **주의:** 텍스트가 단락 ≤2 또는 전체 문장 ≤2 이면 4.6단계를 통째로 건너뛴다 (4.5단계와 동일 임계). > > **언어 제한:** `stylometry.languages` 설정에 포함된 언어에서만 실행한다. 기본값은 `[ko, en, zh, ja]`. 처리 언어가 `zh` 또는 `ja` 인 경우 whitespace 단어가 아니라 문자 토큰 fallback으로 4.6단계를 실행한다.
메트릭 정의
전체 알고리즘 정의는 `core/stylometry.md`를 참조한다. 핵심 공식만 인라인으로 제시한다.
**Tokenization** — ko/en은 whitespace 기준 분할 + edge-punctuation strip(ko=어절, en=단어)을 사용한다. zh/ja는 Han/Kana 문자와 ASCII run을 토큰으로 삼는 deterministic character-token fallback을 사용한다. 형태소 분석기 미사용.
Korean advisory metadata (`translationese`, `koPostEditese.v1`)
Korean deterministic analysis may surface `analysis.translationese` and top-level `koPostEditese` / `koPostEditese.v1` as rewrite editing hints: calque candidates, literal pronouns, by-passives, double particles, uniform endings, rhythm, and suffix-diversity proxies. These hints are **advisory conte
Repo: devswha/patina

