← 목록
기타 2026-06-13 6KB 읽기 6분

북스 e-book 프레임 안정화 + 서고 정리 + 크라우니AI 말걸기 핸드오프

개요

book.crowny.org(:9931, 한선씨 책서버) 작업 계속. 모바일·태블릿·PC에서 안정된 e-book 리딩 프레임으로 정리하고, 서고(도서관)를 정돈했으며, 크라우니 AI(crowny.org:9852)가 "책 읽어보시겠어요?"라고 말걸면 받아주는 핸드오프 진입점을 신설했다.

울트라 워크플로(모델분업: 설계=Opus×2, 한선씨/CSS=Sonnet×2, 착지/카피=Haiku×1) 병행. 통합·컴파일·라이브검증은 메인 세션(Opus).

무엇을 했는지

1. 서고 정리 (library cleanup)

  • 고아 디렉토리 6개 아카이브(되돌림 가능): 웹/ilcrowny-{om,ta,ti,um} + 구 웹/리더/웹/_archive_orphans_20260613/. (ilovecrowny 4버전 통합 이전의 미참조 잔재)
  • 서고는 SSOT data/라이브/책목록.jsonbuild-library.js 데이터주도. 발간 3권(ilovecrowny/crownyai/book3) + enterprise 슬롯. 재생성 멱등 확인.

2. e-book 프레임 안정화 (모바일/태블릿/PC)

  • clamp() 유체 타이포: 고정 px 브레이크포인트 점프 제거(320~1440px 매끄럽게). .reader .art, .reader h1, 서고 .hero h1, 카드 등 전반.
  • safe-area: viewport-fit=cover + env(safe-area-inset-*) → 노치/홈인디케이터 기기에서 테마버튼·진행바·본문·하단컨트롤 잘림 방지.
  • 글자크기 A−/A+ 위젯: localStorage 영속(--fz 0.85~1.40), 챕터·통독 리더(body.rd)에서만 노출, 서고·목차에선 숨김.
  • 적용 방식 = append-override 블록(CSS 캐스케이드 활용) — 17개 수술편집 대신 통합 블록을 CSS 끝에 append해 회귀 위험 최소화. build-reader.js(리더), build-library.js(서고), welcome.html 전부 반영.
  • 3책 전권 재빌드 + 서고 재빌드. 산출물 검증(clamp 14·safe-area 4·fontctl·body.rd) GREEN.

3. 크라우니AI 말걸기 핸드오프 (신규 기능)

  • GET /welcome (착지 게이트) — ?from=ai&book=&v=&q=&level= 쿼리를 받아 따뜻한 착지 페이지(welcome.html) 서빙. "크라우니 AI가 이 책을 권했어요" + 추천 책/버전 카드(클라이언트 JS가 책목록.json 읽어 채움) + "지금 읽기" 버튼 → 리더. 폴백=서고. (즉시 302 대신 따뜻한 한 박자)
  • GET/POST /api/book/recommend{level,interest,q}{book,version,route,title,desc,reason} JSON. 책마다 버전키가 달라(ilovecrowny=ti/om/ta/um, crownyai=kid/fast/general/expert, book3=kid/general/expert) 2단계 매핑(관심→책, 레벨→버전) + 폴백체인. 항상 200(말걸기 신뢰성).
  • crowny.org AI 연동 — philosophy.js 시스템 프롬프트에 핸드오프 링크 가이드 추가: 책 권할 때 [책 보러 가기](https://book.crowny.org/welcome?from=ai&level=<레벨>&q=<관심>), ASCII 토큰(level=kid|fast|general|expert, q=ai|money|world)만 넘기고 책·버전 선택은 책방이 일임(매핑 SSOT 일원화). 호기심 보일 때만 권유.

검증 (라이브 GREEN)

  • 추천 매핑 6/6 패리티 → 전부 실재 리더 200 (q=ai/kid→crownyai kid, q=world/expert→ilovecrowny um, level=fast→crownyai fast 등)
  • /welcome 200(14344B 착지페이지, "크라우니 AI가"+"지금 읽기") — 로컬 9931 + 게이트웨이 book.crowny.org:8443 SNI
  • 발간 3권 reader/full/version 전 동선 200 (로컬+게이트웨이)
  • 프레임 게이팅: 챕터 body.rd→fontctl 노출, 목차/서고 → .fontctl{display:none} 숨김

관련 파일

  • 서버(한선씨): /Users/ef/crowny-agent/책서버.한선 (신규 라우트: 라우트_환영착지, 라우트_추천 + 헬퍼 쿼리제거/쿼리값/관심에서책/레벨에서버전/버전유효인가; 정적인가 /welcome 제외; 라우팅 디스패치)
  • 배포 캐시: /Users/ef/crowny-data/bin/bookagent.toau (1.86MB, launchd com.crowny.bookagent, 원자스왑+kickstart -k)
  • 착지: /Users/ef/crowny-agent/웹/welcome/index.html (14.3KB, 파일응답 단일읽기 — 16384B 한계 이내 유지 필수)
  • 빌드: 웹/build-reader.js(append-override CSS + fontctl), 웹/build-library.js(library.css 교체)
  • AI 연동: /Users/ef/crowny-ai/engine/philosophy.js (핸드오프 링크 가이드)
  • 추천 매핑 데이터: /Users/ef/crowny-agent/data/라이브/추천매핑.json
  • 백업: 책서버.한선.bak.handoff_20260613, build-reader.js.bak.frame_20260613, build-library.js.bak.frame_20260613, bookagent.toau.bak.handoff_20260613

함정/교훈

  • 신호는 한선씨 예약어 — bare 변수/매개변수명 불가("변수명 기대" 컴파일에러), 복합어(관심신호)는 OK → 단서로 회피. (메모리 feedback_hanseon_reserved_sinho + 가드레일 반영)
  • HTTP응답_JSON(코드,데이터)는 내부에서 JSON생성(데이터) 호출 → 라우트에서 JSON생성([...])로 또 감싸면 이중인코딩. 평면 [키,값,...] 배열을 직접 전달.
  • 소스 변경 후 재컴파일 필수 — 라우트_환영착지를 302→파일서빙으로 바꾼 뒤 재컴파일 없이 옛 toau 배포해 /welcome이 302 반환. 별도 포트 스모크테스트로 포착 후 재컴파일·재배포.
  • 정적인가()가 /welcome을 정적(1)으로 판정하면 메인루프가 라우팅 전 가로챔 → 시작하는가(경로,"/welcome")→반환 0 추가 필수. 쿼리스트링은 매칭용 경로NQ로 제거하되 쿼리값 파싱엔 raw 경로 전달.

잔여 이슈

  • welcome.html이 16384B(읽기 한계)에 근접(14.3KB) — 더 커지면 .pN 스트리밍 또는 정적스트리밍 경유로 전환 필요.
  • /api/book/recommend의 desc 필드는 빈문자(""). 착지페이지는 책목록.json에서 desc를 직접 읽으므로 무관하나, 프로그래매틱 호출자용으론 추후 책목록.json 조회해 채울 여지.
  • AI 말걸기 카피의 레벨/관심 추론은 프롬프트 가이드 수준 — 실제 대화에서 토큰 분류 품질은 운영 누적으로 관찰.