CHAPTER 09 / 13
요구사항 · 정책 정의서
개발자에게 넘길 규칙은 무엇인가?
아래 본문은 기존 워크숍 목업 기준입니다. 새로 추가한 여행·회식·모임·선물의 질문과 후보는 다섯 가지 결정, 질문 생성과 설정은 AI 고도화에서 확인하세요. 새 체험은 규칙 기반이며 실제 LLM·다기기 응답 수집은 미연결입니다.
읽는 순서 9 / 13 · 요약
개발자에게 넘길 규칙은 무엇인가?
- 기능 요구 23건(반드시·해야·하면 좋음으로 나눔), 정책 20건, 예외 10건, 수용 기준 8건을 목업 코드 기준으로 한 곳에 모았다.
- 핵심 정책: 참가자 3~8명, 답을 안 낸 사람은 계산·리포트·재확인에서 제외, 재조율은 1회, 개인 조건은 본인 리포트에만 보인다.
- 미결이었던 7건(초대 기본값 · 원문 보관 · 종료 후 열람 · 3명 방 · 예산 선호 · 동점 표시 · 방장 이탈)은 2026-09-06 민수 위임으로 쏠이 결정했고 §3 · §7에 반영했다. 남은 판단은 정책이 아니라 주 버튼 색 · 발언 로그 삭제 · 새 기기 복구 방식이다.
누가 읽나: 개발자 · 정책을 결정할 사람
작성: 페이블 · 2026-09-06 · P0 산출물 ④
목적: 취합 노트·검토 반영·유저 플로우·엔진 코드에 흩어진 규칙을 한 곳에 모은다. 개발자에게 이 문서 하나로 「무엇을, 어떤 규칙으로」를 넘길 수 있어야 한다.
기준: mockup/engine.js · mockup/app.js 2026-09-06 실행 확인. 「목업」 열의 값은 코드에서 직접 읽었다(상수 이름 표기).
갱신: 2026-09-06 §7 미결 7건을 결정값으로 교체(쏠 결정서 v1, 민수 위임). §3 P-07 · P-17 · P-18 · P-19 행 갱신, P-21 · P-22 추가, §5 방장 이탈 행 갱신.
1. 범위와 역할
| 항목 | MVP (발표 데모) | NEXT |
|---|---|---|
| 주제 | 팀 워크숍 1개 | 여행 · 회식 |
| 인원 | 3~8명 (방장 포함) | 9명 이상 |
| 질문 | 6문항 고정 | 주제별 문항 |
| 후보 | 고정 5개 | 생성 (AI 설계서 §7) |
| 실행 | 단일 브라우저 시뮬레이션 | 서버 · 다기기 · 개인 토큰 |
역할: 방장(주제·인원·마감·초대 방식 결정, 협상 시작, 결과 확정) · 참가자(답변, 재확인) · 시스템(구조화, 조율, 설명, 알림). 방장도 참가자로서 답변한다. 방장은 남의 답변을 보지 못하고 대신 답하지 못한다.
2. 기능 요구사항 (MoSCoW)
M = Must(MVP 필수) · S = Should(MVP 권장) · C = Could(여유 시) · W = Won't(이번 범위 밖)
| ID | 기능 | 우선 | 목업 상태 | 근거 |
|---|---|---|---|---|
| FR-01 | 방장이 주제(워크숍) · 인원 3~8 · 답변 마감 · 초대 방식 · 방장 이름을 정해 방을 만든다 | M | 구현 | LIMITS, DEADLINES, S1 |
| FR-02 | 공용 링크 + 6자리 입장 코드 또는 이름별 개인 링크를 만든다 | M | 구현(시뮬레이션) | inviteMode |
| FR-03 | 참가자가 이름을 입력하고 비공개 약속을 읽은 뒤 답변을 시작한다 | M | 구현 | S3 |
| FR-04 | 6문항: 방식 · 시간(선호+상한) · 목적 1·2순위 · 지역 · 예산(선호+상한) · 피할 것(자유서술) | M | 구현 | QUESTIONS |
| FR-05 | 자유서술을 조건 태그로 구조화하고, 제출 전에 사용자가 확인·수정한다 | M | 구현(키워드 7종) / LLM 미구현 | structureAvoid, AI 설계서 §4 |
| FR-06 | 협상 시작 전까지 본인 답변을 수정할 수 있다 | S | 구현 | S5 「답변 고치기」 |
| FR-07 | 방장은 누가 답했는지만 본다. 무엇을 답했는지는 못 본다 | M | 구현 | S2 문구, 데이터 경계 |
| FR-08 | 미응답자에게 자동 리마인드 2회 + 방장 수동 리마인드 | S | 구현(시뮬레이션) | advance(), REMIND_COOLDOWN |
| FR-09 | 마감 시 응답 3명 이상이면 자동 시작, 미만이면 연장(최대 2회) 또는 방 닫기 | M | 구현 | MAX_EXTENSIONS, EXTENSION_MIN |
| FR-10 | 방장이 3명 이상 답한 시점에 조기 시작할 수 있다 (미응답 확인 모달) | S | 구현 | S5 |
| FR-11 | 거부권 필터 → 만족도 → 최저 우선 정렬로 합의안 1개 + 대안 2개를 낸다 | M | 구현 | negotiate, compareRows |
| FR-12 | 조율 화면에 사람 단위 발언 없이 집계 진행 4단계를 보인다 | M | 구현 | makeLog |
| FR-13 | 결과: 최종안 · 지켜진 조건 건수 · 공통 이유(2명 이상) · 선호와 다른 지점(집계) · 탈락 후보와 사유 주제 · 공정성 수치(최저/평균) | M | 구현 | reasons, concessions, kept, dead |
| FR-14 | 설명 문장을 LLM으로 생성하고, 30초 안에 안 되면 템플릿으로 대체한다 | S | 폴백 UI만 구현 | LLM_TIMEOUT_MS, AI 설계서 §5 |
| FR-15 | 본인만 보는 개인 리포트: 지켜진 조건 · 선호와 다른 지점 · 1순위 반영 여부 · 개인 만족도 | M | 구현 | receipt, selectParticipant |
| FR-16 | 최종 재확인: 동의 / 조건부 동의(한 줄 필수) / 재조율 요청(방당 1회, 구조화 성공 필수) | M | 구현 | validateRatify |
| FR-17 | 재확인 마감 24시간. 미응답은 기권. 재조율 요청 없으면 방장이 확정 | M | 구현 | RATIFY_HOURS |
| FR-18 | 결정 완료 화면 + 공유(캘린더 초대 포함) | S | 구현 | S9 |
| FR-19 | 개인 토큰으로 리포트 접근 인증 (URL만 아는 타인은 못 봄) | M (제품) | 미구현 | 취합 노트 §3 |
| FR-20 | 후보 0개일 때 탈락 사유 주제 집계와 재조율 안내 | M | 구현 | negotiate ok:false |
| FR-21 | 여행·회식 주제 | W | 「NEXT」 표시 | 1 Pager |
| FR-22 | 결정 후 예약·일정 등록 연결 | W | 없음 | 1 Pager 약점 4 |
| FR-23 | 대리인 완화 제안 라운드 (후보 0개일 때) | W | 없음 | AI 설계서 §7 |
3. 정책 정의
| ID | 정책 | 값 | 목업 | 상태 |
|---|---|---|---|---|
| P-01 | 참여 인원 | 3~8명 (방장 포함). 3 미만·8 초과 불가 | LIMITS | 확정 (민수 2026-09-04) |
| P-02 | 답변 마감 옵션 | 3시간 / 오늘 자정 / 24시간(기본) / 48시간 | DEADLINES | 확정 |
| P-03 | 자동 시작 조건 | 마감 시 응답 ≥ 3명 | advance() | 확정 |
| P-04 | 마감 연장 | 24시간씩, 최대 2회. 그래도 3명 미만이면 방 닫기 | EXTENSION_MIN, MAX_EXTENSIONS | 확정 |
| P-05 | 미응답자 | 계산 · 개인 리포트 · 재확인 모두 제외. 결과 화면에 「미응답 N명 조건 미반영」 명시. 방장 대행 답변 금지 | eligibleParticipants | 확정 (검토 반영) |
| P-06 | 리마인드 | 자동: 남은 시간 절반 지점 · 마감 1시간 전, 미응답자에게만. 수동: 방장, 쿨다운 30분 | advance(), REMIND_COOLDOWN | 확정 |
| P-07 | 초대 방식 | 공용 링크 + 6자리 코드(정원 차면 닫힘) 기본. 이름별 개인 링크는 선택. 초대 URL·코드는 입장용이며 답변·리포트 열람 권한이 아님 | inviteMode | 확정 (쏠 결정서 v1 2026-09-06, 민수 위임) |
| P-08 | 링크 만료 | 답변 마감 시각 | 문구 | 확정 |
| P-09 | 재확인 마감 | 결과 후 24시간. 미응답 = 기권 | RATIFY_HOURS | 확정 |
| P-10 | 재조율 | 방당 1회. 빈 값 금지, 구조화 성공 뒤에만 제출. 요청자 조건에만 추가. 실패 시 1회 권한 유지 | validateRatify | 확정 (검토 반영) |
| P-11 | 공정성 규칙 | 거부권 → 최저 만족도 ↓ → 평균 ↓ → 비용 ↑ → 일정 짧은 순 → 후보 ID | compareRows | 확정 (검토 반영) |
| P-12 | 공개 경계 | 2명 이상 공통인 조건·차이만 구체화. 단독은 건수만. 개인 만족도·정확한 상한은 본인 리포트만. 사람 단위 발언 없음 | reasons, concessions, makeLog | 확정 (검토 반영) |
| P-13 | 만족도 가중 | 목적 40 · 방식 25 · 지역 20 · 시간 15. 예산 선호 초과 1.5배 이내 −5, 초과 −10 | satisfaction | 확정 |
| P-14 | 상한(거부권) | 시간 상한: 선택보다 긴 일정 탈락. 예산 상한: 초과 후보 탈락. 금지 태그: 후보 태그 일치 시 탈락. 한 명만 걸려도 탈락 | vetoes | 확정 |
| P-15 | 자유서술 어휘 | 태그 7종 (운전·술·숙박·격한 야외·장거리·날음식·이른 출발). 어휘 밖은 목록 선택 | AVOID_RULES | 확정 (확장은 후보 태그와 동시) |
| P-16 | 설명 생성 타임아웃 | 30초 → 템플릿 폴백, 배지 표기 | LLM_TIMEOUT_MS | 확정 |
| P-17 | 원문 보관 | 결정 확정 또는 방 종료 시 원문(피할 것 자유서술·재조율 사유·조건부 동의 문장) 즉시 삭제. 미완료 방은 생성 후 7일(168시간)에 미확정 종료·삭제 | S3 문구 (「가정」 표기 제거 대상) | 확정 (쏠 결정서 v1 2026-09-06, 민수 위임) |
| P-18 | 종료 후 열람 | 확정·종료 시각(closed_at)부터 7일(168시간) 읽기 전용. 이후 결과·구조화 조건·개인 리포트 삭제, 접근 토큰 폐기. 방·참가자에 연결되는 이벤트도 같은 시점에 삭제 | 완료 화면 문구 | 확정 (쏠 결정서 v1 2026-09-06, 민수 위임) |
| P-19 | 소수 응답 보호 | 실제 계산 참여자가 3명이면(정원과 무관) 공통 선호의 구체 내용·조건별 인원수·단독 조건 건수·후보별 탈락 사유 주제·최저/평균 수치를 숨긴다. 공개 화면은 후보의 장소·비용·일정, 응답 현황, 일반 설명만. 재확인 유형별 인원수도 숨김. 본인 리포트는 유지. 4명 이상은 P-12 유지(「완전 익명」 표현 금지) | — | 확정 (쏠 결정서 v1 2026-09-06, 민수 위임) · 추천값과 다름 |
| P-20 | 예산 선호(상한 OFF) | 페널티로만 반영 (P-13). 상한 ON만 탈락 | satisfaction | 확정 (검토 반영 · 2026-09-06 유지 재확인) |
| P-21 | 동점 · 근소한 차 표시 | 거부권 통과 1·2위의 최저·평균 차 dMin·dMean(엔진 정렬에 쓴 값, 표시용 반올림 금지). 둘 다 0이면 「만족도 동점」, 둘 다 1 미만(동점 제외)이면 「근소한 차」. 생존 후보 1개면 표시 없음. 정렬은 P-11 그대로 | 미구현 (UC-49) | 확정 (쏠 결정서 v1 2026-09-06, 민수 위임) |
| P-22 | 방장 이탈 · 방 수명 | 자동 확정 없음. 재확인 마감 뒤 방장 확정 유예 24시간, 그래도 미확정이면 「미확정 종료」. 방 수명은 생성(created_at) 후 최대 7일(168시간)이며 먼저 오는 시점에 종료. 미확정 종료는 완료·동의 지표에 넣지 않음 | 미구현 (UC-39a) | 확정 (쏠 결정서 v1 2026-09-06, 민수 위임) · 추천값과 다름 |
4. 비기능 요구사항
| ID | 항목 | 요구 |
|---|---|---|
| NF-01 | 접근성 | 모달 role=dialog · aria-modal · 포커스 이동/복귀 · ESC, 선택 버튼 aria-pressed, 본문 대비 AA 4.5:1 (현재 보라색 4.48:1 → 대체색, 디자인 벤치마킹 §P0) |
| NF-02 | 성능 | 구조화 p95 3s, 설명 p95 10s, 결과 화면 첫 표시 ≤ 1s (규칙 계산은 즉시) |
| NF-03 | 보안 | 개인 토큰은 추측 불가 길이, 방 URL만으로 리포트 접근 불가, 입장 코드 6자리 + 정원 마감 |
| NF-04 | 데이터 | 원문은 구조화 호출 1회 뒤 만료 시각과 함께 저장, 결정 완료 후 삭제(P-17). 로그에 원문·개인 값 기록 금지 |
| NF-05 | 재현성 | 같은 답변 집합 → 같은 결과. 엔진은 순수 함수 유지, 회귀 테스트(check.mjs, tests/) 통과 |
| NF-06 | 모바일 | 430px 기준 설계, 데스크톱은 중앙 정렬 |
5. 예외 · 에러 케이스
| 상황 | 동작 | 화면 | 목업 |
|---|---|---|---|
| 정원 초과 입장 (공용 링크) | 거부 | 「정원이 찼어요」 | 문구만 |
| 입장 코드 오류 | 재입력 | 오류 문구 | 시뮬레이션 |
| 자유서술 구조화 실패 | 제출 차단, 목록 선택 요청 | 「이해하지 못했어요」 | 구현 |
| 마감 시 응답 < 3 | 연장 선택 또는 방 닫기 | 방장 선택 | 구현 |
| 후보 0개 | 탈락 사유 주제 집계 + 재조율 안내 | 「후보가 없어요」 | 구현 |
| 1·2위 동점 | P-11 후순위 규칙 적용 | 결과에 「근소한 차」 표시 여부 미결 | 규칙만 |
| 재조율 2회째 | 차단 | 「방당 한 번만」 | 구현 |
| 조건부 동의 빈 값 | 차단 | 「실행 조건을 적어주세요」 | 구현 |
| 설명 생성 30초 초과 | 템플릿 | 배지 | 구현(연출) |
| 방장 이탈 | 자동 확정 없음. 재확인 마감 후 24시간 유예 → 미확정 종료. 방 수명 상한 7일 | — | 확정 (P-22) |
6. 수용 기준 (Given / When / Then) — Must 항목
- AC-01 (FR-09) Given 4명 방·마감 24h, When 마감 시각에 응답 3명, Then 자동 시작하고 결과 화면에 「미응답 1명 조건 미반영」이 보인다.
- AC-02 (FR-11) Given 기본 4명 답변, When 조율, Then 우승 「양평 리트릿 워크숍」, 최저 61.5 · 평균 74.1, 가평은 예산 상한·술자리 조건으로 탈락 (
check.mjs). - AC-03 (FR-12) Given 어떤 답변 집합이든, When 조율 화면, Then 참가자 이름·기호·개인 값이 한 글자도 표시되지 않는다.
- AC-04 (FR-13/P-12) Given 단독 조건 1건, When 결과 화면, Then 「그 외 단독 선호 차이 1건」으로만 표시되고 내용은 본인 리포트에만 있다.
- AC-05 (FR-15) Given 참가자 B로 전환, When 내 리포트, Then B의 조건·만족도가 보이고 방장 것이 아니다.
- AC-06 (FR-16) Given 재조율 1회 사용, When 다시 요청, Then 차단 문구. Given 빈 조건부, Then 제출 불가.
- AC-07 (FR-05) Given 「술 안 마셨으면」, When 구조화, Then 태그
drinking확인 카드. Given 「사람 많은 데 싫어요」, Then 실패 안내와 목록 선택. - AC-08 (NF-05) Given 같은 답변 100회, Then 결과 100회 동일.
7. 미결이었던 정책 — 결정 반영 (2026-09-06)
2026-09-06 민수가 wanted 스레드에서 결정을 쏠에게 위임했고(이벤트 f5f5e418…), 쏠이 KKIRI_POLICY_DECISIONS_2026_09_06.md(결정서 v1)로 기록했다. 아래 표는 이 문서가 제시했던 추천값과 실제 결정을 나란히 둔 것이다. 결정값은 §3의 P-07 · P-17 · P-18 · P-19 · P-20 · P-21 · P-22 행에 반영했다. 결정은 설계·개발 적용 기준이며 제품 구현·검증 완료를 뜻하지 않는다. 이 값은 선택한 정책값이지 사용자 조사 측정값이 아니다.
| ID | 쟁점 | 이 문서의 추천(당시) | 결정 (쏠 결정서 v1) | 추천과 다른 점 |
|---|---|---|---|---|
| P-07 | 초대 기본값 | 공용 | 공용 링크 + 6자리 코드 기본, 개인 링크는 선택 | 같음 |
| P-17 | 원문 보관 기간 | 결정 완료 즉시 삭제, 태그만 7일 | 확정·방 종료 시 즉시 삭제. 미완료 방도 생성 후 7일에 종료·삭제 | 미완료 방 상한 추가 |
| P-18 | 결정 후 열람 | 7일 | 종료 후 7일 읽기 전용, 이후 삭제·토큰 폐기 | 같음 + 삭제 범위 명시 |
| P-19 | 3명 방 | 그대로 + 안내 문구 | 실제 계산 참여자 3명이면 상세 공개 이유·집계 수치 생략 | 다름 — 소수 집계로 개인 조건을 추정할 여지를 줄이려는 결정 |
| P-20 | 예산 선호 | 유지 | 유지 (§3에서 이미 확정이었음) | 같음 |
| P-21 | 동점 표시 | 1점 미만 차이면 「근소한 차」 | 표시. dMin·dMean 둘 다 0이면 동점, 둘 다 1 미만이면 근소한 차. 생존 후보 1개면 없음 | 판정식을 두 값 모두로 고정 |
| P-22 | 방장 이탈 | 재확인 마감 후 이의 없으면 자동 확정 | 자동 확정 없음. 24시간 유예 뒤 미확정 종료. 방 수명 최대 7일 | 다름 — 무응답·기권을 동의나 방장 결정으로 바꾸지 않음 |
결정으로 정정해야 할 곳 (이 문서 밖)
- 유즈케이스 UC-37의 대안 「재조율 요청이 있으면 방장은 UC-38 또는 UC-39 선택」 → 미처리 재조율 요청이 있으면 확정 불가(UC-38 먼저). 2026-09-06 반영.
- 유즈케이스 UC-39a(자동 확정) → 「방장 이탈 시 미확정 종료」로 이름과 흐름 변경. 2026-09-06 반영.
- 목업 S3 · S9 문구의 「※ 기간은 가정」 → P-17 · P-18 확정값으로 교체(코드 수정은 별도 작업).
- 쏠 A안 화면설계서 「제안·미결」 A-02 · A-03 · A-05 → 결정서 참조로 갱신(쏠 문서, 쏠이 반영).
- 지표 계획 K-13(30일 재사용률)은 7일 보관 정책과 충돌 → 별도 설계 전까지 미계측.
남아 있는 미결(정책 아님): 주 버튼 색(검정 vs 보라, 스타일 보드), 대리인 발언 로그 삭제 확정(벤치마킹 통합본 §6), 새 기기에서 개인 리포트 복구 방식(쏠 A-02, E4).