diff --git a/docs/superpowers/specs/2026-08-12-studio-page-design.md b/docs/superpowers/specs/2026-08-12-studio-page-design.md new file mode 100644 index 0000000..05fa662 --- /dev/null +++ b/docs/superpowers/specs/2026-08-12-studio-page-design.md @@ -0,0 +1,238 @@ +# `/studio` — 생성 공장을 보여주는 페이지 설계 + +2026-08-12 + +## 왜 만드는가 + +`studios`는 `content/projects.json` 39개 항목 중 **기술 설명이 가장 두꺼운 항목**이다. +5모달리티 MCP 서버, 공유 커널, GPU 중재, SQLite 자산 스토어, 히스토리 보존 subtree +병합, 6층 지문, 320개 넘는 테스트. 최근 투자의 대부분이 여기 들어갔다. + +그런데 사이트에서 이 항목은 **사실상 보이지 않는다.** + +| 필드 | 값 | 결과 | +|---|---|---| +| `featured` | `false` | 홈에 안 뜬다 | +| `private` | `true` | 저장소 링크가 렌더되지 않는다 (Private 규칙) | +| `website` | 없음 | 갈 곳이 없다 | +| `screenshot` | 없음 | 이미지가 없다 | + +그래서 `hasIndexablePage()`가 `false`가 되고, 2026-08-05에 넣은 얇은 페이지 필터가 +**사이트맵에서 제외한다.** 가장 큰 투자가 가장 안 보이는 것이 된다. + +**필터는 옳다. 고쳐야 할 것은 항목이다.** 지금 이 항목은 말만 있고 보여줄 것이 없다. + +## 이 페이지가 하지 않는 것 — 설계의 출발점 + +**AI 생성 이미지를 격자로 늘어놓지 않는다.** + +2026년에 생성 이미지는 변별력이 없다. 누구나 뽑는다. 채용담당자나 잠재 의뢰인에게 +예쁜 생성물 격자는 잘해야 무의미하고, 나쁘면 "AI 슬롭을 포트폴리오에 올린 사람"으로 +읽힌다. **그림은 증거가 아니다.** + +증거가 되는 것은 **공장**이다. 구체적으로 세 가지다. + +1. **로컬에서 돈다.** krea2, Hunyuan3D 2.1, ComfyUI, GPT-SoVITS는 API 호출이 아니라 + 본인 RTX 4080에서 도는 자체 호스팅 모델이다. Midjourney 구독과 다른 층위다. +2. **파이프라인이 있다.** 생성 → 기계 게이트 → 에이전트가 썸네일을 직접 보고 판정 → + 판정이 DB로. 사람이 눈으로 고르는 게 아니라 기계가 밟는다. +3. **계보가 있다.** 3D 자산이 *이 이미지에서* 나왔다는 사실이 DB에 있다. + +따라서 이 페이지의 주인공은 **결과물이 아니라 결과물에 붙은 기계의 기록**이다. +그림은 기록을 걸기 위한 못이다. + +## 페이지 구조 + +``` +1. 헤드 한 줄 정의 + 배지(5모달리티 · 로컬 GPU 1대 · 320+ 테스트) +2. 관통 한 대상을 이미지 → 3D → 영상으로 통과시킨 3홉, 각 홉에 기계 기록 +3. 작동 방식 생성 → 게이트 → 검수 → 판정, 네 단계 +4. 안에 든 것 커널·MCP 서버·갤러리·지문·테스트 +5. 나가는 길 /projects/studios · /hire +``` + +### 2. 관통(the walk) — 이 페이지의 전부 + +**한 대상을 골라 세 모달리티를 통과시키고, 각 홉에 그 공장이 실제로 기록한 값을 +붙인다.** 격자 대신 이것 하나다. + +대상은 **황동 칼라와 산성 녹색 잉크 패드가 달린 공업용 검수 스탬프**다. 고른 이유가 +두 가지 있다. + +- 이 공장의 실제 동작이 **판정(approved / rejected)** 이다. 스탬프는 그 은유를 물건으로 + 만든 것이라 페이지의 주장과 소재가 같은 말을 한다. +- 단일 오브젝트 · 하드서피스 · 명확한 실루엣이라 Hunyuan3D 소스로 적합하다 + (3/4 상부뷰 · 흰 배경 · 균일한 조명 권장을 그대로 만족한다). + +각 홉 카드에 들어가는 값은 **전부 실제 생성 기록에서 온다. 지어내지 않는다.** + +| 홉 | 보여줄 것 | 붙일 기록 | +|---|---|---| +| 1. 이미지 | 최종 이미지 | 모델 `krea2` · seed · 게이트 통과(해상도 · stddev) · 검수 판정과 사유 | +| 2. 3D | GLB(클릭 시 인터랙티브) | 모델 `Hunyuan3D 2.1` · 소스 = 홉 1의 이미지 · faces / verts / bbox · 파일 크기 | +| 3. 영상 | 짧은 무음 루프 | 모델 · 초 · 소스 = 홉 1의 이미지 | + +홉 1에서 **후보 4장 중 2장을 반려한 사실과 그 사유를 그대로 싣는다.** 반려 기록이 +있어야 판정이 장식이 아니라 실제로 작동한다는 게 보인다. 성공만 늘어놓은 파이프라인은 +파이프라인이 아니라 갤러리다. + +### 정직성 — 타협하지 않는 세 가지 + +1. **모든 자산에 생성물임을 표시한다.** 제품 UI는 오직 실제 스크린샷으로만 보여준다는 + 기존 규칙(`Project.screenshot` 타입 주석에 박혀 있다)이 여기에도 적용된다. 생성 이미지를 + `studios`의 `screenshot`에 넣지 않는다. 생성 아트를 **생성 아트로** 보여주는 것은 + 정직하고, 제품 UI인 척하는 순간 Critical 결함이다. +2. **5모달리티 중 3개만 보여줄 수 있다.** 음성·음악 스튜디오는 이 세션에 붙어 있지 + 않고, 애초에 지면에 담을 형식도 아니다. 페이지는 **"세 축을 보여준다"고 명시한다.** + 5개를 다 증명한 것처럼 쓰지 않는다. +3. **숫자는 실측만.** `320+ 테스트`처럼 `projects.json`에 이미 있는 값만 쓴다. 게이트 + 수치·폴리곤 수·파일 크기는 실제 생성 응답에서 옮긴다. + +### 3. 작동 방식 + +`projects.json`의 설명을 네 단계로 편다. 새 사실을 추가하지 않는다. + +1. **생성** — Claude가 MCP 툴을 직접 호출한다. 프롬프트를 사람이 붙여넣는 게 아니다. +2. **기계 게이트** — 해상도·분산 같은 값으로 명백한 실패를 먼저 떨어뜨린다. +3. **검수** — 응답에 썸네일이 이미지 블록으로 붙어 오고, 에이전트가 **그것을 직접 보고** + 프롬프트 부합과 아티팩트를 판정한다. +4. **판정 기록** — `approved`/`rejected`와 사유가 SQLite로 들어가고 갤러리에 배지로 뜬다. + 에이전트의 판단이 라이브러리로 흘러 남는다. + +## 기술 설계 + +### 라우트 + +`src/app/[locale]/studio/page.tsx`. `/hire`·`/about`과 같은 골격 — +`generateMetadata` + `setRequestLocale` + `PageTransition`, `revalidate = 3600`. + +경로는 `/studio`(단수)다. 프로젝트 슬러그는 `studios`(모노레포)지만, 페이지는 목록이 +아니라 장소다. + +### 내비게이션 — 넣지 않는다 + +현재 7개이고, 8월 6일에 영어 라벨이 768~887px에서 줄바꿈해서 브레이크포인트를 `lg`로 +올린 참이다. **8번째를 넣으면 그 수정을 되돌리는 셈이다.** 대신 세 곳에서 들어온다. + +- 홈(`LedgerHome`) — "지금 만들고 있는 것" 자리 +- `/projects/studios` 상세 페이지 +- 사이트맵 (priority 0.7) + +### 3D 표시 — 클릭 후 로드 + +`three` / `@react-three/fiber` / `@react-three/drei`가 이미 의존성에 있다(`/play`가 쓴다). +**하지만 `/studio`가 그 번들을 자동으로 끌면 안 된다.** Pretendard LCP를 잡아 96~98까지 +올려둔 성적을, 공유용으로 만드는 페이지에서 되돌릴 수는 없다. + +- 기본 상태: 정적 포스터 이미지 + "3D로 보기" 버튼 +- 클릭 시에만 `next/dynamic`으로 뷰어와 GLB를 가져온다 +- 즉 **누르기 전까지 비용 0** + +인터랙티브 모델을 놓는 이유: 정적 렌더는 "그림이 있다"고 말하고, 돌려볼 수 있는 +모델은 "자산이 있다"고 말한다. `이걸로 뭘 할 수 있는가`에 답하는 것은 후자다. + +### 영상 + +라이브러리 원본은 20초 세로 25~76MB라 웹에 못 올린다. **ffmpeg로 3~5초 · 무음 · +강압축**해서 `public/`에 커밋한다. 목표 1.5MB 미만. + +- `