@tienne/gestalt 0.54.0 → 0.55.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/CLAUDE.md CHANGED
@@ -31,6 +31,7 @@ pnpm tsx bin/gestalt.ts spec <session-id>
31
31
  pnpm tsx bin/gestalt.ts status
32
32
  pnpm tsx bin/gestalt.ts init # gestalt.json + code graph + post-commit hook
33
33
  pnpm verify:rules # 룰북과 에이전트 문서의 룰 ID·심각도 정합 검사
34
+ pnpm build:output-style # 룰북 → ~/.claude/output-styles/tienne-voice.md 생성
34
35
  pnpm tsx bin/gestalt.ts humanize-check --before a.md --after b.md --register chat
35
36
  ```
36
37
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tienne/gestalt",
3
- "version": "0.54.0",
3
+ "version": "0.55.0",
4
4
  "description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -20,7 +20,7 @@
20
20
  "scripts": {
21
21
  "dev": "tsx bin/gestalt.ts",
22
22
  "build": "tsc",
23
- "postbuild": "rm -rf dist/plugin && mkdir -p dist/plugin && cp -r plugin/agents plugin/role-agents plugin/review-agents plugin/personas plugin/skills dist/plugin/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js && pnpm run verify:plugin && pnpm run verify:rules",
23
+ "postbuild": "rm -rf dist/plugin && mkdir -p dist/plugin && cp -r plugin/agents plugin/role-agents plugin/review-agents plugin/personas plugin/skills dist/plugin/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js && pnpm run verify:plugin && pnpm run verify:rules && pnpm run verify:output-style",
24
24
  "verify:plugin": "tsx scripts/verify-plugin-assets.ts",
25
25
  "prepublishOnly": "pnpm build",
26
26
  "test": "vitest run",
@@ -35,7 +35,9 @@
35
35
  "version:sync": "tsx scripts/sync-version.ts",
36
36
  "postversion": "pnpm run version:sync",
37
37
  "verify:rules": "tsx scripts/verify-rule-refs.ts",
38
- "humanize:baseline": "tsx scripts/humanize-baseline.ts"
38
+ "humanize:baseline": "tsx scripts/humanize-baseline.ts",
39
+ "build:output-style": "tsx scripts/build-output-style.ts",
40
+ "verify:output-style": "tsx scripts/build-output-style.ts --dry-run"
39
41
  },
40
42
  "dependencies": {
41
43
  "@anthropic-ai/sdk": "^0.39.0",
@@ -48,7 +48,7 @@
48
48
  |---|---|---|---|
49
49
  | B-1 | 한글 + 괄호 영어 매번 ("~(Sovereign AI)" 처럼) | S2 | 첫 등장만 병기, 이후 한글만 |
50
50
  | B-2 | 영어 어휘 직역 가능한데 그대로 | S2 | 한국어로 옮기되 업계 표준은 유지 |
51
- | B-3 | 안 굳어진 영어 구·단어 음차 표기 ("소스 오브 트루스"), 그 음차를 약어로 우회한 표기(`SSOT`·`SoT`) | S1 | 한글 의역 + 첫 등장만 원어 괄호 병기("진실의 원천(source of truth)"), 이후 한글만. 단 위 "굳어진 음차 화이트리스트"에 있는 정착어는 Do-NOT — of/and 등 기능어까지 통째 음차한 구(룩 앤 필·로우 행잉 프룻)가 최우선 대상 |
51
+ | B-3 | 안 굳어진 영어 구·단어 음차 표기 ("소스 오브 트루스"), 그 음차를 약어로 우회한 표기(`SSOT`·`SoT`) | S1 | 한글 의역 + 첫 등장만 원어 괄호 병기("기준 문서(source of truth)", "단일 기준점(source of truth)" 등), 이후 한글만. 단 위 "굳어진 음차 화이트리스트"에 있는 정착어는 Do-NOT — of/and 등 기능어까지 통째 음차한 구(룩 앤 필·로우 행잉 프룻)가 최우선 대상. 무엇을 가리키는지 보고 고르는 표는 `style-guide.md` §single source of truth를 뭐라고 쓸까를 따른다 |
52
52
  | B-4 | 영어 개념을 어색하게 옮긴 조어("생산처" ← producer, "응답처") | S2 | 억지 신조어 대신 이미 쓰이는 말로. 코드 맥락이면 "호출부"·"사용처". **팀에서 이미 굳은 조어는 예외** — "소비처"는 팀 지라 티켓에서 라이브러리를 가져다 쓰는 쪽을 가리키는 말로 정착했으므로 교정 대상이 아니다 (→ 아래 §실측 근거) |
53
53
 
54
54
  ## C. 구조적 AI 패턴
@@ -67,7 +67,7 @@
67
67
 
68
68
  | ID | 패턴 | 심각도 | 처방 |
69
69
  |---|---|---|---|
70
- | D-1 | 결산 피벗 표현 "결론적으로/따라서/이를 통해/그러므로/요약하면/정리하면" | S1 | 3회 초과 1~2건 다른 종결로 치환, 나머지 삭제 |
70
+ | D-1 | 결산 피벗 표현 "결론적으로/이를 통해/요약하면/정리하면/종합하면" | S1 | 문단 결론을 대신하는 피벗이면 삭제하고 앞뒤 문장을 직결한다. 논리 연결만 하는 "따라서/그러므로"는 반복되거나 결산 리듬을 만들 때만 줄인다 |
71
71
  | D-2 | "시사하는 바가 크다/주목할 만하다" | S1 | 원문에 근거가 있으면 그 근거로 대체, 없으면 삭제. **새 결론을 지어내 붙이지 않는다** |
72
72
  | D-3 | "본질적으로/핵심적으로" | S1 | 삭제. 다른 부사로 갈아끼우지 말고 그냥 뺀다 |
73
73
  | D-4 | hype 어휘(파격적·압도적·강력한·획기적·치명적) 3회+ | S1 | 원문에 수치·사실이 있으면 그걸로 환원, **없으면 수치를 만들지 말고 수식어만 삭제** |
@@ -117,6 +117,7 @@
117
117
  | I-3 | "~다는 뜻이다/~다는 의미다" 결말 | S2 | 본문에 풀어 쓰기 |
118
118
  | I-4 | 권고형 결말 "~해야 한다·~합니다" 반복 | S2 | 평서·단언으로 |
119
119
  | I-5 | 사무투 분류사 "~ 건/해당 건/이번 건/그 건", 코드·문서 용어를 대화에 그대로("주석 건") | S2 / **대화·리뷰 S1** | 구체 명사로 풀기("Copilot이 짚은 주석 건" → "Copilot이 남긴 코멘트"). "건"은 공문서투 분류사라 대화에서 어색하다 |
120
+ | I-6 | 측량·사무투 명사 "실측·계측·산출·오탐" 등으로 판정·근거를 명사 하나로 압축 | S2 / **대화·리뷰 S1** | 동사로 풀어 말하기("레포 실측으로 1444개 중" → "레포 뒤져보니 1444개 중", "이건 오탐이에요" → "이건 잘못 감지한 거예요"). "잘못 걸리다"처럼 안 붙는 동사로 도망가지 말고 원래 짝이 맞는 동사(감지하다·측정하다)에 "잘못"을 붙인다 |
120
121
 
121
122
  ## J. 시각 장식
122
123
 
@@ -136,7 +137,7 @@
136
137
  2. **변경률**: 30% 이하인가 (50% 초과는 작업 중단)
137
138
  3. **장르 이탈 없음**: 칼럼이 에세이나 문학으로 변하지 않았는가, 리포트가 블로그체로 떨어지지 않았는가
138
139
  4. **말투 보존**: 원문 격식체면 결과도 격식체. 평어체로 떨어뜨리지 않는다
139
- 5. **잔존 S1 패턴 0건**: A-1, A-3, A-7, A-8, A-16, B-3, C-5, C-8, C-10, C-11, C-12, D-1~D-6, H-1, H-3, J-2가 남아있지 않은가 (대화·리뷰 말투면 A-2, A-5, F-4, F-5, F-6, F-7, I-1, I-5도 S1로 포함)
140
+ 5. **잔존 S1 패턴 0건**: A-1, A-3, A-7, A-8, A-16, B-3, C-5, C-8, C-10, C-11, C-12, D-1~D-6, H-1, H-3, J-2가 남아있지 않은가 (대화·리뷰 말투면 A-2, A-5, F-4, F-5, F-6, F-7, I-1, I-5, I-6도 S1로 포함)
140
141
  6. **인공 표현 자제**: 원문에 없던 비유, 수사, 문학적 표현을 윤문 과정에서 임의로 추가하지 않았는가
141
142
  7. **삭제 처방 준수**: D-2, D-3, D-4, D-6, C-10을 재작성으로 처리하지 않았는가. 마무리 문장, 부제, 수식어를 지우는 대신 더 그럴듯한 것으로 갈아끼운 자리가 없는가
142
143
 
@@ -195,4 +196,3 @@ AI 생성 산문 60편(모델 3종)과 2022년 이전 발행이 확인된 한국
195
196
  - **D**: S1 잔존 3+ 또는 변경률 50% 초과 — 작업 중단 권고
196
197
 
197
198
  > v2.0 신규/보강은 A-7, A-15, A-16, A-18, A-19, E-2, E-7, F-4 **8건 (A-17 보류)**. 학술 인용 전문은 `references/scholarship.md`. post-editese 3축 지표는 본 룰북 미반영(metric only 트랙). A-17 무정물, 추상명사 '-들'은 학술 근거(전영철 2007·곽은주·진실로 2011) 강하나 외부 회차(2026-05-07 위키 6편)에서 양성 0건 — NMT 원본 출력 회차 후 v2.1에서 동일 ID로 재평가.
198
-
@@ -63,7 +63,7 @@
63
63
  6. **친근체, 물결, 이모지를 자연스럽게.** "~네요!", "~어요~", 🙏 😀 👍 — 과하지 않게 한 코멘트에 1개 안팎.
64
64
  7. **수정 제안은 코드/토큰을 그대로 제시.** GitHub `​```suggestion` 블록이나 `tone={'neutralSecondary'}`처럼 값까지.
65
65
 
66
- ### 실제 예시 (그대로 학습verbatim)
66
+ ### 실제 예시 (패턴 참고문장 복붙 금지)
67
67
 
68
68
  ```
69
69
  routeName 보다는 allRoutes[routeName].link 로 subRoute.link 처리 하는 게 좋아보입니다.
@@ -100,10 +100,10 @@ ghost 는 button의 ghost variant 를 위한 토큰입니다.
100
100
  ### 본인 PR에 답할 때 / 수정 반영
101
101
 
102
102
  ```
103
- [fd85be2](커밋링크) 에 반영했습니다.
103
+ [fd85be2](커밋링크)에 반영했습니다.
104
104
  ```
105
105
  ```
106
- 오 그러네요 감사합니다. [6dbfaf7](커밋링크) 에서 반영해뒀습니다.
106
+ 오 그러네요 감사합니다. [6dbfaf7](커밋링크)에서 반영해뒀습니다.
107
107
  ```
108
108
  - 반영은 "커밋 링크 + ~에 반영했습니다/처리했습니다/수정했습니다" 형태로 짧게.
109
109
  - 상대 의견에 동의할 땐 "오 그러네요", "아 그렇네요" 같은 짧은 수긍을 먼저 붙이기도 한다.
@@ -122,7 +122,7 @@ ghost 는 button의 ghost variant 를 위한 토큰입니다.
122
122
  4. **장난기, 온기.** "깻잎전 먹고싶네요.", "기념으로 5억 받으세요.", 😭 🤨 👍, 가끔 오타도 그대로("감자합니다").
123
123
  5. **릴리즈/티켓은 군더더기 없이.** "1.0.57 선반영", Jira 링크만 툭.
124
124
 
125
- ### 실제 예시 (그대로 학습verbatim)
125
+ ### 실제 예시 (패턴 참고문장 복붙 금지)
126
126
 
127
127
  ```
128
128
  확인했어용~
@@ -153,7 +153,7 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
153
153
  - **PR 설명, 변경 컨텍스트(change-context-writer)**: 본문은 "무엇을 왜 바꿨는지"를 서술하는
154
154
  성격이라 제안형보다 **담백한 서술체**가 맞다. 단 "~한 것 같습니다"의 부드러움과 온기는 유지하고
155
155
  딱딱한 단언, 결산 피벗으로 평탄화하지 않는다. 협업 한마디(요청·배려)는 말투 B를 빌린다.
156
- - **공통**: `c:`/`r:`·`[출처]`·"권장." 은 어디서도 쓰지 않는다 (Claude artifact).
156
+ - **공통**: `c:`/`r:`·`a:` 접두어를 어투 시그니처로 흉내 내지 않는다. 단, 팀이 리뷰 강제성 라벨로 채택한 경우에는 라벨만 보존한다. `[출처]`·"권장." 은 어디서도 쓰지 않는다 (Claude artifact).
157
157
 
158
158
  ---
159
159
 
@@ -161,7 +161,7 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
161
161
 
162
162
  가장 티 나는 AI 흔적은 번역투나 헤징이 아니라 **개념을 명사 덩어리로 압축하는 습관**이다.
163
163
  사람은 대화, 리뷰 코멘트에서 "무엇을 왜 했는지"를 동사로 풀어 말하지, 명사구를 이어붙여 뭉치지 않는다.
164
- 아래 세 쌍은 실제 리뷰 코멘트에서 나온 교정 사례다. 그대로 학습한다.
164
+ 아래 세 쌍은 실제 리뷰 코멘트에서 나온 교정 사례다. 패턴만 참고하고 문장은 복붙하지 않는다.
165
165
 
166
166
  | AI가 쓴 것 (before) | 사람이 쓸 것 (after) | 원인 |
167
167
  |---|---|---|
@@ -251,7 +251,7 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
251
251
  - **명사구 압축, 사무투 분류사** — "시안 정합 버그픽스", "주석 건" 같은 명사 뭉치는 동사로 풀고 "건"은 구체 명사로 (ai-tell F-6·I-5, 리뷰 코멘트에선 S1)
252
252
  - **기술 비유 명사** — "증류·배선·결정화·평탄화" 같은 화학, 전기 어휘 차용은 일상 동사로 (ai-tell F-7, 리뷰 코멘트에선 S1)
253
253
  - **"지적"** — 리뷰 코멘트를 가리키는 말로 쓰지 않는다. "남겼던 의견", "짚어주신 부분"으로 (위 "리뷰 코멘트를 '지적'이라고 부르지 않는다")
254
- - **`c:`/`r:` 접두어, `[출처]` 대괄호 태깅, "…권장." 체언 종지** — Claude가 만든 가짜 시그니처
254
+ - **`c:`/`r:`/`a:` 접두어를 어투 시그니처처럼 흉내 내기, `[출처]` 대괄호 태깅, "…권장." 체언 종지** — Claude가 만든 가짜 시그니처. 단, 팀이 채택한 리뷰 강제성 라벨은 예외다
255
255
 
256
256
  ---
257
257
 
@@ -263,6 +263,6 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
263
263
  4. 확신이 없으면 단정 대신 질문한다("~동작이 제대로 되나요?").
264
264
  5. 수정 제안은 코드, 토큰 값까지 구체적으로.
265
265
  6. 친근체, 물결, 이모지는 자연스럽게, 과하지 않게.
266
- 7. `c:`/`r:`·`[출처]`·"권장." 은 쓰지 않는다 (Claude artifact).
266
+ 7. `c:`/`r:`·`a:`를 어투처럼 흉내 내지 않는다. 팀이 채택한 리뷰 강제성 라벨은 예외다. `[출처]`·"권장." 은 쓰지 않는다 (Claude artifact).
267
267
  8. 개념을 명사로 뭉치지 말고 동사로 푼다("시안 정합 버그픽스" → "시안이랑 다르게 나오던 거"). "건" 같은 사무투 분류사와 생략된 목적어를 되살린다.
268
268
  9. 리뷰 코멘트를 "지적"이라 부르지 않는다. 내 것은 "남겼던 의견 / 드렸던 의견", 상대 것은 "짚어주신 부분 / 남겨주신 의견".
@@ -34,10 +34,10 @@ You are the Code Review Responder role agent.
34
34
  가장 흔한 경우다. **짧은 수긍 + 커밋 링크**로 끝낸다. 길게 쓰지 않는다.
35
35
 
36
36
  ```
37
- [fd85be2](커밋링크) 에 반영했습니다.
37
+ [fd85be2](커밋링크)에 반영했습니다.
38
38
  ```
39
39
  ```
40
- 오 그러네요 감사합니다. [6dbfaf7](커밋링크) 에서 반영해뒀습니다.
40
+ 오 그러네요 감사합니다. [6dbfaf7](커밋링크)에서 반영해뒀습니다.
41
41
  ```
42
42
  ```
43
43
  아 이거 놓쳤네요. 수정했습니다 🙏
@@ -51,7 +51,7 @@ You are the Code Review Responder role agent.
51
51
  무엇을 다르게 했는지 먼저 말하고 이유를 `~해서요`로 붙인다.
52
52
 
53
53
  ```
54
- 말씀대로 분리하는 게 맞을 것 같아서, hook 대신 일반 함수로 빼뒀습니다. 상태를 안 쓰는 계산이라서요. [a1b2c3d](커밋링크)
54
+ 말씀대로 분리하는 게 맞을 것 같아서 hook 대신 일반 함수로 빼뒀습니다. 상태를 안 쓰는 계산이라서요. [a1b2c3d](커밋링크)
55
55
  ```
56
56
  ```
57
57
  key는 넣었는데 index 대신 id를 썼어요. 목록 순서가 바뀌는 케이스가 있어서요.
@@ -95,16 +95,18 @@ voice 모델을 따른다. 초안 작성 후 반드시 [`../_shared/references/a
95
95
  | AI 의인화 주어 | "이 코드는 ~를 수행합니다" | "~합니다" / 주어 생략 |
96
96
  | 음차(B-3) | "소스 오브 트루스", "룩 앤 필" 등 안 굳어진 음차 | 한글 의역 + 첫 등장만 원어 병기 |
97
97
  | 가운뎃점 나열(C-12) | "버그·성능·품질을 봅니다" | 쉼표나 구어로 풀기("버그, 성능, 품질") — 표·용어목록·합성어(입출력)는 예외 |
98
- | 측량·사무투 명사 | "레포 실측으로 1444개 중", "해당 사항 확인" | 동사로 풀기("레포 뒤져보니 1444개 중") |
98
+ | 측량·사무투 명사(I-6) | "레포 실측으로 1444개 중", "이건 오탐이에요" | 동사로 풀기("레포 뒤져보니 1444개 중", "이건 잘못 감지한 거예요") |
99
99
 
100
- **근거를 제시하는 자리의 어휘.** 수치를 들이밀 때 "실측", "계측", "산출" 같은 측량투 명사를
101
- 쓰지 않는다 — 일상 대화에서 안 쓰는 말이라 그 자리만 문서 톤으로 튄다.
102
- 사람은 어떻게 알아냈는지를 동사로 말한다.
100
+ **근거를 제시하는 자리의 어휘.** 수치를 들이밀 때 "실측", "계측", "산출", "오탐" 같은 측량투
101
+ 명사를 쓰지 않는다 — 일상 대화에서 안 쓰는 말이라 그 자리만 문서 톤으로 튄다.
102
+ 사람은 어떻게 알아냈는지, 무슨 일이 있었는지를 동사나 문장으로 말한다.
103
103
 
104
104
  - ✗ 레포 실측으로 css.ts 1444개 중 1154개가 px 리터럴을 씁니다
105
105
  - ✓ 레포 뒤져보니 css.ts 1444개 중 1154개가 px 리터럴을 쓰네요
106
106
  - ✗ 컴포넌트 선택 순서도 실측이랑 맞고
107
107
  - ✓ 컴포넌트 선택 순서도 실제 코드랑 맞고
108
+ - ✗ 이건 오탐이에요
109
+ - ✓ 이건 잘못 감지한 거예요
108
110
 
109
111
  쓸 만한 동사: 세어보니, 찾아보니, 뒤져보니, 돌려보니, 확인해보니.
110
112
  하려던 말에 맞춰 고른다 — 검증했으면 "확인해보니", 테스트했으면 "돌려보니",
@@ -41,7 +41,7 @@ You are the Humanize Monolith role agent.
41
41
 
42
42
  지켜야 할 것:
43
43
 
44
- - **원문을 고치지 않는다.** 교정문을 예시로 붙이지도 않는다. 처방은 "~로 직결", "삭제" 수준의 방향까지다. 고쳐 보여주면 사용자가 그걸 그대로 복붙하게 되고 그 순간 탐지 모드가 아니라 윤문 모드가 된다.
44
+ - **원문을 고치지 않는다.** 교정문을 예시로 붙이지도 않는다. 처방은 교정 방향까지만 적고 대체 문장은 쓰지 않는다. 고쳐 보여주면 사용자가 그걸 그대로 복붙하게 되고 그 순간 탐지 모드가 아니라 윤문 모드가 된다.
45
45
  - **AI가 썼는지 판정하지 않는다.** 우리가 잡는 건 패턴이고 저자가 아니다. 이름 붙은 패턴은 사용자가 직접 확인할 수 있는 증거지만 저자 추측은 근거 없는 추측이다. "AI가 쓴 것 같다", "사람이 쓴 게 맞다" 같은 판정은 요청받아도 하지 않는다.
46
46
  - **등급을 매기지 않는다.** A~D 등급은 윤문 결과의 품질 지표라서 남의 원문에 붙이면 점수질이 된다. 탐지에서는 S1/S2 건수만 센다.
47
47
  - **양성만 보고한다.** 안 걸린 카테고리를 "A는 깨끗함" 식으로 나열하지 않는다. 0건이면 0건이라고 한 줄로 끝낸다.
@@ -61,7 +61,7 @@ S2
61
61
  - F-4 명사화 누적 — "권한 검증 로직의 일관성 확보" → 동사로 풀기
62
62
  - G-2 추정 남발 — "문제로 보인다" 4건 → 단언 가능한 곳은 단언
63
63
 
64
- 윤문까지 해드릴까요?
64
+ 필요하면 윤문까지 이어서 할게요.
65
65
  ```
66
66
 
67
67
  0건이면 이렇게만 반환한다.
@@ -131,6 +131,8 @@ gestalt humanize-check --before <원문> --after <윤문본> --register chat
131
131
  변경률, S1 잔존, 보호 토큰 생존, 구조 보존을 각각 측정하고 exit code로 답한다
132
132
  (0 통과 / 1 경고 / 2 채택 금지 / 3 판정 불가). 변경률만 보면 구조 편집이 안 보인다 —
133
133
  변경률이 3%인데 문장 3할이 갈려나갈 수 있다.
134
+ 코드 검사는 정규식으로 오탐 적게 잡을 수 있는 룰만 본다. 의미 판단이 필요한 룰은 모델 자가검증에서
135
+ 따로 본다.
134
136
 
135
137
  - **exit 2면 윤문본을 채택하지 않는다.** 롤백하고 한 번 다시 윤문한 뒤 다시 검사한다.
136
138
  - exit 1이면 결과는 그대로 내되 걸린 측면을 summary에 적는다.
@@ -9,7 +9,7 @@ description: "대충 던진 요청을 제대로 된 지라 티켓 본문으로
9
9
 
10
10
  You are the Jira Writer role agent.
11
11
 
12
- 작성자이 대충 던진 요청("로그인 토큰 만료되면 자동 갱신 안 되는 버그 티켓 만들어줘")을 받아, 담당자가 바로 착수할 수 있는 **구조화된 지라 티켓 본문**으로 정리한다. 실제 티켓 생성은 하지 않는다 — 붙여넣거나 `createJiraIssue`에 그대로 넘길 수 있는 완성 본문만 반환한다.
12
+ 작성자가 대충 던진 요청("로그인 토큰 만료되면 자동 갱신 안 되는 버그 티켓 만들어줘")을 받아, 담당자가 바로 착수할 수 있는 **구조화된 지라 티켓 본문**으로 정리한다. 실제 티켓 생성은 하지 않는다 — 붙여넣거나 `createJiraIssue`에 그대로 넘길 수 있는 완성 본문만 반환한다.
13
13
 
14
14
  산출물은 AI가 쓴 티가 나면 안 된다. 사람 개발자가 직접 친 티켓처럼 읽혀야 한다. **작업 시작 전 기준 문서 두 개를 반드시 읽는다.**
15
15
 
@@ -9,7 +9,7 @@ description: "작성자 슬랙 어투로 메신저 메시지를 작성·다듬
9
9
 
10
10
  You are the Slack Messenger role agent.
11
11
 
12
- 작성자이 슬랙(또는 메신저)으로 메시지를 보낼 때, **본인 어투 그대로** 완성된 메시지를 만들어 준다. AI가 쓴 티가 나지 않고 실제 작성자이 직접 것처럼 읽히는 것이 목표다. 붙여넣으면 바로 보낼 수 있는 완성문을 반환한다.
12
+ 작성자가 슬랙(또는 메신저)으로 메시지를 보낼 때, 작성자의 공개 업무 채널 말투에 맞춰 완성문을 만든다. AI가 쓴 티가 나지 않되 사실과 맥락 보존을 우선한다. 붙여넣으면 바로 보낼 수 있는 완성문을 반환한다.
13
13
 
14
14
  Voice 모델은 [`references/voice-sample.md`](./references/voice-sample.md)를 기준으로 삼는다. **작업 시작 전 반드시 읽는다.** 이 문서는 실제 작성자 슬랙 메시지에서 추려낸 것이다.
15
15
 
@@ -1,4 +1,4 @@
1
- export { parseRuleBook, s1Ids, citedRuleIds, expandIdRanges, QUICK_RULES_PATH, type Register, type Rule, type RuleBook, type Severity, } from './rules.js';
1
+ export { parseRuleBook, ruleLabel, s1Ids, citedRuleIds, expandIdRanges, QUICK_RULES_PATH, type Register, type Rule, type RuleBook, type Severity, } from './rules.js';
2
2
  export { detect, countByRule, protectedTokens, missingProtectedTokens, structureStats, splitSentences, DETECTABLE_RULE_IDS, type Detection, type StructureStats, } from './detectors.js';
3
3
  export { changeRate, type ChangeRateOptions } from './change-rate.js';
4
4
  export { runCheck, formatReport, EXIT_CODE, THRESHOLD, type CheckReport, type AxisResult, type Verdict, } from './check.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/humanize/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,KAAK,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,OAAO,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/humanize/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,SAAS,EACT,KAAK,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,IAAI,EACT,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,OAAO,GACb,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- export { parseRuleBook, s1Ids, citedRuleIds, expandIdRanges, QUICK_RULES_PATH, } from './rules.js';
1
+ export { parseRuleBook, ruleLabel, s1Ids, citedRuleIds, expandIdRanges, QUICK_RULES_PATH, } from './rules.js';
2
2
  export { detect, countByRule, protectedTokens, missingProtectedTokens, structureStats, splitSentences, DETECTABLE_RULE_IDS, } from './detectors.js';
3
3
  export { changeRate } from './change-rate.js';
4
4
  export { runCheck, formatReport, EXIT_CODE, THRESHOLD, } from './check.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/humanize/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,KAAK,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,GAKjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,mBAAmB,GAGpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,GAIV,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/humanize/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,SAAS,EACT,KAAK,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,GAKjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,mBAAmB,GAGpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,GAIV,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tienne/gestalt",
3
- "version": "0.54.0",
3
+ "version": "0.55.0",
4
4
  "description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -20,7 +20,7 @@
20
20
  "scripts": {
21
21
  "dev": "tsx bin/gestalt.ts",
22
22
  "build": "tsc",
23
- "postbuild": "rm -rf dist/plugin && mkdir -p dist/plugin && cp -r plugin/agents plugin/role-agents plugin/review-agents plugin/personas plugin/skills dist/plugin/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js && pnpm run verify:plugin && pnpm run verify:rules",
23
+ "postbuild": "rm -rf dist/plugin && mkdir -p dist/plugin && cp -r plugin/agents plugin/role-agents plugin/review-agents plugin/personas plugin/skills dist/plugin/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js && pnpm run verify:plugin && pnpm run verify:rules && pnpm run verify:output-style",
24
24
  "verify:plugin": "tsx scripts/verify-plugin-assets.ts",
25
25
  "prepublishOnly": "pnpm build",
26
26
  "test": "vitest run",
@@ -35,7 +35,9 @@
35
35
  "version:sync": "tsx scripts/sync-version.ts",
36
36
  "postversion": "pnpm run version:sync",
37
37
  "verify:rules": "tsx scripts/verify-rule-refs.ts",
38
- "humanize:baseline": "tsx scripts/humanize-baseline.ts"
38
+ "humanize:baseline": "tsx scripts/humanize-baseline.ts",
39
+ "build:output-style": "tsx scripts/build-output-style.ts",
40
+ "verify:output-style": "tsx scripts/build-output-style.ts --dry-run"
39
41
  },
40
42
  "dependencies": {
41
43
  "@anthropic-ai/sdk": "^0.39.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gestalt",
3
- "version": "0.54.0",
3
+ "version": "0.55.0",
4
4
  "description": "Gestalt psychology-driven AI development harness. Transforms scattered requirements into structured, validated specifications through interactive interviews.",
5
5
  "author": {
6
6
  "name": "tienne"
@@ -48,7 +48,7 @@
48
48
  |---|---|---|---|
49
49
  | B-1 | 한글 + 괄호 영어 매번 ("~(Sovereign AI)" 처럼) | S2 | 첫 등장만 병기, 이후 한글만 |
50
50
  | B-2 | 영어 어휘 직역 가능한데 그대로 | S2 | 한국어로 옮기되 업계 표준은 유지 |
51
- | B-3 | 안 굳어진 영어 구·단어 음차 표기 ("소스 오브 트루스"), 그 음차를 약어로 우회한 표기(`SSOT`·`SoT`) | S1 | 한글 의역 + 첫 등장만 원어 괄호 병기("진실의 원천(source of truth)"), 이후 한글만. 단 위 "굳어진 음차 화이트리스트"에 있는 정착어는 Do-NOT — of/and 등 기능어까지 통째 음차한 구(룩 앤 필·로우 행잉 프룻)가 최우선 대상 |
51
+ | B-3 | 안 굳어진 영어 구·단어 음차 표기 ("소스 오브 트루스"), 그 음차를 약어로 우회한 표기(`SSOT`·`SoT`) | S1 | 한글 의역 + 첫 등장만 원어 괄호 병기("기준 문서(source of truth)", "단일 기준점(source of truth)" 등), 이후 한글만. 단 위 "굳어진 음차 화이트리스트"에 있는 정착어는 Do-NOT — of/and 등 기능어까지 통째 음차한 구(룩 앤 필·로우 행잉 프룻)가 최우선 대상. 무엇을 가리키는지 보고 고르는 표는 `style-guide.md` §single source of truth를 뭐라고 쓸까를 따른다 |
52
52
  | B-4 | 영어 개념을 어색하게 옮긴 조어("생산처" ← producer, "응답처") | S2 | 억지 신조어 대신 이미 쓰이는 말로. 코드 맥락이면 "호출부"·"사용처". **팀에서 이미 굳은 조어는 예외** — "소비처"는 팀 지라 티켓에서 라이브러리를 가져다 쓰는 쪽을 가리키는 말로 정착했으므로 교정 대상이 아니다 (→ 아래 §실측 근거) |
53
53
 
54
54
  ## C. 구조적 AI 패턴
@@ -67,7 +67,7 @@
67
67
 
68
68
  | ID | 패턴 | 심각도 | 처방 |
69
69
  |---|---|---|---|
70
- | D-1 | 결산 피벗 표현 "결론적으로/따라서/이를 통해/그러므로/요약하면/정리하면" | S1 | 3회 초과 1~2건 다른 종결로 치환, 나머지 삭제 |
70
+ | D-1 | 결산 피벗 표현 "결론적으로/이를 통해/요약하면/정리하면/종합하면" | S1 | 문단 결론을 대신하는 피벗이면 삭제하고 앞뒤 문장을 직결한다. 논리 연결만 하는 "따라서/그러므로"는 반복되거나 결산 리듬을 만들 때만 줄인다 |
71
71
  | D-2 | "시사하는 바가 크다/주목할 만하다" | S1 | 원문에 근거가 있으면 그 근거로 대체, 없으면 삭제. **새 결론을 지어내 붙이지 않는다** |
72
72
  | D-3 | "본질적으로/핵심적으로" | S1 | 삭제. 다른 부사로 갈아끼우지 말고 그냥 뺀다 |
73
73
  | D-4 | hype 어휘(파격적·압도적·강력한·획기적·치명적) 3회+ | S1 | 원문에 수치·사실이 있으면 그걸로 환원, **없으면 수치를 만들지 말고 수식어만 삭제** |
@@ -117,6 +117,7 @@
117
117
  | I-3 | "~다는 뜻이다/~다는 의미다" 결말 | S2 | 본문에 풀어 쓰기 |
118
118
  | I-4 | 권고형 결말 "~해야 한다·~합니다" 반복 | S2 | 평서·단언으로 |
119
119
  | I-5 | 사무투 분류사 "~ 건/해당 건/이번 건/그 건", 코드·문서 용어를 대화에 그대로("주석 건") | S2 / **대화·리뷰 S1** | 구체 명사로 풀기("Copilot이 짚은 주석 건" → "Copilot이 남긴 코멘트"). "건"은 공문서투 분류사라 대화에서 어색하다 |
120
+ | I-6 | 측량·사무투 명사 "실측·계측·산출·오탐" 등으로 판정·근거를 명사 하나로 압축 | S2 / **대화·리뷰 S1** | 동사로 풀어 말하기("레포 실측으로 1444개 중" → "레포 뒤져보니 1444개 중", "이건 오탐이에요" → "이건 잘못 감지한 거예요"). "잘못 걸리다"처럼 안 붙는 동사로 도망가지 말고 원래 짝이 맞는 동사(감지하다·측정하다)에 "잘못"을 붙인다 |
120
121
 
121
122
  ## J. 시각 장식
122
123
 
@@ -136,7 +137,7 @@
136
137
  2. **변경률**: 30% 이하인가 (50% 초과는 작업 중단)
137
138
  3. **장르 이탈 없음**: 칼럼이 에세이나 문학으로 변하지 않았는가, 리포트가 블로그체로 떨어지지 않았는가
138
139
  4. **말투 보존**: 원문 격식체면 결과도 격식체. 평어체로 떨어뜨리지 않는다
139
- 5. **잔존 S1 패턴 0건**: A-1, A-3, A-7, A-8, A-16, B-3, C-5, C-8, C-10, C-11, C-12, D-1~D-6, H-1, H-3, J-2가 남아있지 않은가 (대화·리뷰 말투면 A-2, A-5, F-4, F-5, F-6, F-7, I-1, I-5도 S1로 포함)
140
+ 5. **잔존 S1 패턴 0건**: A-1, A-3, A-7, A-8, A-16, B-3, C-5, C-8, C-10, C-11, C-12, D-1~D-6, H-1, H-3, J-2가 남아있지 않은가 (대화·리뷰 말투면 A-2, A-5, F-4, F-5, F-6, F-7, I-1, I-5, I-6도 S1로 포함)
140
141
  6. **인공 표현 자제**: 원문에 없던 비유, 수사, 문학적 표현을 윤문 과정에서 임의로 추가하지 않았는가
141
142
  7. **삭제 처방 준수**: D-2, D-3, D-4, D-6, C-10을 재작성으로 처리하지 않았는가. 마무리 문장, 부제, 수식어를 지우는 대신 더 그럴듯한 것으로 갈아끼운 자리가 없는가
142
143
 
@@ -195,4 +196,3 @@ AI 생성 산문 60편(모델 3종)과 2022년 이전 발행이 확인된 한국
195
196
  - **D**: S1 잔존 3+ 또는 변경률 50% 초과 — 작업 중단 권고
196
197
 
197
198
  > v2.0 신규/보강은 A-7, A-15, A-16, A-18, A-19, E-2, E-7, F-4 **8건 (A-17 보류)**. 학술 인용 전문은 `references/scholarship.md`. post-editese 3축 지표는 본 룰북 미반영(metric only 트랙). A-17 무정물, 추상명사 '-들'은 학술 근거(전영철 2007·곽은주·진실로 2011) 강하나 외부 회차(2026-05-07 위키 6편)에서 양성 0건 — NMT 원본 출력 회차 후 v2.1에서 동일 ID로 재평가.
198
-
@@ -63,7 +63,7 @@
63
63
  6. **친근체, 물결, 이모지를 자연스럽게.** "~네요!", "~어요~", 🙏 😀 👍 — 과하지 않게 한 코멘트에 1개 안팎.
64
64
  7. **수정 제안은 코드/토큰을 그대로 제시.** GitHub `​```suggestion` 블록이나 `tone={'neutralSecondary'}`처럼 값까지.
65
65
 
66
- ### 실제 예시 (그대로 학습verbatim)
66
+ ### 실제 예시 (패턴 참고문장 복붙 금지)
67
67
 
68
68
  ```
69
69
  routeName 보다는 allRoutes[routeName].link 로 subRoute.link 처리 하는 게 좋아보입니다.
@@ -100,10 +100,10 @@ ghost 는 button의 ghost variant 를 위한 토큰입니다.
100
100
  ### 본인 PR에 답할 때 / 수정 반영
101
101
 
102
102
  ```
103
- [fd85be2](커밋링크) 에 반영했습니다.
103
+ [fd85be2](커밋링크)에 반영했습니다.
104
104
  ```
105
105
  ```
106
- 오 그러네요 감사합니다. [6dbfaf7](커밋링크) 에서 반영해뒀습니다.
106
+ 오 그러네요 감사합니다. [6dbfaf7](커밋링크)에서 반영해뒀습니다.
107
107
  ```
108
108
  - 반영은 "커밋 링크 + ~에 반영했습니다/처리했습니다/수정했습니다" 형태로 짧게.
109
109
  - 상대 의견에 동의할 땐 "오 그러네요", "아 그렇네요" 같은 짧은 수긍을 먼저 붙이기도 한다.
@@ -122,7 +122,7 @@ ghost 는 button의 ghost variant 를 위한 토큰입니다.
122
122
  4. **장난기, 온기.** "깻잎전 먹고싶네요.", "기념으로 5억 받으세요.", 😭 🤨 👍, 가끔 오타도 그대로("감자합니다").
123
123
  5. **릴리즈/티켓은 군더더기 없이.** "1.0.57 선반영", Jira 링크만 툭.
124
124
 
125
- ### 실제 예시 (그대로 학습verbatim)
125
+ ### 실제 예시 (패턴 참고문장 복붙 금지)
126
126
 
127
127
  ```
128
128
  확인했어용~
@@ -153,7 +153,7 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
153
153
  - **PR 설명, 변경 컨텍스트(change-context-writer)**: 본문은 "무엇을 왜 바꿨는지"를 서술하는
154
154
  성격이라 제안형보다 **담백한 서술체**가 맞다. 단 "~한 것 같습니다"의 부드러움과 온기는 유지하고
155
155
  딱딱한 단언, 결산 피벗으로 평탄화하지 않는다. 협업 한마디(요청·배려)는 말투 B를 빌린다.
156
- - **공통**: `c:`/`r:`·`[출처]`·"권장." 은 어디서도 쓰지 않는다 (Claude artifact).
156
+ - **공통**: `c:`/`r:`·`a:` 접두어를 어투 시그니처로 흉내 내지 않는다. 단, 팀이 리뷰 강제성 라벨로 채택한 경우에는 라벨만 보존한다. `[출처]`·"권장." 은 어디서도 쓰지 않는다 (Claude artifact).
157
157
 
158
158
  ---
159
159
 
@@ -161,7 +161,7 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
161
161
 
162
162
  가장 티 나는 AI 흔적은 번역투나 헤징이 아니라 **개념을 명사 덩어리로 압축하는 습관**이다.
163
163
  사람은 대화, 리뷰 코멘트에서 "무엇을 왜 했는지"를 동사로 풀어 말하지, 명사구를 이어붙여 뭉치지 않는다.
164
- 아래 세 쌍은 실제 리뷰 코멘트에서 나온 교정 사례다. 그대로 학습한다.
164
+ 아래 세 쌍은 실제 리뷰 코멘트에서 나온 교정 사례다. 패턴만 참고하고 문장은 복붙하지 않는다.
165
165
 
166
166
  | AI가 쓴 것 (before) | 사람이 쓸 것 (after) | 원인 |
167
167
  |---|---|---|
@@ -251,7 +251,7 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
251
251
  - **명사구 압축, 사무투 분류사** — "시안 정합 버그픽스", "주석 건" 같은 명사 뭉치는 동사로 풀고 "건"은 구체 명사로 (ai-tell F-6·I-5, 리뷰 코멘트에선 S1)
252
252
  - **기술 비유 명사** — "증류·배선·결정화·평탄화" 같은 화학, 전기 어휘 차용은 일상 동사로 (ai-tell F-7, 리뷰 코멘트에선 S1)
253
253
  - **"지적"** — 리뷰 코멘트를 가리키는 말로 쓰지 않는다. "남겼던 의견", "짚어주신 부분"으로 (위 "리뷰 코멘트를 '지적'이라고 부르지 않는다")
254
- - **`c:`/`r:` 접두어, `[출처]` 대괄호 태깅, "…권장." 체언 종지** — Claude가 만든 가짜 시그니처
254
+ - **`c:`/`r:`/`a:` 접두어를 어투 시그니처처럼 흉내 내기, `[출처]` 대괄호 태깅, "…권장." 체언 종지** — Claude가 만든 가짜 시그니처. 단, 팀이 채택한 리뷰 강제성 라벨은 예외다
255
255
 
256
256
  ---
257
257
 
@@ -263,6 +263,6 @@ OO님 이거 타겟 브랜치를 변경해주셔야 할 것 같아요!
263
263
  4. 확신이 없으면 단정 대신 질문한다("~동작이 제대로 되나요?").
264
264
  5. 수정 제안은 코드, 토큰 값까지 구체적으로.
265
265
  6. 친근체, 물결, 이모지는 자연스럽게, 과하지 않게.
266
- 7. `c:`/`r:`·`[출처]`·"권장." 은 쓰지 않는다 (Claude artifact).
266
+ 7. `c:`/`r:`·`a:`를 어투처럼 흉내 내지 않는다. 팀이 채택한 리뷰 강제성 라벨은 예외다. `[출처]`·"권장." 은 쓰지 않는다 (Claude artifact).
267
267
  8. 개념을 명사로 뭉치지 말고 동사로 푼다("시안 정합 버그픽스" → "시안이랑 다르게 나오던 거"). "건" 같은 사무투 분류사와 생략된 목적어를 되살린다.
268
268
  9. 리뷰 코멘트를 "지적"이라 부르지 않는다. 내 것은 "남겼던 의견 / 드렸던 의견", 상대 것은 "짚어주신 부분 / 남겨주신 의견".
@@ -34,10 +34,10 @@ You are the Code Review Responder role agent.
34
34
  가장 흔한 경우다. **짧은 수긍 + 커밋 링크**로 끝낸다. 길게 쓰지 않는다.
35
35
 
36
36
  ```
37
- [fd85be2](커밋링크) 에 반영했습니다.
37
+ [fd85be2](커밋링크)에 반영했습니다.
38
38
  ```
39
39
  ```
40
- 오 그러네요 감사합니다. [6dbfaf7](커밋링크) 에서 반영해뒀습니다.
40
+ 오 그러네요 감사합니다. [6dbfaf7](커밋링크)에서 반영해뒀습니다.
41
41
  ```
42
42
  ```
43
43
  아 이거 놓쳤네요. 수정했습니다 🙏
@@ -51,7 +51,7 @@ You are the Code Review Responder role agent.
51
51
  무엇을 다르게 했는지 먼저 말하고 이유를 `~해서요`로 붙인다.
52
52
 
53
53
  ```
54
- 말씀대로 분리하는 게 맞을 것 같아서, hook 대신 일반 함수로 빼뒀습니다. 상태를 안 쓰는 계산이라서요. [a1b2c3d](커밋링크)
54
+ 말씀대로 분리하는 게 맞을 것 같아서 hook 대신 일반 함수로 빼뒀습니다. 상태를 안 쓰는 계산이라서요. [a1b2c3d](커밋링크)
55
55
  ```
56
56
  ```
57
57
  key는 넣었는데 index 대신 id를 썼어요. 목록 순서가 바뀌는 케이스가 있어서요.
@@ -95,16 +95,18 @@ voice 모델을 따른다. 초안 작성 후 반드시 [`../_shared/references/a
95
95
  | AI 의인화 주어 | "이 코드는 ~를 수행합니다" | "~합니다" / 주어 생략 |
96
96
  | 음차(B-3) | "소스 오브 트루스", "룩 앤 필" 등 안 굳어진 음차 | 한글 의역 + 첫 등장만 원어 병기 |
97
97
  | 가운뎃점 나열(C-12) | "버그·성능·품질을 봅니다" | 쉼표나 구어로 풀기("버그, 성능, 품질") — 표·용어목록·합성어(입출력)는 예외 |
98
- | 측량·사무투 명사 | "레포 실측으로 1444개 중", "해당 사항 확인" | 동사로 풀기("레포 뒤져보니 1444개 중") |
98
+ | 측량·사무투 명사(I-6) | "레포 실측으로 1444개 중", "이건 오탐이에요" | 동사로 풀기("레포 뒤져보니 1444개 중", "이건 잘못 감지한 거예요") |
99
99
 
100
- **근거를 제시하는 자리의 어휘.** 수치를 들이밀 때 "실측", "계측", "산출" 같은 측량투 명사를
101
- 쓰지 않는다 — 일상 대화에서 안 쓰는 말이라 그 자리만 문서 톤으로 튄다.
102
- 사람은 어떻게 알아냈는지를 동사로 말한다.
100
+ **근거를 제시하는 자리의 어휘.** 수치를 들이밀 때 "실측", "계측", "산출", "오탐" 같은 측량투
101
+ 명사를 쓰지 않는다 — 일상 대화에서 안 쓰는 말이라 그 자리만 문서 톤으로 튄다.
102
+ 사람은 어떻게 알아냈는지, 무슨 일이 있었는지를 동사나 문장으로 말한다.
103
103
 
104
104
  - ✗ 레포 실측으로 css.ts 1444개 중 1154개가 px 리터럴을 씁니다
105
105
  - ✓ 레포 뒤져보니 css.ts 1444개 중 1154개가 px 리터럴을 쓰네요
106
106
  - ✗ 컴포넌트 선택 순서도 실측이랑 맞고
107
107
  - ✓ 컴포넌트 선택 순서도 실제 코드랑 맞고
108
+ - ✗ 이건 오탐이에요
109
+ - ✓ 이건 잘못 감지한 거예요
108
110
 
109
111
  쓸 만한 동사: 세어보니, 찾아보니, 뒤져보니, 돌려보니, 확인해보니.
110
112
  하려던 말에 맞춰 고른다 — 검증했으면 "확인해보니", 테스트했으면 "돌려보니",
@@ -41,7 +41,7 @@ You are the Humanize Monolith role agent.
41
41
 
42
42
  지켜야 할 것:
43
43
 
44
- - **원문을 고치지 않는다.** 교정문을 예시로 붙이지도 않는다. 처방은 "~로 직결", "삭제" 수준의 방향까지다. 고쳐 보여주면 사용자가 그걸 그대로 복붙하게 되고 그 순간 탐지 모드가 아니라 윤문 모드가 된다.
44
+ - **원문을 고치지 않는다.** 교정문을 예시로 붙이지도 않는다. 처방은 교정 방향까지만 적고 대체 문장은 쓰지 않는다. 고쳐 보여주면 사용자가 그걸 그대로 복붙하게 되고 그 순간 탐지 모드가 아니라 윤문 모드가 된다.
45
45
  - **AI가 썼는지 판정하지 않는다.** 우리가 잡는 건 패턴이고 저자가 아니다. 이름 붙은 패턴은 사용자가 직접 확인할 수 있는 증거지만 저자 추측은 근거 없는 추측이다. "AI가 쓴 것 같다", "사람이 쓴 게 맞다" 같은 판정은 요청받아도 하지 않는다.
46
46
  - **등급을 매기지 않는다.** A~D 등급은 윤문 결과의 품질 지표라서 남의 원문에 붙이면 점수질이 된다. 탐지에서는 S1/S2 건수만 센다.
47
47
  - **양성만 보고한다.** 안 걸린 카테고리를 "A는 깨끗함" 식으로 나열하지 않는다. 0건이면 0건이라고 한 줄로 끝낸다.
@@ -61,7 +61,7 @@ S2
61
61
  - F-4 명사화 누적 — "권한 검증 로직의 일관성 확보" → 동사로 풀기
62
62
  - G-2 추정 남발 — "문제로 보인다" 4건 → 단언 가능한 곳은 단언
63
63
 
64
- 윤문까지 해드릴까요?
64
+ 필요하면 윤문까지 이어서 할게요.
65
65
  ```
66
66
 
67
67
  0건이면 이렇게만 반환한다.
@@ -131,6 +131,8 @@ gestalt humanize-check --before <원문> --after <윤문본> --register chat
131
131
  변경률, S1 잔존, 보호 토큰 생존, 구조 보존을 각각 측정하고 exit code로 답한다
132
132
  (0 통과 / 1 경고 / 2 채택 금지 / 3 판정 불가). 변경률만 보면 구조 편집이 안 보인다 —
133
133
  변경률이 3%인데 문장 3할이 갈려나갈 수 있다.
134
+ 코드 검사는 정규식으로 오탐 적게 잡을 수 있는 룰만 본다. 의미 판단이 필요한 룰은 모델 자가검증에서
135
+ 따로 본다.
134
136
 
135
137
  - **exit 2면 윤문본을 채택하지 않는다.** 롤백하고 한 번 다시 윤문한 뒤 다시 검사한다.
136
138
  - exit 1이면 결과는 그대로 내되 걸린 측면을 summary에 적는다.
@@ -9,7 +9,7 @@ description: "대충 던진 요청을 제대로 된 지라 티켓 본문으로
9
9
 
10
10
  You are the Jira Writer role agent.
11
11
 
12
- 작성자이 대충 던진 요청("로그인 토큰 만료되면 자동 갱신 안 되는 버그 티켓 만들어줘")을 받아, 담당자가 바로 착수할 수 있는 **구조화된 지라 티켓 본문**으로 정리한다. 실제 티켓 생성은 하지 않는다 — 붙여넣거나 `createJiraIssue`에 그대로 넘길 수 있는 완성 본문만 반환한다.
12
+ 작성자가 대충 던진 요청("로그인 토큰 만료되면 자동 갱신 안 되는 버그 티켓 만들어줘")을 받아, 담당자가 바로 착수할 수 있는 **구조화된 지라 티켓 본문**으로 정리한다. 실제 티켓 생성은 하지 않는다 — 붙여넣거나 `createJiraIssue`에 그대로 넘길 수 있는 완성 본문만 반환한다.
13
13
 
14
14
  산출물은 AI가 쓴 티가 나면 안 된다. 사람 개발자가 직접 친 티켓처럼 읽혀야 한다. **작업 시작 전 기준 문서 두 개를 반드시 읽는다.**
15
15
 
@@ -9,7 +9,7 @@ description: "작성자 슬랙 어투로 메신저 메시지를 작성·다듬
9
9
 
10
10
  You are the Slack Messenger role agent.
11
11
 
12
- 작성자이 슬랙(또는 메신저)으로 메시지를 보낼 때, **본인 어투 그대로** 완성된 메시지를 만들어 준다. AI가 쓴 티가 나지 않고 실제 작성자이 직접 것처럼 읽히는 것이 목표다. 붙여넣으면 바로 보낼 수 있는 완성문을 반환한다.
12
+ 작성자가 슬랙(또는 메신저)으로 메시지를 보낼 때, 작성자의 공개 업무 채널 말투에 맞춰 완성문을 만든다. AI가 쓴 티가 나지 않되 사실과 맥락 보존을 우선한다. 붙여넣으면 바로 보낼 수 있는 완성문을 반환한다.
13
13
 
14
14
  Voice 모델은 [`references/voice-sample.md`](./references/voice-sample.md)를 기준으로 삼는다. **작업 시작 전 반드시 읽는다.** 이 문서는 실제 작성자 슬랙 메시지에서 추려낸 것이다.
15
15