Skip to content
Back to skills

L10n

ASecurity

소스 문자열 현지화 — 하드코딩 문자열·로케일 키 누락·확장률 폭 초과를 번역 전에 잡는다. 로케일 집합의 단일 출처. 트리거 "현지화", "l10n", "로케일", "다국어", "하드코딩 문자열", "ARB".

  • 2 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 19, 2026
ai-agentsc#bash

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add snwlee/Nereus --skill l10n --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of L10n?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for L10n
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/snwlee-l10n/badge)](https://www.skillsdirectory.com/skills/snwlee-l10n)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: l10n
description: 소스 문자열 현지화 — 하드코딩 문자열·로케일 키 누락·확장률 폭 초과를 번역 전에 잡는다. 로케일 집합의 단일 출처. 트리거 "현지화", "l10n", "로케일", "다국어", "하드코딩 문자열", "ARB".
---

# l10n

nereus:common 규칙을 따른다. 담당 에이전트: l10n-engineer.
**엔진·프레임워크와 무관하다** — Luau 든 C# 이든 Dart 든 같은 규칙으로 소스를 훑는다.
**게임·비게임을 가리지 않는다** — 배경화면 앱도 게임도 같은 결함을 낸다.

현지화 결함은 출시 **후에** 드러나고, 그때는 고치는 비용이 몇 배가 된다.
이 스킬은 **번역을 실행하지 않고** 번역하면 깨질 곳을 지금 찾는다.

## 0. 로케일 집합은 `locales.json` 이 단일 출처다

```bash
cat "${CLAUDE_PLUGIN_ROOT}/locales.json"
```

**두 집합이 들어 있다.**

| 집합 | 예 | 쓰는 곳 |
|---|---|---|
| 스토어 로케일 (`stores: ["play"]`) | `ko-KR` · `en-US` · `zh-CN` | 등재 텍스트·이미지 |
| 소스 언어 별칭 (`aliasOf`) | `ko` · `en` · `zh` | 소스 문자열 표(ARB 등) |

**하나로 뭉치지 않는다.** Play 는 `ko-KR` 을 쓰고 소스 표는 `ko` 를 쓴다 —
뭉치면 한쪽이 반드시 깨진다. 별칭 항목은 `stores: []` 이고 가리키는 로케일과
수치가 같다(테스트가 강제한다). **별칭은 편의지 두 번째 출처가 아니다.**

**알 수 없는 로케일은 기본값으로 떨어지지 않고 던진다.** 조용히 건너뛰면
그 로케일이 검사되지 않은 채 통과한다.

### 추정값은 출처를 필드마다 표시한다

86종의 확장률을 실측 없이 지어낼 수 없다. 그래서 값마다 근거가 붙는다:

| `expansionBasis` | 뜻 |
|---|---|
| `legacy-estimate` | 원래 8종에 있던 업계 통념 추정 |
| `group-estimate` | 스크립트·어족 그룹의 대표값을 물려받았다 |
| `measured` | 실측. 생기면 여기로 올린다 |

`expansion` 과 `avgCharWidth` 는 **다른 축**이다. 한글은 번역하면 글자 수가 줄지만
(`expansion` 0.8) 글자당 폭은 전각이라 라틴의 두 배다(`avgCharWidth` 1.0). 섞지 않는다.

## 1. 검사

`scanL10n` 을 부른다 (`lib/l10n-scan.mjs`).

| 인자 | 뜻 |
|---|---|
| `locales` | `loadLocales()` 결과 |
| `tables` | 로케일별 문자열 테이블. `{ en: { "hud.jump": "Jump" }, ko: { ... } }` |
| `sources` | 훑을 소스. `[{ file, text }]` |
| `maxWidth` | UI 폭. 0 이면 폭 검사를 하지 않는다 |
| `fontMetrics` | 로케일별 폰트 메트릭. 주면 실측 폭, 안 주면 근사 |
| `accessor` | 문자열 테이블 접근자. 기본 `L(`. Flutter 는 `l10n.` |
| `exclude` | 제외 규칙. `{ generated: [경로 조각], devMessage: [줄 토큰] }` |

| 위반 코드 | 뜻 |
|---|---|
| `hardcoded` | 접근자를 거치지 않은 사용자 노출 문자열 |
| `missing-key` | 기준 로케일에 있는 키가 그 로케일에 없다 |
| `overflow` | 폭이 `maxWidth` 를 넘는다. `fontMetrics` 가 없으면 `approx: true` 가 붙는다 |

## 2. 사용자에게 도달하지 않는 것은 위반이 아니다

`skipped: [{ reason, count }]` 로 **분류와 셈을 같이 낸다.** 조용히 버리면
"검사해서 통과한 것"과 "아예 안 본 것"이 구분되지 않는다.

| `reason` | 판정 |
|---|---|
| `generated` | 경로가 `generated/`·`.g.dart`·`.freezed.dart`·`.generated.cs` 등. l10n 도구 **산출물**이다 |
| `dev-message` | 줄에 `throw`·`assert(`·`Exception(`·로그 호출. 사용자에게 도달하지 않는다 |

**생성물은 파일 단위, 개발자 메시지는 줄 단위**로 판정한다. 생성물이 아닌 파일에도
개발자 메시지는 섞여 있고, 그 파일의 사용자 문자열은 계속 검사되어야 한다.

> **실측(2026-09-13, ToonTone):** 461건이 나왔고 그중 진짜 결함은 **0건**이었다.
> l10n 도구가 **직접 만든** 번역 테이블이 "하드코딩"으로 잡혔다 — 정확히 거꾸로다.
> **461:0 이면 사람이 게이트를 끈다. 끄게 만드는 게이트는 게이트가 아니다.**
> 제외를 넣은 뒤 69건이 되었고, 그 안에서 실제 버그를 찾았다 —
> `LeaderboardPeriod.label` 이 `'오늘'`·`'이번 주'`·`'전체'` 를 하드코딩해 리턴하고
> 리더보드 화면이 그대로 렌더한다. 영어 로케일에서 한국어가 나온다.

패턴은 언어·프레임워크마다 다르다(`.g.dart` 는 Dart, `.generated.cs` 는 Unity).
`exclude` 로 덮어쓴다 — 스택이 늘 때마다 lib 을 고치면 안 된다.

## 3. 숫자·복수형·날짜

문자열 테이블에 문장을 통째로 넣는다. `"You have " .. n .. " coins"` 처럼 조각내면
복수형·어순이 다른 언어에서 고칠 방법이 없다. 자리표시자를 쓴다.

## 4. 하지 말 것

- **로케일 목록을 코드에 박지 않는다.** 늘리는 것은 `locales.json` 한 줄이다.
- **알 수 없는 로케일을 기본값으로 처리하지 않는다.** 던진다.
- **스토어 등재를 여기서 보지 않는다.** `storelisting` 이 한다.
- **폰트·글리프를 여기서 보지 않는다.** `typeface` 가 한다.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.