# 2026-05-06

## 자동갱신 토글 (코디 작업)

`behive_web.py` 상단바에 **자동 갱신 토글** 추가. 본인/가희 계좌현황 탭에서만, 페이지 foreground일 때만 10초마다 `location.reload()`. 감시종목 탭·백그라운드·잠금화면에선 멈춤. 상태는 localStorage 영속.

- 초기 사양은 3초였지만 부하 검토 후 10초로 완화. `RENDER_CACHE_TTL`도 60s → 10s로 동기화 (매 reload마다 신선한 키움 데이터).
- NXT 운영시간(평일 08:00~20:00 KST) 밖이면 토글 자체 비활성 (`disabled` + `.closed` CSS, 라벨 "장마감"). 주말도 동일.

## KRX 휴장일 자동 관리 (코디 작업)

자동토글의 비활성 판정에 한국 공휴일까지 포함. investing.com에서 휴장일을 받아오는 시스템 신규 구축.

### 구성
- 신규 스크립트: `scripts/holiday_sync.py` — `https://kr.investing.com/holiday-calendar/service/getCalendarFilteredData` POST(country[]=11, dateFrom~dateTo)로 올해+내년 KRX 휴장일 fetch. "서울 증권 거래소" 필터.
- 신규 state: `state/market_holidays.json` — `{fetched_at, source, years, holidays:{YYYY-MM-DD: 휴장명}}`. 2026 13개(설날 3일·추석 2일 등) 부트스트랩 완료. 2027은 investing.com에 미공개.
- 신규 launchd: `ai.openclaw.stock.holiday-sync` — 매주 일요일 03:00 KST. 실패 시 stderr만 남기고 기존 파일 유지 (웹뷰는 옛 데이터로 계속 동작).
- behive_web 통합: `_load_holidays()` mtime-cache + `_market_active_now()`에 휴장일 체크 추가.

### 사용처
- `behive_web.py` 자동갱신 토글 비활성 판정.
- 사용자가 "휴장일 언제야?" 류 질문하면 `holiday_sync.py --show` 또는 JSON 직접 읽어서 답할 것 (외부 검색·LLM 추론 금지).
- 향후 새 자동화도 같은 파일을 단일 진실 공급원으로 참조 — **휴장일 하드코딩 금지**.

### 문서·메모리
- CLAUDE.md (Scripts·Scheduled Jobs 섹션), TASKS.md (단순 스크립트 작업 §1), 레이 MEMORY.md (담당 트리거·운영 규칙·시장 운영 정보 섹션) 모두 갱신.
- 운영 상세는 `memory/holiday_calendar.md` (reference type).

### 검증
- 어린이날(2026-05-05), 설날 3일, 추석, 광복절 대체, 크리스마스 등 13개 케이스 단위 테스트 통과.
- 평일 정상시간(2026-05-06 11:00) → MARKET=true 확인.
- launchd 등록 확인 (Weekday=0 Sunday, Hour=3, Minute=0).

## 휴장일 self-skip 정책 (코디 작업, 같은 날 추가)

`holiday_sync.py`에 헬퍼(`is_holiday`, `is_holiday_today`, `is_market_day_today`) 추가하고, 4개 launchd 작업이 진입부에서 self-skip하도록 변경. **launchd plist는 안 건드림** — 트리거↔작업 분리 원칙 유지.

| 스크립트 | 게이트 위치 | 휴장일 동작 |
|---|---|---|
| `watchlist_monitor.py` | `is_market_hours()` 내부 | 평일 weekday 체크 직후에 휴장일 체크 추가 → check 진입은 하지만 키움 호출 직전에 스킵 |
| `stock_portfolio_report.py` | `main()` `mode=='send'` 분기 | 휴장일이면 메일·텔레그램 발송 자체 스킵 (시세·잔고 무변동). `run` 모드는 그대로 통과 |
| `briefing_fallback.py` | `main()` 진입부 | 휴장일이면 retry/final 모두 즉시 종료. **final 모드의 거짓 "스냅샷 없음" 텔레그램 경보 차단**이 핵심 동기 |

휴장일에도 그대로 둔 트리거: behive-web(상시 조회), send-balance(월간), ipo-calendar-sync(외부 데이터), holiday-sync(일요일), main 브리핑(일반 뉴스), 비하이브 종목분석 요약(유튜브는 휴장 무관), whooing-sync(카드결제 무관).

운영 가이드는 `memory/holiday_calendar.md` 사용처 섹션에 정리. 새 자동화는 반드시 `is_market_day_today()`를 import해서 사용 — 휴장일 하드코딩 금지.

## 매매 절차 원칙 도입 + orders 모듈 구축 (코디 작업, 같은 날 후속)

**계기:** 키움 REST API 매매 이벤트(100만원 매수 시 2만원 쿠폰)에서 시작. 관리자님과 사양 합의 후 매매 인프라 구축 진행.

**정책 전환:** SOUL.md "**매매 절대 원칙**(주문 함수 절대 부재)" → "**매매 절차 원칙**(사람 PIN echo 가 마지막 게이트)"으로 갱신. `kiwoom_client.py` 의 조회 전용 원칙은 **그대로 유지**, 주문 함수는 `orders/` 패키지로 **분리**.

**구성:** `agents/stock/workspace/scripts/orders/` 패키지 신규.
- `__init__.py`(정책 docstring) + `limits.json`(한도·딜레이·시간대·PIN·라우팅 단일 진실 공급원) + `sidecar.py`(kill switch) + `pin.py`(파일 기반 + flock, cross-process 활성 카드) + `ledger.py`(append-only) + `guards.py`(12종 검증) + `datasource.py`(키움 → market_data) + `kiwoom_order.py`(kt10000/kt10001) + `card.py`(텔레그램 카드 포맷터, 매수/매도·계좌·종목·가격 4개 *bold*) + `handler.py`(흐름 + CLI + send_telegram 통합) + `expiry_watcher.py`(launchd 진입점, 등록 안 함) + `tests/test_guards.py`(81건)
- skill 신규: `skills/order-trading/SKILL.md`(자연어 매매), `skills/order-controls/SKILL.md`(PIN echo + 단축어)

**확정 한도/정책:** 4계좌 전체(가희 포함), 1회/1일/잔고% 한도 없음, 시장가 허용(NXT·KRX 단일가 시간 거부), 가격 가드 ±30%, 거래 간 60초·동일 종목 10분, PIN 본인 4자리/가희 8자리 영숫자, 카드+PIN 분리 발송, 계좌 default 없음 — 미명시 시 넘버링 되묻기.

**상태:** 사이드카 **default ON** 상태로 첫 1주 검증 대기. 검증 후 ka10004 호가창 응답 필드명·NXT eligible 플래그·체결(filled) 폴링 보강 예정.

**상세:** `memory/orders_module.md` (영구 reference).
