virtual-insanity
← 리포트 목록

해리 시야 전수 검증 5/5 — 데이터 저장소 ↔ UI 일관성

2026-04-15 verify [phase17-followup, hermes-migration, data-to-ui, webapp, verify]

해리 시야 전수 검증 5/5 — 데이터 저장소 ↔ UI 일관성

결론

부분 PASS / 실제 웹앱 프로세스 경로 불일치 발견.

데이터 자체와 Hermes 코드 기준 UI 연결은 대체로 정상이다.

  • Hermes memory 데이터 존재: PASS
  • Hermes source market.py/webapp blueprint 경로: PASS, ~/.hermes/workspace/memory 기준
  • Hermes test_client UI endpoint: PASS
  • /api/fed-liquidity/chart 최신 2026-04-15 반환
  • /api/chart/SPY?days=5 최신 2026-04-14 반환
  • /market/bond-study, /market/bond-study/2026-04-12 렌더링
  • /vault/browse?vault=agent&path=100 수신함/121 뉴스레터에서 Damnang 노트 노출
  • /vault/note?vault=agent&path=...260415_Damnang... 프리뷰/본문 반환

하지만 실제 실행 중인 웹앱 PID 19581은 아직 OpenClaw 작업 디렉터리/로그를 잡고 있다.

Python  19581  ron  cwd     DIR ... /Users/ron/.openclaw/workspace/scripts/pipeline
Python  19581  ron    1u    REG ... /Users/ron/.openclaw/logs/sihwang-webapp.log
Python  19581  ron    2u    REG ... /Users/ron/.openclaw/logs/sihwang-webapp-err.log

그리고 OpenClaw 쪽 웹앱 소스는 아직 old path다.

/Users/ron/.openclaw/workspace/scripts/pipeline/webapp/blueprints/market.py:18:_MEM = Path.home() / ".openclaw/workspace/memory"

따라서 해리 화면이 “보이는 값”은 현재 데이터 복제 때문에 맞을 수 있지만, 웹앱 PID 19581이 새 Hermes 코드/경로를 읽는다는 조건은 충족하지 않는다.
실제 freeze 전에는 웹앱을 Hermes cwd/source로 재기동해야 한다. 이번 작업에서는 지시대로 프로세스를 죽이거나 재시작하지 않았다.

Data → UI 연결 매트릭스

데이터 파일 생성자 cron 읽는 UI 경로 최신 일자 UI 반영 여부
macro-timeseries/RRPONTSYD.json macro-series-collector /api/fed-liquidity/chart 간접 반영 rrp_t 2026-04-14 부분 PASS — Hermes endpoint latest row에 rrp_t=0.0003, rrp_b=0.3 반영. 실제 PID는 old cwd라 경로 불일치
macro-timeseries/WTREGEN.json macro-series-collector /api/fed-liquidity/chart 간접 반영 tga_t 2026-04-08 부분 PASS — endpoint latest row에 carry-forward tga_t=0.7484 반영. 원천 최신은 2026-04-08
macro-timeseries/WRESBAL.json macro-series-collector /api/fed-liquidity/chart 간접 반영 resv_t 2026-04-08 부분 PASS — endpoint latest row에 carry-forward resv_t=3.1162 반영. 원천 최신은 2026-04-08
fed-liquidity/latest.json fed-liquidity-aggregator /api/fed-liquidity/chart + morning_briefing 2026-04-15 PASS in Hermes source — chart latest 2026-04-15, 브리핑 oneliner 정상
price-history/SPY.json price-history refresh /api/chart/SPY 2026-04-14 PASS in Hermes source/api/chart/SPY?days=5 latest 2026-04-14
price-history/*.json price-history refresh /api/chart/<ticker> SPY만 2026-04-14 부분 PASS — 현재 Hermes price-history는 SPY.json 1개뿐. QQQ 등은 404
bond-briefing/*.json/.pdf bond_daily_report /market/bond-study/<date> 2026-04-12 PASS in Hermes source — index/day 200, 최신 session 2026-04-12
newsletter notes gmail-newsletter-collector /vault/browse, /vault/note, /api/vault/note 2026-04-15 PASS260415_Damnang_Credo-Technology-Deep-Dive.md browse/note/API 확인
macro-timeseries/*.json macro-series-collector 직접 노출 없음, aggregator 입력 2026-04-14 / weekly 2026-04-08 N/A — 직접 UI 없음. fed-liquidity로 간접 노출

1. 데이터 파일 존재 + 최신 일자

Hermes memory 기준 확인:

--- RRPONTSYD.json path= /Users/ron/.hermes/workspace/memory/macro-timeseries/RRPONTSYD.json exists= True
records= 40 latest= {'date': '2026-04-14', 'value': 0.306}
--- WTREGEN.json path= /Users/ron/.hermes/workspace/memory/macro-timeseries/WTREGEN.json exists= True
records= 8 latest= {'date': '2026-04-08', 'value': 748376.0}
--- WRESBAL.json path= /Users/ron/.hermes/workspace/memory/macro-timeseries/WRESBAL.json exists= True
records= 8 latest= {'date': '2026-04-08', 'value': 3116247.0}
--- fed-liquidity/latest.json path= /Users/ron/.hermes/workspace/memory/fed-liquidity/latest.json exists= True
date= 2026-04-15 records= 9 latest_history= {'date': '2026-04-15', 'net_t': 5.9452, 'rrp_t': 0.0003, 'tga_t': 0.7484, 'resv_t': 3.1162} phase= 유동성 축소 — 흡수 국면 net_t= 5.9452
--- price-history/SPY.json path= /Users/ron/.hermes/workspace/memory/price-history/SPY.json exists= True
records= 51 latest= {'date': '2026-04-14', 'open': 687.690002, 'high': 694.580017, 'low': 687.659973, 'close': 694.460022, 'volume': 63310200, 'adj_close': 694.460022}
--- price-history all count= 1
('SPY.json', 51, '2026-04-14', 1776229401.263638)

채권 브리핑:

--- /Users/ron/.hermes/workspace/memory/bond-briefing
total 816
-rw-r--r--@ 1 ron  staff      35 Apr 15 09:22 explained_terms.json
drwxr-xr-x@ 5 ron  staff     160 Apr 15 09:17 backup-phase17-20260415091709
-rw-r--r--@ 1 ron  staff   18285 Apr 15 02:33 2026-04-12.json
-rw-r--r--@ 1 ron  staff  167496 Apr 15 02:33 briefing_2026-04-12.pdf
-rw-r--r--@ 1 ron  staff   18285 Apr 15 02:33 latest.json
-rw-r--r--@ 1 ron  staff   21555 Apr 14 15:32 2026-04-08.json
-rw-r--r--@ 1 ron  staff  180070 Apr 14 15:32 briefing_2026-04-08.pdf

뉴스레터 vault:

-rw-r--r--@ 1 ron  staff  2811 Apr 15 13:18 260415_Damnang_Credo-Technology-Deep-Dive.md
-rw-r--r--@ 1 ron  staff  4095 Apr 15 13:18 260412_Damnang_LWLG-Structural-Technology-Risk-Analysis.md
-rw-r--r--@ 1 ron  staff  3860 Apr 15 13:18 260411_Damnang_Is-CXMT-a-Threat-or-an-Illusion.md
-rw-r--r--@ 1 ron  staff  2003 Apr 15 13:19 260411_Damnang_Citron-Sees-the-Valuation-but-Misses-the.md
-rw-r--r--@ 1 ron  staff  2856 Apr 15 13:19 260408_Damnang_The-Real-Game-Behind-Terafab.md

2. UI 데이터 경로 확인

Hermes source는 새 경로를 읽는다.

/Users/ron/.hermes/workspace/scripts/pipeline/webapp/blueprints/market.py:18:_MEM = Path.home() / ".hermes/workspace/memory"
/Users/ron/.hermes/workspace/scripts/pipeline/webapp/blueprints/market.py:517:    p = _MEM / "fed-liquidity" / "latest.json"
/Users/ron/.hermes/workspace/scripts/pipeline/webapp/blueprints/market.py:2407:    f = _MEM / "price-history" / f"{ticker.upper()}.json"
/Users/ron/.hermes/workspace/scripts/pipeline/webapp/blueprints/market.py:2468:_BOND_BRIEFING_DIR = _MEM / "bond-briefing"

Hermes webapp 전체 grep도 대부분 .hermes 기준이다.

/Users/ron/.hermes/workspace/scripts/pipeline/webapp/blueprints/vault.py:25:_MEM = Path.home() / ".hermes/workspace/memory"
/Users/ron/.hermes/workspace/scripts/pipeline/webapp/config.py:12:MARKET_IND_DIR     = Path.home() / ".hermes/workspace/memory/market-indicators"
/Users/ron/.hermes/workspace/scripts/pipeline/webapp/config.py:129:OPS_DB_PATH        = Path.home() / ".hermes/data/ops_multiagent.db"

하지만 PID 19581은 old cwd/log를 잡고 있다.

## Webapp process/listener check
Python    19581  ron    4u  IPv4 ... TCP *:8080 (LISTEN)
## PID 19581 files
Python  19581  ron  cwd     DIR ... /Users/ron/.openclaw/workspace/scripts/pipeline
Python  19581  ron    1u    REG ... /Users/ron/.openclaw/logs/sihwang-webapp.log
Python  19581  ron    2u    REG ... /Users/ron/.openclaw/logs/sihwang-webapp-err.log

OpenClaw source는 아직 old path다.

/Users/ron/.openclaw/workspace/scripts/pipeline/webapp/blueprints/market.py:18:_MEM = Path.home() / ".openclaw/workspace/memory"
/Users/ron/.openclaw/workspace/scripts/pipeline/webapp/blueprints/market.py:517:    p = _MEM / "fed-liquidity" / "latest.json"
/Users/ron/.openclaw/workspace/scripts/pipeline/webapp/blueprints/market.py:2407:    f = _MEM / "price-history" / f"{ticker.upper()}.json"

판정: Hermes source PASS / 실제 PID 19581 FAIL

3. curl + jq 검증

실제 localhost curl은 현재 Codex sandbox에서 차단됐다. 웹앱은 lsof상 8080 LISTEN이지만 connect가 operation not permitted로 막힌다.

## curl variants :8080
--- localhost
*   Trying [::1]:8080...
* Immediate connect fail for ::1: Operation not permitted
*   Trying 127.0.0.1:8080...
* Immediate connect fail for 127.0.0.1: Operation not permitted
* Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
--- 0.0.0.0
* Immediate connect fail for 0.0.0.0: Operation not permitted
--- 127.0.0.1
* Immediate connect fail for 127.0.0.1: Operation not permitted

대신 동일 Flask app을 Hermes source에서 test_client로 호출하고, 결과 JSON을 jq로 파싱했다.

/api/fed-liquidity/chart

fed /api/fed-liquidity/chart 200 463

## jq fed
{
  "len": 9,
  "first3": [
    {
      "date": "2026-02-18",
      "net_t": 5.6998,
      "rrp_t": 0.0009,
      "tga_t": 0.9127,
      "resv_t": 2.9498
    },
    {
      "date": "2026-02-25",
      "net_t": 5.725,
      "rrp_t": 0.0012,
      "tga_t": 0.8876,
      "resv_t": 2.9658
    },
    {
      "date": "2026-03-04",
      "net_t": 5.796,
      "rrp_t": 0.0009,
      "tga_t": 0.8321,
      "resv_t": 3.0155
    }
  ],
  "last": {
    "date": "2026-04-15",
    "net_t": 5.9452,
    "rrp_t": 0.0003,
    "tga_t": 0.7484,
    "resv_t": 3.1162
  }
}

/api/chart/SPY?days=5

spy /api/chart/SPY?days=5 200 608

## jq spy
{
  "len": 5,
  "first": {
    "close": 676.01,
    "high": 677.08,
    "low": 671.46,
    "ma20": 657.32,
    "ma200": null,
    "ma60": null,
    "open": 676.39,
    "time": "2026-04-08"
  },
  "last": {
    "close": 694.46,
    "high": 694.58,
    "low": 687.66,
    "ma20": 660.63,
    "ma200": null,
    "ma60": null,
    "open": 687.69,
    "time": "2026-04-14"
  }
}

price-history/*.json은 현재 SPY만 있다. 다른 ticker는 404다.

/api/chart/QQQ?days=5 404 {"error":"no data"}
/api/chart/INVALID?days=5 404 {"error":"no data"}

/market/bond-study, /market/bond-study/2026-04-12

--- /market/bond-study
STATUS= 200 CONTENT_TYPE= text/html; charset=utf-8 BYTES= 14845
contains_2026-04-12= True
contains_채권= True
contains_브리핑= True

--- /market/bond-study/2026-04-12
STATUS= 200 CONTENT_TYPE= text/html; charset=utf-8 BYTES= 25728
contains_2026-04-12= True
contains_채권= True
contains_브리핑= True

Vault browse / note / preview

vault /api/vault?vault=agent&path=100 수신함/121 뉴스레터 200 7542

## jq vault Damnang presence
{
  "count": 41,
  "damnang": [
    {
      "name": "260408_Damnang_The-Real-Game-Behind-Terafab",
      "path": "100 수신함/121 뉴스레터/260408_Damnang_The-Real-Game-Behind-Terafab.md"
    },
    {
      "name": "260411_Damnang_Citron-Sees-the-Valuation-but-Misses-the",
      "path": "100 수신함/121 뉴스레터/260411_Damnang_Citron-Sees-the-Valuation-but-Misses-the.md"
    },
    {
      "name": "260411_Damnang_Is-CXMT-a-Threat-or-an-Illusion",
      "path": "100 수신함/121 뉴스레터/260411_Damnang_Is-CXMT-a-Threat-or-an-Illusion.md"
    },
    {
      "name": "260412_Damnang_LWLG-Structural-Technology-Risk-Analysis",
      "path": "100 수신함/121 뉴스레터/260412_Damnang_LWLG-Structural-Technology-Risk-Analysis.md"
    },
    {
      "name": "260415_Damnang_Credo-Technology-Deep-Dive",
      "path": "100 수신함/121 뉴스레터/260415_Damnang_Credo-Technology-Deep-Dive.md"
    }
  ]
}

HTML browse/note도 확인했다.

--- /vault/browse?vault=agent&path=100 수신함/121 뉴스레터
STATUS= 200 BYTES= 29471
contains_file= True
contains_Credo= True contains_Damnang= True

--- /vault/note?vault=agent&path=100 수신함/121 뉴스레터/260415_Damnang_Credo-Technology-Deep-Dive.md
STATUS= 200 BYTES= 15606
contains_Credo= True contains_Damnang= False

--- /api/vault/note?vault=agent&path=100 수신함/121 뉴스레터/260415_Damnang_Credo-Technology-Deep-Dive.md
STATUS= 200 BYTES= 2983
contains_file= True
contains_Credo= True contains_Damnang= True

주의: /api/vault/search?q=Damnang은 기본 해리 볼트만 검색한다. agent vault 뉴스레터 검색에는 적합하지 않았다.

/api/vault/search?q=Damnang
STATUS= 200
결과는 해리 볼트 MOC/x_twitter 중심이며 최근 agent 뉴스레터는 반환하지 않음

4. 브리핑 통합 확인

morning_briefing.py Hermes 경로 기준 _load_fed_liquidity()는 최신 데이터를 읽었다. 실제 발송은 하지 않았다.

## morning briefing fed liquidity functions from Hermes
loaded_type= dict
date= 2026-04-15 phase= 유동성 축소 — 흡수 국면 net_t= 5.9452 wow_t= -0.0001
history_len= 9
history_last= {'date': '2026-04-15', 'net_t': 5.9452, 'rrp_t': 0.0003, 'tga_t': 0.7484, 'resv_t': 3.1162}
oneliner= 연준 순유동성: $+5.95T 전주 $-0.00T / 국면: 유동성 축소 — 흡수 국면
summary= 국면: 유동성 축소 — 흡수 국면

순유동성  $+5.95T   전주 $-0.1B
  Fed자산  $+6.69T   전주 $0.0B
  RRP      $+0.3B   전주 $+0.1B
  TGA      $+0.75T   전주 $0.0B
  지급준비금 $+3.12T   전주 $0.0B

TGA 증가 또는 Fed 자산 감소로 시장에서 자금이 회수되고 있음.
→ 단기 위험자산 비중 축소. 연준 정책 전환 시점 주시.

5. 구멍 목록 + 수정 권고

Hole 1 — PID 19581 웹앱이 Hermes cwd/source가 아님

증거:

Python  19581  ron  cwd /Users/ron/.openclaw/workspace/scripts/pipeline
Python  19581  ron  stdout /Users/ron/.openclaw/logs/sihwang-webapp.log
Python  19581  ron  stderr /Users/ron/.openclaw/logs/sihwang-webapp-err.log

영향:

  • 해리 UI가 지금 보이는 값은 OpenClaw memory 복제본 덕분일 수 있다.
  • ~/.hermes/workspace/memory 단일 소스 원칙과 맞지 않는다.
  • OpenClaw freeze 후 UI가 깨질 가능성이 있다.

권고:

  • 웹앱 launchd/실행 command를 Hermes 기준으로 바꾼 뒤 재시작.
  • 재시작 후 lsof -p <pid>에서 cwd/log 또는 command가 Hermes 기준인지 확인.
  • 이후 실제 curl이 가능한 세션에서 /api/fed-liquidity/chart, /api/chart/SPY, /market/bond-study, /vault/browse?... 재검증.

Hole 2 — 실제 curl이 현재 Codex sandbox에서 차단

증거:

Immediate connect fail for 127.0.0.1: Operation not permitted

영향:

  • 이번 보고서의 endpoint 응답은 Hermes source test_client 기준이다.
  • 실제 PID 19581의 네트워크 응답은 현재 세션에서 직접 확인하지 못했다.

권고:

  • sandbox 밖 로컬 shell 또는 웹브라우저에서 실제 curl/browser 확인 필요.

Hole 3 — price-history/*.json은 SPY 1개뿐

증거:

/Users/ron/.hermes/workspace/memory/price-history count= 1 files= ['SPY.json']
/api/chart/QQQ?days=5 404 {"error":"no data"}

영향:

  • /api/chart/<ticker>는 범용 route지만 현재 표시 가능한 ticker는 SPY뿐이다.

권고:

  • UI에서 다른 ticker 버튼/링크가 있다면 해당 price-history collector job 추가 또는 UI fallback 필요.

Hole 4 — Vault search는 agent newsletter 검색과 불일치

증거:

  • /api/vault?vault=agent&path=100 수신함/121 뉴스레터: Damnang 노출 PASS
  • /vault/note?vault=agent&path=...: note preview PASS
  • /api/vault/search?q=Damnang: 해리 볼트만 검색, agent 뉴스레터 미반영

권고:

  • 검색 UI가 agent vault까지 찾길 기대한다면 /api/vault/searchvault=agent 옵션 지원 필요.
  • 현재는 browse/note 링크로 접근해야 정상.

Hole 5 — macro-series-collector 다음 실행 리스크

이번 검증의 UI 데이터는 존재하지만, 앞선 s9 검증 기준 /Users/ron/.hermes/fred_api_key가 없어 macro collector 다음 cron이 실패할 수 있다.

권고:

  • FRED key를 Hermes 경로에 배치하거나 cron env에 주입.

최종 판단

  • 데이터 저장소 → Hermes source UI 연결: PASS
  • 현재 PID 19581 실제 운영 UI가 Hermes source를 읽는지: FAIL
  • 해리 화면 기준 freeze 준비: FAIL / 보류

가장 큰 문제는 데이터가 아니라 웹앱 프로세스 실행 위치다.
Hermes source로 test_client를 돌리면 화면 데이터는 맞게 나온다. 하지만 실제 PID 19581은 old OpenClaw cwd/log 상태라, OpenClaw freeze 전에 재기동/launchd 정정이 필요하다.

자체평가

  • 정확성: 4.6/5 — 데이터 파일, Hermes source, test_client UI, PID 경로를 분리해 확인했다.
  • 완성도: 4.3/5 — 실제 curl은 sandbox 정책으로 실패해 test_client로 대체했다. PID mismatch는 수정하지 않고 보고했다.
  • 검증: 4.5/5 — 파일 최신성, source grep, lsof, curl 시도, jq 파싱, 브리핑 함수, vault browse/note를 확인했다.
  • 최소 변경: 5/5 — 데이터/프로세스/코드 수정 없이 보고서와 임시 /tmp/*.json만 생성했다.
  • 종합: 4.6/5

Remaining Risks: - Gateway/webapp 계열에서 “프로세스는 살아 있지만 status/cwd/source가 기대와 다른” 패턴이 반복된다. freeze 전 프로세스 실행 경로 검증을 필수 게이트로 추가해야 한다.


재시작 후 재개 확인 — 2026-04-15

중단 지점이던 운영 웹앱 PID 19581의 실행 경로 mismatch만 이어서 확인했다. 데이터/API 검증 전체를 처음부터 반복하지 않았다.

추가 확인 1 — LaunchAgent 파일은 Hermes 기준으로 패치됨

plutil -lint /Users/ron/Library/LaunchAgents/com.openclaw.sihwang-webapp.plist
→ OK

ProgramArguments:
  /usr/bin/python3
  /Users/ron/.hermes/workspace/scripts/pipeline/run_webapp.py
WorkingDirectory:
  /Users/ron/.hermes/workspace/scripts/pipeline
stdout/stderr:
  /Users/ron/.hermes/logs/sihwang-webapp*.log
plist mtime:
  Apr 15 14:35:33 2026

판정: 파일상 실행 정의는 PASS. 이전 보고서의 “launchd/실행 command를 Hermes 기준으로 바꿔야 함” 권고 중 파일 패치는 이미 반영되어 있다.

추가 확인 2 — launchd 메모리 상태는 아직 OpenClaw 기준

launchctl print gui/501/com.openclaw.sihwang-webapp
state = running
pid = 19581
arguments:
  /usr/bin/python3
  /Users/ron/.openclaw/workspace/scripts/pipeline/run_webapp.py
working directory:
  /Users/ron/.openclaw/workspace/scripts/pipeline
stdout/stderr:
  /Users/ron/.openclaw/logs/sihwang-webapp*.log

판정: 운영 프로세스는 아직 FAIL. plist 파일은 Hermes로 바뀌었지만, launchd가 이미 로드한 job definition은 구버전 OpenClaw 값을 유지하고 있다. 즉, bootout/bootstrap 또는 unload/load 재로드가 필요하다.

추가 확인 3 — 현재 8080 listener도 OpenClaw 프로세스

lsof -nP -iTCP:8080 -sTCP:LISTEN
Python 19581 ... TCP *:8080 (LISTEN)

lsof -p 19581
cwd  /Users/ron/.openclaw/workspace/scripts/pipeline
stdout /Users/ron/.openclaw/logs/sihwang-webapp.log
stderr /Users/ron/.openclaw/logs/sihwang-webapp-err.log

판정: PID 19581은 아직 OpenClaw 실행체다.

추가 확인 4 — Hermes webapp import는 정상

cd /Users/ron/.hermes/workspace/scripts/pipeline
OPENCLAW_WEBAPP_SKIP_APP_BOOTSTRAP=1 python3 - <<'PY'
import run_webapp
app = run_webapp.build_app()
print(run_webapp.__file__)
print(app.root_path)
PY

/Users/ron/.hermes/workspace/scripts/pipeline/run_webapp.py
/Users/ron/.hermes/workspace/scripts/pipeline/webapp

판정: Hermes 코드 자체는 로드 가능하다. 문제는 코드가 아니라 서비스 재로드 미실행이다.

실행하지 않은 조치

/Users/ron/.hermes/workspace/scripts/maintenance/sihwang_webapp_restart.sh는 현재 포트 8080 listener를 종료한 뒤 LaunchAgent를 다시 load하는 구조다. 기존 지시의 “webapp 프로세스 죽이지 말 것(PID 19581)” 제약 때문에 이번 검증 세션에서는 실행하지 않았다.

현재 결론 업데이트

  • 데이터 저장소 → Hermes source UI 연결: PASS 유지
  • LaunchAgent plist 파일 경로: PASS로 개선됨
  • launchd 로드된 job definition: FAIL
  • 현재 8080 운영 프로세스: FAIL
  • 필요 조치: 승인된 운영 재시작 1회. 재시작 후 launchctl print gui/501/com.openclaw.sihwang-webapplsof -p <new_pid>에서 .hermes 경로 확인 필요

구체 재개 요청 재검증 — 2026-04-15 15:17 KST

해리의 추가 지시로 이전에 no-kill 제약 때문에 남긴 감점 항목을 다시 시도했다. 이번에는 재시작까지 시도했지만, 현재 Codex 샌드박스 권한에서 launchctl 서비스 제어와 localhost 네트워크 연결이 차단되어 운영 PID 교체와 실제 curl은 완료되지 못했다. 대신 동일 Hermes source의 Flask test_client로 endpoint 로직/JSON을 재검증했다.

1) webapp PID 확인 + 필요시 재시작 시도

재시작 전 상태:

lsof -nP -iTCP:8080 -sTCP:LISTEN
Python 19581 ... TCP *:8080 (LISTEN)

launchctl print gui/501/com.openclaw.sihwang-webapp
pid = 19581
arguments:
  /usr/bin/python3
  /Users/ron/.openclaw/workspace/scripts/pipeline/run_webapp.py
working directory:
  /Users/ron/.openclaw/workspace/scripts/pipeline
stdout/stderr:
  /Users/ron/.openclaw/logs/sihwang-webapp*.log

plist 파일은 Hermes 기준이지만 launchd 메모리 정의는 OpenClaw 기준이라, 단순 kickstart만으로는 새 plist 반영이 불확실했다. 그래서 bootout → bootstrap → kickstart 순서로 시도했다.

launchctl bootout gui/501/com.openclaw.sihwang-webapp
→ Boot-out failed: 1: Operation not permitted

launchctl bootstrap gui/501 /Users/ron/Library/LaunchAgents/com.openclaw.sihwang-webapp.plist
→ Bootstrap failed: 5: Input/output error

launchctl kickstart -k gui/501/com.openclaw.sihwang-webapp
→ Could not kickstart service "com.openclaw.sihwang-webapp": 1: Operation not permitted

재시작 후 상태:

PID=19581
cwd  /Users/ron/.openclaw/workspace/scripts/pipeline
stdout /Users/ron/.openclaw/logs/sihwang-webapp.log
stderr /Users/ron/.openclaw/logs/sihwang-webapp-err.log

판정: FAIL / 권한 차단. 현재 세션에서는 launchd 제어가 막혀 실제 운영 PID를 Hermes로 교체하지 못했다.

2) /api/fed-liquidity/chart 실제 curl 시도

curl http://127.0.0.1:8080/api/fed-liquidity/chart
→ Immediate connect fail for 127.0.0.1: Operation not permitted
→ curl: (7) Failed to connect to 127.0.0.1 port 8080

Python socket도 동일하게 차단됐다.

127.0.0.1 PermissionError [Errno 1] Operation not permitted
localhost PermissionError [Errno 1] Operation not permitted
0.0.0.0 PermissionError [Errno 1] Operation not permitted

판정: 실제 curl 검증 BLOCKED. 서비스가 8080 LISTEN 중인 것은 lsof로 보이나, 현재 Codex 샌드박스가 localhost TCP 연결을 막는다.

대체 검증 — Hermes Flask test_client:

/api/fed-liquidity/chart status=200

응답 샘플:

{
  "dates": ["2026-02-18", "2026-02-25", "2026-03-04", "2026-03-11", "2026-03-18", "2026-03-25", "2026-04-01", "2026-04-08", "2026-04-15"],
  "rrp_b": [0.9, 1.2, 0.9, 0.6, 0.7, 0.8, 2.1, 0.2, 0.3],
  "rrp_t": [0.0009, 0.0012, 0.0009, 0.0006, 0.0007, 0.0008, 0.0021, 0.0002, 0.0003]
}

중요 발견:

  • 원천 데이터 RRPONTSYD.json에는 2026-04-14 value=0.306이 존재한다.
  • 그러나 /api/fed-liquidity/chart는 raw RRP 시계열을 직접 반환하지 않고, fed-liquidity/latest.json의 주간/통합 history를 반환한다.
  • 따라서 endpoint JSON에는 2026-04-14 / 0.306 원문이 그대로 나오지 않는다. 대신 최신 집계 row는 2026-04-15 rrp_t=0.0003, rrp_b=0.3으로 노출된다.

판정: 요청 기대값과 endpoint 설계 불일치. 2026-04-14 RRP 0.306은 데이터 파일에는 PASS, /api/fed-liquidity/chart 응답에는 그대로 나오지 않음.

3) /api/chart/SPY?days=30 실제 curl 시도

curl http://127.0.0.1:8080/api/chart/SPY?days=30
→ curl: (7) Failed to connect to 127.0.0.1 port 8080

대체 검증 — Hermes Flask test_client:

/api/chart/SPY?days=30 status=200 len=30 first=2026-03-03 last=2026-04-14
/api/chart/SPY?days=51 status=200 len=51 first=2026-01-30 last=2026-04-14
/api/chart/SPY status=200 len=51 first=2026-01-30 last=2026-04-14

원천 파일:

/Users/ron/.hermes/workspace/memory/price-history/SPY.json
rows=51
first=2026-01-30
last=2026-04-14 close=694.460022

판정:

  • 원천 데이터 51일 존재: PASS
  • /api/chart/SPY?days=30가 51일을 반환하는지: FAIL / 설계상 30개만 반환
  • 51일 확인은 /api/chart/SPY 또는 /api/chart/SPY?days=51에서 PASS

4) /vault embed 최신 담낭이 노트 5건 링크 동작

실제 curl은 localhost 차단으로 실패. Hermes Flask test_client/api/vault 목록과 /vault/note, /api/vault/note 링크를 확인했다.

최신 Damnang 5건:

260415_Damnang_Credo-Technology-Deep-Dive
260412_Damnang_LWLG-Structural-Technology-Risk-Analysis
260411_Damnang_Is-CXMT-a-Threat-or-an-Illusion
260411_Damnang_Citron-Sees-the-Valuation-but-Misses-the
260408_Damnang_The-Real-Game-Behind-Terafab

링크 검증:

각 5건 모두:
/vault/note?vault=agent&path=... → 200
/api/vault/note?vault=agent&path=... → 200

판정: PASS by test_client. 실제 브라우저/curl은 현재 세션 네트워크 차단 때문에 미확인.

5) morning_briefing.py _fed_liquidity_oneliner() 실제 호출

loaded_keys= ['date', 'history', 'interpretation', 'investment_signal', 'mom_m', 'mom_t', 'net_m', 'net_t', 'phase', 'phase_color', 'resv_m', 'resv_t', 'resv_wow_m', 'resv_wow_t', 'rrp_m', 'rrp_t', 'rrp_wow_m', 'rrp_wow_t', 'tga_m', 'tga_t', 'tga_wow_m', 'tga_wow_t', 'walcl_m', 'walcl_t', 'walcl_wow_m', 'walcl_wow_t', 'wow_m', 'wow_t']
date= 2026-04-15
phase= 유동성 축소 — 흡수 국면
oneliner= 연준 순유동성: $+5.95T 전주 $-0.00T / 국면: 유동성 축소 — 흡수 국면

판정: PASS. 한국어 oneliner 정상 출력.

이번 재검증 최종 판정

항목 결과 근거
webapp 운영 PID Hermes 재시작 FAIL/BLOCKED launchctl bootout/bootstrap/kickstart 모두 권한 차단, PID 19581 OpenClaw 유지
실제 curl /api/fed-liquidity/chart BLOCKED localhost TCP 연결이 sandbox에서 Operation not permitted
fed liquidity endpoint 데이터 PARTIAL Hermes test_client 200. 단, endpoint는 2026-04-14 RRP 0.306 raw 값을 직접 반환하지 않고 2026-04-15 rrp_b=0.3 집계값 반환
실제 curl /api/chart/SPY?days=30 BLOCKED localhost TCP 연결 차단
SPY 51일 데이터 PASS/PARTIAL 원천 51 rows, /api/chart/SPY 또는 days=51은 51 rows. days=30은 설계상 30 rows
vault 최신 Damnang 5건 링크 PASS by test_client 5건 모두 /vault/note, /api/vault/note 200
morning briefing oneliner PASS 한국어 oneliner 출력

조치 필요

현재 남은 핵심은 여전히 운영 프로세스 재로드다. 현재 세션에서는 권한 차단으로 할 수 없었다.

필요 명령은 샌드박스 밖 로컬 터미널에서 다음 순서다.

launchctl bootout gui/$(id -u)/com.openclaw.sihwang-webapp
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.openclaw.sihwang-webapp.plist
launchctl kickstart -k gui/$(id -u)/com.openclaw.sihwang-webapp
launchctl print gui/$(id -u)/com.openclaw.sihwang-webapp | grep -E 'run_webapp|working directory|pid'
lsof -p <new_pid> | grep -E '.hermes|sihwang-webapp'

그 다음 실제 터미널에서 curl 재확인 필요:

curl -s http://127.0.0.1:8080/api/fed-liquidity/chart | jq .
curl -s 'http://127.0.0.1:8080/api/chart/SPY?days=30' | jq '.data | length'