# stock-lab → stock 리네이밍 Design

**작성일**: 2026-05-15
**작성자**: gahusb
**상태**: Approved for implementation
**선행 spec**: Confidence Signal Pipeline V2 Phase 0 (`2026-05-15-confidence-signal-pipeline-v2-architecture.md`)

---

## 1. 목표

`stock-lab` 컨테이너/디렉토리/환경변수의 `-lab` 접미사를 제거해 **stock** 으로 graduation. lab 네이밍 규칙 (`feedback_lab_naming.md`) 에 따라 정식 서비스로 명확화.

본 리네이밍은 **Confidence Signal Pipeline V2 Phase 1** 작업 시작 전 선행. 이름이 stock-lab인 채로 Phase 1 spec/plan/code 가 작성되면 다시 갱신하는 비용 회피.

**Why**: 메모리 `feedback_lab_naming.md` 정책 — "-lab은 개발/연구 단계에만, 정식 서비스에는 미사용". stock 서비스는 (a) 8 노드 screener 완성, (b) 캔버스 UI, (c) AI 뉴스 Phase 1, (d) V2 시그널 파이프라인의 중심 = 정식 graduation 단계.

---

## 2. 범위

**포함**:
- web-backend 디렉토리 `git mv stock-lab stock`
- `docker-compose.yml` 4 곳 갱신
- agent-office 환경변수 `STOCK_LAB_URL` → `STOCK_URL` 코드 + 컴포즈
- nginx config (`nginx/default.conf` in web-backend repo) `upstream stock-lab` → `stock`
- 운영 문서 (`web-backend/CLAUDE.md`, `README.md`, `STATUS.md`, scripts)
- workspace `CLAUDE.md` + web-ui `CLAUDE.md`
- 메모리 4개 (`project_workspace.md`, `project_scale.md`, `project_stock_screener.md`, `nas_infra.md`)
- 메모리 정책 추가 (`feedback_lab_naming.md` 에 stock graduation 케이스 등재)

**범위 외 (NOT)**:
- API URL 경로 (`/api/stock/...` 그대로)
- Python `app.*` import 경로
- DB 파일명 (`stock.db` 그대로)
- frontend 라우트 (`/stock/*` 그대로)
- 다른 lab 의 이름 (lotto/music-lab/blog-lab/realestate-lab/packs-lab/travel-proxy 모두 그대로)
- 과거 spec/plan 문서 (`docs/superpowers/specs|plans/2026-05-*.md`) — 역사적 기록 유지
- `.venv` 디렉토리 — gitignore, 사용자 로컬에서 재생성

---

## 3. 변경 매트릭스

### 3.1 web-backend 코드 (필수)

| 파일 | 변경 |
|------|------|
| `stock-lab/` → `stock/` | `git mv` |
| `docker-compose.yml` | service key `stock-lab` → `stock` (1) / container_name `stock-lab` → `stock` (1) / build.context `./stock-lab` → `./stock` (1) / frontend.depends_on의 `stock-lab` → `stock` (1) |
| `agent-office/app/config.py` | `STOCK_LAB_URL = os.getenv("STOCK_LAB_URL", ...)` → `STOCK_URL = os.getenv("STOCK_URL", ...)` |
| `agent-office/app/service_proxy.py` | `from .config import STOCK_LAB_URL` → `STOCK_URL`. 함수 본문의 `STOCK_LAB_URL` 사용처 5개 (fetch_stock_news / fetch_stock_indices / summarize_stock_news / refresh_screener_snapshot / run_stock_screener) → `STOCK_URL` |
| `agent-office/app/agents/stock.py` | `STOCK_LAB_URL` 직접 참조 시 갱신 (만약 있다면) |
| `agent-office/tests/test_stock_screener_job.py` | mock URL 또는 env var 참조 갱신 |
| `agent-office docker-compose.yml 부분` | `STOCK_LAB_URL=http://stock-lab:8000` → `STOCK_URL=http://stock:8000` |
| `nginx/default.conf` | `upstream stock-lab { server stock-lab:8000; }` → `upstream stock { server stock:8000; }` + `proxy_pass http://stock-lab` → `http://stock` |
| `web-backend/CLAUDE.md` | stock-lab 언급 모두 stock 으로 |
| `web-backend/README.md` | 동일 |
| `web-backend/STATUS.md` | 동일 |
| `web-backend/scripts/deploy-nas.sh`, `deploy.sh` | stock-lab 호출/경로 갱신 |

### 3.2 web-ui (문서만)

| 파일 | 변경 |
|------|------|
| `web-ui/CLAUDE.md` | stock-lab 언급을 stock 으로 (디렉토리 경로 표 포함) |

**과거 spec/plan 문서들** (`web-ui/docs/superpowers/specs|plans/2026-05-*.md`): 역사적 기록 유지 — **변경 없음**.

### 3.3 workspace 최상위

| 파일 | 변경 |
|------|------|
| `workspace/CLAUDE.md` | "stock-lab" 컨테이너 이름 표 + 디렉토리 경로 갱신 |

### 3.4 메모리 (controller 직접 적용)

| 메모리 | 변경 |
|--------|------|
| `project_workspace.md` | stock-lab → stock |
| `project_scale.md` | 백엔드 서비스 표의 stock-lab 행 갱신, `stock-lab/` 디렉토리 → `stock/` |
| `project_stock_screener.md` | 다수 언급 (백엔드 위치) 갱신 |
| `nas_infra.md` | Docker 서비스 포트 표 + nginx 라우팅 |
| `feedback_lab_naming.md` | stock graduation 사례 추가 (2026-05-15) |

---

## 4. 작업 순서

```
1. 사전 검토 (10분)
   - 본 spec 의 3장 매트릭스 모든 파일이 grep 결과와 일치하는지 cross-check
   - `.venv` / `__pycache__` 제외 확인
   - nginx default.conf 의 정확한 변경 줄 식별

2. web-backend 디렉토리 + 컴포즈 + agent-office 코드 (한 commit)
   - git mv stock-lab stock
   - docker-compose.yml 4 곳
   - agent-office config.py, service_proxy.py, agents/stock.py, tests/
   - nginx/default.conf
   - web-backend의 CLAUDE.md, README.md, STATUS.md, scripts/

3. workspace + web-ui CLAUDE.md (별도 commit, 각 repo)
   - workspace/CLAUDE.md
   - web-ui/CLAUDE.md

4. 메모리 갱신 (controller 직접)
   - 4개 메모리 파일 + feedback_lab_naming.md graduation 케이스

5. 배포 검증
   - web-backend push → Gitea webhook → deployer rsync + docker compose up
   - docker logs stock --tail 30
   - docker ps 에서 stock 컨테이너 healthy
   - curl https://gahusb.synology.me/api/stock/news (200)
   - curl https://gahusb.synology.me/api/stock/screener/runs (200)
   - agent-office 다음 16:30 cron 결과 (텔레그램) 정상 도착 확인 또는 수동 트리거
```

---

## 5. 위험 및 완화

| 위험 | 완화 |
|------|------|
| nginx config 가 옛 호스트 `stock-lab` 으로 라우팅 → 502 | nginx config 도 같은 commit 에 포함. deployer rsync 가 web-backend repo 의 nginx 폴더를 NAS runtime 에 동기화 |
| agent-office 가 옛 환경변수 `STOCK_LAB_URL` 사용 → connection refused | 컴포즈의 환경변수 항목 동시 변경. agent-office 재기동 후 새 변수 적용 |
| `.env` 파일에 `STOCK_LAB_URL=...` 남아 있으면 새 변수 빈 값 → 기본값 `http://stock:8000` fallback | service_proxy 의 `os.getenv("STOCK_URL", "http://stock:8000")` default 확인. 운영 .env 갱신은 사용자 1회 작업 |
| 다른 lab 의 stock-lab 호출 누락 | grep `STOCK_LAB_URL` 결과 5개 파일 모두 commit 에 포함. 추가 누락 시 다음 cron 실패로 즉시 발견 |
| 컨테이너 교체 다운타임 | 약 10초 (docker compose up 의 stop+start). 1인 운영 + 비치명적, 허용 |
| Python `app.*` import 경로 회귀 | 디렉토리 이름만 변경. 빌드 컨텍스트 변경으로 도커 이미지 안의 app 패키지 그대로. 회귀 없음 (76 + 신규 테스트 전부 통과 검증) |
| 메모리 갱신 누락 | grep "stock-lab" / "STOCK_LAB" 메모리 폴더 0건 검증 |
| 과거 spec/plan 문서의 stock-lab 언급 | 역사적 기록 — 의도적 보존. 미래 spec 부터 stock 사용 |

---

## 6. 테스트 / 검증

### 6.1 자동 (코드 검증)

```bash
# stock-lab 잔여 참조 0건 (의도적 보존 spec/plan 제외)
grep -rln "stock-lab\|STOCK_LAB" /c/Users/jaeoh/Desktop/workspace/web-backend/ \
  | grep -v "\.venv" | grep -v "__pycache__" | grep -v "/docs/" | grep -v "\.git"
# Expected: 0 lines

# agent-office 테스트
cd /c/Users/jaeoh/Desktop/workspace/web-backend/agent-office
python -m pytest tests/test_stock_screener_job.py -v
# Expected: PASS

# stock pytest
cd /c/Users/jaeoh/Desktop/workspace/web-backend/stock
python -m pytest --ignore=app/test_scraper.py -q
# Expected: 76+ tests passed
```

### 6.2 수동 (배포 검증)

배포 후 NAS:
```bash
docker logs stock --tail 30
docker logs agent-office --tail 20
docker ps --format "{{.Names}}: {{.Status}}" | grep stock
```

브라우저 / curl:
- `https://gahusb.synology.me/api/stock/news` → 200
- `https://gahusb.synology.me/api/stock/screener/runs` → 200
- `https://gahusb.synology.me/stock/screener` (web-ui) → 캔버스 모드 진입 정상

agent-office 수동 트리거 (다음 cron 기다리지 않고):
```bash
curl -X POST "https://gahusb.synology.me/api/agent-office/command" \
  -H "Content-Type: application/json" \
  -d '{"agent":"stock","action":"run_ai_news"}'
```
응답 `{"ok": true}` + 텔레그램 도착 → stock 호스트 라우팅 정상.

---

## 7. 운영 영향

| 항목 | 영향 |
|------|------|
| 다운타임 | ~10초 (컨테이너 교체) |
| 사용자 영향 | 없음 (API URL/UI 경로 그대로) |
| .env 파일 갱신 | 사용자 1회 (STOCK_LAB_URL 줄 삭제 또는 STOCK_URL 추가) |
| frontend 재배포 | 불필요 (web-ui 는 문서만 변경) |
| 다른 lab 영향 | agent-office 만 영향 (환경변수). 나머지 lab 무영향 |

---

## 8. Phase 1 와의 관계

본 리네이밍 완료 후 즉시 **Confidence Signal Pipeline V2 Phase 1** spec 작성 (이전 발표 디자인 그대로, 새 이름 `stock` 기준). 의존성:
```
[본 리네이밍 spec/plan/실행]  →  [Phase 1 spec → plan → 실행]
       1-2시간                          1주
```

---

## 9. 완료 조건 (DoD)

- [ ] `web-backend/stock-lab/` 디렉토리 사라지고 `stock/` 존재 (git history 보존)
- [ ] `docker-compose.yml` 의 4 곳 갱신
- [ ] agent-office env 변수 `STOCK_LAB_URL` 코드/컴포즈/문서에서 0건
- [ ] nginx config `upstream stock-lab` 0건, `upstream stock` 존재
- [ ] grep "stock-lab" 결과: 의도적 보존 (`docs/superpowers/*`) 외 0건
- [ ] stock pytest 76+ tests passed
- [ ] 배포 후 `docker ps` 에 `stock` 컨테이너 healthy
- [ ] curl `/api/stock/news`, `/api/stock/screener/runs` 200
- [ ] agent-office `run_ai_news` 수동 트리거 텔레그램 도착
- [ ] 메모리 4 파일 갱신 + `feedback_lab_naming.md` graduation 케이스 등재
