@tienne/gestalt 0.51.0 → 0.52.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 (67) hide show
  1. package/CLAUDE.md +7 -4
  2. package/dist/package.json +4 -3
  3. package/dist/plugin/role-agents/_shared/references/README.md +13 -0
  4. package/dist/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +66 -15
  5. package/dist/plugin/role-agents/_shared/references/style-guide.md +40 -0
  6. package/dist/plugin/role-agents/code-review-responder/AGENT.md +1 -1
  7. package/dist/plugin/role-agents/code-review-writer/AGENT.md +1 -1
  8. package/dist/plugin/role-agents/harness-architect/AGENT.md +1 -1
  9. package/dist/plugin/role-agents/humanize-monolith/AGENT.md +20 -2
  10. package/dist/plugin/role-agents/jira-writer/AGENT.md +11 -11
  11. package/dist/plugin/role-agents/slack-messenger/AGENT.md +1 -1
  12. package/dist/plugin/skills/dispatch/SKILL.md +3 -3
  13. package/dist/plugin/skills/execute/SKILL.md +1 -1
  14. package/dist/plugin/skills/jira-create/SKILL.md +5 -5
  15. package/dist/plugin/skills/presentation/SKILL.md +6 -6
  16. package/dist/plugin/skills/review-reply/SKILL.md +3 -3
  17. package/dist/plugin/skills/slack-send/SKILL.md +2 -2
  18. package/dist/src/cli/commands/humanize-check.d.ts +8 -0
  19. package/dist/src/cli/commands/humanize-check.d.ts.map +1 -0
  20. package/dist/src/cli/commands/humanize-check.js +29 -0
  21. package/dist/src/cli/commands/humanize-check.js.map +1 -0
  22. package/dist/src/cli/index.d.ts.map +1 -1
  23. package/dist/src/cli/index.js +11 -0
  24. package/dist/src/cli/index.js.map +1 -1
  25. package/dist/src/code-graph/rrf.d.ts +4 -4
  26. package/dist/src/code-graph/rrf.js +4 -4
  27. package/dist/src/execute/parallel-groups.d.ts +1 -1
  28. package/dist/src/execute/parallel-groups.js +1 -1
  29. package/dist/src/gestalt/surface-labels.d.ts +3 -3
  30. package/dist/src/gestalt/surface-labels.js +1 -1
  31. package/dist/src/humanize/change-rate.d.ts +13 -0
  32. package/dist/src/humanize/change-rate.d.ts.map +1 -0
  33. package/dist/src/humanize/change-rate.js +86 -0
  34. package/dist/src/humanize/change-rate.js.map +1 -0
  35. package/dist/src/humanize/check.d.ts +39 -0
  36. package/dist/src/humanize/check.d.ts.map +1 -0
  37. package/dist/src/humanize/check.js +150 -0
  38. package/dist/src/humanize/check.js.map +1 -0
  39. package/dist/src/humanize/detectors.d.ts +28 -0
  40. package/dist/src/humanize/detectors.d.ts.map +1 -0
  41. package/dist/src/humanize/detectors.js +134 -0
  42. package/dist/src/humanize/detectors.js.map +1 -0
  43. package/dist/src/humanize/index.d.ts +5 -0
  44. package/dist/src/humanize/index.d.ts.map +1 -0
  45. package/dist/src/humanize/index.js +5 -0
  46. package/dist/src/humanize/index.js.map +1 -0
  47. package/dist/src/humanize/rules.d.ts +34 -0
  48. package/dist/src/humanize/rules.d.ts.map +1 -0
  49. package/dist/src/humanize/rules.js +95 -0
  50. package/dist/src/humanize/rules.js.map +1 -0
  51. package/package.json +4 -3
  52. package/plugin/.codex-plugin/plugin.json +1 -1
  53. package/plugin/role-agents/_shared/references/README.md +13 -0
  54. package/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +66 -15
  55. package/plugin/role-agents/_shared/references/style-guide.md +40 -0
  56. package/plugin/role-agents/code-review-responder/AGENT.md +1 -1
  57. package/plugin/role-agents/code-review-writer/AGENT.md +1 -1
  58. package/plugin/role-agents/harness-architect/AGENT.md +1 -1
  59. package/plugin/role-agents/humanize-monolith/AGENT.md +20 -2
  60. package/plugin/role-agents/jira-writer/AGENT.md +11 -11
  61. package/plugin/role-agents/slack-messenger/AGENT.md +1 -1
  62. package/plugin/skills/dispatch/SKILL.md +3 -3
  63. package/plugin/skills/execute/SKILL.md +1 -1
  64. package/plugin/skills/jira-create/SKILL.md +5 -5
  65. package/plugin/skills/presentation/SKILL.md +6 -6
  66. package/plugin/skills/review-reply/SKILL.md +3 -3
  67. package/plugin/skills/slack-send/SKILL.md +2 -2
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: slack-send
3
3
  version: "1.0.0"
4
- description: "슬랙 메시지를 권윤학님 어투로 다듬어 승인 게이트를 거친 뒤 전송하거나 예약한다. 메시지를 '보내달라/전달해달라/공지해달라/예약 발송해달라'는 요청 시 자동 발동. slack-messenger로 초안 → 채널과 발송 시각 확인 → 미리보기 승인 → slack_send_message/slack_schedule_message. 전송까지 하는 스킬이다. 문구만 다듬고 보내지는 않으려면 slack-messenger를 호출한다."
4
+ description: "슬랙 메시지를 권윤학님 어투로 다듬어 승인 단계를 거친 뒤 전송하거나 예약한다. 메시지를 '보내달라/전달해달라/공지해달라/예약 발송해달라'는 요청 시 자동 발동. slack-messenger로 초안 → 채널과 발송 시각 확인 → 미리보기 승인 → slack_send_message/slack_schedule_message. 전송까지 하는 스킬이다. 문구만 다듬고 보내지는 않으려면 slack-messenger를 호출한다."
5
5
  triggers:
6
6
  # 전송 의도
7
7
  - "슬랙 보내"
@@ -74,7 +74,7 @@ outputs:
74
74
  - DM: `slack_search_users`로 상대 → `user_id`(그대로 channel_id로 사용).
75
75
  - 확정한 채널명·ID를 사용자에게 노출해 **대상이 맞는지 확인**한다.
76
76
 
77
- ### 4. 미리보기 + 승인 게이트 (필수)
77
+ ### 4. 미리보기 + 승인 단계 (필수)
78
78
 
79
79
  아래를 한 화면에 모아 보여주고 명시적 승인을 받는다.
80
80
 
@@ -0,0 +1,8 @@
1
+ export interface HumanizeCheckOptions {
2
+ before: string;
3
+ after: string;
4
+ register?: string;
5
+ json?: boolean;
6
+ }
7
+ export declare function humanizeCheckCommand(options: HumanizeCheckOptions): void;
8
+ //# sourceMappingURL=humanize-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanize-check.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/humanize-check.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAWD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAmBxE"}
@@ -0,0 +1,29 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { formatReport, runCheck, EXIT_CODE } from '../../humanize/index.js';
4
+ function read(label, path) {
5
+ const full = resolve(process.cwd(), path);
6
+ if (!existsSync(full)) {
7
+ console.error(`${label} 파일이 없습니다: ${full}`);
8
+ process.exit(EXIT_CODE.unknown);
9
+ }
10
+ return readFileSync(full, 'utf-8');
11
+ }
12
+ export function humanizeCheckCommand(options) {
13
+ const register = options.register === 'chat' ? 'chat' : 'doc';
14
+ const before = read('원문', options.before);
15
+ const after = read('윤문본', options.after);
16
+ if (before.trim().length === 0) {
17
+ console.error('원문이 비어 있어 판정할 수 없습니다.');
18
+ process.exit(EXIT_CODE.unknown);
19
+ }
20
+ const report = runCheck(before, after, { register });
21
+ if (options.json) {
22
+ console.log(JSON.stringify(report, null, 2));
23
+ }
24
+ else {
25
+ console.log(formatReport(report));
26
+ }
27
+ process.exit(report.exitCode);
28
+ }
29
+ //# sourceMappingURL=humanize-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanize-check.js","sourceRoot":"","sources":["../../../../src/cli/commands/humanize-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAU5E,SAAS,IAAI,CAAC,KAAa,EAAE,IAAY;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,cAAc,IAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAA6B;IAChE,MAAM,QAAQ,GAAa,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAEzC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAErD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,SAAS,IAAI,OAAO,CAsFnC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,SAAS,IAAI,OAAO,CAiGnC"}
@@ -8,6 +8,7 @@ import { initCommand } from './commands/init.js';
8
8
  import { graphVisualizeCommand } from './commands/graph-visualize.js';
9
9
  import { updateCommand } from './commands/update.js';
10
10
  import { usageReportCommand } from './commands/usage-report.js';
11
+ import { humanizeCheckCommand } from './commands/humanize-check.js';
11
12
  import { getVersion } from '../core/version.js';
12
13
  export function createCli() {
13
14
  const program = new Command();
@@ -73,6 +74,16 @@ export function createCli() {
73
74
  noBrowser: options.browser === false,
74
75
  });
75
76
  });
77
+ program
78
+ .command('humanize-check')
79
+ .description('Judge a humanized draft against the rulebook (exit 0 pass / 1 warn / 2 abort)')
80
+ .requiredOption('--before <path>', 'Original text file')
81
+ .requiredOption('--after <path>', 'Humanized text file')
82
+ .option('--register <doc|chat>', 'Register to judge against (default: doc)', 'doc')
83
+ .option('--json', 'Emit the full report as JSON')
84
+ .action((options) => {
85
+ humanizeCheckCommand(options);
86
+ });
76
87
  program
77
88
  .command('usage-report')
78
89
  .description('Show event frequency report grouped by event type')
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -3,13 +3,13 @@ export interface ScoredFile {
3
3
  score: number;
4
4
  }
5
5
  /**
6
- * Reciprocal Rank Fusion — 여러 랭킹 리스트를 하나로 합산한다.
6
+ * Reciprocal Rank Fusion — 여러 순위 목록을 하나로 합산한다.
7
7
  *
8
- * 각 리스트의 항목에 대해 1/(k + rank) 점수를 누적하고,
8
+ * 각 목록의 항목마다 1/(k + rank) 점수를 누적하고,
9
9
  * 내림차순으로 정렬하여 반환한다.
10
10
  *
11
- * @param lists - ScoredFile 랭킹 리스트 배열 (0-based index가 rank로 사용됨)
12
- * @param k - RRF 상수 (default: 60). 높을수록 하위 랭크의 영향이 줄어든다.
11
+ * @param lists - ScoredFile 순위 목록 배열 (0-based index가 rank로 사용됨)
12
+ * @param k - RRF 상수 (default: 60). 높을수록 하위 순위의 영향이 줄어든다.
13
13
  */
14
14
  export declare function reciprocalRankFusion(lists: ScoredFile[][], k?: number): ScoredFile[];
15
15
  //# sourceMappingURL=rrf.d.ts.map
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Reciprocal Rank Fusion — 여러 랭킹 리스트를 하나로 합산한다.
2
+ * Reciprocal Rank Fusion — 여러 순위 목록을 하나로 합산한다.
3
3
  *
4
- * 각 리스트의 항목에 대해 1/(k + rank) 점수를 누적하고,
4
+ * 각 목록의 항목마다 1/(k + rank) 점수를 누적하고,
5
5
  * 내림차순으로 정렬하여 반환한다.
6
6
  *
7
- * @param lists - ScoredFile 랭킹 리스트 배열 (0-based index가 rank로 사용됨)
8
- * @param k - RRF 상수 (default: 60). 높을수록 하위 랭크의 영향이 줄어든다.
7
+ * @param lists - ScoredFile 순위 목록 배열 (0-based index가 rank로 사용됨)
8
+ * @param k - RRF 상수 (default: 60). 높을수록 하위 순위의 영향이 줄어든다.
9
9
  */
10
10
  export function reciprocalRankFusion(lists, k = 60) {
11
11
  const scoreMap = new Map();
@@ -25,7 +25,7 @@ export declare function buildDepMap(tasks: AtomicTask[]): Map<string, Set<string
25
25
  export declare function computeReadyTaskIds(tasks: AtomicTask[], topologicalOrder: string[], completedTaskIds: string[]): string[];
26
26
  /**
27
27
  * DAG 위상 정렬 기반으로 병렬 실행 가능한 태스크 그룹을 계산한다.
28
- * 동일 레이어의 태스크들은 의존성이 없어 동시에 실행 가능하다.
28
+ * 같은 묶음에 있는 태스크는 의존성이 없어 동시에 실행 가능하다.
29
29
  *
30
30
  * @returns string[][] — 각 배열이 동시 실행 가능한 태스크 ID 목록
31
31
  */
@@ -47,7 +47,7 @@ export function computeReadyTaskIds(tasks, topologicalOrder, completedTaskIds) {
47
47
  }
48
48
  /**
49
49
  * DAG 위상 정렬 기반으로 병렬 실행 가능한 태스크 그룹을 계산한다.
50
- * 동일 레이어의 태스크들은 의존성이 없어 동시에 실행 가능하다.
50
+ * 같은 묶음에 있는 태스크는 의존성이 없어 동시에 실행 가능하다.
51
51
  *
52
52
  * @returns string[][] — 각 배열이 동시 실행 가능한 태스크 ID 목록
53
53
  */
@@ -1,12 +1,12 @@
1
1
  import { GestaltPrinciple } from '../core/types.js';
2
2
  /**
3
- * 표면/심층 분리 (Figure-Ground) 표면 레이어 단일 소스.
3
+ * 표면/심층 분리 (Figure-Ground)에서 표면 문자열을 정의하는 단 한 곳.
4
4
  *
5
5
  * 코드 내부는 게슈탈트 원리(GestaltPrinciple enum)와 에이전트 식별자를 그대로 쓰지만,
6
6
  * 사용자에게 돌려주는 표면 문자열에는 게슈탈트 용어가 새어 나가면 안 된다.
7
7
  * 이 모듈이 내부 식별자를 평범한 한국어·영어 문구로 잇는 유일한 매핑 지점이다.
8
8
  *
9
- * 심층 레이어(README·docs·LLM 시스템 프롬프트·내부 타입) 이 모듈을 거치지 않고
9
+ * 심층 (README, docs, LLM 시스템 프롬프트, 내부 타입) 이 모듈을 거치지 않고
10
10
  * 게슈탈트 어휘를 그대로 유지한다.
11
11
  */
12
12
  export type SurfaceLang = 'ko' | 'en';
@@ -34,7 +34,7 @@ export declare function getConsistencyHint(lang?: SurfaceLang): string;
34
34
  */
35
35
  export declare const BANNED_SURFACE_TERMS: readonly string[];
36
36
  /**
37
- * MCP 도구 응답에서 심층 레이어(LLM 지시 프롬프트) 필드 키.
37
+ * MCP 도구 응답에서 심층 (LLM 지시 프롬프트) 필드 키.
38
38
  * 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로 표면 누수 검사 대상에서 제외한다.
39
39
  */
40
40
  export declare const DEEP_PROMPT_KEYS: readonly string[];
@@ -88,7 +88,7 @@ export const BANNED_SURFACE_TERMS = [
88
88
  'gestalt',
89
89
  ];
90
90
  /**
91
- * MCP 도구 응답에서 심층 레이어(LLM 지시 프롬프트) 필드 키.
91
+ * MCP 도구 응답에서 심층 (LLM 지시 프롬프트) 필드 키.
92
92
  * 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로 표면 누수 검사 대상에서 제외한다.
93
93
  */
94
94
  export const DEEP_PROMPT_KEYS = [
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 변경률 — 원문과 윤문본이 얼마나 달라졌는지.
3
+ *
4
+ * 어절 단위 LCS로 측정한다. 문자 단위 DP는 1만자만 넘어가도 셀이 억 단위라 못 쓰고,
5
+ * 어절 단위면 같은 글이 수천 토큰이라 DP가 그대로 돈다.
6
+ * 공식은 1 - 2·LCS / (len(a) + len(b)) — difflib.SequenceMatcher.ratio()와 같다.
7
+ */
8
+ export interface ChangeRateOptions {
9
+ /** 헤딩·불릿 산문화로 부풀려진 변경률을 걷어내고 본문만 비교 */
10
+ ignoreMarkup?: boolean;
11
+ }
12
+ export declare function changeRate(before: string, after: string, options?: ChangeRateOptions): number;
13
+ //# sourceMappingURL=change-rate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-rate.d.ts","sourceRoot":"","sources":["../../../src/humanize/change-rate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAuED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAWjG"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 변경률 — 원문과 윤문본이 얼마나 달라졌는지.
3
+ *
4
+ * 어절 단위 LCS로 측정한다. 문자 단위 DP는 1만자만 넘어가도 셀이 억 단위라 못 쓰고,
5
+ * 어절 단위면 같은 글이 수천 토큰이라 DP가 그대로 돈다.
6
+ * 공식은 1 - 2·LCS / (len(a) + len(b)) — difflib.SequenceMatcher.ratio()와 같다.
7
+ */
8
+ /** 어절이 이 수를 넘으면 DP를 포기하고 순서를 무시한 겹침 비율로 떨어뜨린다 */
9
+ const TOKEN_DP_CAP = 6000;
10
+ const SUMMARY_BLOCK = /<!--\s*HUMANIZE-SUMMARY[\s\S]*?-->/g;
11
+ const MARKUP = /^\s{0,3}(?:#{1,6}\s+|[-*+]\s+|\d+\.\s+|>\s?)|[*_`~]|^\s*\|.*\|\s*$/gm;
12
+ function normalize(text, ignoreMarkup) {
13
+ let out = text.replace(SUMMARY_BLOCK, ' ');
14
+ if (ignoreMarkup)
15
+ out = out.replace(MARKUP, ' ');
16
+ return out.replace(/\s+/g, ' ').trim();
17
+ }
18
+ function tokenize(text) {
19
+ return text.split(' ').filter(Boolean);
20
+ }
21
+ function lcsLength(a, b) {
22
+ if (a.length === 0 || b.length === 0)
23
+ return 0;
24
+ // 앞뒤로 그대로인 구간은 DP에 넣을 이유가 없다
25
+ let head = 0;
26
+ while (head < a.length && head < b.length && a[head] === b[head])
27
+ head += 1;
28
+ let tail = 0;
29
+ while (tail < a.length - head &&
30
+ tail < b.length - head &&
31
+ a[a.length - 1 - tail] === b[b.length - 1 - tail]) {
32
+ tail += 1;
33
+ }
34
+ const midA = a.slice(head, a.length - tail);
35
+ const midB = b.slice(head, b.length - tail);
36
+ const common = head + tail;
37
+ if (midA.length === 0 || midB.length === 0)
38
+ return common;
39
+ const rows = midA.length + 1;
40
+ const cols = midB.length + 1;
41
+ let prev = new Uint32Array(cols);
42
+ let curr = new Uint32Array(cols);
43
+ for (let i = 1; i < rows; i += 1) {
44
+ const ai = midA[i - 1];
45
+ for (let j = 1; j < cols; j += 1) {
46
+ curr[j] = ai === midB[j - 1] ? prev[j - 1] + 1 : Math.max(prev[j], curr[j - 1]);
47
+ }
48
+ const swap = prev;
49
+ prev = curr;
50
+ curr = swap;
51
+ curr.fill(0);
52
+ }
53
+ return common + prev[cols - 1];
54
+ }
55
+ /**
56
+ * 순서를 버리고 어절 다중집합의 겹침만 센다.
57
+ * DP를 돌릴 수 없는 크기에서 쓰는 근사치라 실제보다 변경률을 낮게 본다 — 검사가
58
+ * 놓칠지언정 없는 과윤문을 만들어내지는 않는 쪽으로 틀렸다.
59
+ */
60
+ function overlapCount(a, b) {
61
+ const counts = new Map();
62
+ for (const token of a)
63
+ counts.set(token, (counts.get(token) ?? 0) + 1);
64
+ let common = 0;
65
+ for (const token of b) {
66
+ const left = counts.get(token) ?? 0;
67
+ if (left > 0) {
68
+ counts.set(token, left - 1);
69
+ common += 1;
70
+ }
71
+ }
72
+ return common;
73
+ }
74
+ export function changeRate(before, after, options = {}) {
75
+ const ignoreMarkup = options.ignoreMarkup ?? false;
76
+ const a = tokenize(normalize(before, ignoreMarkup));
77
+ const b = tokenize(normalize(after, ignoreMarkup));
78
+ if (a.length === 0 && b.length === 0)
79
+ return 0;
80
+ if (a.length === 0 || b.length === 0)
81
+ return 1;
82
+ const tooBig = a.length > TOKEN_DP_CAP || b.length > TOKEN_DP_CAP;
83
+ const common = tooBig ? overlapCount(a, b) : lcsLength(a, b);
84
+ return 1 - (2 * common) / (a.length + b.length);
85
+ }
86
+ //# sourceMappingURL=change-rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-rate.js","sourceRoot":"","sources":["../../../src/humanize/change-rate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type Register, type RuleBook } from './rules.js';
2
+ export type Verdict = 'pass' | 'warn' | 'abort';
3
+ export declare const EXIT_CODE: Record<Verdict | 'unknown', number>;
4
+ export declare const THRESHOLD: {
5
+ readonly changeWarn: 0.3;
6
+ readonly changeAbort: 0.5;
7
+ readonly sentenceDrop: 0.25;
8
+ };
9
+ export interface AxisResult {
10
+ axis: 'change-rate' | 'residual-s1' | 'preservation' | 'structure';
11
+ verdict: Verdict;
12
+ detail: string;
13
+ evidence?: string[];
14
+ }
15
+ export interface CheckReport {
16
+ register: Register;
17
+ verdict: Verdict;
18
+ exitCode: number;
19
+ changeRate: number;
20
+ changeRateNoMarkup: number;
21
+ axes: AxisResult[];
22
+ residualS1: {
23
+ ruleId: string;
24
+ before: number;
25
+ after: number;
26
+ }[];
27
+ introduced: {
28
+ ruleId: string;
29
+ before: number;
30
+ after: number;
31
+ }[];
32
+ }
33
+ export interface RunCheckOptions {
34
+ register?: Register;
35
+ book?: RuleBook;
36
+ }
37
+ export declare function runCheck(before: string, after: string, options?: RunCheckOptions): CheckReport;
38
+ export declare function formatReport(report: CheckReport): string;
39
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/humanize/check.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,EAAE,MAAM,CAKzD,CAAC;AAEF,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,cAAc,GAAG,WAAW,CAAC;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjE;AAsHD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,WAAW,CA0Bb;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAaxD"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * 윤문 결과를 코드가 판단하는 검사.
3
+ *
4
+ * 모델이 스스로 매긴 변경률·등급은 참고값이다. 문자 기반 변경률 하나로는
5
+ * 구조 편집이 안 보인다 — 변경률 2.8%인데 문장 3할이 갈려나간 사례가 있다.
6
+ * 그래서 변경률, 잔존, 보존, 구조 4가지 측면에서 각각 측정하고, 판단한다.
7
+ */
8
+ import { changeRate } from './change-rate.js';
9
+ import { countByRule, missingProtectedTokens, structureStats } from './detectors.js';
10
+ import { parseRuleBook, s1Ids } from './rules.js';
11
+ export const EXIT_CODE = {
12
+ pass: 0,
13
+ warn: 1,
14
+ abort: 2,
15
+ unknown: 3,
16
+ };
17
+ export const THRESHOLD = {
18
+ changeWarn: 0.3,
19
+ changeAbort: 0.5,
20
+ sentenceDrop: 0.25,
21
+ };
22
+ const WORST = { pass: 0, warn: 1, abort: 2 };
23
+ function worst(verdicts) {
24
+ return verdicts.reduce((acc, v) => (WORST[v] > WORST[acc] ? v : acc), 'pass');
25
+ }
26
+ function pct(value) {
27
+ return `${(value * 100).toFixed(1)}%`;
28
+ }
29
+ function checkChangeRate(rate, rateNoMarkup) {
30
+ const detail = `변경률 ${pct(rate)} (마크업 제외 ${pct(rateNoMarkup)})`;
31
+ if (rate >= THRESHOLD.changeAbort) {
32
+ return { axis: 'change-rate', verdict: 'abort', detail: `${detail} — 50% 이상, 채택 금지` };
33
+ }
34
+ if (rate >= THRESHOLD.changeWarn) {
35
+ return { axis: 'change-rate', verdict: 'warn', detail: `${detail} — 30% 이상, 과윤문 의심` };
36
+ }
37
+ return { axis: 'change-rate', verdict: 'pass', detail };
38
+ }
39
+ function checkResidualS1(book, register, before, after) {
40
+ const targets = s1Ids(book, register);
41
+ const beforeCounts = countByRule(before, targets);
42
+ const afterCounts = countByRule(after, targets);
43
+ const residual = targets
44
+ .map((ruleId) => ({
45
+ ruleId,
46
+ before: beforeCounts.get(ruleId) ?? 0,
47
+ after: afterCounts.get(ruleId) ?? 0,
48
+ }))
49
+ .filter((row) => row.after > 0);
50
+ if (residual.length === 0) {
51
+ return {
52
+ axis: { axis: 'residual-s1', verdict: 'pass', detail: 'S1 잔존 0건' },
53
+ residual,
54
+ };
55
+ }
56
+ const evidence = residual.map((row) => `${row.ruleId}: ${row.before} → ${row.after}`);
57
+ return {
58
+ axis: {
59
+ axis: 'residual-s1',
60
+ verdict: 'warn',
61
+ detail: `S1 ${residual.length}종 잔존`,
62
+ evidence,
63
+ },
64
+ residual,
65
+ };
66
+ }
67
+ /** 철칙 — AI 티는 빼기만 하고 넣지 않는다. 늘어난 룰이 있으면 윤문이 새 티를 심은 것이다 */
68
+ function findIntroduced(before, after) {
69
+ const beforeCounts = countByRule(before);
70
+ const afterCounts = countByRule(after);
71
+ return [...afterCounts.entries()]
72
+ .map(([ruleId, count]) => ({ ruleId, before: beforeCounts.get(ruleId) ?? 0, after: count }))
73
+ .filter((row) => row.after > row.before)
74
+ .sort((a, b) => b.after - b.before - (a.after - a.before));
75
+ }
76
+ function checkPreservation(before, after) {
77
+ const missing = missingProtectedTokens(before, after);
78
+ if (missing.length === 0) {
79
+ return { axis: 'preservation', verdict: 'pass', detail: '수치·인용·코드·고유명사 전부 생존' };
80
+ }
81
+ return {
82
+ axis: 'preservation',
83
+ verdict: 'abort',
84
+ detail: `보호 토큰 ${missing.length}건 유실 — 의미 불변 위반`,
85
+ evidence: missing.slice(0, 10),
86
+ };
87
+ }
88
+ function checkStructure(before, after, introduced) {
89
+ const a = structureStats(before);
90
+ const b = structureStats(after);
91
+ const problems = [];
92
+ const drop = a.sentences === 0 ? 0 : (a.sentences - b.sentences) / a.sentences;
93
+ if (drop > THRESHOLD.sentenceDrop) {
94
+ problems.push(`문장 ${a.sentences} → ${b.sentences} (${pct(drop)} 감소) — 내용 유실 의심`);
95
+ }
96
+ if (b.codeFences < a.codeFences) {
97
+ problems.push(`코드블록 ${a.codeFences / 2} → ${b.codeFences / 2}`);
98
+ }
99
+ if (b.links < a.links) {
100
+ problems.push(`링크 ${a.links} → ${b.links}`);
101
+ }
102
+ for (const row of introduced.slice(0, 5)) {
103
+ problems.push(`${row.ruleId} 신규 유입 ${row.before} → ${row.after}`);
104
+ }
105
+ if (problems.length === 0) {
106
+ return { axis: 'structure', verdict: 'pass', detail: '구조·정보량 보존' };
107
+ }
108
+ return {
109
+ axis: 'structure',
110
+ verdict: 'warn',
111
+ detail: `구조 이상 ${problems.length}건`,
112
+ evidence: problems,
113
+ };
114
+ }
115
+ export function runCheck(before, after, options = {}) {
116
+ const register = options.register ?? 'doc';
117
+ const book = options.book ?? parseRuleBook();
118
+ const rate = changeRate(before, after);
119
+ const rateNoMarkup = changeRate(before, after, { ignoreMarkup: true });
120
+ const changeAxis = checkChangeRate(rate, rateNoMarkup);
121
+ const { axis: s1Axis, residual } = checkResidualS1(book, register, before, after);
122
+ const preservationAxis = checkPreservation(before, after);
123
+ const introduced = findIntroduced(before, after);
124
+ const structureAxis = checkStructure(before, after, introduced);
125
+ const axes = [changeAxis, s1Axis, preservationAxis, structureAxis];
126
+ const verdict = worst(axes.map((a) => a.verdict));
127
+ return {
128
+ register,
129
+ verdict,
130
+ exitCode: EXIT_CODE[verdict],
131
+ changeRate: rate,
132
+ changeRateNoMarkup: rateNoMarkup,
133
+ axes,
134
+ residualS1: residual,
135
+ introduced,
136
+ };
137
+ }
138
+ export function formatReport(report) {
139
+ const head = `검사 ${report.verdict.toUpperCase()} (exit ${report.exitCode}) / 말투 ${report.register}`;
140
+ const lines = [head, ''];
141
+ for (const axis of report.axes) {
142
+ const mark = axis.verdict === 'pass' ? 'OK' : axis.verdict === 'warn' ? '경고' : '중단';
143
+ lines.push(`[${mark}] ${axis.axis} — ${axis.detail}`);
144
+ for (const item of axis.evidence ?? []) {
145
+ lines.push(` ${item}`);
146
+ }
147
+ }
148
+ return lines.join('\n');
149
+ }
150
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/humanize/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 룰 ID별 결정적 탐지기.
3
+ *
4
+ * 여기 있는 건 정규식만으로 오탐 없이 셀 수 있는 룰뿐이다. D-5 의인화 주어처럼
5
+ * 뜻을 봐야 판단되는 룰은 일부러 뺐다 — 검사가 오탐으로 멈추면 아무도 안 쓴다.
6
+ * 탐지기가 없는 룰은 모델이 자체검증으로 본다.
7
+ */
8
+ export interface Detection {
9
+ ruleId: string;
10
+ count: number;
11
+ samples: string[];
12
+ }
13
+ export declare function splitSentences(text: string): string[];
14
+ export declare const DETECTABLE_RULE_IDS: string[];
15
+ export declare function detect(text: string, ruleIds?: readonly string[]): Detection[];
16
+ export declare function countByRule(text: string, ruleIds?: readonly string[]): Map<string, number>;
17
+ /** 원문에서 한 글자도 바뀌면 안 되는 토큰을 뽑는다 */
18
+ export declare function protectedTokens(text: string): string[];
19
+ export declare function missingProtectedTokens(before: string, after: string): string[];
20
+ export interface StructureStats {
21
+ sentences: number;
22
+ headings: number;
23
+ bullets: number;
24
+ codeFences: number;
25
+ links: number;
26
+ }
27
+ export declare function structureStats(text: string): StructureStats;
28
+ //# sourceMappingURL=detectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../../../src/humanize/detectors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA8CD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKrD;AA4CD,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAAmC,CAAC;AAE5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAgB7E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAE1F;AAcD,kCAAkC;AAClC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAStD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9E;AAID,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS3D"}