오케스트레이터 규칙 10-1 전제 정정안 — 실제 갱신 경로(fi-morning-brief → macro_series_collector) 반영
규칙 10-1 전제 정정안
실측 시각: 2026-09-28 14:19 KST
[권고]
1순위 — 규칙 10-1의 갱신 주체 문구를 교체한다.
- 무엇을: scripts/orchestrator.py 464~472행 RON_SYSTEM_PROMPT 규칙 10-1에서 "매일 market_indicator_tracker.py가 이미 수집해"를 "평일 07:10 fi-morning-brief 크론이 fi-morning-brief.sh를 통해 macro_series_collector.py로 핵심 11개 시리즈만 갱신한다"로 바꾸고, 근거파일 지시 대상 스크립트를 market_indicator_tracker.py → macro_series_collector.py + fi-morning-brief.sh로 교체한다.
- 왜: market_indicator_tracker 크론은 꺼져 있다(enabled=False, state=paused, paused_at 2026-08-17 13:31, 마지막 실행 2026-08-16 07:05 error). 이 전제로 발행된 태스크가 실존하지 않는 갱신 주체를 근거로 인용해 반려됐다(#40274, #40279, #40277, #40284, #40285 모두 failed — 오늘 같은 주제 5건).
- 기대효과: 같은 주제 반려 5건/일 → 0건. 근거파일 인용 대상이 실제 호출 체인과 일치.
2순위 — "last_updated와 최신 data 날짜를 함께 적으라"는 조건을 규칙에 추가한다. - 왜: 전체 수집 크론(macro-series-collector, 평일 06:50)도 꺼져 있다(enabled=False, 마지막 2026-08-14). fi-morning-brief는 11개 시리즈만 새로 받으므로, 폴더의 51개 파일 중 나머지 40개는 수동 실행이 없으면 멈춘다. 실측상 폴더 51개 중 1개는 5월 11일 이후 그대로다. 파일 수정시각·last_updated만 보고 "최신"이라 쓰면 틀린다 — 오늘 DGS10/BAMLC0A0CM은 last_updated=2026-09-28이지만 마지막 data 날짜는 2026-09-24다(FRED 게시 지연 + 주말). - 기대효과: 신선도 판단 오류(수집일=데이터일 혼동) 차단, 11개 밖 시리즈 요청 시 stale 여부가 보고서에 드러남.
[현황]
| 항목 | 실측값 | 출처 |
|---|---|---|
| market-indicator-tracker 크론 | enabled=False, state=paused, last_run 2026-08-16 07:05, last_status=error | /Users/ron/.hermes/cron/jobs.json (id ocRESTORE-market-indicator-tracker) |
| macro-series-collector 크론(전체 46개) | enabled=False, 50 6 * * 1-5, last_run 2026-08-14 06:50 | 같은 파일 (id macro-series-collector) |
| fi-morning-brief 크론 | enabled=True, 10 7 * * 1-5, last_run 2026-09-28 07:11, last_status=ok | 같은 파일 (id fi-morning-brief) |
| 실제 호출 체인 | fi-morning-brief → scripts/migrated/fi-morning-brief.sh 11행 → scripts/pipeline/macro_series_collector.py --series {sid} | fi-morning-brief.sh 10~11행 |
| 크론이 갱신하는 시리즈 | 11개: DGS2 DGS5 DGS10 DGS30 T10Y2Y DFII10 T10YIE T5YIFR BAMLC0A0CM BAMLH0A0HYM2 BAMLEMCBPIOAS | fi-morning-brief.sh 10행 |
| 저장 경로·필드 | memory/macro-timeseries/{SERIES_ID}.json, "last_updated" = 수집일 | macro_series_collector.py 31행, 213행 |
| 폴더 파일 수 / 수정시각 분포 | 51개 / 9월 28일 13:10~13:11 50개, 5월 11일 1개 | ls -l memory/macro-timeseries |
| BAMLC0A0CM.json | last_updated=2026-09-28, 161건, 마지막 data 2026-09-24 = 0.79 | 파일 직접 파싱 |
| DGS10.json | last_updated=2026-09-28, 154건, 마지막 data 2026-09-24 = 5.18 | 파일 직접 파싱 |
| 오늘 동일 주제 반려 | #40274, #40277, #40279, #40284, #40285 = failed 5건, #40275 needs_evidence 1건 | ops_multiagent.db bus_commands |
주의: 9월 28일 13:10~13:11에 50개 파일이 한꺼번에 바뀐 것은 07:10 크론(11개만)으로는 설명되지 않는다. 같은 시각대 진단 태스크(#40275/#40277)가 전체 수집을 수동 실행한 흔적으로 추정되며, 실행 주체는 미확인이다. 따라서 "파일 수정시각이 오늘이면 매일 자동 갱신 중"이라는 추론은 성립하지 않는다.
기존 문구 vs 수정 문구 비교표
| 구분 | 기존 문구 (orchestrator.py 464~472행) | 수정 문구 (제안) |
|---|---|---|
| 갱신 주체 | "매일 market_indicator_tracker.py가 이미 수집해 memory/macro-timeseries/{series_id}.json에 저장해둔다." | "평일 07:10 fi-morning-brief 크론이 scripts/migrated/fi-morning-brief.sh를 실행하고, 이 스크립트가 scripts/pipeline/macro_series_collector.py --series 로 핵심 11개 시리즈(DGS2·DGS5·DGS10·DGS30·T10Y2Y·DFII10·T10YIE·T5YIFR·BAMLC0A0CM·BAMLH0A0HYM2·BAMLEMCBPIOAS)만 memory/macro-timeseries/{series_id}.json에 갱신한다. market_indicator_tracker 크론과 전체 수집 크론(macro-series-collector)은 2026-08 이후 꺼져 있으므로 갱신 주체로 쓰지 않는다." |
| FRED 호출 금지 | "FRED API 조회/새 호출을 시키지 말고 … 실제 시리즈 JSON 파일을 읽어 최신값을 확인" | 유지 |
| BAMLC0A0CM 지시 | "memory/macro-timeseries/BAMLC0A0CM.json을 직접 파싱" | 유지 (11개 안에 포함되어 평일 갱신됨을 명시) |
| 근거파일 지시 | "근거/근거파일에는 해당 JSON 경로와 scripts/pipeline/market_indicator_tracker.py를 함께 적으라" | "근거/근거파일에는 해당 JSON 경로, scripts/pipeline/macro_series_collector.py(저장 로직 31행·last_updated 213행), scripts/migrated/fi-morning-brief.sh 11행(호출 지점)을 함께 적으라" |
| 신선도 조건 | 없음 | 신설: "보고에는 파일의 last_updated 값과 data 배열 마지막 원소의 date를 함께 적는다(예: last_updated=2026-09-28 / 최신 data=2026-09-24). 파일 수정시각만으로 최신이라 쓰지 않는다. 대상 시리즈가 위 11개 밖이면 자동 갱신 대상이 아니므로 최신 data 날짜가 5영업일 이상 지났을 때 stale로 명시한다." |
| 검증값 문장 | "exit code 0 또는 통과를 적으라" | 유지 |
| 재시도 3회 규칙 | "재점검/재분석/재실행 3회 이상이면 지시문을 고쳐 재발행" | 유지 |
수정 문구 전문 (제안, 적용은 codex)
10-1. 금리·크레딧스프레드·환율 등 FRED/시계열 지표 태스크는 평일 07:10 fi-morning-brief 크론이
scripts/migrated/fi-morning-brief.sh를 실행하고, 이 스크립트가
scripts/pipeline/macro_series_collector.py --series 로 핵심 11개 시리즈
(DGS2·DGS5·DGS10·DGS30·T10Y2Y·DFII10·T10YIE·T5YIFR·BAMLC0A0CM·BAMLH0A0HYM2·BAMLEMCBPIOAS)를
memory/macro-timeseries/{series_id}.json에 갱신한다. market_indicator_tracker 크론과
전체 수집 크론(macro-series-collector)은 꺼져 있으므로 갱신 주체로 인용하지 말 것.
body에 "FRED API 조회", "FRED API 새 호출"을 시키지 말고 반드시 "memory/macro-timeseries/ 폴더의
실제 시리즈 JSON 파일(예: BAMLC0A0CM.json)을 읽어 최신값을 확인"이라고 쓸 것.
완료 보고의 근거/근거파일에는 해당 JSON 경로, scripts/pipeline/macro_series_collector.py,
scripts/migrated/fi-morning-brief.sh 11행을 함께 적고, 파일의 last_updated 값과
data 마지막 원소의 date를 함께 적으라고 명시할 것(수정시각만으로 '최신' 판정 금지,
11개 밖 시리즈는 최신 data가 5영업일 이상 지났으면 stale로 명시).
검증값 문장 끝에는 반드시 "exit code 0" 또는 "통과"를 적으라고 명시할 것. (이하 재시도 규칙 유지)
[리스크]
- 단일 장애점: 11개 핵심 시리즈의 유일한 자동 갱신 경로가 fi-morning-brief.sh 11행이다. 이 줄은
>/dev/null 2>&1로 실패를 삼키므로 수집 실패가 크론 last_status=ok 뒤에 숨는다(브리핑 발송만 성공해도 ok). last_updated/data 날짜 병기 조건이 이 조용한 실패를 드러내는 유일한 장치다. - 범위 공백: 나머지 40개 시리즈는 자동 갱신 경로가 없다. 규칙 문구만 고치고 크론을 그대로 두면 11개 밖 지표 태스크는 계속 stale 데이터로 돌아간다 — 전체 수집 크론 재활성화 여부는 크론 활성/비활성 변경이므로 해리 확인 사항이다.
- 의존: fi_market_snapshot.py 4행 주석도 "macro_series_collector가 매일 수집"이라 적혀 있어 같은 오해를 재생산한다(문서 정합성 부채, 코드 영향 없음).
- 테스트 영향: scripts/tests/test_orchestrator_task_quality.py가 macro_series_collector를 참조한다. codex가 규칙 문구를 바꿀 때 이 테스트의 기대 문자열도 함께 확인해야 한다.
[검증방법]
적용(codex) 후 판정 기준:
1. grep -n "market_indicator_tracker" scripts/orchestrator.py → 규칙 10-1 범위(464~475행)에서 0건. 기대값 0, 1건 이상이면 미적용.
2. grep -n "fi-morning-brief.sh" scripts/orchestrator.py → 1건 이상.
3. grep -n "last_updated" scripts/orchestrator.py → 규칙 10-1 범위에서 1건 이상.
4. python3 -m py_compile scripts/orchestrator.py → exit 0, python3 -m pytest scripts/tests/test_orchestrator_task_quality.py -q → 전부 통과.
5. KPI: 적용 후 7일간 bus_commands에서 제목에 BAMLC0A0CM/macro-timeseries/10-1 포함 태스크의 failed·needs_evidence 비율. 오늘 기준 6건 중 6건(100%) → 목표 20% 이하.
6. 롤백 조건: pytest 실패, 또는 적용 후 3일 내 동일 주제 반려가 오히려 늘면 이전 문구로 되돌린다.