virtual-insanity
← 리포트 목록

JP모건 크레딧 간행물 누락 대응 — 대체 목록 경로 제안서

2026-09-26 cowork [외사리서치, jpmorgan, 수집커버리지, US-IG, discovery, 제안서, 주간크레딧요약]

[정본] 이 문서가 JP모건 크레딧 간행물 누락 대체경로 제안의 정본이다(#40069/#40077/#40085). 관계: /Users/ron/knowledge-agent/400-reports/260926_cowork_jpm-collection-gap-proposal.md(05:50)는 같은 날 먼저 쓴 선행 진단·참고본이며, 그 문서의 1순위 두 건(외사별일일 날짜 창·JP모건 간행물 메타 라우팅)은 06:22~06:29 이미 코드 반영돼 이 문서 §0·§8로 흡수했다. 진단 원본은 /Users/ron/knowledge-agent/400-reports/260926_hermes_jpmorgan-discovery-gap.md.

JP모건 크레딧 간행물 누락 대응 — 대체 목록 경로 제안서

참고본에서 가져올 실측: 서버 50건 고정(요청 변수로 못 늘림)·섹션 화면 약관 동의 차단은 참고본 14~34행, 라우팅 재현은 58~60행.

입력 진단: [[260926_hermes_jpmorgan-discovery-gap]] (홈 피드 50건 고정 · 크레딧 데스크 간행물 43회 중 8/27 1회 노출) 이 문서는 코드 없는 제안서다. 구현은 codex, 포털 실측은 ron(브라우저 세션 9236) 담당.

0. [현황] 이번 작성 시 추가 실측 (입력 보고서 이후 변화)

항목 실측값 근거
JP모건 수집 스크립트 실제 파일 collect_jpmorgan_archive.py (19,552바이트, 8/27 16:23 수정) 1개. 백업 collect_jpmorgan_archive.py.bak-cfp-20260814 ls -la scripts/ \| grep -i jpm
목록 주소 FEED_URL = .../mcp-home/api/data-service/feed-content?type=research 단일 채널 스크립트 38행
요청·열람 한도 포털 요청 90회, 본문 열람 12건/회 스크립트 49~50행
9/26 06:00 실행 목록 50 · 포함 20(전부 중복) · 저장 0 · 주제 제외 30 · listing_channels: home_research_feed 50 runs/20260926/jpmorgan/discovery-summary.json
9/26 새로 뜬 문서 3건: Securitized Products Weekly(9/25), FX Markets Weekly(9/25), "An in-depth look at the question of 144A index inclusion"(9/25, GPS-5456329-0) — 셋 다 주제 제외 9/25 대비 9/26 discovery.jsonl id 차집합
주제 필터 보강 9/26 06:22 report_routing.py에 JP모건 크레딧 간행물 3종(Credit Market Outlook & Strategy / High Grade Weekly Spotlight / HG Credit Foreign Demand Monitor) 메타 일치 시 포함 규칙 추가됨 (백업 report_routing.py.bak-jpmpub-20260926). 144A 문서는 06:00 실행 당시 이 규칙 적용 전이라 제외됐고, 재판정 시 include / ig_market 로 바뀜 diff 결과 + classify_report() 재현
주간 폴더 JP모건 노트 9/21~9/26 볼트 날짜 폴더에 *jpmorgan* 파일 0건 (같은 기간 전체 md 7·35·31·28·32·0건) find "외사 리서치/<날짜>" -iname "*jpmorgan*"

판단: 필터 쪽 구멍은 9/26 06:22 보강으로 절반 메워졌다. 남은 병목은 "목록에 안 뜨는 것"(노출)과 "주말 수집분이 볼트로 안 넘어가는 것"(변환 시차) 두 가지다.

1. [권고]

1순위 — 간행물(시리즈)별 목록 채널을 홈 피드 옆에 두 번째 채널로 추가

  • 무엇: 홈 피드(feed-content?type=research)는 그대로 두고, JP모건 포털의 간행물별 목록(High Grade Weekly Spotlight, HG Credit Foreign Demand Monitor, Credit Market Outlook & Strategy, US High Grade 데일리류)을 시리즈 단위로 조회하는 두 번째 목록 채널(listing_channel=publication_series)을 붙인다.
  • 왜: 8/27 1회 노출 때 크레딧 데스크 제목 10건이 떴고 그중 IG 관련 4건이 필터를 통과해 실제 저장됐다 — 문서 자체는 우리 계정으로 열린다. 막힌 건 목록 한 곳(개인화 피드)에 100% 의존하는 구조뿐이다.
  • 선행 조건(코드 착수 전, ron): 살아있는 크롬 세션(9236)에서 간행물 페이지를 열어 실제로 호출되는 목록 주소·파라미터·응답 형태(문서 id, 발행일, publications 메타)를 1회 기록한다. 현재 이 주소는 미실측 — 확인 전 codex 착수 금지.
  • 기대효과: JP모건 주간 IG 입력 시리즈가 현재 사실상 1종(Credit Market Outlook, 9/19 이후 목록 0건)에서 3~4종으로. 8/27 실측 기준 한 번 노출 시 IG 관련 저장 4건.

2순위 — 기대 시리즈 감시(조용한 누락을 경고로 전환)

  • 무엇: 시리즈별 발행 주기 표(예: Credit Market Outlook & Strategy 매주 금, High Grade Weekly Spotlight 매주)를 설정 파일로 두고, "주기 + 2일" 동안 어느 채널에도 안 뜨면 수집 상태를 ok 대신 listing_gap 경고로 올린다.
  • 왜: 9/21~9/26 6회 실행 전부 ok, warnings: []로 찍혔지만 크레딧 간행물 신규 노출은 0이었다. 1순위가 포털 개편으로 깨져도 이 감시가 있어야 드러난다. 1순위와 독립적이라 먼저 적용 가능.
  • 기대효과: "5일 0건인데 전부 ok" 상태를 늦어도 발행 주기 +2일(수요일) 안에 경고로 노출. 오탐 목표 주 3회 미만.

3순위(보조) — 검색형 조회 + 메일 알림 백업선

  • (a) 포털 검색 화면에서 "High Grade", "HG Credit" 키워드·최근 7일 조건으로 조회하는 채널. 1순위 주소를 못 찾을 때의 대안이다.
  • (b) 포털의 크레딧 시리즈 메일 알림을 수집용 지메일로 구독해 기존 메일 수집기로 받는다. collect_broker_mail_archive.py는 이미 JP모건 인식 규칙(25·39·50행)을 갖고 있으나 9/21~25 JP모건 저장 0건. 구독 설정은 해리 계정 작업이라 해리 확인 필요.
  • 기대효과: 포털 목록 구조와 무관한 이중화. 효과 크기는 구독 후 1주 실측 전까지 미확인.

별도 권고 — 주말 수집분의 볼트 변환 시차 해소 (주간 요약본 직접 영향)

  • 볼트 노트 변환 크론 research-brief-prepare-0620은 평일(20 6 * * 1-5)만 돈다. 주간 크레딧 요약본 크론 5c45c26045be(0 9 * * 0, 일요일 09:00)는 볼트 날짜 폴더(target-6 ~ target)의 노트만 읽는다. 따라서 금요일 미국 발행분(Credit Market Outlook & Strategy 등)이 토·일 새벽에 수집돼도 일요일 09:00 요약본에는 못 들어간다.
  • 조치 후보: 일요일 08:30에 _write_obsidian_notes(target, 'daily')를 직접 호출하는 짧은 사전 단계(요약본 크론 앞단)를 추가. 1~3순위와 무관하게 효과가 있다.

2. 후보별 기대효과·위험 비교

후보 기대효과 위험 선행조건 적용 난이도
A. 간행물별 목록 채널 (1순위) IG 시리즈 3~4종 상시 노출, 발행 당일 포착 포털 내부 주소 의존 → 개편 시 조용히 깨짐. 요청 수 증가(현재 한도 90회/실행) 9236 세션에서 목록 주소 실측 중
B. 데스크별 목록(Credit Research 사업부 전체) 시리즈명을 몰라도 신규 크레딧 간행물 포착 HY·LATAM·CNH·유럽 크레딧이 대량 유입 → 주제 필터 부담. 9/26 신규 규칙(businessGroup == credit research + 북미/글로벌)이 이미 있어 걸러낼 수는 있음 동일 중
C. 검색 조회 (3순위 a) 주소 개편에 상대적으로 강함 검색 결과 정렬·페이지 규칙 미확인, 키워드 누락 시 빠짐 검색 API 실측 중
D. 기대 시리즈 감시 (2순위) 누락을 "보이게" 만듦 — 수집량 자체는 안 늘림 휴일·발행 중단 시 오탐 주기 표 작성 하
E. 메일 알림 (3순위 b) 포털 구조와 무관한 백업선 해리 계정 설정 필요, 메일 본문 링크가 로그인 필요 주소일 수 있음 해리 확인 하~중
F. 일요일 볼트 변환 사전 단계 (별도 권고) 금요일 발행분이 당주 요약본에 반영 일요일 수집 실패 시 효과 없음. 변환 중 run() 호출 금지(일요일 게이트·발송 분기 섞임) — 함수 직접 호출만 없음 하

권고 조합: D + F를 먼저(설계·위험 모두 낮음), A는 주소 실측 후, B는 A가 불가능할 때, C·E는 보조.

3. 주간 크레딧 요약본(일요일 크론 5c45c26045be) 입력 영향

  • 요약 스크립트 build_weekly_credit_house_summary.py의 collect_house_material()(96행)은 대상 주간 날짜 폴더의 00_외사별일일/*_jpmorgan_외사별일일.md → 없으면 분류 폴더 *_jpmorgan_*.md가 가리키는 원문 발췌 순으로 재료를 모은다. 재료가 없으면 해당 하우스는 missing으로 빠진다(317~319행).
  • 이번 주(9/27 일요일 실행, 대상 9/21~9/27) 예상: 9/21~9/26 폴더에 JP모건 노트 0건 → JP모건 블록 누락 확정적. HOUSE_ORDER 첫 번째 하우스(40행)가 비는 셈이다. 전체 발송 게이트(하우스 3개 이상, 327행)는 다른 외사로 통과 가능하므로 오류 없이 JP모건만 조용히 빠진 채 발송된다.
  • 144A 편입 분석(GPS-5456329-0, 9/25 발행, 크레딧 간행물 메타)은 9/26 06:22 필터 보강 후라 9/27 새벽 수집에서 저장될 수 있으나, 평일 전용 변환 크론 때문에 9/27 09:00 요약본에는 들어가지 않는다(별도 권고 F 미적용 시).
  • 1순위(A) 적용 후 기대: JP모건 재료가 주 1종 → 3~4종, 요약본 JP모건 블록이 "Credit Market Outlook 1건 요약"에서 "IG 시장·해외수요·섹터 스포트라이트 교차 요약"으로 두꺼워진다.
  • 2순위(D) 적용 후 기대: 요약본 근거목록(<주차>_크레딧_리포트요약_근거목록.json)과 별개로, JP모건이 빠진 이유가 "그 주 발행 없음"인지 "목록 미노출"인지 수집 단계에서 구분된다.

4. codex 위임 대상 파일 (ls로 실존 확인, 2026-09-26)

경로 기준: /Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine/scripts/

파일 (실존·크기·수정일) 변경 내용 관련 후보
/Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine/scripts/collect_jpmorgan_archive.py (19,552B, 8/27, 주 대상 수집 스크립트) 두 번째 목록 채널 추가, record_routed(listing_channel=...)에 채널값 분리, _row_metadata()의 ingest/jpmorgan_feed 값을 채널별로 구분, 채널 간 문서 id 중복 제거 A·B·C
discovery_log.py (25,508B, 8/12) listing_channels 채널별 집계, listing_gap 경고 상태 추가 A·D
check_source_health.py (18,308B, 9/3) 70행 안내문 "최신 5건 목록만 확인" → 실제(홈 피드 50건 + 채널 추가 시 반영)로 정정, 기대 시리즈 경고 판정 D
collect_daily_archive.py (24,490B, 9/8) 요약 상태에 listing_gap 반영(ok와 분리) D
report_routing.py (30,194B, 9/26 06:22) 9/26 보강 규칙 유지. 채널 B 도입 시 HY·LATAM·CNH·유럽 제외 규칙이 JP모건 블록 안에서 먼저 걸리는지 회귀 확인만 B
collect_broker_mail_archive.py (11,338B, 8/16) JP모건 알림 메일 본문 링크 → 문서 id 추출 E
신규 설정 data/jpmorgan_expected_series.json 시리즈명·발행 요일·허용 지연일 D
크론 5c45c26045be 앞단(스크립트 신규 또는 기존 호출) 일요일 08:30 _write_obsidian_notes(target,'daily') 직접 호출 F

위임 방법: codex exec --skip-git-repo-check --sandbox workspace-write -C <레포> - < prompt.md (workspace/scripts/codex_answer.sh는 아무 일도 안 하는 스텁이므로 사용 금지). 위임 전 .bak-<태그>-<YYYYMMDD> 백업, 위임 후 diff -u <백업> <현재>로 실제 변경 확인.

5. [리스크]

  • 단일 장애점: 현재 JP모건 목록 채널 1개(listing_channels: home_research_feed 50) 100% 의존. 개인화 구성이 바뀌면 경고 없이 누락(8/27 사례는 반대 방향 증거).
  • 포털 주소 의존: 채널 A·B·C 모두 포털 내부 API에 기대므로 개편 시 깨진다 → D(감시)를 반드시 같이 둔다.
  • 요청 한도: 채널 추가 시 요청 수 증가. 현재 한도 90회/실행·연속 실패 2회 중단(49~52행). 두 번째 채널 실패가 첫 채널 수집까지 끊지 않도록 예산을 채널별로 분리해야 한다.
  • 권한: 스크립트 11~12행 주석상 과거 "CFP-RESEARCH onboarding" 오류 이력이 있다 — 시리즈 목록 주소가 다른 권한 영역이면 열람 불가일 수 있음(미확인).
  • 변환 시차(F 미적용 시): 금요일 발행 크레딧 주간지가 구조적으로 다음 주 요약본으로 밀린다.

6. [검증방법]

대상 측정 지표 명령 기대값 롤백 조건
A/B/C 채널 채널별 발견 행수 python3 -c "import json;rows=[json.loads(l) for l in open('runs/<날짜>/jpmorgan/discovery.jsonl')];print(len(rows),{r['listing_channel'] for r in rows})" 5영업일 매일 채널 2종 이상, High Grade/HG Credit 제목 주 1건 이상 저장 수집 시간 2배 초과 또는 로그인 오류 신규 발생 → 채널 비활성화, 홈 피드 단독 복귀
D 감시 경고 정확도 한 시리즈의 마지막 노출일을 시험용으로 주기 초과 처리 후 check_source_health.py 실행 listing_gap 경고 1건 오탐 주 3회 이상 → 허용 지연일 조정
F 변환 일요일 09:00 전 JP모건 노트 존재 find "외사 리서치/<일요일>" -iname "*jpmorgan*" \| wc -l (08:45 시점) 토·일 저장분 있으면 1 이상 요약본 크론 지연·실패 시 사전 단계 제거
요약본 JP모건 블록 포함 여부 근거목록 JSON의 sources에 jpmorgan 키 존재 여부 적용 후 4주 중 3주 이상 포함 —
필터(9/26 보강) 144A 문서 저장 grep GPS-5456329-0 runs/20260927/jpmorgan/discovery.jsonl fetch_status saved 또는 duplicate 제외로 남으면 메타 publications 값 재확인

7. 다음 행동 (담당)

  1. ron: 9236 세션에서 간행물별 목록 주소·응답 형태 1회 실측 → 이 문서 §1에 추가.
  2. codex: D(감시) + F(일요일 변환 사전 단계) 먼저 구현 — 포털 실측 불필요.
  3. codex: 1번 결과가 나오면 A 구현(실패 시 B, 그다음 C).
  4. 해리 확인: E(메일 알림 구독) 진행 여부.

8. codex 후속 태스크 초안 (코드 수정 필요 항목만, 정리만 — 2026-09-26 ron 대행)

레포 절대경로: /Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine 수집기 실제 위치: /Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine/scripts/collect_jpmorgan_archive.py (19,552B, 8/27 16:23). 워크스페이스(/Users/ron/.hermes/workspace/)에는 JP모건 수집 스크립트가 없다 — 과거 제출에 인용된 collect_jpmorgan_archive.py(워크스페이스 루트)·jpm_credits.py·fetch_jpm_feed.sh는 실존하지 않는 경로이므로 인용 금지.

이미 반영돼 태스크 불필요 (재발행 금지)

  • JP모건 간행물 메타 라우팅: scripts/report_routing.py 148행 _JPMORGAN_CREDIT_PUBLICATIONS, 404·417행 분기 (9/26 06:22, 백업 .bak-jpmpub-20260926).
  • 외사별일일 날짜 창: scripts/build_house_daily_digest.py 396행 _collection_window(), 408행 _in_collection_window(), 428행 호출 (9/26 06:29, 백업 .bak-window-20260926).
  • 확인: cd /Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine && python3 -m pytest tests/test_build_house_daily_digest_window.py tests/test_report_routing.py -q → 13 passed (2026-09-26 ron 실행).

T1 [codex, 선행조건 없음, 우선] 기대 시리즈 감시 (후보 D)

  • 대상 파일·함수:
  • 신규 data/jpmorgan_expected_series.json — 시리즈명·발행 요일·허용 지연일(Credit Market Outlook & Strategy 금+2, U.S. Fixed Income Markets Weekly, Global FI Markets Weekly, US Weekly Prospects, The J.P. Morgan View, High Grade Weekly Spotlight).
  • scripts/collect_jpmorgan_archive.py — 신규 _series_staleness(listing_rows, expected, today) -> list[str]; collect()(255행)에서 _fetch_feed()(199행) 결과로 호출, 결과를 result["stale_series"]에 넣고 비어 있지 않으면 status="partial".
  • scripts/check_source_health.py 70행 안내문 "jpmorgan": "최신 5건 목록만 확인" → 실제값(홈 피드 50건)으로 정정 + stale_series 존재 시 listing_gap 경고.
  • scripts/collect_daily_archive.py — _run_with_retry()(110행) 이후 coverage 집계(360~391행)에서 listing_gap을 ok와 분리 표기(exit code 정책은 기존 유지).
  • scripts/discovery_log.py 350행 listing_channels 요약 옆에 stale_series 필드 추가.
  • 테스트: 신규 tests/test_jpmorgan_series_staleness.py — (a) 9/22 runs/20260922/jpmorgan/discovery.jsonl 재현 시 [] (b) Credit Market Outlook 행 제거 시 ["Credit Market Outlook & Strategy"]·status=partial.
  • 검증 명령: cd /Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine && python3 -m py_compile scripts/collect_jpmorgan_archive.py scripts/check_source_health.py scripts/collect_daily_archive.py scripts/discovery_log.py && python3 -m pytest tests/test_jpmorgan_series_staleness.py tests/test_report_routing.py -q

T2 [codex, 선행조건 없음, 우선] 일요일 볼트 변환 사전 단계 (후보 F)

  • 대상 파일·함수: scripts/deliver_research_link_brief.py 1133행 _write_obsidian_notes(target, mode) — 수정하지 않고 import만. 신규 scripts/prepare_weekend_obsidian_notes.py: 인자 날짜(일요일) 기준 토·일 두 날짜로 _write_obsidian_notes(d, "daily")만 직접 호출(main()/--send 경로 호출 금지 — 발송 분기 섞임). 크론 5c45c26045be(0 9 * * 0) 프롬프트 절차 1번 앞에 이 스크립트 실행 1줄 추가(크론 신설·비활성화 없음, 프롬프트 수정만).
  • 테스트: 신규 tests/test_prepare_weekend_obsidian_notes.py — _write_obsidian_notes를 monkeypatch해 2026-09-27 입력 시 호출 인자가 [(2026-09-26,'daily'),(2026-09-27,'daily')]이고 텔레그램 발송 함수 호출 0회.
  • 검증 명령: cd /Users/ron/knowledge-agent/400-reports/hermes-research-sales-engine && python3 -m py_compile scripts/prepare_weekend_obsidian_notes.py && python3 -m pytest tests/test_prepare_weekend_obsidian_notes.py -q; 운영 확인은 일요일 08:45 find "/Users/ron/knowledge-agent/400-reports/외사 리서치/<일요일>" -iname "*jpmorgan*" | wc -l.

T3 [codex, 선행조건 있음 — 착수 보류] 간행물·섹션별 두 번째 목록 채널 (후보 A→B→C)

  • 선행조건: (1) 해리가 JP모건 세션에서 리서치 앱 약관(Research Application Addendum) 1회 수락(참고본 28행) (2) ron이 세션 9236에서 목록 주소·파라미터·응답 형태 1회 실측해 §1에 기록. 둘 다 충족 전 착수 금지.
  • 대상 파일·함수: scripts/collect_jpmorgan_archive.py — 신규 _fetch_series_listing(session, budget, series) -> list[dict](199행 _fetch_feed 옆), collect()에서 doc_id 기준 중복 제거 병합, 323~441행 하드코딩 listing_channel="home_research_feed" 7곳을 행별 채널값으로 교체, 176행 _row_metadata()의 채널 구분, _Budget(49~52행 한도)을 채널별로 분리해 두 번째 채널 실패가 홈 피드를 끊지 않게. 참고 구현: scripts/collect_bofa_portal_archive.py SECTIONS(24~28행).
  • 테스트: 신규 tests/test_jpmorgan_listing_channels.py — 실측 응답 픽스처로 채널 2종 병합·중복 제거·두 번째 채널 예외 시 홈 피드 결과 보존.
  • 검증 명령: python3 -m pytest tests/test_jpmorgan_listing_channels.py -q 후 python3 scripts/collect_jpmorgan_archive.py --max-reports 12 --max-opens 12 결과 discovery.jsonl의 listing_channel 2종 이상.

T4 [codex, 선행조건 있음 — 해리 확인] 메일 알림 백업선 (후보 E)

  • 선행조건: 해리가 JP모건 크레딧 시리즈 메일 알림 구독 여부 확인.
  • 대상 파일·함수: scripts/collect_broker_mail_archive.py 144행 _urls()에서 JP모건 문서 id(GPS-\d+-\d) 추출, 110행 classify_broker() 이후 id를 collect_jpmorgan_archive._try_fetch_document()(218행)로 넘기는 연결.
  • 테스트: 신규 tests/test_broker_mail_jpm_docid.py — 알림 메일 본문 샘플에서 id 추출.
  • 검증 명령: python3 -m pytest tests/test_broker_mail_jpm_docid.py -q.

위임 방식은 §4 그대로(백업 .bak-<태그>-<YYYYMMDD> → codex exec → diff -u로 실제 변경 확인). 권장 순서: T1·T2 동시 → T3(선행조건 충족 후) → T4(해리 확인 후).