외사 리서치 수집 파이프라인 구조 재설계
1. 이번 설계의 기준
- 목적: 매일 05:45 수집이 한 번 빠져도, 놓친 리포트를 나중에 회수하고, 무엇을 놓쳤는지 사후에 증명하고, 브라우저 장애가 5개 하우스 동시 장애로 번지지 않게 만드는 것.
- 절대 유지할 것
- 골드만 요청 상한 유지
blocked.json유지- 자동 로그인 확대 금지
- 외부 재배포 금지
- 용어
- API(Application Programming Interface): 브라우저 대신 서비스가 제공하는 공식 호출 방식
- CDP(Chrome DevTools Protocol): 크롬을 원격 조종하는 디버그 연결 방식
- JSONL(JSON Lines): 문서 1건당 한 줄씩 적는 텍스트 형식. 부분 확인과 압축이 쉬움
2. 현재 코드와 상태에서 확인한 사실
2-1. 현재 구조
- 오케스트레이터:
scripts/collect_daily_archive.py - 저장 계층:
scripts/archive_common.py - 분류 규칙:
scripts/report_routing.py - 브라우저 세션 관리:
scripts/broker_session_manager.py - 세션 워머:
scripts/warm_broker_sessions.py - 실행 흔적 저장:
runs/<날짜>/<하우스>/... - 전역 보관 색인:
data/archive_index.json
2-2. 2026-08-12 현재 실측
data/archive_index.json항목 수: 1,330건data/archive_index.json크기: 약 2.38MB- 저장소 사용량
raw/: 약 808MBruns/: 약 547MBdata/: 약 3.7MBruns/20260812/기준 목록 아티팩트 크기- 노무라
listing-054550.json: 약 1.96MB - HSBC
listing-054609.json: 약 30KB - 나머지 6곳
portal-latest.json: 249B ~ 1.1KB 수준 요약본
2-3. 결함 A 관련 추가 확인
- HSBC는 현재 코드가 날짜 조건을 보내지 않음.
RowsPerPage/MaxNumberOfRows만 바꿈. - 2026-08-12 읽기 전용 확인 결과
rows=100→ 100건, 가장 오래된 발행일2026-08-10rows=150→ 150건, 가장 오래된 발행일2026-08-07rows=200→ 200건, 가장 오래된 발행일2026-08-07rows=300→ 300건, 가장 오래된 발행일2026-08-06- 같은 확인에서
includepaging=true,page=2,start=101,offset=100은 응답 건수·날짜 범위를 바꾸지 못함. - BofA는 현재 코드상 날짜·페이지 인자를 쓰지 않음. 다만 현재 열린
https://markets.ml.com/high-grade탭 안에 Advanced Search링크(/researchlibrary/advancedsearch)searchKey- 숨은
formDate - HTML/PDF 리소스 URL hidden field 가 보임. 즉 검색 UI 흔적은 있으나, 실제 날짜/페이지 파라미터는 이번 확인에서 확정 못 함.
- 모간스탠리는 현재 코드가 홈 카드와
MorningSummary만 읽음. - 인증된
portal-content-service/content/Home?...응답: 200, 섹션 9개 - 인증된
portal-content-service/content/auto/Home?...응답: 200, 섹션 4개 - 카드 수는
Home2/5/0/7/4/7/3/3/7,MorningSummary6개 수준 - 홈 콘텐츠 API는 확인됐지만 날짜/페이지 검색 API는 이번 확인에서 확정 못 함.
2-4. 결함 C 관련 추가 확인
- 현재
broker_session_manager.py는 여전히 - 씨티, 모간스탠리, 골드만, TD, 바클레이즈를 포트 9227 / 프로필
citi-velocity에 묶음 - BofA만 9233 전용
- 2026-08-12 현재 프로필 크기
citi-velocity: 3.0GBgoldman-marquee: 1.5GBbofa-markets: 165MBhsbc-research: 136MBnomura-now: 163MBmatrix-ms: 12MBciti-velocity내부 큰 항목Default/Cache: 951MBDefault/Extensions: 1.2GBDefault/Code Cache: 300MBDefault/Service Worker: 170MB- 가장 큰 확장 폴더는 366MB, 329MB 두 개가 확인됨
warm_broker_sessions.py는 현재 탭/웹소켓 상태 점검과 알림만 하고 재시작은 하지 않음
3. 결함 A 설계안 — 백필 능력의 명시화와 자동 재시도 구조
3-1. 설계 목표
- 하우스별로 지금 코드가 실제로 가능한 백필 범위와 포털 잠재 능력의 확인 상태를 분리해 기록
- 백필 요청이 능력을 넘으면 최근 것만 다시 받아오는 식의 묵시적 동작 금지
- 실패 날짜를 자동 적재하고, 가능한 하우스만 다음 실행에서 자동 재시도
- HSBC·BofA·모간스탠리는 “가능성 탐색”과 “운영용 백필”을 분리
3-2. 제안 데이터 구조
A. 하우스별 능력 레지스트리
신규 파일: data/source_capabilities.json
{
"version": 1,
"updated_at": "2026-08-12T00:00:00+09:00",
"sources": {
"nomura": {
"collector_mode": "api_direct",
"backfill_contract": {
"status": "supported",
"date_filter": "direct_range",
"pagination": "offset",
"page_size_confirmed": 100,
"max_pages_confirmed": 10,
"implemented_lookback_days": null,
"effective_result_ceiling": 1000,
"warning_on_exceed": "result_ceiling"
},
"portal_capability_status": "confirmed"
},
"hsbc": {
"collector_mode": "http_cookie_reuse",
"backfill_contract": {
"status": "partial",
"date_filter": "none",
"pagination": "not_confirmed",
"page_size_confirmed": 300,
"implemented_lookback_days": null,
"observed_oldest_publication_by_page_size": {
"100": "2026-08-10",
"150": "2026-08-07",
"200": "2026-08-07",
"300": "2026-08-06"
},
"warning_on_exceed": "recent_count_only"
},
"portal_capability_status": "partially_confirmed"
}
}
}
핵심은 implemented_lookback_days만 두지 말고 아래를 같이 둬야 한다는 점임.
status:supported | partial | unsupporteddate_filter:direct_range | fixed_window | none | home_onlypagination:offset | page_number | cursor | none | not_confirmedimplemented_lookback_days: 현재 코드가 실제 보장하는 범위portal_capability_status:confirmed | partially_confirmed | unknownwarning_on_exceed: 초과 요청 시 어떤 경고를 낼지
B. 백필 대기열
신규 파일: data/backfill_queue.json
{
"version": 1,
"items": [
{
"id": "hsbc:2026-08-03:2026-08-06",
"source": "hsbc",
"requested_window": {"start": "2026-08-03", "end": "2026-08-06"},
"reason": "daily_collection_failed_or_missing",
"priority": "critical",
"capability_assessment": "unsupported_recent_count_only",
"status": "pending_warning",
"attempt_count": 0,
"last_result": null,
"created_at": "2026-08-12T05:46:00+09:00"
}
]
}
상태값
pending: 다음 실행에서 자동 재시도 가능pending_warning: 자동 재시도하면 오해를 낳으므로 먼저 경고만 내야 함runningresolvedblocked_capability_gap: 포털/코드 능력 부족으로 자동 회수 불가manual_hold
3-3. 제안 인터페이스
A. 백필 판정 인터페이스
신규 모듈 제안: scripts/archive_capabilities.py
assess_backfill(source, start_date, end_date) -> assessment- 반환값 예시
{
"source": "hsbc",
"requested_window": {"start": "2026-08-03", "end": "2026-08-06"},
"status": "unsupported",
"effective_window": null,
"warning_code": "recent_count_only",
"message": "HSBC 현재 수집기는 날짜 조건 없이 최신 일부만 조회함. 2026-08-03~2026-08-06 백필 보장 불가"
}
B. 수집기 반환 계약 확장
각 collect_<house>_archive.py의 collect() 결과에 아래 필드를 추가하는 설계를 권장함.
requested_windoweffective_windowcapability_statuswarningsdiscovery_artifact
초과 요청인데 능력 밖이면 수집 자체를 unsupported_backfill로 종료해야 함. 기본 동작으로 최근 목록 재수집 금지.
3-4. 자동 재시도 흐름
collect_daily_archive.py가 일일 수집 수행- 하우스 실패, 일부 문서 실패, 또는 목록 대비 저장 누락이 있으면
backfill_queue.json에 적재 - 다음 실행에서
- 먼저 당일 수집 수행
- 그 다음
backfill_queue.json에서pending만 제한적으로 수행 pending_warning과blocked_capability_gap은 자동 수집 대신 실행 결과 요약에 정확한 날짜를 적은 경고로 남김
권장 이유
- 당일 05:45 수집이 최우선임
- 백필이 골드만 상한, 브라우저 부하, 차단 리스크를 밀어내면 안 됨
3-5. 하우스별 설계 판단
노무라
- 그대로 백필 주력 소스로 둠
- 단,
1000건 상한을 능력 레지스트리에 명시 - 요청 날짜 범위는 넓어도 결과 1000건을 넘기면 “미회수 가능 구간 있음” 경고 필요
바클레이즈
- 현재 설계상 14일 보장으로 명시
- 14일 초과 요청은
- 최근 14일은 실행
- 나머지 구간은
blocked_capability_gap으로 분리 기록 - “일부만 회수됨”을 명시해야 함
골드만 / TD
- 현재 구현은 14일 컷오프이므로 일단 능력 레지스트리에 현행 구현 14일로 명시
- 다만 이것이 포털 한계인지 코드 한계인지는 분리 표기
implemented_lookback_days: 14portal_capability_status: unknown- 이렇게 해 두면 나중에 코드 수정만으로 넓힐 수 있는지 판단이 쉬움
씨티
- 현재는
landing + publication feed(21일)의 혼합 구조 - 능력 레지스트리도 하우스 단위가 아니라 채널 단위를 허용해야 함
landing_home: 홈 최신 카드만publication_feed: 21일, cursor 미구현- 백필 요청 시 “이 문서가 feed 대상 시리즈인지”에 따라 지원 여부가 갈림
HSBC
- 즉시 적용 권장안: 운영 기본
rows=100을 바로 올리지 말고, 검증 후 단계 상향 - 이번 확인으로
rows=300까지는 서버가 응답을 받아 줌 - 따라서 레지스트리에
page_size_confirmed: 300pagination: not_confirmedwarning_on_exceed: recent_count_only를 먼저 기록- 다음 단계 조사 경로
rows=500,rows=1000단발 검증- 응답 시간·HTML 크기·중복률 측정
- 가장 오래된 발행일이 실제로 얼마나 넓어지는지 확인
includepaging=true,page=2,start,offset은 이번 확인에서 효과 없었으므로 운영 설계에는 넣지 않음
BofA
- 현재 collector 능력은
unsupported로 두는 것이 안전함 - 이유: 날짜/페이지를 쓰지 않고, 초과 요청 시 최근 것만 다시 읽게 됨
- 다음 조사 경로는 명확함
- 이미 보이는
/researchlibrary/advancedsearch우선 확인 searchKey,formDate, hidden resource URL을 쓰는 실제 요청을 네트워크에서 캡처- 검색 요청에 날짜/페이지 인자가 붙는지 확인
- 이번 실행에서 실제 날짜/페이지 파라미터는 확인 못 함
모간스탠리
- 현재 collector 능력은
unsupported또는partial_home_only - 이유: 홈/모닝서머리 카드만 확인됐고 검색 API는 확정 못 함
- 다음 조사 경로
- 홈에서 실제 검색·필터 조작 시 호출되는 API 캡처
- 현재 확인된
portal-content-service가 홈 고정 카드용인지, 검색에도 재사용되는지 분리 확인 scripts/probe_ms_search.py는 후보 탐침 흔적일 뿐, 운영 근거로 쓰지 않음- 이번 실행에서 검색용 날짜/페이지 API는 확인 못 함
3-6. 이 설계의 위험과 트레이드오프
- 장점
- “백필 가능/불가”가 하우스별로 명확해짐
- HSBC처럼 실제로는 못 가져오는데 duplicates만 쌓이는 착시 제거
- 다음 실행 자동 재시도 가능
- 비용
- collector 반환 계약이 커짐
- 하우스별 능력 표를 계속 갱신해야 함
- 되돌리기 비용
- 낮음. 기존 수집 경로를 없애지 않고 경고·큐 레이어를 덧붙이는 구조이기 때문
4. 결함 B 설계안 — 발견 목록 보존의 표준화
4-1. 설계 목표
- 8개 하우스 모두 같은 최소 단위로 “발견 목록 전체”를 남김
- 저장 여부뿐 아니라 왜 저장되지 않았는지 남김
- 나중에 날짜 하나를 집어도 “발견 → 분류 → 저장/실패”를 재구성 가능하게 함
archive_index.json과 역할을 분리
4-2. 제안 파일 배치
실행별 상세 목록
runs/YYYYMMDD/<house>/discovery.jsonlruns/YYYYMMDD/<house>/discovery-summary.json
기존 파일과의 관계
- 현재
portal-latest.json은 당분간 유지 - 현재
listing-*.json도 당분간 유지 가능 - 하지만 새 기준은
discovery.jsonl+discovery-summary.json - 대시보드·후속 스크립트는 점진적으로 새 형식으로 이동
4-3. JSONL 한 줄의 최소 스키마
{
"run_id": "20260812T0545",
"source": "goldman-sachs",
"listing_channel": "research_reports",
"source_doc_id": "9af2c021-...",
"title": "US IG Weekly",
"publication_date": "2026-08-12",
"discovered_rank": 4,
"routing_action": "include",
"routing_bucket": "ig_market",
"routing_reason": "direct_us_ig",
"fetch_status": "duplicate",
"archive_key": "goldman-sachs:9af2c021-...",
"failure_reason": null
}
필수 필드
source_doc_idtitlepublication_daterouting_action(include | exclude)routing_reasonfetch_statussavedduplicateexcluded_by_routingfailednot_attempted_due_capunsupported_backfillblockedfailure_reason
권장 추가 필드
listing_channelsectionpage_number또는cursorsource_url또는 URL 비식별 참조archive_keyraw_meta_path
4-4. 저장 규칙
- collector가 문서를 “보는 순간” 한 줄 생성
- 라우팅에서 제외돼도 남김
- 중복으로 건너뛰어도 남김
- fetch 실패면
failure_reason기록 - 상한 때문에 밀렸으면
not_attempted_due_cap
이렇게 해야 “몇 건을 못 가져왔는지”와 “일부러 안 가져온 것인지”가 갈림.
4-5. archive_index.json과의 관계
archive_index.json
- 역할: 실제 저장된 원문 파일의 전역 재고표
- 포함 대상:
saved,duplicate로 이어질 수 있는 저장 성공 이력 - 포함하지 않을 대상:
exclude,failed,not_attempted_due_cap
discovery.jsonl
- 역할: 그날 포털에서 무엇을 봤는지에 대한 증거
- 포함 대상: 본 모든 것
archive_index와의 연결:archive_key로만 참조
즉, archive_index는 창고 목록이고, discovery.jsonl은 현장 출입기록임. 섞으면 둘 다 망가짐.
4-6. 보존기간 정책
현재 runs/가 이미 크므로 목록 보존은 압축 전제로 설계하는 것이 맞음.
권장 정책
- 최근 14일: 평문
discovery.jsonl - 15일~180일:
discovery.jsonl.gz - 실패·차단·백필대기·unsupported 항목이 있는 날짜: 365일 보존
discovery-summary.json: 365일 이상 유지 가능- 기존 대형
listing-*.json은 새 구조 안정화 후 요약본만 남기고 압축 또는 제거
이 정책을 권하는 이유
- 노무라 목록은 이미 MB 단위
- 하지만 텍스트 반복이 많아 압축 효율이 높음
- “문제가 있었던 날”은 오래 남겨야 하고, 정상일은 압축만 해도 충분함
4-7. 이 설계의 위험과 트레이드오프
- 장점
- 사후 감사가 가능해짐
- 누락, 의도적 제외, 중복을 명확히 분리 가능
- 결함 A의 자동 백필 큐가 정확해짐
- 비용
- 모든 collector에 공통 기록 로직 추가 필요
runs/저장량이 증가- 되돌리기 비용
- 낮음. 기존
portal-latest.json을 유지한 채 병행 저장 가능
5. 결함 C 설계안 — 9227 단일 장애점 제거와 안전 재시작
5-1. 최종 권고 구조
권고 결론
종착점은 하우스별 전용 프로필 + 전용 포트가 맞음.
다만 한 번에 5개를 다 찢지 말고 단계적으로 이동해야 함.
이유
- 지금 문제의 핵심은 “로그인을 다시 해야 해서 불편함”보다 하나 멎으면 5개가 같이 죽는 구조임
- 세션은 프로필 안 쿠키로 유지될 가능성이 높고, 재시작 설계로 검증 가능함
- 현재
citi-velocity가 3.0GB까지 비대해졌고, 그 안에 캐시·확장·서비스워커가 누적돼 있음 - 공유 유지 + 복구 강화만으로는 장애 반경 자체는 줄지 않음
5-2. 왜 다시 왕복하지 않게 되는가
앞으로의 판단 기준을 숫자로 고정해야 함.
공유 유지 허용 조건
아래를 20 영업일 연속 만족할 때만 공유 유지 허용
- 같은 포트에 묶인 하우스 수 2개 이하
- 프로필 크기 1GB 이하
- 웹소켓 stall 0회
- blocked.json 유입 0회
- 수집 성공률 95% 이상
전용 분리 유지 조건
아래 중 하나라도 만족하면 재통합 금지
- 한 포트 장애가 3개 이상 하우스에 영향
- 프로필 1GB 초과 또는 증가속도 급격
- 같은 포트 stall 1회 이상
- 인증 오류가 타 하우스로 전염
이 기준을 문서로 고정하면 “이번엔 통합, 다음엔 재분리”식 왕복을 줄일 수 있음.
5-3. 제안 토폴로지
즉시 목표
- BofA: 현행 전용 유지
- Citi: 전용 유지 또는 9227 단독화
- Morgan Stanley: 전용 분리
- Goldman Sachs: 전용 분리
- TD Securities: 전용 분리
- Barclays: 전용 분리
즉, 9227에 5개를 묶는 구조는 끝내는 방향으로 설계함.
단계적 이행
- 1단계: 9227은 Citi만 남기기
- 2단계: Morgan Stanley 분리
- 3단계: Goldman Sachs 분리
- 4단계: TD / Barclays 분리
이 순서를 권하는 이유
- Morgan과 Goldman은 업무 중요도와 장애 흔적이 큼
- TD / Barclays는 구조가 비교적 단순함
- Citi는 기존 프로필의 중심이므로 마지막에 정리하는 편이 안전함
참고
- 파일시스템에는
matrix-ms,goldman-marquee프로필 디렉토리가 이미 있으나, 현재 로그인 유효성은 확인 못 함 - 따라서 “새 프로필 생성”보다 “기존 후보 프로필 재사용 또는 현재 프로필 복제 후 정리”를 비교해야 함
5-4. 프로필 비대화 대응 정책
신규 정책 파일 제안: data/profile_hygiene_policy.json
운영 기준
- 500MB 초과: 경고
- 1GB 초과: 정리 예약
- 2GB 초과: 장애 고위험
정리 대상
Default/CacheDefault/Code CacheDefault/GPUCacheextensions_crx_cache- 중복 버전 확장 폴더
- 오래된
Service Worker캐시
건드리지 말아야 할 것
CookiesLogin DataLocal StoragePreferences전체 삭제- 프로필 전체 초기화
확장 프로그램 기준
- 브로커 접근에 실제 필요한 확장만 남김
- 같은 확장의 중복 버전은 최신만 남기고 이전 버전 제거 후보로 표시
- 확장 제거는 전용 프로필 복제본에서 먼저 검증 후 본 프로필 반영
5-5. “응답은 하지만 조종은 안 되는” 상태의 감지와 재시작 절차
상태 판단 기준
신규 상태 파일: data/browser_health_state.json
포트별로 아래를 기록
http_alivews_alivews_handshake_mstab_countprofile_size_mbchrome_uptimelast_restart_atrestart_count_today
자동 재시작 트리거
아래 중 하나면 재시작 후보
/json/version은 응답하지만ws_alive=false- 웹소켓 handshake 지연이 임계치 초과
- collector가 같은 포트에서 연속
connect_over_cdp실패 - warm 단계와 collect 단계 둘 다 같은 stall 확인
안전 재시작 절차
신규 스크립트 제안: scripts/recover_broker_port.py
절차
- 포트 잠금 획득
- 현재 탭 목록을
runs/YYYYMMDD/browser/port-<port>-pre-restart.json에 저장 - 수집 중 아님 확인
- Chrome 정상 종료 시도
- 제한시간 내 미종료 시 강제 종료
- 같은 프로필·같은 포트로 재기동
/json/version+ 웹소켓 handshake 확인- 필요한 브로커 홈 탭만 복원
- 로그인 여부는
warm_broker_sessions.py의attention_hint로만 판정 - 결과를
runs/YYYYMMDD/browser/port-<port>-restart.json에 기록
중요
- 재시작은 허용하되 자동 로그인은 하지 않음
- 세션 유지 여부는 쿠키 기반으로 검증만 함
5-6. 세션 유지 검증 설계
재시작 설계는 “될 것 같다”가 아니라 하우스별 오프아워 리허설로 검증해야 함.
하우스별 검증 항목
- 재시작 전 탭 URL, 제목, 인증 확인 힌트 기록
- 재시작 후 같은 프로필 재오픈
- collector가 로그인 페이지로 가지 않는지 확인
- 1건 이상 목록 조회 가능한지 확인
blocked.json변동 없는지 확인
성공 기준
- 재시작 후 로그인 재입력 없이 collector 정상 시작
- warm 상태
attention=null - 해당 포트의
ws_alive=true
5-7. 하나 실패해도 나머지가 살아남는 격리 방안
최종 방안
- 하우스별 전용 포트/프로필
- 포트별 잠금과 재시작 분리
- 포트별 건강상태 개별 기록
과도기 방안
- 전면 분리 전이라도 재시작 단위를 포트 단위로 고정
- 9227 공유가 남아 있는 동안에는
- 그 포트 장애를 “하우스 5개 개별 실패”가 아니라 포트 1개 장애로 먼저 인식
- 다른 전용 포트(BofA 등)는 건드리지 않음
5-8. 이 설계의 위험과 트레이드오프
하우스별 전용 프로필·포트
- 장점: 장애 반경 최소, 재시작 판단 단순, 프로필 비대화 원인 분리 쉬움
- 단점: 초기 로그인 작업 증가, 운영 대상 프로필 수 증가, 메모리 사용량 증가 가능
- 되돌리기 비용: 중간. 다시 통합하려면 포트/프로필 정책을 되돌려야 함
공유 유지 + 복구 강화만 수행
- 장점: 초반 변경량 적음
- 단점: 단일 장애점 유지, 재시작해도 5개 동시 영향
- 되돌리기 비용: 낮음
- 판단: 과도기 보완책으로만 적합, 종착점으로는 부적합
6. 구현 순서와 의존관계
1단계 — C의 탐지·재시작 가드 먼저
대상
warm_broker_sessions.py확장 또는 별도 복구 스크립트browser_health_state.json
왜 먼저인가
- 9227 문제는 하루 수집 전체를 한 번에 날릴 수 있음
- 백필 구조보다 당장 내일 새벽 장애 반경 축소가 더 급함
2단계 — A/B 공통 기반: 능력 레지스트리 + discovery 공통 스키마
대상
data/source_capabilities.jsondiscovery.jsonl스키마
왜 이 순서인가
- 자동 백필도, 누락 판정도, 목록 보존도 이 두 개를 공통 전제로 씀
3단계 — B 적용: 6개 요약형 collector를 전체 목록 저장형으로 통일
대상
- BofA, Citi, Morgan Stanley, Goldman, TD, Barclays
왜 이 순서인가
- 지금 가장 큰 운영 공백은 “놓친 건수 자체를 모른다”는 점임
- A의 자동 재시도도 B가 있어야 정확해짐
4단계 — A 적용: 자동 백필 큐와 초과요청 경고
대상
collect_daily_archive.pybackfill_queue.json
왜 이 순서인가
- 목록 증거가 쌓인 뒤에야 자동 백필 우선순위가 맞아짐
5단계 — C 구조 분리: 9227 해체
대상
broker_session_manager.py의 포트/프로필 배치- 프로필 정리 정책
왜 마지막인가
- 구조 분리는 효과가 크지만 리허설 없이 바로 가면 운영 충격이 큼
- 앞 단계에서 재시작 검증과 상태 기록을 먼저 갖춘 뒤 나가는 편이 안전함
7. 검증 방법
7-1. 결함 A 검증
능력 레지스트리 검증
- 하우스별 샘플 요청 3종
- 지원 범위 안
- 경계값
- 지원 범위 밖
- 기대 결과
- 지원 안:
unsupported_backfill또는blocked_capability_gap - 부분 지원:
partial+ 정확한effective_window - 최근 재수집으로 조용히 빠지지 않을 것
HSBC 검증
rows=100/150/300/500순차 검증- 기록할 것
- 응답 코드
- 응답 시간
- 문서 수
- 가장 오래된 발행일
- 중복률
- 성공 기준
source_capabilities.json값이 실제 결과와 일치
자동 재시도 검증
- 테스트용 queue 항목 3개 삽입
- 지원 가능
- 부분 지원
- 지원 불가
- 다음 실행에서 상태 전이가 설계대로 바뀌는지 확인
7-2. 결함 B 검증
목록-요약 정합성 검증
하우스별로 아래가 맞아야 함.
discovery.jsonl전체 줄 수 =discoveredrouting_action=include수 =eligiblefetch_status=saved수 =savedfetch_status=duplicate수 =duplicatesfetch_status=failed수 =failed개수
사후 재구성 검증
임의의 날짜 1개를 골라 아래 질문이 전부 답돼야 함.
- 무엇을 발견했는가
- 무엇을 저장했는가
- 무엇을 라우팅에서 제외했는가
- 무엇이 실패했는가
- 무엇이 상한 때문에 시도조차 안 됐는가
archive_index 연결 검증
saved또는duplicate레코드만archive_key를 가져야 함exclude/failed는archive_key가 없어야 함
7-3. 결함 C 검증
stall 감지 검증
- warm 단계에서
ws_alive측정값이 파일로 남는지 확인 - collector
connect_over_cdp실패와 같은 포트 건강상태가 연결되는지 확인
재시작 검증
하우스별 오프아워 리허설 1회씩
- 재시작 전 건강상태 저장
- 정상 종료 후 재기동
- collector로 목록 1회 확인
- 로그인 필요 여부 기록
성공 기준
- 재기동 후
ws_alive=true - 해당 collector가 로그인 페이지가 아니라 실제 목록/본문으로 진입
blocked.json변화 없음
분리 검증
- 하우스 하나를 전용 포트로 옮긴 뒤
- 그 포트를 강제 종료해도 다른 하우스 수집이 계속 되는지 확인
- 성공 기준
- 장애 반경이 옮긴 하우스 1곳으로 한정
8. 하지 말아야 할 것
--lookback-days만 공통으로 받게 하고, 지원 안 되는 하우스가 최근 것만 다시 가져오게 두기-
이유: 이번 문제의 핵심 착시를 그대로 재생산함
-
발견 목록 전체를
archive_index.json에 합치기 -
이유: 저장 재고표와 발견 증거가 섞여 중복판정이 오염됨
-
골드만 상한 완화로 백필 부족분을 메우기
-
이유: 차단 리스크가 설계 제약보다 우선함
-
blocked.json을 우회하거나 자동 해제하기 -
이유: 차단 사고 재발 가능성이 큼
-
BofA·모간스탠리 조사 전까지 “백필 지원”으로 분류하기
-
이유: 확인 못 한 것을 가능하다고 표기하면 다시 같은 오판이 남
-
9227을 유지한 채 재시작만 붙이고 끝내기
-
이유: 장애 감지는 좋아져도 장애 반경은 그대로임
-
5개 하우스를 한 번에 전부 새 프로필로 옮기기
-
이유: 세션 유지 검증 없이 한꺼번에 가면 운영 충격이 큼
-
프로필 정리 때 쿠키·로그인데이터까지 밀기
- 이유: 자동 로그인 확대 금지 조건과 정면 충돌함
9. 승인 판단용 한 줄 결론
- A: 하우스별 백필 능력을 “가능/부분가능/불가”로 기계적으로 선언하고, 능력 밖 요청은 경고로 막아야 함
- B: 8개 하우스 모두 발견 목록 전체를 같은 형식으로 남겨야 함
- C: 9227 공유는 과도기 보완만 하고, 종착점은 하우스별 전용 프로필·전용 포트로 가야 함