[참고본] 정본은 /Users/ron/knowledge-agent/400-reports/260926_cowork_jpmorgan-discovery-alternative-proposal.md 이다. 이 문서는 선행 진단(실측 근거)으로만 유지한다. 아래 1순위 두 건은 2026-09-26 06:22(report_routing.py)·06:29(build_house_daily_digest.py
_collection_window)에 이미 반영됐다.
JP모건 수집 경로 한계 진단 및 대체 목록 경로 제안서
조사 시각: 2026-09-26 05:20~05:50 KST · 방식: 실행 로그·색인 재집계 + 살아있는 JPM 세션(CDP 9236)에서 읽기 전용 조회(GET만, 저장·동의 클릭 없음)
대상 코드: hermes-research-sales-engine/scripts/collect_jpmorgan_archive.py(492행), report_routing.py, build_house_daily_digest.py
[권고]
한 줄 결론: "JPM이 9월에 안 보인다"는 한 가지 원인이 아니라 서로 다른 세 층이 겹친 것이다. ① 목록이 서버 고정 50건(요청 변수로 못 늘림) ② 그 50건 중 크레딧 데스크 글은 제목 규칙에 안 걸리면 빠짐 ③ JPM 주간물은 금·토 발행이라 토·일에만 저장되는데, 외사별일일은 평일에만 돌고 "그날 저장분"만 봐서 JPM이 구조적으로 0건이 된다. 제외 규칙이 주간물만 남긴 게 아니라 목록 자체가 주간물 위주이고, 외사별일일 0건은 목록과 무관한 날짜 창 문제다.
- 1순위 — 외사별일일 날짜 창 보정 (codex, 목록 경로 문제와 무관하게 즉시 효과)
- 무엇을:
build_house_daily_digest.pymain()의 409~410행collected != target.isoformat()조건을 "직전 평일 다음날 ~ target"(월요일이면 토·일·월 포함)으로 넓힌다. 새 도우미 함수_collection_window(target) -> tuple[date, date]1개 추가. - 왜: JPM 색인 46건의 최초 저장 요일이 토 22 / 일 13 / 금 5 / 목 5 / 월 1이고, 9월 JPM 저장일 5개(09-06 일, 09-12 토, 09-13 일, 09-19 토, 09-20 일)가 전부 주말이다. 외사별일일 크론(
research-house-daily-0815,15 8 * * 1-5)은 평일에만 돌아 이 5일치를 한 번도 못 본다. - 기대효과: 9월 JPM 외사별일일 0건 → 월요일마다 1건(4~5개 리포트 묶음). 9월(01~25) 기준 0/19 평일 → 3/19(09-07·14·21 월요일 3회 — 주말 저장분 11건 전부 흡수). 바클레이즈 등 평일 수집 외사는 변화 없음(창이 target 하루와 같음).
- 1순위(병행) — JPM 라우팅의 간행물 메타 인정 (codex)
- 무엇을:
report_routing.py402~411행if source_key == "jpmorgan":분기에 "publications에Credit Market Outlook & Strategy·High Grade Weekly Spotlight·HG Credit Foreign Demand Monitor가 있거나businessGroup == "Credit Research"이고regions에 NorthAmerica/Global 포함이면include/ig_market" 규칙 추가. 신규 상수_JPMORGAN_CREDIT_PUBLICATIONS. - 왜: 오늘(09-26) 피드에 새로 뜬
An in-depth look at the question of 144A index inclusion(GPS-5456329-0, 09-25, Credit Research, 간행물=Credit Market Outlook & Strategy, 1.6조달러 HG 채권 지수편입 이슈)이US IG·한국물·미국 금리/거시 연결이 확인되지 않음(536행)으로 제외됐다. JPM 분기는 제목 정규식만 보고(407행), 간행물 메타는 안 본다. 메타 조합에 따라 결과가 흔들리는 것도 확인(아래 현황 3) — 간행물명으로 확정하는 규칙이 필요한 이유. - 기대효과: 오늘 피드 기준 +1건, 크레딧 데스크 단발 리포트(연 수십 건 추정 — 미확인)가 노출되는 날 놓치지 않음.
- 2순위 — 두 번째 목록 채널(섹션별 목록) 도입, 단 선행조건 1건은 해리 조치 필요
- 무엇을: BofA 방식(
SECTIONS튜플 → 섹션마다 목록 조회 → 합쳐서 중복 제거)을 JPM에 이식. 후보 섹션은 메뉴 API에서 실측한Research & Insights > Research > Global Research(JPMM_IDresearch),Asset Classes(research.asset_classes),My Research(research.my_research),Global Index Research(research.bond_index). - 선행조건(차단 요인): 이 네 화면을 새 탭으로 열면 모두 "Terms of Use — Research Application Addendum … By clicking Accept" 동의 화면에서 멈추고, 목록 호출이 한 번도 안 나간다(XHR은 메뉴·프로필·핑뿐). CFP 검색 경로(
/research/CFP?page=search,page=publication)는 "Authentication Error Page … (user: hychoi280, page: search)"로 막힌다. 약관 동의는 법적 동의 행위라 에이전트가 누르지 않는다 → 해리가 JPM 세션에서 리서치 앱 약관을 1회 수락해야 섹션 목록 주소를 실측할 수 있다. - 동의 후 codex 작업: (a) 살아있는 세션에서 위 화면이 부르는 목록 주소·응답 형태를 먼저 실측(추측 구현 금지) (b)
SECTIONS상수 +_fetch_section_listing(session, budget, section) -> list[dict]추가 (c)collect()에서_fetch_feed()결과와 합쳐doc_id로 중복 제거,listing_channel에 섹션명 기록. - 기대효과: 크레딧 데스크 간행물(High Grade Weekly Spotlight 등)의 상시 노출. 08-27 단 1회 노출 때 5건이 전부 저장된 선례로 볼 때, 노출만 되면 필터·본문 경로는 이미 통과한다.
- 2순위(병행, 선행조건 없음) — 기대 시리즈 감시
- 무엇을:
collect_jpmorgan_archive.py에EXPECTED_SERIES(US Weekly Prospects, U.S. Fixed Income Markets Weekly, Global FI Markets Weekly, Credit Market Outlook & Strategy, The J.P. Morgan View) +_series_staleness(listing_rows) -> list[str]추가. 최신 발행일이 9일 초과면result["stale_series"]에 넣고status="partial". - 왜: 지금은 목록이 안 움직여도
ok로 찍힌다(09-22→23→24 목록 id 차집합 0/0, 3일 연속 완전 동일). - 하지 말 것 — 50건 상한 조정: 상한은 우리 코드가 아니라 서버 쪽이다.
&size=200/&limit=200/&pageSize=200/&page=2/&offset=50/&assetClass=FixedIncome/&publicationId=238전부 같은 50건(첫 idGPS-5463860-0동일)을 돌려줬고,type=credit|fixedincome|publications|news는 HTTP 500. 우리 쪽 상한(MAX_ARTICLE_OPENS=12, 50행)도 9월 내내not_attempted_due_cap=0이라 병목이 아니다. 상한 숫자를 올리는 수정은 효과 0이다.
[현황]
1. discovery.jsonl 분포 (runs/2026092{2..5}/jpmorgan/)
| 실행일 | 목록 | 발행일 범위 | include | exclude | fetch_status | 버킷 |
|---|---|---|---|---|---|---|
| 09-22 | 50 | 08-07~09-21 | 23 | 27 | duplicate 23 / excluded 27 | other_review 27, macro_deep 19, ig_market 4 |
| 09-23 | 50 | 08-07~09-21 | 23 | 27 | 동일 | 동일 |
| 09-24 | 50 | 08-07~09-21 | 23 | 27 | 동일 | 동일 |
| 09-25 | 50 | 08-10~09-24 | 21 | 29 | duplicate 21 / excluded 29 | other_review 29, macro_deep 17, ig_market 4 |
- 연속 실행 간 새 문서: 09-22→23 0건, 09-23→24 0건, 09-24→25 2건(Oil Markets Weekly 09-24, Flows & Liquidity 09-23 — 둘 다 제외 타당). 09-26 오늘 조회: 새 3건(Securitized Products Weekly, FX Markets Weekly, 144A 편입 분석).
- 09-25 목록 50행은 서로 다른 제목 16개뿐: US Weekly Prospects 7, Equity Strategy 6, Flows & Liquidity 5, U.S. FI Markets Weekly 4, Credit Market Outlook & Strategy 4, Securitized Products Weekly 4, Oil Markets Weekly 3 … → 주간 연재물 묶음이라 6주치가 50칸에 들어간다.
- 제외 29건 사유: 주식 전략 8, 연결 확인 안 됨 11(Flows & Liquidity 5·Oil 3·Perspectives 2·EM 1), 환율 5, 구조화 4, 비미국 1. 제목을 전부 대조한 결과 크레딧 데스크 글은 0건 — 제외 규칙이 크레딧을 막은 사례는 이 4일 안에는 없다. 즉 "주간물만 남는 것"은 목록 구조 때문이다(판정: 필터 제외 아님, 목록 미노출).
- 43회 전체 실행 이력(08-13~09-25, 3,000행, listing_channel 100%
home_research_feed)에서 크레딧 데스크 제목은 08-27 회차에만 1회 노출: High Grade Weekly Spotlight, HG Credit Foreign Demand Monitor, European Credit Weekly ×2, High Yield Weekly Spotlight, LATAM Corporates Daily, CNH Credit Markets. 같은 날 18:47 재조회 목록에선 이미 사라짐 → 피드가 계정 맞춤·회전형이라는 증거. 그 회차에 노출된 5건은 전부 html+pdf+txt로 저장됨(access_status=retrieved_html, 본문 45,073~51,770자).
2. archive_index.json (jpmorgan 46건)
- 시리즈: 위 주간 5종 40건 + 08-27 단발 노출 5건 + EM Outlook 1건.
- 최초 저장 요일: 토 22 / 일 13 / 금 5 / 목 5 / 월 1. 9월 저장 = 09-06(일) 2, 09-12(토) 1, 09-13(일) 3, 09-19(토) 1, 09-20(일) 4 = 11건, 전부 주말.
- 대조: 바클레이즈는 같은 기간 저장일 09-21 2 / 22 5 / 23 4 / 24 4 / 25 5 (평일 매일), 발행일 09-21~24 일별 4~5건. 바클레이즈는 live.barcap.com/RSX/content-archive/v1/REST/publication/search를 상품군(Credit & Securitized 2594052, Macro 2594054)별로 pageSize=100, pubDateRange=2 weeks로 두 번 부른다 — 서버가 페이지 크기·기간을 받아주는 검색 API가 있다는 점이 JPM과의 결정적 차이다.
- 볼트 외사 리서치/2026-09-*/00_외사별일일/: JPM 파일 0/19 평일, 바클레이즈 18/19. 반면 분류 폴더에는 JPM 노트 11개가 주말 날짜 폴더(09-06·12·13·19·20)에 정상 존재 → 원문은 들어왔는데 외사별일일만 비는 것.
3. 라우팅 재현(읽기 전용, 오늘 피드 원행으로 classify_report 호출)
- 144A 글 실제 메타 전체 → exclude(regions를 US로 바꾸거나 비워도 exclude). 반면 최소 메타(assetClasses=FixedIncome, regions=US, businessGroup=Credit Research, 간행물명, 요약 빈칸)로 만들면 include(ig_market) → 판정이 요약·지역 등 메타 조합에 따라 흔들린다(단일 원인 필드는 미특정). JPM 분기(402~411행)는 제목 정규식(_JPMORGAN_FIXED_INCOME_INCLUDE)만 보고, 일반 경로의 _DIRECT_IG는 "HG bonds"/"US Agg" 표현을 못 잡는다.
- 참고로 08-27에 저장된 HG Weekly Spotlight·HG Credit Foreign Demand Monitor는 현재 규칙에서도 include(ig_market, 최소 메타로 재현) → 노출만 되면 통과.
4. 대체 경로 탐색 결과(오늘 실측)
- 홈 탭이 부르는 목록류 주소: mcp-home/api/search-service/saved-search·recent-search(둘 다 null), dp-gateway/omni-channel-api/public/dpweb/menu(151KB 메뉴 트리). 메뉴의 리서치 항목은 위 2순위 후보 4개 + FICC Market Structure & Liquidity(research.ficc_market_structure).
- 리서치 앱 네 화면 모두 약관 동의 화면에서 정지 → 목록 호출 없음. 저장된 검색이 비어 있어 "My Research"에 구독을 걸어두면 개인화 목록으로 쓸 여지가 있으나 미확인(약관 수락 후 실측 필요).
[리스크]
- 단일 장애점: JPM 목록은
FEED_URL(38행) 하나이고 서버가 50건·맞춤형으로 고정한다. 피드 구성(개인화 로직)이 바뀌면 주간 5종마저 사라질 수 있고, 지금 구조에선 그걸ok로 보고한다(2순위 감시가 없는 한 조용한 누락). - 약관 수락 의존: 2순위 섹션 경로는 해리 계정의 리서치 앱 약관 수락 없이는 실측조차 불가. 수락 후에도 섹션 목록이 CFP 권한(docstring 11~13행의 "not onboarded onto CFP-RESEARCH")에 막힐 가능성 있음 — 현재 본문(
CFP?page=article_page)은 열리지만page=search/page=publication은 인증 오류, 즉 권한이 화면 종류별로 다르다. - 날짜 창 보정의 부작용: 월요일 외사별일일이 토·일·월 3일치를 묶으면 바클레이즈 등도 주말 저장분이 월요일에 합쳐진다(현재 주말 저장분은 어느 외사든 외사별일일에서 누락 중이므로 오히려 복구). 주간 크레딧 요약(
build_weekly_credit_house_summary.py)은target-6~target날짜 폴더 파일을 읽으므로, 월요일 외사별일일 md가 생기면 JPM 재료가 늘어난다 — 중복 인용 여부는 검증 필요. - 라우팅 완화의 오탐:
businessGroup=Credit Research만으로 include하면 European Credit Weekly, LATAM Corporates Daily, CNH Credit Markets(08-27 노출분)까지 들어온다. regions에 Europe/LatAm/Asia가 있으면 기존 지역 배제를 먼저 적용해야 한다. - 세션 부하: 섹션 추가 시 요청 수 증가. 현재
MAX_PORTAL_REQUESTS=90, 요청 간격 3초, 실제 사용 하루 1~9회라 여유는 충분.
[검증방법]
codex 구현 후 아래 기준으로 판정한다(모두 발송 없이 실행).
- 외사별일일 날짜 창 —
cd hermes-research-sales-engine && python3 scripts/build_house_daily_digest.py --date 2026-09-21 --no-upload(발송 플래그--send금지) - 기대값:
외사 리서치/2026-09-21/00_외사별일일/260921_jpmorgan_외사별일일.md생성, "포함 리포트: 4건"(09-20 저장 4건) 이상. 바클레이즈 파일 건수는 변경 전과 동일하거나 주말분만큼 증가. - 단위:
_collection_window(date(2026,9,21))→(2026-09-19, 2026-09-21),_collection_window(date(2026,9,23))→(2026-09-23, 2026-09-23). - 롤백 조건: 평일(화~금) 외사별일일 건수가 변경 전과 달라지면 되돌림.
- 라우팅 —
python3 -c "from report_routing import classify_report; ..."로GPS-5456329-0(144A, regions=NorthAmerica, publications=Credit Market Outlook & Strategy) →include/ig_market. 동시에 European Credit Weekly(regions=Europe) → exclude 유지, Securitized Products Weekly → exclude 유지. - 회귀: 09-22~25 discovery.jsonl 200행을 새 규칙으로 재분류해 include 수 변화를 표로 제출. 기대: 증가 0~1건(크레딧 데스크 글이 그 4일 목록에 없었으므로), 감소 0건.
- 기대 시리즈 감시 — 09-22 목록으로 재현 시
stale_series=[], 목록에서 Credit Market Outlook & Strategy 행을 빼고 돌리면stale_series=["Credit Market Outlook & Strategy"],status=partial. - 섹션 채널(약관 수락 후) —
python3 scripts/collect_jpmorgan_archive.py --max-reports 12 --max-opens 12실행 결과에서discovery.jsonl의listing_channel값이 2종 이상, 발견 수 > 50, 한 주 동안 High Grade Weekly Spotlight 또는 HG Credit Foreign Demand Monitor가 최소 1회 저장. 실패 기준: 섹션 목록이 인증 오류를 내면status=partial+ 홈 피드 결과는 그대로 저장(홈 피드 수집이 줄면 롤백). - KPI(2주 관찰): JPM 평일 외사별일일 ≥ 주 1건, JPM 신규 저장 ≥ 주 5건 유지, 크레딧 데스크 간행물 ≥ 주 1건(섹션 채널 가동 후).
해리 확인 필요 1건
JPM 사이트 리서치 메뉴를 처음 열면 뜨는 약관 동의(Research Application Addendum) 를 해리 계정으로 한 번 수락해야 2순위 섹션 목록 경로를 실측할 수 있다. 에이전트가 대신 누르지 않았다(법적 동의 행위).
근거 경로
hermes-research-sales-engine/scripts/collect_jpmorgan_archive.py11~13행(CFP 권한 메모), 38행(FEED_URL), 49~50행(상한), 199~215행(_fetch_feed), 323행(listing_channel="home_research_feed")hermes-research-sales-engine/scripts/report_routing.py138~146행(JPM 제목 정규식), 402~411행(JPM 분기), 536행(연결 미확인 제외)hermes-research-sales-engine/scripts/build_house_daily_digest.py409~410행(수집일=target 필터)hermes-research-sales-engine/scripts/collect_bofa_portal_archive.py24~28행(SECTIONS), 319행(섹션 반복)hermes-research-sales-engine/scripts/collect_barclays_archive.py191~206행(_search, pageSize 100), 215~217행(상품군 2개)hermes-research-sales-engine/runs/2026092{2,3,4,5}/jpmorgan/discovery.jsonl·discovery-summary.json,runs/20260827/jpmorgan/listing-055724.untitled.json·listing-184740.jsonhermes-research-sales-engine/data/archive_index.json(jpmorgan 46건)/Users/ron/.hermes/cron/jobs.json—research-house-daily-0815(15 8 * * 1-5),c1dcf1d3c808daily-broker-archive(45 5 * * *)