@decencia/ch-cli 1.31.10 → 1.31.12

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.
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-issue-coder
3
3
  description: GitHub issue 1개를 입력으로 받아 끝까지 처리하는 코딩 에이전트. 이슈 읽기 → 소통채널 spec/SQA 확인 → git worktree+브랜치에서 구현 → 자체 소프트리뷰 루프 → unittest + SQA → PR 생성 → 소통채널 workStatus·이슈 기록. 다수 병렬 실행 전제, PR까지만(머지·base 브랜치 직접 push·이슈 close는 사람).
4
4
  tools: Read, Write, Edit, Grep, Glob, Bash, Agent
5
5
  model: opus
6
- version: 1.31.10
6
+ version: 1.31.12
7
7
  ---
8
8
 
9
9
  ## 역할
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-pr-merger
3
3
  description: issue-coder가 낸 PR을 기본 완전 자율로 base 브랜치(기본 브랜치 또는 sprint 통합 브랜치)에 머지하는 에이전트. 핵심 역량은 다수 병렬 worktree가 만든 충돌을 작업 의도 기반(semantic)으로 해결하는 것. CI green+충돌없음이면 바로 squash 머지, 충돌이면 의도대로 해결 후 테스트로 검증하여 머지. 재SQA·전면 재리뷰는 하지 않음. 다수 PR은 직렬 머지.
4
4
  tools: Read, Write, Edit, Grep, Glob, Bash
5
5
  model: opus
6
- version: 1.31.10
6
+ version: 1.31.12
7
7
  ---
8
8
 
9
9
  ## 역할
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-terraformer
3
3
  description: 소통채널을 쓰지 않던 기존 코드베이스를 역분석하여 소통채널 프로젝트로 편입(terraforming)하는 자율 에이전트. 코드가 single source of truth — 코드를 읽어 DB 스키마 → 기능명세(spec) → PRD를 bottom-up으로 역생성한다(SQA 제외). 대량 분석은 서브에이전트 병렬, 코드로 못 메우는 의도는 [추정]으로 채우고 "사람확인 질문 리스트"를 산출물로 남긴다. PR/머지·이슈 발행은 하지 않음.
4
4
  tools: Read, Write, Edit, Grep, Glob, Bash, Agent
5
5
  model: opus
6
- version: 1.31.10
6
+ version: 1.31.12
7
7
  ---
8
8
 
9
9
  ## 역할
@@ -0,0 +1,10 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * `ch ia` — IA(정보구조) 문서. 프로젝트당 1건.
4
+ *
5
+ * 배치(route)는 여기서 다루지 않는다 — 그건 `ch screens --route`가 SSOT다.
6
+ * 이 리소스가 맡는 것은 route로 표현되지 않는 **내비게이션 체계**다:
7
+ * 역할별 GNB, 허브 메뉴, 진입 규칙, 그리고 그렇게 배치한 근거(본문).
8
+ */
9
+ export declare function registerIaCommand(program: Command): void;
10
+ //# sourceMappingURL=ia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ia.d.ts","sourceRoot":"","sources":["../../src/commands/ia.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkHxD"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerIaCommand = registerIaCommand;
4
+ const client_1 = require("../client");
5
+ const output_1 = require("../output");
6
+ const utils_1 = require("../utils");
7
+ /**
8
+ * `ch ia` — IA(정보구조) 문서. 프로젝트당 1건.
9
+ *
10
+ * 배치(route)는 여기서 다루지 않는다 — 그건 `ch screens --route`가 SSOT다.
11
+ * 이 리소스가 맡는 것은 route로 표현되지 않는 **내비게이션 체계**다:
12
+ * 역할별 GNB, 허브 메뉴, 진입 규칙, 그리고 그렇게 배치한 근거(본문).
13
+ */
14
+ function registerIaCommand(program) {
15
+ const ia = program.command('ia').description('IA(정보구조) 관리');
16
+ ia.command('get')
17
+ .description('IA 조회')
18
+ .action(async () => {
19
+ const globalOpts = program.opts();
20
+ try {
21
+ const client = (0, client_1.createClient)({ projectId: globalOpts.project });
22
+ const { data } = await client.get('/ia');
23
+ if (globalOpts.json || globalOpts.csv || globalOpts.quiet) {
24
+ (0, output_1.formatOutput)(data, globalOpts);
25
+ return;
26
+ }
27
+ if (!data) {
28
+ (0, output_1.printInfo)('IA가 아직 작성되지 않았습니다.');
29
+ return;
30
+ }
31
+ (0, output_1.printInfo)(`${data.title} (v${data.currentVersion})`);
32
+ const navs = data.navigations ?? [];
33
+ if (navs.length) {
34
+ (0, output_1.printTable)(['역할', '메뉴', '주 CTA'], navs.map((n) => [
35
+ n.role ?? '',
36
+ (n.items ?? []).map((i) => i.label).join(' · '),
37
+ n.primaryCta ? `${n.primaryCta.label}` : '',
38
+ ]));
39
+ }
40
+ const hubs = data.hubs ?? [];
41
+ if (hubs.length) {
42
+ (0, output_1.printTable)(['허브', '화면', '메뉴'], hubs.map((h) => [
43
+ h.name ?? '',
44
+ h.screenId ?? '',
45
+ (h.items ?? []).map((i) => i.label).join(' · '),
46
+ ]));
47
+ }
48
+ const rules = data.entryRules ?? [];
49
+ if (rules.length) {
50
+ (0, output_1.printInfo)('진입 규칙:');
51
+ rules.forEach((r, i) => (0, output_1.printInfo)(` ${i + 1}. ${r}`));
52
+ }
53
+ }
54
+ catch {
55
+ // Error already handled
56
+ }
57
+ });
58
+ ia.command('set')
59
+ .description('IA 생성/수정 (navigations·hubs·entry-rules는 통째 교체)')
60
+ .requiredOption('--title <title>', 'IA 문서 제목')
61
+ .option('--file <path>', '본문(트리·배치 근거) 마크다운 파일 — 내용이 저장된다')
62
+ .option('--navigations <jsonFile>', '역할별 GNB JSON 파일 (IaNavigation[]) — 통째 교체')
63
+ .option('--hubs <jsonFile>', '허브 JSON 파일 (IaHub[]) — 통째 교체')
64
+ .option('--entry-rules <jsonFile>', '진입 규칙 JSON 파일 (string[]) — 통째 교체')
65
+ .option('--no-version', '버전 기록 없이 수정 (기본: 항상 새 버전 기록)')
66
+ .action(async (options) => {
67
+ const globalOpts = program.opts();
68
+ try {
69
+ const body = { title: options.title };
70
+ if (options.file !== undefined) {
71
+ body.content = (0, utils_1.readContentFile)(options.file, '--file');
72
+ }
73
+ const arrays = [
74
+ ['navigations', options.navigations, '--navigations'],
75
+ ['hubs', options.hubs, '--hubs'],
76
+ ['entryRules', options.entryRules, '--entry-rules'],
77
+ ];
78
+ for (const [key, path, flag] of arrays) {
79
+ if (path === undefined)
80
+ continue;
81
+ const parsed = (0, utils_1.readJsonFile)(path, flag);
82
+ if (!Array.isArray(parsed)) {
83
+ (0, output_1.printError)(`${flag}: JSON 배열이어야 합니다.`);
84
+ return;
85
+ }
86
+ body[key] = parsed;
87
+ }
88
+ if (globalOpts.dryRun) {
89
+ (0, output_1.printInfo)(`[DRY-RUN] IA "${options.title}" 생성/수정 요청`);
90
+ return;
91
+ }
92
+ const client = (0, client_1.createClient)({ projectId: globalOpts.project });
93
+ const params = {};
94
+ if (options.version === false)
95
+ params.newVersion = 'false';
96
+ const { data } = await client.put('/ia', body, { params });
97
+ (0, output_1.formatOutput)(data, globalOpts);
98
+ (0, output_1.printSuccess)(data.message || 'IA가 저장되었습니다.');
99
+ }
100
+ catch (e) {
101
+ if (e?.__handled)
102
+ return;
103
+ (0, output_1.printError)(e?.message ?? String(e));
104
+ }
105
+ });
106
+ ia.command('versions')
107
+ .description('IA 버전 이력 조회')
108
+ .action(async () => {
109
+ const globalOpts = program.opts();
110
+ try {
111
+ const client = (0, client_1.createClient)({ projectId: globalOpts.project });
112
+ const { data } = await client.get('/ia/versions');
113
+ (0, output_1.formatOutput)(data, globalOpts);
114
+ }
115
+ catch {
116
+ // Error already handled
117
+ }
118
+ });
119
+ }
120
+ //# sourceMappingURL=ia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ia.js","sourceRoot":"","sources":["../../src/commands/ia.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -55,6 +55,7 @@ const db_tables_1 = require("./commands/db-tables");
55
55
  const screens_1 = require("./commands/screens");
56
56
  const userflows_1 = require("./commands/userflows");
57
57
  const policies_1 = require("./commands/policies");
58
+ const ia_1 = require("./commands/ia");
58
59
  const backup_1 = require("./commands/backup");
59
60
  const handoff_1 = require("./commands/handoff");
60
61
  const notifications_1 = require("./commands/notifications");
@@ -116,6 +117,7 @@ program.hook('preAction', (thisCommand) => {
116
117
  (0, screens_1.registerScreensCommand)(program);
117
118
  (0, userflows_1.registerUserflowsCommand)(program);
118
119
  (0, policies_1.registerPoliciesCommand)(program);
120
+ (0, ia_1.registerIaCommand)(program);
119
121
  (0, backup_1.registerBackupCommand)(program);
120
122
  (0, handoff_1.registerHandoffCommand)(program);
121
123
  (0, notifications_1.registerNotificationsCommand)(program);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decencia/ch-cli",
3
- "version": "1.31.10",
3
+ "version": "1.31.12",
4
4
  "description": "Decencia Communication Channel CLI",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-change-manager
3
3
  description: 기존 소통채널 프로젝트의 기능 추가/수정을 사용자와 대화로 명확화 → 전파 스킬로 연관 PRD/spec/DB/SQA 일괄 갱신 → 변경으로 생긴 새 할일을 GitHub 이슈로 발행하는 오케스트레이터 스킬. (1)대화로 변경 내용 확정 → (2)[게이트] 영향 범위 확인 후 전파 적용 → (3)[게이트] 할일 목록 확인 후 이슈 발행. "이 기능 바꿀래"·"기획 수정"·"이거 추가해줘(기존 프로젝트)" 류 요청 시.
4
4
  allowed-tools: Bash(ch:*) Bash(git:*) Bash(gh:*) Read Write
5
- version: 1.31.10
5
+ version: 1.31.12
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -10,7 +10,7 @@ description: |
10
10
  (3) 명세·DB·SQA가 서로 어긋나 있는 의심이 들 때 (정합성 점검),
11
11
  (4) PRD 갱신 후 하위 spec/db/SQA로 변경분을 흘려보내야 할 때,
12
12
  (5) Sprint 진행 중 도메인 규칙·스키마가 흔들렸을 때 연쇄 갱신이 필요할 때.
13
- version: 1.31.10
13
+ version: 1.31.12
14
14
  ---
15
15
 
16
16
  <!-- ch-version-gate -->
@@ -10,7 +10,7 @@ description: |
10
10
  (4) ch screens 명령(list/get/create/update/delete/migrate)으로 화면을 다루거나 레거시 프로젝트를 화면 모드로 이관할 때,
11
11
  (5) spec의 화면 연결을 CLI로 걸거나 풀 때 (`ch specs screen-refs`),
12
12
  (6) Spec ID를 JIRA 스타일(`LOGIN-001`)로 직접 지정할 때 (`ch specs create --id`).
13
- version: 1.31.10
13
+ version: 1.31.12
14
14
  ---
15
15
 
16
16
  <!-- ch-version-gate -->
@@ -200,6 +200,20 @@ ch specs update <specId> --db-tables tbl_users,tbl_sessions
200
200
  ch specs update <specId> --db-tables "" # 모두 해제
201
201
  ```
202
202
 
203
+ ## IA 명령 (`ch ia`)
204
+
205
+ 프로젝트당 1건인 정보구조 문서다. 작성 기준은 [[2t-decencia-channel-ia-v2]].
206
+
207
+ ```bash
208
+ ch ia get [--json]
209
+ ch ia set --title "<제목>" --file ./ia.md --navigations ./navigations.json --hubs ./hubs.json --entry-rules ./entry-rules.json
210
+ ch ia versions
211
+ ```
212
+
213
+ - `--navigations`·`--hubs`·`--entry-rules`는 각각 **JSON 배열 파일**이고 **통째 교체**다. 수정 전 `ch ia get --json`으로 받아 편집한다(Read-before-Write).
214
+ - 메뉴의 `screenId`는 실존 화면이어야 한다(없으면 400). 죽은 메뉴를 서버가 막는다.
215
+ - **route는 여기 넣지 않는다** — 배치의 SSOT는 `ch screens --route`다.
216
+
203
217
  ### 화면 연결 (`ch specs screen-refs`)
204
218
 
205
219
  `ui.screenRefs`는 **서버 관리 필드**다. `ch specs update --ui`로 보내면 서버가 버리고 기존 값을 지킨다. 화면 연결은 이 전용 커맨드로만 바꾼다 (웹 화면 선택기와 같은 경로 — `PATCH /specs/:id/screen-refs`).
@@ -8,7 +8,7 @@ description: |
8
8
  (2) DB 테이블 단위로 컬럼·인덱스·보안규칙을 등록·수정할 때,
9
9
  (3) 새 테이블을 추가하면서 전체 인벤토리도 함께 업데이트할 때,
10
10
  (4) spec.dbTableRefs와 양방향 동기화가 필요한 작업 시.
11
- version: 1.31.10
11
+ version: 1.31.12
12
12
  ---
13
13
 
14
14
  <!-- ch-version-gate -->
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-github-issue
3
3
  description: gh CLI로 현재 repo에 GitHub 이슈를 작성한다. 이슈 1개=유형 1개(feat/fix/bug), 표준 본문 양식(작업내용·관련 명세 백링크·완료조건)으로 발행. "이슈 만들어줘"/"깃헙 이슈로 등록해줘" 요청 시, 또는 소통채널 기획·명세 작업 후 처리할 일들을 GitHub 이슈로 옮길 때 사용. 멱등성/중복방지·확인단계는 다루지 않음(요청대로 바로 생성).
4
4
  allowed-tools: Bash(gh:*) Bash(git:*) Read Write
5
- version: 1.31.10
5
+ version: 1.31.12
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: 2t-decencia-channel-ia-v2
3
+ description: |
4
+ [2t][v2] 소통채널 화면 IA(정보구조) 설계 가이드.
5
+ 화면을 만들기 전에 내비게이션 구조를 먼저 정한다 — 최상위 메뉴·허브·그룹 배치·route 부여.
6
+ 배치 기준은 "사용자가 어디서 찾는가"(탐색)이지 "어느 기능에 속하는가"(도메인·Epic)가 아니다.
7
+ Use when:
8
+ (1) 화면설계서를 쓰기 전에 화면들의 배치·route를 정할 때,
9
+ (2) 기존 프로젝트의 IA가 어색해 재배치를 검토할 때,
10
+ (3) "이 화면이 왜 여기 있지" 같은 구조 문제를 점검할 때.
11
+ version: 1.31.12
12
+ ---
13
+
14
+ <!-- ch-version-gate -->
15
+ ## ⚠️ 시작 전 필수 — 버전 게이트 (생략 금지)
16
+
17
+ 이 스킬로 **어떤 작업이든 수행하기 전에 가장 먼저** 아래를 실행한다:
18
+
19
+ ```bash
20
+ ch check
21
+ ```
22
+
23
+ - exit code 0(통과)이 **아니면 즉시 중단**한다. 출력에 안내된 업데이트 명령(`npm install -g @decencia/ch-cli@latest` 또는 `ch setup-skill`)을 사용자에게 전달하고, 갱신이 끝나기 전까지 **이 스킬의 어떤 단계도 진행하지 않는다.**
24
+ - `ch`가 미설치/미인증이어도 먼저 `ch check`를 시도한다. (네트워크 불가 시 ch check는 통과시키되 경고를 남긴다.)
25
+
26
+ 구버전 스킬·CLI 사용을 막기 위한 게이트다. 건너뛰지 말 것.
27
+
28
+
29
+ # 화면 IA(정보구조) 설계
30
+
31
+ 화면들을 어떤 구조로 배치할지 정하는 단계다. 산출물은 **내비게이션 트리 + 화면별 route**다.
32
+
33
+ > **작성 순서상 ④다** — ①기능명세 → ②유저플로우 → ③정책정의서 → DB 스키마 다음, **⑤화면설계서 앞**이다.
34
+ > 유저플로우 뒤여야 한다. 여정을 알아야 "사용자가 어디서 찾는가"로 배치할 수 있다.
35
+
36
+ ## 0. 이 단계가 없으면 무슨 일이 생기나
37
+
38
+ IA를 따로 정하지 않으면 화면마다 route를 개별로 적게 되고, 그 route들이 모여 트리로 그려진다.
39
+ IA가 설계물이 아니라 **부산물**이 되는 것이다. 그러면 각 화면은 그 순간 손에 잡히는 분류를 근거로
40
+ 삼는데, 보통 그게 Epic이다.
41
+
42
+ 실제로 겪은 사고: 내 문의·신고·계정은 `/my` 아래 넣고, 내 공고·내 견적·내 거래는 `/buyer`·`/supplier`로
43
+ 갈랐다. 똑같은 "내 데이터"인데 왜 문의는 마이페이지이고 견적은 아닌지 설명할 근거가 없었다.
44
+ 기준 없이 두 방식을 섞은 것이다.
45
+
46
+ ## 1. IA의 축은 탐색이다
47
+
48
+ **기준 질문: "사용자가 이 화면을 찾을 때 어디를 먼저 클릭하는가."**
49
+ 모든 배치 판단은 이 질문 하나로 한다.
50
+
51
+ - 🚫 **Epic을 IA로 쓰지 마라.** Epic(AUTH·ORDER·BID…)은 명세를 관리하는 축이다. 사용자가 화면을
52
+ 찾아가는 축과 다르다. 우연히 겹칠 수는 있지만, 겹치는지 확인하지 않고 복사하면 안 된다.
53
+ - 🚫 **기능 소속으로 route를 정하지 마라.** "견적 작성은 공급자 기능이니 `/supplier`"는 개발자의 분류다.
54
+ 공급회원이 "내가 낸 견적"을 찾을 때 실제로 어디를 누르는지와는 별개다.
55
+
56
+ ## 2. 배치 규칙 4가지
57
+
58
+ 1. **"내 ○○"는 한 부모 아래 모은다.** 내 공고·내 견적·내 거래·내 문의·내 계정은 역할이 달라도
59
+ 같은 허브에 둔다. 하나만 밖에 있다면 그 이유를 한 줄로 답할 수 있어야 한다.
60
+ 2. **역할 차이는 부모를 나누는 축이 아니다.** 같은 위치에서 내용이 갈리게 한다.
61
+ 구매회원이 `/my/deals`를 열면 구매 거래가, 공급회원이 열면 공급 거래가 보인다.
62
+ 3. **자식이 있는 경로에는 화면이 있어야 한다.** `/buyer` 아래 화면이 5개인데 `/buyer` 자체에 화면이
63
+ 없으면 그 묶음은 입구가 없는 셈이다.
64
+ 4. **최상위는 GNB에 담기는 수만큼.** 보통 5~7개다. 넘으면 묶고, 3단계보다 깊어지면 평평하게 편다.
65
+
66
+ ## 3. 절차
67
+
68
+ 입력: 화면 목록(아직 route는 없는 상태) · 유저플로우 · 역할 정의 · 허브 성격 spec
69
+
70
+ 1. **역할별 진입 직후 화면**을 정한다. 로그인하면 어디로 가나. 그 화면이 그 역할의 허브다.
71
+ 2. **최상위 내비게이션 항목**을 뽑는다. 비회원에게 보이는 것과 회원에게 보이는 것을 나눈다.
72
+ 3. 화면을 항목 아래 **배치**한다. 배치할 때마다 §1의 기준 질문에 답한다. 답이 막히면 그 화면은
73
+ 자리가 틀린 것이다.
74
+ 4. **route를 부여한다.** 트리의 경로가 곧 route다. 화면 ID 슬러그도 같은 계층을 반영한다.
75
+ 5. **트리를 그려 사용자 승인을 받는다**(§4).
76
+ 6. §5 구조 검증을 통과할 때까지 3~5를 되풀이한다.
77
+
78
+ ## 4. 산출물 — 트리로 제시한다
79
+
80
+ ```
81
+ / 메인 SCR-HOME 누구나
82
+ ├─ /products 제품 검색 SCR-PRODUCTS 누구나
83
+ ├─ /rfqs 공개 공고 SCR-RFQ-LIST 누구나
84
+ │ └─ /rfqs/[id] 공고 상세 SCR-RFQ-DETAIL 누구나
85
+ ├─ /my 마이페이지 (역할별 허브) SCR-MY 회원
86
+ │ ├─ /my/rfqs 내 구매공고 SCR-MY-RFQS 구매회원
87
+ │ ├─ /my/bids 내 견적 SCR-MY-BIDS 공급회원
88
+ │ ├─ /my/deals 내 거래 SCR-MY-DEALS 회원 (역할별 내용)
89
+ │ └─ /my/account 계정·회사 관리 SCR-MY-ACCOUNT 회원
90
+ └─ /admin 관리자 콘솔 SCR-ADMIN-DASH 관리자
91
+ ```
92
+
93
+ **배치표(행=화면, 열 하나가 route)로 승인받지 않는다.** 표에서는 구조가 보이지 않아서, 잘못된 배치가
94
+ 그대로 통과한다. 사람은 트리를 봐야 "견적이 왜 마이페이지 밖에 있지"를 즉시 알아챈다.
95
+
96
+ ### 승인받은 결과는 반드시 저장한다
97
+
98
+ 트리를 승인받고 대화에만 남기면, 나중에 GNB가 바뀌었을 때 무엇이 진실인지 판별할 수 없다.
99
+ **IA 리소스**(프로젝트당 1건)에 올린다 — 웹 "IA" 탭에서도 같은 문서를 본다.
100
+
101
+ ```bash
102
+ ch ia get [--json] # 현재 IA (Read-before-Write)
103
+ ch ia set --title "LUBridge 정보구조" --file ./ia.md \ # 트리 그림 + 배치 근거(마크다운)
104
+ --navigations ./navigations.json \ # 역할별 GNB
105
+ --hubs ./hubs.json \ # 허브와 그 아래 메뉴
106
+ --entry-rules ./entry-rules.json # 진입·노출 규칙
107
+ ch ia versions # 변경 이력
108
+ ```
109
+
110
+ `navigations.json` — 역할별 GNB (배열 통째 교체):
111
+
112
+ ```json
113
+ [
114
+ { "role": "비회원",
115
+ "items": [ { "label": "제품 검색", "screenId": "SCR-PRODUCTS" },
116
+ { "label": "공고", "screenId": "SCR-RFQS" } ],
117
+ "primaryCta": { "label": "회원가입", "screenId": "SCR-SIGNUP" } },
118
+ { "role": "구매회원",
119
+ "items": [ { "label": "제품 검색", "screenId": "SCR-PRODUCTS" } ],
120
+ "primaryCta": { "label": "공고 등록", "screenId": "SCR-MY-RFQ-NEW" } }
121
+ ]
122
+ ```
123
+
124
+ `hubs.json` — 허브와 그 아래 메뉴:
125
+
126
+ ```json
127
+ [
128
+ { "name": "마이페이지", "screenId": "SCR-MY",
129
+ "items": [ { "label": "내 구매공고", "screenId": "SCR-MY-RFQS", "role": "구매회원" },
130
+ { "label": "내 견적", "screenId": "SCR-MY-BIDS", "role": "공급회원" } ] }
131
+ ]
132
+ ```
133
+
134
+ - `screenId`는 **실존 화면만 허용**한다(없으면 서버가 400). 죽은 메뉴를 기계가 잡아 준다.
135
+ - **route는 여기 담지 않는다.** 배치의 SSOT는 `screens.route`다 — 같은 값을 두 곳에 두면 반드시 어긋난다.
136
+ IA 문서가 맡는 것은 route로 표현되지 않는 것(무엇을 GNB에 얹었나, 왜 그렇게 묶었나)이다.
137
+ - 본문(`--file`)에는 **승인받은 트리 그림과 배치 근거**를 적는다. 근거가 사라지면 다음 사람은
138
+ 이유를 모른 채 트리만 보게 되고, 그때부터 IA는 다시 흐트러진다.
139
+
140
+ ## 5. 구조 검증 (승인 전 필수)
141
+
142
+ - [ ] **형제 일관성** — 같은 성격의 화면이 서로 다른 부모에 흩어져 있지 않은가. ("내 ○○"가 대표적)
143
+ - [ ] **고아 부모** — 자식이 있는 경로에 화면이 있는가.
144
+ - [ ] **탐색 역질문** — 화면마다 "사용자가 이걸 찾으려면 어디부터 클릭하나"를 한 줄로 답할 수 있는가.
145
+ 답이 "URL 직접 입력"이면 그 화면은 IA에 자리가 없는 것이다.
146
+ - [ ] **명세 대조** — 허브 성격 spec(마이페이지 등)이 "무엇을 담는다"고 적어놨으면 IA가 그대로 따르는가.
147
+ 어긋나면 둘 중 하나가 틀린 것이므로 임의로 정하지 말고 사용자에게 묻는다.
148
+ - [ ] **깊이·폭** — 최상위 5~7개, 경로 3단계 이내.
149
+ - [ ] **유저플로우 도달** — 각 플로우의 화면들이 트리 위에서 이어지는가.
150
+ (누락 화면 전수 대조는 화면을 만든 뒤 [[2t-decencia-channel-screen-v2]] §5-1에서 따로 한다)
151
+
152
+ ## 6. 기존 프로젝트의 IA를 고칠 때
153
+
154
+ route는 수정할 수 있지만 **화면 ID는 불변**이다. 재배치하면 ID와 경로가 어긋나 보인다
155
+ (`SCR-SUPPLIER-BID-LIST`가 `/my/bids`에 놓이는 식). 감수하거나 삭제 후 재생성해야 하는데,
156
+ 후자는 spec 연결(`screenRefs`)이 끊긴다. 와이어프레임의 GNB·서브내비와 `data-screen-link`도
157
+ 함께 고쳐야 한다. **비용을 먼저 알리고 사용자 판단을 받는다.**
158
+
159
+ ## 7. 흔한 함정
160
+
161
+ - **Epic을 그대로 그룹으로 쓰기** — 이 단계가 생긴 이유다 (§1).
162
+ - **역할로 최상위를 가르기** — `/buyer`·`/supplier`로 시작하면 "내 것"이 두 곳으로 찢어진다 (§2-2).
163
+ - **배치표로 승인받기** — 구조가 안 보인다 (§4).
164
+ - **화면을 다 만든 뒤에 IA를 보기** — 그때는 되돌리는 비용이 크다 (§6).
165
+ - **IA를 대화에만 남기기** — 승인받은 트리를 `ch ia set`으로 저장하지 않으면, 나중에 GNB가 바뀌어도
166
+ 무엇이 진실인지 판별할 수 없다. 배치 근거는 특히 잃기 쉽다 (§4).
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-orchestrator
3
3
  description: 소통채널 작업의 단일 진입점(디스패처). 사용자 요청을 듣고 7종(bootstrap·terraformer·change-manager·github-issue·issue-coder·pr-merger·sprint-runner) 중 적절한 곳으로 라우팅하고, 필요하면 여러 단계를 순차 오케스트레이션한다. 대화형 스킬은 메인 세션에서 Skill로, 자율 에이전트는 Agent로 위임. "소통채널 작업 해줘"·"이거 어떻게 처리하지?"처럼 무엇부터 할지 모를 때, 또는 신규기획/코드편입/기획변경/이슈/구현/머지/스프린트실행 어디로든 시작할 때.
4
4
  allowed-tools: Skill Agent Read Bash(ch:*) Bash(gh:*) Bash(git:*)
5
- version: 1.31.10
5
+ version: 1.31.12
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -8,7 +8,7 @@ description: |
8
8
  (1) 정책정의서를 새로 쓰거나 수정할 때,
9
9
  (2) 유저플로우·기능명세를 검토하다 "이건 정해진 게 없다"는 질문이 나왔을 때,
10
10
  (3) 알림 발송 매트릭스·크레딧 지급 기준·타임아웃 처리 같은 횡단 정책을 정리할 때.
11
- version: 1.31.10
11
+ version: 1.31.12
12
12
  ---
13
13
 
14
14
  <!-- ch-version-gate -->
@@ -7,7 +7,7 @@ description: |
7
7
  (1) PRD를 작성하거나 갱신할 때,
8
8
  (2) PRD 구성에서 Epic/스토리 구조를 후속 spec 작성에 매핑할 때,
9
9
  (3) Read-before-Write 규칙으로 PRD content를 안전하게 수정해야 할 때.
10
- version: 1.31.10
10
+ version: 1.31.12
11
11
  ---
12
12
 
13
13
  <!-- ch-version-gate -->
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-project-bootstrap
3
3
  description: 신규 기획을 사용자와 대화하며 step-by-step으로 소통채널 프로젝트로 만드는 오케스트레이터 스킬. (1)대화로 PRD 완성 → (2)기능명세(spec) 내용 확정 → (3)spec 업로드 → (4)유저플로우 → (5)정책정의서 → (6)DB 스키마·spec 연결 → (7)화면설계서(화면 생성·연결) → (8)검증기준서(SQA). 각 단계 사용자 승인 게이트, 작성 디테일은 기존 2t-decencia-channel-*-v2 스킬을 적극 재사용. "새 기획 만들어줘"·"프로젝트 처음부터 세팅" 류 요청 시.
4
4
  allowed-tools: Bash(ch:*) Bash(git:*) Read Write
5
- version: 1.31.10
5
+ version: 1.31.12
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -27,10 +27,11 @@ ch check
27
27
 
28
28
  ## 핵심 원칙
29
29
  - **각 단계마다 사용자 승인 게이트.** "괜찮다"는 확인 없이는 절대 다음 단계로 넘어가지 않는다. 수정 요청이면 그 단계를 반복.
30
- - **기획 문서 작성 순서는 고정이다: ①기능명세 → ②유저플로우 → ③정책정의서 → ④화면설계서⑤검증기준서.** 기능적 기획(①~③)을 다 끝낸 뒤 개발적 형상(DB·화면)으로 들어간다.
30
+ - **기획 문서 작성 순서는 고정이다: ①기능명세 → ②유저플로우 → ③정책정의서 → ④IA 설계 ⑤화면설계서 → ⑥검증기준서.** 기능적 기획(①~③)을 다 끝낸 뒤 개발적 형상(DB·IA·화면)으로 들어간다.
31
31
  - **DB 스키마는 ③과 ④ 사이에 끼어든다** — 정책(만료·상태·타임아웃)이 스키마를 결정하므로 정책 뒤가 맞고, "테이블.컬럼"을 참조하는 첫 문서가 화면설계서라 그 앞이어야 한다.
32
- - **화면·DB 모두 "비워뒀다 나중에 연결"이다**spec보다 화면을 먼저 만들지 않고(§7에서 연결), 테이블도 먼저 만들지 않는다(§6에서 연결·refs 보강).
33
- - 작성 디테일은 호출: PRD→`2t-decencia-channel-prd-v2`, 기능명세→`2t-decencia-channel-spec-v2`, 유저플로우→`2t-decencia-channel-userflow-v2`, 정책→`2t-decencia-channel-policy-v2`, 화면→`2t-decencia-channel-screen-v2`(+`cli-v2` §3 screens 명령), DB→`2t-decencia-channel-db-schema-v2`, SQA→`2t-decencia-channel-sqa-v2`, 업로드→`2t-decencia-channel-cli-v2`.
32
+ - **IA(화면 배치·route)는 화면을 만들기 전에 따로 정한다** 화면마다 route를 즉석에서 지으면 IA가 설계물이 아니라 부산물이 되고, 그 순간 손에 잡히는 분류(Epic)를 근거로 삼게 된다. 유저플로우 뒤여야 "사용자가 어디서 찾는가"로 배치할 수 있다.
33
+ - **화면·DB 모두 "비워뒀다 나중에 연결"이다** — spec보다 화면을 먼저 만들지 않고8에서 연결), 테이블도 먼저 만들지 않는다(§6에서 연결·refs 보강).
34
+ - 작성 디테일은 호출: PRD→`2t-decencia-channel-prd-v2`, 기능명세→`2t-decencia-channel-spec-v2`, 유저플로우→`2t-decencia-channel-userflow-v2`, 정책→`2t-decencia-channel-policy-v2`, IA→`2t-decencia-channel-ia-v2`, 화면→`2t-decencia-channel-screen-v2`(+`cli-v2` §3 screens 명령), DB→`2t-decencia-channel-db-schema-v2`, SQA→`2t-decencia-channel-sqa-v2`, 업로드→`2t-decencia-channel-cli-v2`.
34
35
 
35
36
  ## Use when
36
37
  - "새 기획 만들어줘", "프로젝트 처음부터 세팅해줘", 아이디어/요구사항을 소통채널 프로젝트로 구조화하고 싶을 때.
@@ -41,14 +42,15 @@ ch check
41
42
  (1) PRD → (2) 기능명세 내용 확정 → (3) spec 업로드(연결 없이)
42
43
  → (4) 유저플로우 → (5) 정책정의서
43
44
  → (6) DB 스키마 + spec 연결(dbTableRefs·흐름 refs 보강)
44
- → (7) 화면설계서(화면 생성·연결) → (8) 검증기준서(SQA)
45
+ → (7) IA 설계(내비게이션 트리·route 확정)
46
+ → (8) 화면설계서(화면 생성·연결) → (9) 검증기준서(SQA)
45
47
  ```
46
48
 
47
- (2)~(8) 기획 문서 작성 순서 ①기능명세→②유저플로우→③정책정의서→④화면설계서→⑤검증기준서에 대응하고, DB 스키마(6)는 ③과 ④ 사이에 끼어든다.
49
+ (2)~(9) 기획 문서 작성 순서 ①기능명세→②유저플로우→③정책정의서→④IA 설계→⑤화면설계서→⑥검증기준서에 대응하고, DB 스키마(6)는 ③과 ④ 사이에 끼어든다.
48
50
 
49
51
  - spec은 **테이블·화면 연결 없이** 먼저 올린다. 로직 플로우도 이 시점엔 `refs` 없이 완결 문장으로만 쓴다(서버가 refs의 tableId를 실존 검증하므로).
50
52
  - 테이블 연결(`dbTableRefs`)과 흐름 `refs`는 §6에서 `ch specs update`로 보강한다.
51
- - 화면 연결(`screenRefs`)은 화면을 만든 뒤 §7에서 `ch specs screen-refs`로 건다.
53
+ - 화면 연결(`screenRefs`)은 화면을 만든 뒤 §8에서 `ch specs screen-refs`로 건다.
52
54
 
53
55
  ---
54
56
 
@@ -63,7 +65,7 @@ ch check
63
65
  - **신규 프로젝트는 서버가 `screensEnabled: true` + `storySpecsEnabled: true`로 만든다.** 화면 정보의 SSOT는 screens 리소스다. **신규 프로젝트 spec에는 `ui.route`를 쓰지 않는다.**
64
66
  - `storySpecsEnabled=true`면 spec은 **스토리 명세 구조**다(스토리문장·사전 조건·로직 플로우·비즈니스 규칙 — [[2t-decencia-channel-spec-v2]] §1). 기존 프로젝트(플래그 없음)는 종전 ui/logic 구조 그대로다.
65
67
  - 기존 프로젝트를 이어 쓰면 `ch projects info --json`으로 `screensEnabled`를 본다. **키가 아예 없거나 false면 레거시다.** (레거시 프로젝트 응답에는 이 키가 없다. 없음 = false로 읽는다.)
66
- - **레거시는 route 방식을 그대로 유지한다.** §7(화면설계서)을 건너뛰고 spec의 `ui.route`를 계속 쓴다.
68
+ - **레거시는 route 방식을 그대로 유지한다.** §7(IA 설계)·§8(화면설계서)을 건너뛰고 spec의 `ui.route`를 계속 쓴다.
67
69
 
68
70
  ### 0-2. 레거시를 화면 모드로 옮길 때만
69
71
  - `ch screens migrate --dry-run`으로 계획을 보고 → 사용자 확인 → `ch screens migrate`.
@@ -84,7 +86,7 @@ ch check
84
86
  - Epic은 도메인 단위 코드로 (AUTH/PROD/ORDER/POINT/ADMIN/SYS … — [[2t-decencia-channel-spec-v2]] §3). PRD 기능 요구사항의 카테고리와 같은 코드다.
85
87
  - spec 본문은 스토리 명세 구조로 짠다: 스토리문장(As a/I want/So that 줄글) · 사전 조건 · 로직 플로우 · 비즈니스 규칙.
86
88
  - interactionMap·primaryActions·keyInformation·stateTransitions는 쓰지 않는다 — 스토리 명세에 없다.
87
- - 화면 연결(`screenRefs`)은 지금은 비워둔다. 화면이 아직 없다 — §7에서 연결한다.
89
+ - 화면 연결(`screenRefs`)은 지금은 비워둔다. 화면이 아직 없다 — §8에서 연결한다.
88
90
  - 레거시 프로젝트(§0-1)는 예외다. 종전 ui/logic 구조([[2t-decencia-channel-spec-v2]] §L)로 쓴다.
89
91
  - 이 단계의 산출물은 **기능 목록 + spec 본문 초안**이다. 항목: 이름 · Spec ID(EPIC-NNN) · epic · points · 스토리문장 · 필요 테이블 후보(§6에서 사용).
90
92
  - → **[게이트] 사용자 확인.** OK면 3단계.
@@ -92,7 +94,7 @@ ch check
92
94
  ## 3. spec 업로드
93
95
  *(기능명세 승인 후)*
94
96
 
95
- spec을 서버에 만든다. **테이블·화면 연결은 싣지 않는다** — DB는 §6, 화면은 §7에서 연결한다.
97
+ spec을 서버에 만든다. **테이블·화면 연결은 싣지 않는다** — DB는 §6, 화면은 §8에서 연결한다.
96
98
 
97
99
  ```bash
98
100
  ch specs create --id PROJ-001 --name "프로젝트 목록" \
@@ -107,9 +109,9 @@ ch specs create --id PROJ-001 --name "프로젝트 목록" \
107
109
 
108
110
  - `logic.json`은 로직 플로우 시나리오(실패·차단 분기 포함) + businessRules — [[2t-decencia-channel-spec-v2]] §7·§8.
109
111
  - ⚠️ **이 시점엔 흐름 `refs`를 넣지 않는다** — 테이블이 아직 없고, 서버가 refs의 tableId를 실존 검증해 400이 난다. 완결 문장으로만 쓰고 §6에서 refs를 보강한다.
110
- - `--ui`도 넣지 않는다. 화면이 아직 없다 — 연결은 §7에서 `ch specs screen-refs`로 건다.
112
+ - `--ui`도 넣지 않는다. 화면이 아직 없다 — 연결은 §8에서 `ch specs screen-refs`로 건다.
111
113
  - 레거시 프로젝트(§0-1)는 종전 플래그(`--type`·`--content`·`--ui ui.json`)를 그대로 쓴다 — [[2t-decencia-channel-cli-v2]] §1.
112
- - **spec마다 Story TC 2겹을 함께 등록한다** — 해피패스(결과 상태까지)+실패 분기당 1개, Story당 2~5개([[2t-decencia-channel-sqa-v2]] §2). SQA 시트가 없으면 `ch sqa create`로 먼저 만든다. 권한·상태 누적 검증은 여기서 하지 않는다(§8의 시나리오·B축 몫).
114
+ - **spec마다 Story TC 2겹을 함께 등록한다** — 해피패스(결과 상태까지)+실패 분기당 1개, Story당 2~5개([[2t-decencia-channel-sqa-v2]] §2). SQA 시트가 없으면 `ch sqa create`로 먼저 만든다. 권한·상태 누적 검증은 여기서 하지 않는다(§9의 시나리오·B축 몫).
113
115
  - → **[게이트] 사용자 확인.** OK면 4단계.
114
116
 
115
117
  ## 4. 유저플로우
@@ -134,26 +136,42 @@ ch specs create --id PROJ-001 --name "프로젝트 목록" \
134
136
  2. 로직 플로우 `refs` 보강 — `ch specs get <id> --json`으로 logic을 받아 각 단계·노드에 `refs`(tableId·field·direction·toState)를 채우고 `ch specs update <id> --logic <파일>`로 통째 교체 (Read-before-Write — [[2t-decencia-channel-spec-v2]] §10-2)
135
137
  - → **[게이트] 사용자 확인.** OK면 7단계.
136
138
 
137
- ## 7. 화면설계서 — 화면 생성·연결
138
- *(DB 스키마 후에만. 레거시 프로젝트는 건너뛴다 — §0-1)*
139
+ ## 7. IA 설계 — 화면 묶기 + 내비게이션 구조·route 확정
140
+ *(DB 스키마 후, 화면 생성 전. 레거시 프로젝트는 건너뛴다 — §0-1)*
139
141
 
140
- 기능들을 **화면에 배치**한다. 화면은 사용자가 실제로 마주하는 단위다.
141
- 화면마다 적을 내용(필수 기재항목 6종·디스크립션 작성규칙·예외상태 4종)은 [[2t-decencia-channel-screen-v2]]를 따른다.
142
+ **화면을 만들기 전에 어디에 놓일지를 먼저 정한다.** 작성 기준은 [[2t-decencia-channel-ia-v2]]를 따른다.
142
143
 
143
- **입력**: §2의 기능 목록 + §4에서 만든 spec ID.
144
+ **입력**: §2의 기능 목록 + §4 유저플로우 + spec ID + 역할 정의.
144
145
 
145
146
  **절차**
146
- 1. 기능을 **사용자 맥락**으로 묶는다. 같은 사용자가 한 자리에서 연달아 하는 일이면 한 화면이다.
147
- 2. 화면 배치 초안을 표로 제시한다.
147
+ 1. 기능을 **사용자 맥락**으로 묶어 화면 목록을 만든다. 같은 사용자가 한 자리에서 연달아 하는 일이면 한 화면이다.
148
+ (묶는 원칙과 이름 규칙은 아래 "🚫 1 spec = 1 화면으로 뽑지 마라"·"🔴 화면 이름" 참조)
149
+ 2. 화면들을 **내비게이션 트리에 배치하고 route를 부여**한다 — [[2t-decencia-channel-ia-v2]] §1~§4.
150
+ 배치 기준은 "사용자가 이 화면을 찾을 때 어디를 먼저 클릭하는가"다. **Epic을 그대로 그룹으로 쓰지 않는다.**
151
+ 3. [[2t-decencia-channel-ia-v2]] §5 **구조 검증**을 돌린다(형제 일관성·고아 부모·탐색 역질문·명세 대조·깊이/폭).
152
+ 4. → **[게이트] 사람이 승인한다.** **배치표가 아니라 트리로** 보여준다 — 표에서는 구조가 보이지 않아
153
+ 잘못된 배치가 그대로 통과한다. 승인 전에는 아무것도 만들지 않는다.
154
+ 5. 승인받은 결과를 **저장한다** — `ch ia set --title ... --file ./ia.md --navigations ./navigations.json
155
+ --hubs ./hubs.json --entry-rules ./entry-rules.json` ([[2t-decencia-channel-ia-v2]] §4).
156
+ 대화에만 남기면 나중에 무엇이 진실인지 판별할 수 없다. 웹 "IA" 탭에서 같은 문서를 본다.
157
+ - → OK면 8단계.
158
+
159
+ ## 8. 화면설계서 — 화면 생성·연결
160
+ *(IA 승인 후에만)*
161
+
162
+ 승인된 트리대로 화면을 만든다. 화면마다 적을 내용(필수 기재항목 6종·디스크립션 작성규칙·예외상태 4종)은
163
+ [[2t-decencia-channel-screen-v2]]를 따른다. **route·배치는 §7에서 이미 정해졌다 — 여기서 새로 짓지 않는다.**
148
164
 
149
- | 화면ID | 화면명 | route | 목적 | 접근권한 | figmaNodeId | 페이지 파일 | 담기는 기능(spec) | 진입/이탈 |
165
+ **절차**
166
+ 1. §7 트리의 화면별 세부 항목을 채운다.
167
+
168
+ | 화면ID | 화면명 | route(§7 확정) | 목적 | 접근권한 | figmaNodeId | 페이지 파일 | 담기는 기능(spec) | 진입/이탈 |
150
169
  |---|---|---|---|---|---|---|---|---|
151
170
  | SCR-PROJECTS | 프로젝트 목록 | /projects | 프로젝트를 찾아 들어간다 | developer | 123:456 | src/app/projects/page.tsx | 목록 조회·검색·정렬·생성·삭제 | 대시보드에서 진입 / 행 클릭 시 상세로 |
152
171
 
153
- 화면명은 아래 **화면 이름 규칙**을 지킨다. figmaNodeId·페이지 파일은 화면 소유 필드다(모르면 비워둔다).
172
+ figmaNodeId·페이지 파일은 화면 소유 필드다(모르면 비워둔다).
154
173
 
155
- 3. **[게이트] 사람이 승인한다.** 승인 전에는 아무것도 만들지 않는다.
156
- 4. 승인되면 화면을 만든다.
174
+ 2. 화면을 만든다.
157
175
 
158
176
  ```bash
159
177
  ch screens create --id SCR-PROJECTS --name "프로젝트 목록" \
@@ -167,7 +185,7 @@ ch screens create --id SCR-PROJECTS --name "프로젝트 목록" \
167
185
 
168
186
  ⚠️ 페이지 파일 플래그는 `--page-file`이다. `--file`이 아니다. `ch screens`의 `--file`은 **purpose 본문을 읽을 파일**이라 이미 점유돼 있다.
169
187
 
170
- 5. 배치표대로 **spec을 화면에 연결**한다. spec 하나당 한 번 실행한다.
188
+ 3. 배치표대로 **spec을 화면에 연결**한다. spec 하나당 한 번 실행한다.
171
189
 
172
190
  ```bash
173
191
  ch specs screen-refs PROJ-001 --screens SCR-PROJECTS
@@ -179,11 +197,11 @@ ch specs screen-refs PROJ-002 --screens SCR-PROJECTS,SCR-PROJECT-DETAIL # 화
179
197
  - 없는 화면 ID면 400으로 거절당한다. 화면을 먼저 만들어야 하는 이유다.
180
198
  - 연결을 풀려면 `--screens ""`.
181
199
 
182
- 6. 검증: `ch specs get PROJ-001 --json`의 `ui.screenRefs`와 `ch screens get SCR-PROJECTS --json`의 `relatedSpecIds`가 **양쪽 다** 채워졌는지 본다.
200
+ 4. 검증: `ch specs get PROJ-001 --json`의 `ui.screenRefs`와 `ch screens get SCR-PROJECTS --json`의 `relatedSpecIds`가 **양쪽 다** 채워졌는지 본다.
183
201
 
184
- 7. **유저플로우 대조 검증** — 4단계에서 만든 유저플로우를 기준으로, 여정의 모든 페이지가 빠짐없이 화면으로 만들어졌는지 전수 대조한다. 절차·대조표 양식은 [[2t-decencia-channel-screen-v2]] §5-1. 누락 화면이 나오면 2~6을 그 화면에 대해 반복한다.
202
+ 5. **유저플로우 대조 검증** — 4단계에서 만든 유저플로우를 기준으로, 여정의 모든 페이지가 빠짐없이 화면으로 만들어졌는지 전수 대조한다. 절차·대조표 양식은 [[2t-decencia-channel-screen-v2]] §5-1. 누락 화면이 나오면 §7 IA 트리에 자리를 잡은 뒤 1~4를 그 화면에 대해 반복한다.
185
203
 
186
- 8. → **[게이트] 사용자 확인.** §5-1 대조표를 함께 보여준다. OK면 8단계.
204
+ 6. → **[게이트] 사용자 확인.** §5-1 대조표를 함께 보여준다. OK면 9단계.
187
205
 
188
206
  ### 🚫 1 spec = 1 화면으로 뽑지 마라
189
207
  그러면 화면이 route의 복사본이 된다. 화면 모델을 만든 이유가 사라진다.
@@ -217,7 +235,7 @@ ch specs screen-refs PROJ-002 --screens SCR-PROJECTS,SCR-PROJECT-DETAIL # 화
217
235
  ### 화면의 단위는 사용자가 이동하는 URL이다
218
236
  탭·모달·바텀시트는 별도 화면이 아니다. 그 화면의 `states`·`entryPoints`로 적는다.
219
237
 
220
- ## 8. 검증기준서 (SQA)
238
+ ## 9. 검증기준서 (SQA)
221
239
  *(화면 연결 후에만 — 작성 순서 마지막. Story TC는 §3에서 이미 등록됨)*
222
240
  - `2t-decencia-channel-sqa-v2`로 마무리한다: **시나리오**(§4.6 — 유저플로우 기반 5~10개, 역할별 여정·상태 누적 확인 포인트, 대응 TC 등록·매핑, Sprint 완료조건으로 할당) + **B축**(비기능 핵심 9개) + **§4.5 커버리지 게이트**(전 spec에 TC 2겹이 있는지 최종 검증).
223
241
 
@@ -9,7 +9,7 @@ description: |
9
9
  (1) 화면(screens) 문서를 작성·수정할 때,
10
10
  (2) 화면의 표시 데이터·액션·입력 검증·예외상태를 기재할 때,
11
11
  (3) 웹 "화면" 탭의 IA 트리·화면 상세에 올릴 내용을 쓸 때.
12
- version: 1.31.10
12
+ version: 1.31.12
13
13
  ---
14
14
 
15
15
  <!-- ch-version-gate -->
@@ -33,7 +33,11 @@ ch check
33
33
 
34
34
  역할 분담: 흐름(시나리오)은 spec([[2t-decencia-channel-spec-v2]] §7), 여정 갈림길은 유저플로우([[2t-decencia-channel-userflow-v2]]), 횡단 정책은 정책정의서([[2t-decencia-channel-policy-v2]]). 화면설계서는 **그 화면 안에서 보이는 것·눌리는 것**만 적는다.
35
35
 
36
- > **작성 순서상 ④다** — ①기능명세 → ②유저플로우 → ③정책정의서 → DB 스키마가 끝난 뒤에 화면을 만든다. **spec보다 화면을 먼저 만들지 않는다.** 화면을 만들면서 `ch specs screen-refs <specId> --screens <ids>`로 기존 spec들과 연결하고, 그다음 ⑤검증기준서로 넘어간다.
36
+ > **작성 순서상 ⑤다** — ①기능명세 → ②유저플로우 → ③정책정의서 → DB 스키마 → **④IA 설계**가 끝난 뒤에 화면을 만든다. **spec보다 화면을 먼저 만들지 않는다.** 화면을 만들면서 `ch specs screen-refs <specId> --screens <ids>`로 기존 spec들과 연결하고, 그다음 ⑥검증기준서로 넘어간다.
37
+ >
38
+ > ⚠️ **route와 배치는 여기서 정하지 않는다.** 화면이 트리의 어디에 놓이고 route가 무엇인지는
39
+ > ④에서 이미 결정돼 있어야 한다 — [[2t-decencia-channel-ia-v2]]. 화면마다 route를 즉석에서 지으면
40
+ > IA가 설계물이 아니라 부산물이 되고, 그 순간 손에 잡히는 분류(Epic)를 근거로 삼게 된다.
37
41
 
38
42
  ## 1. 필수 기재항목
39
43
 
@@ -75,6 +79,7 @@ ch check
75
79
  - 웹 "화면" 탭은 화면들을 **IA 트리**(route 계층)로 보여준다. 유저플로우와 같은 zoom in/out·pan 뷰어다.
76
80
  - 노드를 클릭하면 화면 상세가 열린다: **좌측 와이어프레임 뷰 · 우측 디스크립션**(§1 항목들).
77
81
  - 트리가 읽히려면 route를 계층적으로 짓는다 (`/store/orders` → `/store/orders/[id]`). 화면 ID 슬러그도 계층을 반영한다.
82
+ - 이 트리의 **모양을 결정하는 것은 ④ IA 설계**다([[2t-decencia-channel-ia-v2]]). 여기서는 그 결정을 화면 문서에 옮겨 적을 뿐이다. 트리를 보고 배치가 어색하면 화면을 고치지 말고 IA 단계로 되돌아간다.
78
83
 
79
84
  ## 4-1. 와이어프레임 — HTML로 실제 렌더
80
85
 
@@ -192,6 +197,18 @@ ch screens update SCR-ORDER-DETAIL \
192
197
 
193
198
  전부 ✅가 될 때까지 4를 반복한다. 완성된 대조표가 곧 사람 확인용 증빙이다.
194
199
 
200
+ ### 내비게이션 대조도 함께 한다
201
+
202
+ 위 대조는 **화면 누락**만 잡는다. 메뉴가 낡은 것은 못 잡는다 — 실제로 대조표가 전부 ✅인데
203
+ IA는 낡아 있던 적이 있다. `ch ia get`으로 IA를 받아 두 가지를 더 본다.
204
+
205
+ - [ ] **죽은 메뉴** — GNB·허브의 각 항목이 실존 화면을 가리키는가. (서버가 저장 시 막지만, 화면을
206
+ 지운 뒤에는 IA에 그대로 남는다)
207
+ - [ ] **고아 화면** — 어느 GNB·허브에도 없고 다른 화면의 `actions` 대상도 아닌 화면이 있는가.
208
+ 있다면 사용자가 도달할 방법이 없다는 뜻이다.
209
+
210
+ 어긋나면 화면이 아니라 **IA를 고친다**([[2t-decencia-channel-ia-v2]] §4의 `ch ia set`).
211
+
195
212
  ## 6. 흔한 함정
196
213
 
197
214
  - **컴포넌트 설명에 모든 걸 밀어 넣기** — 조건절·정책 ID·조건 붙은 출처 표기까지 한 문장에 담으면
@@ -12,7 +12,7 @@ description: |
12
12
  (3) 스토리문장·사전 조건·로직 플로우·비즈니스 규칙을 작성할 때,
13
13
  (4) Story 규모를 Story Point(`--points`)로 매길 때,
14
14
  (5) 신규 spec ID를 `AUTH-001` 같은 JIRA 스타일로 부여할 때 (`ch specs create --id`).
15
- version: 1.31.10
15
+ version: 1.31.12
16
16
  ---
17
17
 
18
18
  <!-- ch-version-gate -->
@@ -119,6 +119,8 @@ Epic은 기능 묶음이 아니라 **도메인** 단위다. 대문자 코드로
119
119
  - PRD 기능 요구사항의 카테고리 = Epic 코드다 ([[2t-decencia-channel-prd-v2]]).
120
120
  - Spec ID prefix도 같은 코드를 쓴다: Epic `AUTH` → `AUTH-001`, `AUTH-002` (§4).
121
121
  - spec의 `domains[]`(복수)는 분류 필터고, `epic`(단수)은 소속이다. Story는 Epic 하나에만 속한다.
122
+ - 🚫 **Epic을 화면 IA(내비게이션 구조)로 옮기지 마라.** Epic은 명세를 관리하는 축이고, IA는 사용자가
123
+ 화면을 찾아가는 축이라 서로 다르다. 화면 배치는 [[2t-decencia-channel-ia-v2]]가 정한다.
122
124
 
123
125
  ---
124
126
 
@@ -7,7 +7,7 @@ description: |
7
7
  (1) sprint를 구성할 때,
8
8
  (2) Σ spec.points 기반 sprint 용량 산정이 필요할 때,
9
9
  (3) Epic·도메인·의존성을 함께 고려해 spec을 sprint에 배분할 때.
10
- version: 1.31.10
10
+ version: 1.31.12
11
11
  ---
12
12
 
13
13
  <!-- ch-version-gate -->
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-sprint-runner
3
3
  description: 특정 Sprint를 끝까지 실행(run)하는 오케스트레이터 스킬. Sprint의 spec을 시드로 이슈 목록을 분해·발행(github-issue)하고, GitHub milestone에 묶인 이슈를 상태별로 분류해 issue-coder(병렬)·pr-merger(직렬)로 전진시킨 뒤, 사람확인이 필요한 곳에서 멈춘다. 사람이 확인·체크 후 재호출하면 멱등하게 이어간다(반복 루프). "스프린트 돌려줘"·"sprint N 실행"·"이 스프린트 개발 진행해줘" 류 요청 시.
4
4
  allowed-tools: Skill Agent Read Bash(ch:*) Bash(gh:*) Bash(git:*)
5
- version: 1.31.10
5
+ version: 1.31.12
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -12,7 +12,7 @@ description: |
12
12
  (4) 보안/성능/접근성/호환성 비기능 TC를 시트에 채워야 할 때,
13
13
  (5) 명세 영역별 완성형 TC 번들(퍼블리싱/프론트/백엔드 디센시아 운영 관점 포함)을 가져다 쓸 때,
14
14
  (6) Sprint 종료 전 spec별 TC 통과·시나리오 통과 여부를 점검할 때.
15
- version: 1.31.10
15
+ version: 1.31.12
16
16
  ---
17
17
 
18
18
  <!-- ch-version-gate -->
@@ -8,7 +8,7 @@ description: |
8
8
  (1) 유저플로우(사용자 여정 분기도)를 새로 그리거나 수정할 때,
9
9
  (2) PRD·Epic-Story 목록에서 플로우로 그릴 대상을 고를 때,
10
10
  (3) 웹 "유저플로우" 탭에 올릴 Mermaid 코드를 작성할 때.
11
- version: 1.31.10
11
+ version: 1.31.12
12
12
  ---
13
13
 
14
14
  <!-- ch-version-gate -->
@@ -8,7 +8,7 @@ description: |
8
8
  (2) "작업 현황 적어줘", "workStatus 갱신해줘" 요청 시,
9
9
  (3) Sprint 종료 회고나 인수인계용으로 spec별 진행 상태를 정리할 때,
10
10
  (4) `ch specs update --work-status` 또는 웹 "작업 현황" 탭에서 갱신할 때.
11
- version: 1.31.10
11
+ version: 1.31.12
12
12
  ---
13
13
 
14
14
  <!-- ch-version-gate -->