소셜 생성기 착수 프로세스

소셜 하나를 옮길 때 무엇을 순서대로 하고 무엇을 물어야 하는지를 담았습니다. 이번 소셜의 실제 결정은 착수 문서가 따로 갖습니다.

§1이 페이지를 언제 여나

이 절이 답하는 것 — 언제 열고, 무엇을 하면 끝나는가.

소셜 하나를 착수하기 직전에 엽니다. X 를 옮기면서 실제로 밟은 순서를 그대로 적어 두었고, 그때 대화로만 나왔던 판단들을 §4 로 끌어냈습니다.

이 페이지는 바뀌지 않습니다. 소셜마다 바뀌는 것 — 그 소셜에서 실제로 무엇을 결정해야 하는지 — 은 별도 착수 문서가 갖습니다.

이번 소셜의 결정은 여기에

Reddit 착수 문서 — 결정 9건

고르면 답이 문장으로 조립됩니다. 그대로 돌려주시면 §2 의 단계 2 부터 진행됩니다.
다음 소셜은 같은 자리에 {social}-kickoff.html 로 만듭니다.

규칙과 역할이 다릅니다

guides/social-generator-rubric.md(R-1 ~ R-18)는 무엇을 지켜야 하나입니다. 구속력은 거기에만 있습니다.

이 페이지는 어떤 순서로 하고 무엇을 물어야 하나입니다. 규칙을 다시 설명하지 않고, 어느 단계에서 어느 규칙을 훑는지만 가리킵니다.

§2프로세스 6단계

이 절이 답하는 것 — 순서가 어떻게 되고, 사람 승인이 걸리는 지점이 어디인가.

단계 0 근거 읽기 audit · 기존 fetcher 단계 1 계획서 초안 결정 목록을 뽑는다 단계 2 소셜 문서 {social}.md 확정 단계 3 선행 작업 스키마 · 타입 · classify 단계 4 구현 · 테스트 생성기 + 회귀 단계 5 전수 점검 루브릭 23항목 사람 승인 착수 문서 사람 리뷰 버그 점검 이후 커밋
사람이 멈추는 곳은 둘뿐입니다 — 착수 전 결정(§5)과 구현 후 리뷰. 나머지는 이어서 굴러갑니다.
단계산출물그 단계에서 훑는 규칙
0없음 — 읽기만§3 참조. 여기를 건너뛰면 이미 있는 답을 다시 구한다
1{social}-kickoff.html
결정 카드 + URL 매핑표 + 필드 배치표
§4 의 결정 축을 그 소셜에 대입해 답해야 할 것만 남긴다. 표 둘의 규격은 §4 끝
2docs/features/social-generator/{social}.md결정 로그 · URL 종류별 산출 · 필드 매핑 · 확인 항목
3스키마 · 타입 · classify 변경§5 체크포인트. 빠뜨리면 mongoose 가 조용히 버린다
4생성기 + 단위 테스트R-1 ~ R-18 전부
5점검 결과루브릭 체크리스트 23항목 + 실물 Writer 통과 확인
X 에서 단계 5 가 실제로 잡은 것

자기 자신을 인용하는 트윗에 루프가 끝나지 않아 66초 만에 힙이 터졌습니다. 단위 테스트 23개는 전부 통과하고 있었습니다 — 정상 입력만 넣었기 때문입니다.

그래서 단계 5 는 "테스트가 초록인가" 가 아니라 적대적 입력을 직접 넣어 보는 것입니다. 순환·빈 문자열·한쪽만 있는 응답이 그 축입니다.

§3단계 0 · 근거 읽기

이 절이 답하는 것 — 무엇이 어느 파일에 이미 있고, 건너뛰면 무슨 손해가 나는가.

어디무엇이 있나X 에서 실제로
scaffold/{social}.json
→ liveTests
유료 실호출 원문. 요청 URL·응답 본문·그때 확정한 것🔴 안 보고 실호출을 다시 요청했다. 중첩 author 가 33키라는 것도, 정지 계정 응답 모양도 이미 거기 있었다
scaffold/{social}.json
→ objectFields[]
필드별 keep/skip/key 판정과 traderValue 등급skip 의 근거가 "응답에 존재하나 fetcher 미사용" 이라 가치 판단이 아님을 발견 → X-8
scaffold/{social}.json
→ urlPatterns[]
URL 형태별 관측 건수trending 82건을 발견해 unknown 에서 건져냈다
qna/{social}.md사람이 내린 판정과 그 이유trending 을 unknown 으로 두기로 한 판단의 근거
sources/{social}.html위 JSON 을 사람이 읽는 형태로 렌더한 것. 필드마다 변동성·파싱 상태·최종 결정·트레이딩 유용성 네 칸이 한 줄에 보인다. 부록에 미채택 대안 소스의 raw 스키마가 있다🔴 YouTube 에서 이 표에 없어서 안 봤다. 사람이 지적해 발견됐다. 부록에서 apify 전용 필드(channelBannerUrl·isChannelVerified)를 찾았고, 그것이 "Data API 로는 못 얻는다" 의 근거가 됐다
{social}/{social}.types.tsfetcher 가 이미 주는 것. 두 경로의 필드 수를 여기서 센다R-18 판정의 입력. YouTube 는 7 vs 2 가 여기서 나온다
⚠️ 덤프가 잘려 있을 수 있습니다

audit 이 스스로 경고한 패턴입니다 — "기존 문서 덤프가 ... 로 절단돼 있어 놓치고 있었음(IG alt · TikTok isSlideshow 와 동일 패턴)".

X 에서 또 나왔습니다. 프로필 응답의 entities{...} 로 잘려 있어서 그 한 필드 때문에 실호출 1건이 필요했습니다. 값이 ...{...} 로 끝나면 그 자리는 "확인 안 됨" 으로 셉니다.

⚠️ 둘이 어긋나면 JSON 이 맞습니다

sources/{social}.htmlscaffold/render.py 가 JSON 에서 만들어 내는 렌더 결과입니다. 그런데 자동 재렌더가 없어서, JSON 을 고쳐도 HTML 은 예전 그대로 남습니다.

YouTube 에서 실제로 갈렸습니다. 이미지 자산 작업이 JSON 의 썸네일 판정을 remove 에서 "재검토 · top-level 대상" 으로 바꾸고 영상 썸네일 행을 새로 넣었는데, HTML 은 8일 전 상태라 그 행이 아예 없었습니다. HTML 만 봤다면 이미지 관련 결정을 통째로 못 봤을 것입니다.

그래서 판정과 필드 목록은 JSON 에서 읽고, HTML 은 한눈에 훑는 용도와 부록(미채택 소스 raw 스키마) 때문에 엽니다. 부록은 JSON 에도 있지만 HTML 쪽이 읽기 쉽습니다.

§4매번 반복되는 결정 축

이 절이 답하는 것 — 소셜이 바뀌어도 똑같이 물어야 하는 것들.

단계 1 에서 이 일곱 줄을 그 소셜에 대입해 착수 문서의 결정 목록을 만듭니다. 이미 답이 정해지는 축은 빼고, 사람이 골라야 하는 것만 남깁니다.

결정 축무엇을 묻나X 는 이렇게 답했다
fan-out 범위한 URL 이 객체 몇 개가 되나인용 사슬을 깊이 2까지 편다. 묶음 1~3개, 추가 호출 0건 (X-1)
딸려오는 객체의 채워짐
R-18
같은 객체를 만드는 두 경로가 같은 필드를 내나공짜로 통과했다 — 트윗의 author 가 33키 완전 프로필이었다. 다른 소셜은 대개 통과 못 한다
비객체 URL객체가 아닌 주소를 어떻게 끝내나검색·intent·trending 을 호출 0회로 행 1건씩 만든다 (X-10~12)
비용·게이트유료면 누가 판정하나커뮤니티가 20 credits 라 opt-in. 생성기가 스스로 판정한다 (X-4)
실패 어휘FetchStatus 가 필요한가SUSPENDED 신설. 정지와 미존재는 재시도 정책이 갈린다 (X-3)
data최상위가 아닌 값을 뭘 담나스레드 3종. 소셜 원래 이름 그대로 (X-6 · G-7)
보조 호출실패를 흡수해도 되나trending 제목만 흡수 — 실패해도 시각이 남기 때문 (R-15 예외)
이미지 자산
2026-08-10 신설
어느 이미지를 어느 자리에 매핑하나profilePictureavatarUrl, mediamediaUrls. 8소셜이 전부 이미지 필드를 갖는데 이름이 다 다릅니다avatar·iconImg·profilePicUrl·thumbnails·iconUrl. fetcher 는 원본 이름을 유지하고 통일은 여기서만 일어납니다
지표 그릇
2026-08-10 신설
*MetricsInput자리가 있나followers 는 있었습니다. following·contentCount조회축이 아니라 data 로 내렸습니다 (X-13). 팔로워류가 소셜마다 fans·followersCount·subscriberCount 로 갈리는데 그릇은 followers 하나입니다
답을 고를 때 함께 재는 것

축마다 선택지를 나열하는 것으로는 부족합니다. X 에서 결정을 가른 것은 늘 숫자 하나였습니다 — trending 82건, 커뮤니티 20 credits, quoted_tweet 의 33키, 관측 0건.

그래서 착수 문서의 선택지에는 그 숫자를 함께 적습니다. 없으면 단계 0 으로 돌아가 찾습니다.

착수 문서에 함께 넣는 표 둘

결정 카드만으로는 부족합니다. 카드는 사람이 이미 문제라고 알아챈 것만 담기 때문입니다. 그래서 착수 문서에는 카드와 함께 표 을 넣습니다. 순서가 있습니다 — 무엇이 만들어지는지가 정해져야 그 객체의 필드가 어디로 가는지를 정할 수 있습니다.

① URL 매핑표 — 무엇이 들어오고 무엇이 되나

그 소셜로 들어올 수 있는 URL 형태를 전부 늘어놓고, classify() 가 어떤 sourceType 으로 가르는지, 그래서 어떤 객체가 만들어지는지까지 잇습니다. 칸은 URL 형태 · 관측 건수 · sourceType · sourceKey · 무엇이 되나 · 걸린 결정 여섯입니다.

관측 건수 칸을 비우지 않습니다

결정을 가르는 것이 늘 그 숫자였습니다. YouTube 에서 playlist 를 0건 으로 확인하고 권장안이 뒤집혔습니다 — 0건짜리를 위해 ContentSubtype 어휘를 늘릴 이유가 없기 때문입니다. X 에서 trending 을 살린 근거도 같은 칸의 82건 이었습니다.

확정된 뒤에는 이 표에 호출 수 · 묶음 개수 · rootRef · status 가 붙어 {social}.md"URL 종류별 산출" 절이 됩니다(x.md §4 가 그 형태입니다). 착수 시점에는 아직 결정이 안 나서 그 네 칸을 채울 수 없으므로, 여기서는 여섯 칸까지만 만듭니다.

② 필드 배치표 — 각 값이 스키마의 어디로 가나

fetcher 가 주는 값을 하나도 빠짐없이 늘어놓고, 각각이 스키마의 어느 자리로 가는지 적습니다. 객체마다 표 하나씩 만들고, 각 표를 세 구역으로 나눕니다.

구역무엇이 들어가나판정 기준
top-levelplatformKey·displayName·bio·outboundUrls·avatarUrl 같은 스키마 본체 필드소셜이 바뀌어도 같은 뜻인 값. 자리 이름이 이미 정해져 있습니다
metrics*MetricsInput 에 자리가 있는 수치독립적인 조회·정렬·비교 축인가. 숫자라서가 아닙니다 — following 은 숫자인데 data 입니다
data그 소셜에서만 뜻이 통하는 부가값키 이름은 소셜 원래 필드명 그대로 (G-7)
이 표가 실제로 잡아내는 것

YouTube 에서 배치표를 짜자마자 결정 카드에 없던 문제 넷이 한꺼번에 드러났습니다. subscriberCount 가 들어갈 이름이 미정이고, 채널 누적 viewCount갈 자리가 아예 없고, handle영구히 비고(핸들을 주는 필드가 audit 에서 remove 됐습니다), 아바타는 audit 판정이 아직 remove 인 채였습니다.

넷 다 "빠진 자리" 라서 카드를 쓰는 단계에서는 안 보입니다. 빈칸은 늘어놓아야 보입니다.

표의 빈칸이 곧 §5 의 작업 목록입니다

배치표에서 "자리 없음" 이 나온 행은 그대로 선행 작업이 됩니다 — 입력 계약에 필드를 더하거나, 그 값을 버리기로 정하거나 둘 중 하나여야 하고, 정하지 않고 넘어가면 mongoose 가 조용히 버립니다.

§5선행 작업 체크포인트

이 절이 답하는 것 — 스키마에 없는 것을 더할 때 함께 고쳐야 하는 자리.

한 곳만 고치면 조용히 틀립니다. X 에서 AccountDataInput 을 빠뜨렸다가 나중에 발견했습니다. 입력 계약에 필드가 없으면 mongoose strict 가 값을 조용히 버립니다 — 예외도 로그도 없습니다.

무엇을 고쳐야 하는지는 §4 의 배치표가 이미 말해 줍니다. 표에서 "자리 없음" 으로 남은 행이 전부 여기의 입력입니다 — 새로 만들 필드가 없으면 이 절은 통째로 건너뜁니다.

새 필드를 더할 때

새 종류·상태를 더할 때

생성기를 다 만든 뒤

규칙의 정본은 guides/social-generator-rubric.md(R-*), 근거는 docs/features/social-generator/decisions.md(G-*), 소셜별 결정은 docs/features/social-generator/{social}.md 입니다. 이 페이지는 소셜이 바뀌어도 그대로입니다. 이번 소셜의 결정은 docs/features/social-generator/{social}-kickoff.html 가 갖고, 확정되면 {social}.md 로 옮겨 적습니다.