# DEVLOG > 날짜별 작업 이력. 맨 위가 최신. "왜 그렇게 했는가"는 결정 노트로 링크되어 있으면 그쪽 참고. > 이전 DEVLOG(구 Phase 0~4 체계)는 `old/2026.09.04/docs/DEVLOG.md`에 보관. ## 열린 이슈 - **유형 B(금리형 규약) 카탈로그가 없음** — 유형 A·C·D는 채웠다. B는 게임오버 게이지 최대치 변경·상점 가격 배율 등 판 전체 변수라 §20.2 소량 배치 콘텐츠 작업 때 채울 것. - **공보(axis_pr) 축 선택지가 여전히 7개로 최소 수준** — 축별 재배정으로 1개→7개까지 늘렸지만 다른 축(12~14개)에 비하면 적다. 공보로 "일괄 처리"(같은 축 5장)를 노리기는 아직 빠듯하다. §20.2 신규 카드 작성 때 공보 축을 우선 보강할 것. - **평택-서울 원격 세션 안정성 문제 원인 미파악** — 2026-09-15 작업 중 VS Code Remote-SSH 연결이 끊겨 커밋 전 작업이 통째로 유실됐다(재구현으로 복구). 왜 끊겼는지 원인 조사 안 됨 — 재발 방지책 필요. - **라운드 주목도 한도(21 + 라운드당 +5), 상점 가격, 게이지 상승 장수 구간 수치 등은 전부 가안** — 실측 플레이로 튜닝 예정. 2026-09-18에 접수량을 누적 카운터로 바꾸면서 한도가 실질적으로 더 타이트해졌으므로(§20.1과 연동해) 다시 볼 것. 결정 노트: [[2026-09-18-라운드-접수량-누적카운터]] - **이월 누적이 실제로 압박이 되는지 미검증** — 주목도 라운드 분리(2026-09-17) 이후 이월분은 게이지·코인 가산에만 작용한다. 이월을 쌓아두고 매 라운드 한도까지 새로 받는 플레이가 지배 전략이 되지 않는지 확인 필요. 결정 노트: [[2026-09-17-주목도-라운드-분리]] - **상점이 사실상 비어 있음** — 지금 유일한 품목(오염 카드 직접 처리)이 의회 실적 납입(코인 1개=실적 5점, §9.3)과 경쟁이 안 돼 "살 이유가 없다"는 피드백. 자산·소모품 등 3차 품목이 들어와야 근본 해결(§20.2 이후 우선 작업 후보). 코인 납입 환산율 하향은 상점이 채워진 뒤 다시 볼 것 — 지금 건드리면 상점 완성 후 또 바뀌어야 한다. --- ## 2026-09-18 — 외부 플레이테스트 배포 준비 (시놀로지 NAS) + 모바일 실기 대응 **무엇을 왜:** 이제부터 외부 테스터에게 링크를 공유해 피드백을 받기로 해서, "모바일에서 링크만 누르면 플레이되고, 배포는 한 줄로 끝나는" 상태를 만들었다. 기존 NAS 인프라(Web Station nginx + DuckDNS + 인증서)를 그대로 쓴다 — 조사해 보니 서브도메인 DNS·443 포워딩·인증서가 모두 이미 동작 중이었고(구 HTML 프로토타입이 같은 경로로 서빙되고 있었다), 실제 블로커는 두 개뿐이었다. - **서브패스 asset 경로 (배포 시 빈 화면이 되는 블로커)**: Web Station 문서 루트 하위 폴더로 서빙하는데 Vite 기본 `base: '/'`는 asset을 도메인 루트에서 찾아 전부 404가 된다. `base: './'`(상대 경로)로 바꿨다 — 특정 서브패스에 고정되지 않아 폴더를 옮겨도 재빌드가 필요 없다. 로컬에서 `/projectss/` 하위로 서빙해 프로덕션 빌드가 실제로 뜨는 것까지 확인 - **모바일 `100vh` → `100dvh`**: `100vh`는 주소창이 숨은 상태 기준 높이라, 주소창이 보이는 동안 화면 아래 60~100px이 잘린다. `body`가 `overflow:hidden`이어서 스크롤로 닿을 수도 없어 **화면 맨 아래의 "정산하기" 버튼이 가려지는** 실제 문제였다. `vh`는 구형 폴백으로 남겼다. `#root`의 `width: 100vw`도 `100%`로 바꿨다(100vw는 데스크톱 스크롤바 폭만큼 가로 넘침) - **빌드 식별자 표시**: 여러 명에게 며칠에 걸쳐 피드백을 받으면 "어느 빌드였나"가 반드시 꼬인다. `vite.config.js`가 빌드 시각+커밋 해시(`0918-2239·6398599`)를 주입하고 상태 줄 오른쪽에 흐리게 표시한다 — 테스터가 스크린샷만 찍어도 버전이 남는다 - **``·`theme-color`·`description`**: 링크를 공유·북마크할 때 보이는 이름을 게임 제목으로 바꾸고, 모바일 브라우저 바 색을 다크 UI에 맞췄다. 확대 차단(`user-scalable=no`)은 작은 글씨를 읽어야 하는 테스터의 접근성을 해쳐서 넣지 않았다 - **`deploy.sh` + `npm run deploy`**: `vite build` 후 NAS에 올린다. `--dry-run`으로 보낼 파일 목록만 먼저 확인 가능. 배포용 SSH 키(ed25519) 생성, `ssh-copy-id`로 등록 완료 — 이후 비밀번호 없이 배포된다. 실제 배포까지 검증 완료: **https://play.mint-grape.duckdns.org/projectss/** - **배포 과정에서 겪은 삽질 2건, 재발 방지용으로 기록**: 1. `ssh-copy-id` 직후에도 계속 비밀번호를 요구함 → 홈 디렉터리가 `drwxrwxrwx`(777), `~/.ssh`도 777, `authorized_keys`도 777이었다. OpenSSH는 키 소유자 외 그룹/기타 쓰기 권한이 있으면 StrictModes로 그 키를 무시하고 조용히 비밀번호 인증으로 넘어간다 — 클라이언트 쪽엔 에러가 안 보여서 원인 파악이 까다로웠다. `chmod 755 ~ && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys`로 해결 2. 키 인증은 성공했는데(`Authenticated ... using "publickey"`) **rsync만** 항상 `rsync error: rsync service is no running (code 43)`로 실패. DSM 제어판의 "파일 서비스 → rsync 활성화"와 사용자 애플리케이션 권한(rsync 체크)을 둘 다 켜고 `rsyncd.service`가 `active (running)`인 것까지 확인했는데도 동일 에러 — SSH 전송 모드(`-e ssh`)인데도 시놀로지의 `/usr/bin/rsync`가 별도 게이트(아마 daemon 설정의 사용자 화이트리스트)에 걸리는 것으로 보이나, 이 프로젝트 빌드 결과물이 400KB 안팎이라 rsync의 증분 전송 이점이 없어서 원인을 더 파지 않고 **`scp -O`(레거시 exec 프로토콜)로 교체**했다. 이 NAS는 SFTP 서브시스템도 꺼져 있어(`-O` 없는 최신 scp는 "subsystem request failed") `-O`가 필수. `rm -rf "$REMOTE_DIR" && mkdir -p` 후 scp로 옮겨 rsync `--delete`와 같은 "매번 깨끗하게" 효과를 낸다 - iPhone 13 크기(390×664)로 실기 검증: 터치 스와이프 정상(CDP로 실제 터치 입력 전송), 결재 카드·정산하기·합본 버튼 모두 화면 안, 상점·의회 화면도 스크롤 없이 들어감, 실패 요청 0건, 콘솔 에러 0건. 배포 후 공개 URL에서 최신 빌드 asset 해시가 그대로 서빙되는 것까지 확인 ## 2026-09-18 — 라운드 접수량 버그 수정 + 책상/결재 화면 정보 재배치 + 토큰→코인 용어 통일 **무엇을 왜:** 플레이 피드백 4건(주목도 미차감 버그, 상점 빈 상품, 상점 UX 오해, 재화 명칭)을 먼저 원인 분석·해결안으로 정리해 사용자에게 제시하고, 방향이 확정된 항목만 반영했다. 상점 품목 확충은 3차(자산·소모품) 이후로, 코인 납입 환산율 조정은 상점이 채워진 뒤로 보류. - **라운드 접수량 크리티컬 버그 수정**: 합본을 여러 번 하면 라운드가 끝나지 않던 문제 (피드백: "합본을 많이 하면 라운드가 너무 길어진다"). `roundAttention(deskCards, round)`이 책상 카드를 필터링해 매번 다시 합산하는 파생값이라, 합본으로 카드가 사라지면 접수량도 같이 줄어 한도(21)에 다시 도달할 때까지 계속 새로 받을 수 있었다. CoreGameScreen이 직접 들고 관리하는 순수 누적 카운터(`roundIntake`, 라운드가 바뀔 때만 0으로 리셋)로 교체 — 결정 노트: [[2026-09-18-라운드-접수량-누적카운터]] - **DeskBar/CoreSwipeCard 정보 역할 분리**: "이번 라운드 접수량/한도"(카드를 더 받을지 판단)는 결재 화면(CoreSwipeCard)이 전담하고, DeskBar는 "책상에 지금 쌓인 것"(총 주목도, 축별 분포, 게이지·지출 가산)만 보여주도록 재배치. 중복 표시·죽은 CSS(zone 배너 등) 정리. `attentionZone` 판정을 desk.js 단일 함수로 통일해 CoreSwipeCard가 갖고 있던 로컬 중복 로직 제거 - **토큰 → 코인 용어 일괄 변경**: 상점이 본격 가동되면서 "토큰"보다 "코인"이 재화를 직관적으로 떠올리게 한다는 피드백. `core/` 전체(식별자·CSS 클래스·주석·UI 텍스트, 17개 파일)와 기획서 SSOT를 함께 갱신 — §10.4 자산 스키마의 구 3종 토큰 JSON 예시는 3차 미구현 상태라 제외했다. lucide `Coins` 아이콘을 책상 바·상점·의회의 코인 표시에 추가. `--color-token-budget` CSS 변수는 레거시 참조용 컴포넌트가 계속 쓰므로 그대로 두고 `--color-coin` 별칭만 신설(같은 값을 가리킴) — `--color-token-info`는 재화와 무관한 범용 강조색이라 이름을 바꾸지 않았다 - Playwright로 검증: 4장 소멸하는 합본 전후 접수량이 17→17로 불변임을 직접 확인(이전엔 이 케이스가 버그였다), 버스트 임계 정상 작동(주목도 25에서 한도 21 초과 종료) 확인, 전체 페이지 텍스트에 "토큰" 잔존 0건·코인 아이콘 렌더 확인, 콘솔 에러 0건 ## 2026-09-17 — 플레이 피드백 5건 반영 (합본 결재 리뉴얼 후속) **무엇을 왜:** 합본 결재 리뉴얼(같은 날 앞선 작업) 이후 나온 밸런스 피드백 5건. 그중 "결재 카드가 고정으로 등장하는 것 같다"는 실제 버그였다 — 카드 인덱스를 그냥 +1씩 돌려서 CSV 파일 순서 그대로, 매 실행마다 완전히 동일한 순서로 반복되고 있었다(진짜 무작위가 아니라 결정론적 순환). 이게 "위협 축도 거의 등장 안 함" 피드백의 상당 부분을 설명한다 — 테스트할 때마다 같은 초반 카드만 봤을 것이다. 결정 노트: [[2026-09-17-게이지상승-장수기준-복원]] - **결재 카드 셔플 큐 도입**: Fisher–Yates로 섞은 덱에서 앞부터 뽑고, 큐가 비면 다시 섞어 채운다. 한 바퀴 안에서는 같은 카드가 반복되지 않으면서 실행마다·바퀴마다 순서가 달라진다. Playwright로 3번 재로딩해 첫 카드가 매번 다른 것, 15회 연속 뽑기에서 직전 반복 0회 확인 - **게이지 상승 기준을 등급 합계(주목도) → 카드 장수로 재설계** (등급 배율은 유지): 실제 카드 등급이 1~4급에 몰려 있어 등급 합계만으로는 3~4장을 쌓아도 최하 구간(+0.5%)을 못 벗어났다. 장수 구간(1~2장 0.5% → 3~4장 3.0% → 5~6장 6.0% → 7~9장 10.0% → 10장+ 15.0%+)을 1차 기준으로 되돌리고 `축 평균 등급/5` 배율을 곱해 등급도 계속 의미를 갖게 했다. 시뮬레이션으로 검증: 등급6 카드가 쌓이는 축은 12장째에 게임오버, 3장째에 전 구간 대비 6배 점프(0.6%→3.6%) - **위협 축 카드 1개 재배정**: id11 "사이비 종교 인신 공양" 좌측("군사 개입 지시")이 인사 축 이었는데, 고대 신 소환 저지 개입이 인사(HR) 사안일 리 없다 — 위협 축으로 이동(4급→5급). 위협 11→12개 - **완전 무행동 카드 제거**: id15 "전임 국장 비밀 금고"가 좌/우 모두 오염 없는 유일한 카드였다 (결재해도 아무 일도 안 일어남). 좌측("강제 개방 지시")에 대외/6급 부여 — 비자금 발견 시 정치적 위험이라는 기존 `tag_corruption` 태그와도 맞는다. 우측("영구 봉인")은 안전 선택으로 유지 - **"오염 카드 한쪽만 있는 선택지가 많아 초반엔 안전 선택 메리트가 없다"는 피드백은 카드 데이터가 아니라 게이지 곡선 문제로 판단해 별도 수정 안 함** — 위 장수 기준 재설계로 3장 이상 쌓일 때의 손해가 뚜렷해졌으므로, 안전 선택의 가치는 이걸로 회복된다고 보고 카드 재배분은 보류 - Playwright로 셔플·다양성·게이지 표시 전부 재확인, 콘솔 에러 0건 ## 2026-09-17 — 열린 이슈 3건 해소 + 플레이 피드백 4건 반영 **무엇을 왜:** 축별 등급 분포 확인에서 공보 축이 43개 선택지 중 1개뿐인 게 드러났고(대중 공황 게이지가 사실상 죽은 축), 유형 D 부재로 내부 명분이 무용지물이었으며, 혼합 명분은 자리표시자 였다. 여기에 플레이 피드백 4건을 같이 처리했다. 그중 **주목도 미초기화는 게임 진행이 불가능한 크리티컬 버그**여서 설계 결정이 필요했다 — 결정 노트: [[2026-09-17-주목도-라운드-분리]] - **공보 축 보강**: 서사 기준으로 축이 어긋난 선택지 6개를 공보로 재배정(영상 유출 후속, 진정제 배포, 감시망 구축, 전 병력 투입, 시민 포기 폭격, 폭로전). 공보 1→7개, 축 분포 위협11/인사14/공보7/대외13으로 균형 개선. 신규 카드 작성이 아니라 재배정이라 §20.2 범위 밖 - **유형 D(이득 규약) 5종 신설**: 토큰 즉시 지급 / 게이지 완화 / 지출 가산 완화 / 주목도 한도 +8 / 실적 요구치 −20. 후보 등장률 30%, 내부 명분의 강제 상정 대상에 포함 — 이게 내부 명분의 존재 이유다. `gaugeSurchargeOf`·`tokenSurchargeOf` 등을 징벌 전용에서 규약 공용으로 일반화 - **13석 표결 실제 구현**: `tallyVotes`(최대잔여법, 결정적 해시라 개입해도 표가 흔들리지 않음) + `applyVoteSwing`. 혼합 명분이 "직접 통과 지정"에서 §7.3 스펙대로 **1표 이동**으로 바뀌었고, 동점은 스윙 전 득표가 많던 쪽이 이겨 **1표 차에서만 뒤집힌다**. 의회 화면에 예상 득표·표 차· "혼합 명분으로 뒤집을 수 있음/없음" 힌트를 노출 - **주목도 라운드 분리**(크리티컬 버그 수정): 한도 판정은 이번 라운드분, 게이지·토큰 가산은 총계(이월 포함). 카드에 받은 라운드 번호를 기록해 구분. 기존엔 이월 때문에 2라운드가 시작하자마자 버스트가 무한 반복됐다 - **"정산하기" 버튼을 결재 카드 아래로 이동** — 툴바 구석에 있어 핵심 결정 버튼인 걸 모른다는 피드백. 이번 라운드 주목도/한도/남은 여유를 버튼 옆에 같이 표시 - **툴팁 신설**(`InfoTooltip`·`ProtocolChip`): 규약·징벌·명분을 누르면 "정확히 무엇이 막혔는지"를 띄운다. 설명 문구는 UI가 추측하지 않고 `council.js`의 `protocolEffectDetail`· `justificationDetail`이 카탈로그에서 생성 — 예: "「일괄 처리」 족보 사용 불가 / 조건 「같은 축 5장」. 합본 판정에서 제외되어 실적 40·명분 2 손실". 모바일 대상이라 hover가 아닌 클릭으로 연다 - 부수 수정: 이득 규약의 음수 가산이 지출을 할인하지 않도록 `tokenSurcharge`를 0에서 끊음, 좁은 화면에서 의회 감사 행이 잘리던 문제(`flex-wrap`), 툴팁 조사 오류("일괄 처리이(가)") - Playwright로 버스트→상점→의회→2라운드 전체 검증: 2라운드가 0/26으로 리셋되고 이월 23은 별도 표시, 합본→명분 획득→명분 툴팁, 규약 툴팁, 자율 정산 모두 확인. 콘솔 에러 0건 ## 2026-09-16 — 라운드/회기 이층 구조 폐지, 주목도 하드 캡(버스트) 재도입 **무엇을 왜:** 직전 재구현에서 도입한 "라운드(손)+회기(정산·의회 텀)" 이층 구조와 "결재 8건 고정" 방식이 실제 의도와 어긋났다 — 원래는 **라운드마다 정산·의회를 거치고, 그 압박을 합본·상점으로 넘어서는 것**이 핵심 재미였고, 라운드 종료도 고정 건수가 아니라 **주목도가 라운드별 한도(21에서 시작, 라운드마다 증가)를 넘으면 강제 종료, 아니면 자율 종료**하는 블랙잭식 구조여야 했다. 결정 노트: [[2026-09-16-라운드-주목도-하드캡-복원]] - `desk.js`: 고정 경고/초과 임계치(30/40/41)를 없애고 `roundAttentionCap(round)` + 한도 상대적 구간(`normal`/`warning`/`bust`)으로 교체 - `CoreGameScreen.jsx`: `session`/`handNumber` 이층 상태를 단일 `round`로 되돌리고, 결재마다 주목도가 한도를 넘는지 즉시 검사해 초과 시 합본 기회 없이 상점 단계로 강제 전환. 플레이어가 스스로 끝낼 수 있는 "정산하기" 액션 신설 - `DeskBar.jsx`: 주목도를 "현재/한도"로 표시, 정산하기 버튼 추가, 한도초과(bust) 시각 경고 - `CouncilScreen.jsx`: 징벌 규약 5개 초과 시 목록 접기/펼치기 추가 (§9.2 UI 요건 반영) - 기획서 §2(코어 루프)를 단일 라운드 구조로 재작성, §4.2-B를 하드 캡 서술로 교체, §19 결정 완료 사항 표의 "라운드 종료 방식"·"이층 구조" 행을 뒤집힌 결정으로 갱신, §20.1 미결정 사항의 관련 항목 정리 - Playwright로 상신 시 라운드 번호 증가, 상태 표시 라벨(제N라운드) 확인 완료, 콘솔 에러 0건 ## 2026-09-16 — 등급 확장 재구현 + 등급 1·3 데이터 보강, 문서 체계 정비 ## 2026-09-16 — 등급 확장 재구현 + 등급 1·3 데이터 보강, 문서 체계 정비 **무엇을 왜:** 2026-09-15에 서울(Base) PC에서 Remote-SSH로 작업한 등급 1~10 확장·주목도 시스템·5장 포커 핸드·토큰 1종 통합 작업이 커밋 전 연결 끊김으로 유실됐다. 평택(현재 PC) 로컬 체크아웃(`2차 구현 완료` 커밋 시점)에서 전체를 다시 구현했다. 재구현 과정에서 `cards.csv` 등급 재매핑이 등급 1·3을 전혀 생성하지 못한다는 문제를 추가로 발견해 같이 고쳤다 — 결정 노트: [[2026-09-15 ProjectSS 카드등급확장-주목도시스템]] - `core/engine/symbols.js`·`desk.js`·`hands.js`·`council.js`·`shop.js`·`pollutionPool.js` 및 관련 컴포넌트 9종 전체를 등급 1~10 / 주목도 / 5장 포커 핸드(8종, 투페어 신설) / 토큰 1종 기준으로 재작성 - `cards.csv` 43개 선택지, `pollution_pool.csv` 19→27개 항목 등급 재매핑 — (유형, 원본등급) 전단사 매핑으로 등급 1~10 전 구간을 채움 (평균 4.14, 8결재 라운드 예상 주목도 33, §4.3 기준선인 경고구간 30~40에 부합). `pollution_pool.csv`에 등급 1·3 전용 신규 항목 8개 추가(축별 2개씩) - Playwright로 실제 브라우저 구동 확인 — 등급 1·3 카드가 실제 이름·플레이버와 함께 등장하는 것까지 확인, 콘솔 에러 0건 - CLAUDE.md 정비: 흩어져 있던 기획 문서 7종 참조를 `ProjectSS_코어시스템_기획서.md` 단일 참조(§ 매핑 포함)로 교체, Phase 진행 표를 없애고 §17 체크박스가 유일한 진행 상황 원본이 되도록 변경, "결정 노트" 규칙 신설(`T-decision.md` 양식 + DEVLOG 위키링크 연동) - `ProjectSS_코어시스템_기획서.md` §17에 실제 구현 상태 체크(1차 전체 완료, 2차는 상점/명분 개입이 3차·4차 의존성 때문에 부분 완료) ## 2026-09-05 — 플레이테스트 UX 피드백 5건 반영 **무엇을 왜:** 1차 그레이박스를 실제로 플레이한 뒤 나온 문제 5건(책상 정보 부족, 스와이프 레이아웃 겹침, 족보 판정 기준 안 보임, 게이지 상승 체감 안 됨, 선택 서사 부족)을 고쳤다. 결정 노트: [[2026-09-05_core-graybox-ux-feedback]] - `DeskBar`를 축×등급 매트릭스로 확장 + 축 클릭 시 개별 카드 상세 팝업(`DeskDetailPopup`) 추가 - `CoreSwipeCard` 레이아웃 변경 — 좌/우 예고를 카드 위 오버레이에서 상단 고정 슬롯으로 이동해 결재 카드 본문과 겹치지 않게 함 - `HandGuidePopup`(족보표) 신규 — 이 게임 기호로 족보 조건·예시를 보여줌 - 게이지 상승 기준을 "카드 장수"에서 "등급 가중 오염 압력"으로 변경 (이후 2026-09-15 결정으로 "주목도" 개념으로 흡수·재조정됨) - `pollution_pool.csv`를 처음으로 실제 연결 — 오염 카드가 축 라벨이 아니라 실제 이름·사연을 갖게 됨 - 부수적으로 `cards.csv` 등급 3~4 선택지 6곳 추가(당시 1~4 스케일 기준) ## 2026-09-05 — 구현 우선순위 2차 완료 (§17: 상점·규약·실적 감사·명분) 라운드 구조(결재 8건 → 상점 → 의회 → 다음 라운드) 도입. `ShopScreen`·`CouncilScreen`· `core/engine/council.js`·`core/engine/shop.js` 신규. Playwright로 라운드 전체 구동 확인, 콘솔 에러 0건. 플레이는 했지만 이 시점엔 피드백 정리 전이었음(다음날 위 피드백으로 이어짐). ## 2026-09-05 — 구현 우선순위 1차 완료 (§17: 기호 체계·책상·족보·토큰) `client/src/core/` 신설 — 기존 `components/`·`engine/`(GameScreen.jsx 중심 구조)는 참조용으로 남기고 새 진입점으로 전환. 축 인장(lucide Tornado/Hand/Megaphone/Stamp) + 등급 점 표기, 책상 상시 노출 UI, 3장 족보 판정(당시), 합본 기반 토큰 산출 구현. ## 2026-09-04 — 코어시스템 기획서 기준 신규 개발 착수 `rework/combined-filing` 브랜치 생성. 기존 문서 전체를 `old/2026.09.04/`로 이동하고 `ProjectSS_코어시스템_기획서.md`를 단일 원본으로 도입 — 기존 코드베이스는 참조용으로만 남기고 이 문서 기준으로 신규 개발한다는 방침 확정.