docs: SSOT 문서 허브 도입 및 동기화 자동 검증 게이트 (#350) #352

Closed
agentson wants to merge 1 commits from feature/issue-350-doc-ssot into feature/v3-session-policy-stream
10 changed files with 196 additions and 89 deletions
Showing only changes of commit 4ca582b418 - Show all commits

View File

@@ -8,6 +8,13 @@
- TASK: `TASK-...` - TASK: `TASK-...`
- TEST: `TEST-...` - TEST: `TEST-...`
## Docs Sync (SSOT)
- [ ] `docs/README.md` 라우팅/역할 영향 여부 확인
- [ ] SSOT 문서(architecture/commands/testing/ouroboros registry) 업데이트 또는 "변경 없음" 명시
- [ ] 요약 문서(`README.md`, `CLAUDE.md`)에 가변 수치 하드코딩 추가 없음
- SSOT 반영 위치(링크):
## Ticket Stage ## Ticket Stage
- Current stage: `Implemented` / `Integrated` / `Observed` / `Accepted` - Current stage: `Implemented` / `Integrated` / `Observed` / `Accepted`

View File

@@ -47,6 +47,9 @@ jobs:
- name: Validate Ouroboros docs - name: Validate Ouroboros docs
run: python3 scripts/validate_ouroboros_docs.py run: python3 scripts/validate_ouroboros_docs.py
- name: Validate docs sync
run: python3 scripts/validate_docs_sync.py
- name: Lint - name: Lint
run: ruff check src/ tests/ run: ruff check src/ tests/

View File

@@ -44,6 +44,9 @@ jobs:
- name: Validate Ouroboros docs - name: Validate Ouroboros docs
run: python3 scripts/validate_ouroboros_docs.py run: python3 scripts/validate_ouroboros_docs.py
- name: Validate docs sync
run: python3 scripts/validate_docs_sync.py
- name: Lint - name: Lint
run: ruff check src/ tests/ run: ruff check src/ tests/

View File

@@ -2,6 +2,10 @@
AI-powered trading agent for global stock markets with self-evolution capabilities. AI-powered trading agent for global stock markets with self-evolution capabilities.
## Documentation Entry
문서 우선순위/역할은 [docs/README.md](docs/README.md)를 기준으로 한다.
## Quick Start ## Quick Start
```bash ```bash
@@ -83,7 +87,7 @@ SCANNER_TOP_N=3 # Max candidates per scan
### Trading Mode Integration ### Trading Mode Integration
Smart Scanner runs in both `TRADE_MODE=realtime` and `daily` paths. On API failure, domestic stocks fall back to a static watchlist; overseas stocks fall back to a dynamic universe (active positions, recent holdings). Smart Scanner behavior and mode integration are defined in [docs/architecture.md](docs/architecture.md).
## Documentation ## Documentation
@@ -122,7 +126,7 @@ src/
├── broker/ # KIS API client (domestic + overseas) ├── broker/ # KIS API client (domestic + overseas)
├── context/ # L1-L7 hierarchical memory system ├── context/ # L1-L7 hierarchical memory system
├── core/ # Risk manager (READ-ONLY) ├── core/ # Risk manager (READ-ONLY)
├── dashboard/ # FastAPI read-only monitoring (10 API endpoints) ├── dashboard/ # FastAPI read-only monitoring (endpoint details: docs/commands.md)
├── data/ # External data integration (news, market data, calendar) ├── data/ # External data integration (news, market data, calendar)
├── evolution/ # Self-improvement (optimizer, daily review, scorecard) ├── evolution/ # Self-improvement (optimizer, daily review, scorecard)
├── logging/ # Decision logger (audit trail) ├── logging/ # Decision logger (audit trail)
@@ -133,7 +137,7 @@ src/
├── main.py # Trading loop orchestrator ├── main.py # Trading loop orchestrator
└── config.py # Settings (from .env) └── config.py # Settings (from .env)
tests/ # 998 tests across 41 files tests/ # Test suite (details: docs/testing.md)
docs/ # Extended documentation docs/ # Extended documentation
``` ```

View File

@@ -2,6 +2,10 @@
KIS(한국투자증권) API로 매매하고, Google Gemini로 판단하며, 자체 전략 코드를 TDD 기반으로 진화시키는 자율 주식 트레이딩 에이전트. KIS(한국투자증권) API로 매매하고, Google Gemini로 판단하며, 자체 전략 코드를 TDD 기반으로 진화시키는 자율 주식 트레이딩 에이전트.
## 문서 네비게이션
문서 전체 라우팅/역할/우선순위는 [docs/README.md](docs/README.md)를 기준으로 본다.
## 아키텍처 ## 아키텍처
``` ```
@@ -39,7 +43,7 @@ KIS(한국투자증권) API로 매매하고, Google Gemini로 판단하며, 자
| 컨텍스트 | `src/context/` | L1-L7 계층형 메모리 시스템 | | 컨텍스트 | `src/context/` | L1-L7 계층형 메모리 시스템 |
| 분석 | `src/analysis/` | RSI, ATR, Smart Volatility Scanner | | 분석 | `src/analysis/` | RSI, ATR, Smart Volatility Scanner |
| 알림 | `src/notifications/` | 텔레그램 양방향 (알림 + 9개 명령어) | | 알림 | `src/notifications/` | 텔레그램 양방향 (알림 + 9개 명령어) |
| 대시보드 | `src/dashboard/` | FastAPI 읽기 전용 모니터링 (10개 API) | | 대시보드 | `src/dashboard/` | FastAPI 읽기 전용 모니터링 (엔드포인트 목록은 `docs/commands.md`) |
| 진화 | `src/evolution/` | 전략 진화 + Daily Review + Scorecard | | 진화 | `src/evolution/` | 전략 진화 + Daily Review + Scorecard |
| 의사결정 로그 | `src/logging/` | 전체 거래 결정 감사 추적 | | 의사결정 로그 | `src/logging/` | 전체 거래 결정 감사 추적 |
| 데이터 | `src/data/` | 뉴스, 시장 데이터, 경제 캘린더 연동 | | 데이터 | `src/data/` | 뉴스, 시장 데이터, 경제 캘린더 연동 |
@@ -153,19 +157,10 @@ docker compose up -d ouroboros
## 테스트 ## 테스트
998개 테스트가 41개 파일에 걸쳐 구현되어 있습니다. 최소 커버리지 80%. 테스트 정책/실행/구성은 [docs/testing.md](docs/testing.md)를 기준으로 한다.
``` - 최소 커버리지: 80%
tests/test_main.py — 거래 루프 통합 - 전체 수집 기준: `pytest --collect-only -q`
tests/test_scenario_engine.py — 시나리오 매칭
tests/test_pre_market_planner.py — 플레이북 생성
tests/test_overseas_broker.py — 해외 브로커
tests/test_telegram_commands.py — 텔레그램 명령어
tests/test_telegram.py — 텔레그램 알림
... 외 35개 파일 ※ 파일별 수치는 CI 기준으로 변동 가능
```
**상세**: [docs/testing.md](docs/testing.md)
## 기술 스택 ## 기술 스택
@@ -174,7 +169,7 @@ tests/test_telegram.py — 텔레그램 알림
- **AI**: Google Gemini Pro - **AI**: Google Gemini Pro
- **DB**: SQLite (5개 테이블: trades, contexts, decision_logs, playbooks, context_metadata) - **DB**: SQLite (5개 테이블: trades, contexts, decision_logs, playbooks, context_metadata)
- **대시보드**: FastAPI + uvicorn - **대시보드**: FastAPI + uvicorn
- **검증**: pytest + coverage (998 tests) - **검증**: pytest + coverage (`docs/testing.md` 기준)
- **CI/CD**: Gitea CI (`.gitea/workflows/ci.yml`) - **CI/CD**: Gitea CI (`.gitea/workflows/ci.yml`)
- **배포**: Docker + Docker Compose - **배포**: Docker + Docker Compose
@@ -209,7 +204,7 @@ The-Ouroboros/
│ ├── config.py # Pydantic 설정 │ ├── config.py # Pydantic 설정
│ ├── db.py # SQLite 데이터베이스 │ ├── db.py # SQLite 데이터베이스
│ └── main.py # 비동기 거래 루프 │ └── main.py # 비동기 거래 루프
├── tests/ # 998개 테스트 (41개 파일) ├── tests/ # 테스트 스위트 (세부는 docs/testing.md 참조)
├── Dockerfile # 멀티스테이지 빌드 ├── Dockerfile # 멀티스테이지 빌드
├── docker-compose.yml # 서비스 오케스트레이션 ├── docker-compose.yml # 서비스 오케스트레이션
└── pyproject.toml # 의존성 및 도구 설정 └── pyproject.toml # 의존성 및 도구 설정

29
docs/README.md Normal file
View File

@@ -0,0 +1,29 @@
# Documentation Map
이 문서는 저장소 문서의 단일 라우팅/역할 정의다.
각 문서는 아래 역할 범위를 넘지 않는다.
## Reading Order
1. [Project README](../README.md): 빠른 시작, 개요
2. [Architecture](architecture.md): 시스템 구성/데이터 흐름
3. [Workflow](workflow.md): 개발/PR/검증 절차
4. [Commands](commands.md): 실행/운영 명령 레퍼런스
5. [Testing](testing.md): 테스트 전략/작성/운영
6. [Ouroboros Hub](ouroboros/README.md): 기획/요구사항/실행 통제 문서군
## Single Source of Truth (SSOT)
- 아키텍처/동작 기준: [Architecture](architecture.md)
- 실행 명령 기준: [Commands](commands.md)
- 테스트 정책 기준: [Testing](testing.md)
- 요구사항/REQ 기준: [Requirements Registry](ouroboros/01_requirements_registry.md)
- 작업/TASK 기준: [Code Work Orders](ouroboros/30_code_level_work_orders.md)
- 수용/TEST 기준: [Acceptance Plan](ouroboros/40_acceptance_and_test_plan.md)
## Authoring Rules
- `README.md`, `CLAUDE.md`는 입문/요약 역할만 가진다.
- 가변 수치(테스트 개수, API 개수, 세부 파일별 케이스 수)는 요약 문서에 고정값으로 중복 기재하지 않는다.
- 수치/정책 상세는 SSOT 문서에만 기록하고, 요약 문서에서는 링크로 참조한다.
- 동일 내용이 2개 이상 문서에 반복되면 요약 + 링크 형태로 축약한다.

View File

@@ -136,9 +136,12 @@ No decorator needed for async tests.
# Install all dependencies (production + dev) # Install all dependencies (production + dev)
pip install -e ".[dev]" pip install -e ".[dev]"
# Run full test suite with coverage (998 tests across 41 files) # Run full test suite with coverage
pytest -v --cov=src --cov-report=term-missing pytest -v --cov=src --cov-report=term-missing
# Validate docs sync rules (SSOT/duplication guard)
python3 scripts/validate_docs_sync.py
# Run a single test file # Run a single test file
pytest tests/test_risk.py -v pytest tests/test_risk.py -v
@@ -201,8 +204,8 @@ Dashboard runs as a daemon thread on `DASHBOARD_HOST:DASHBOARD_PORT` (default: `
| `GET /api/performance` | Performance metrics by market and combined | | `GET /api/performance` | Performance metrics by market and combined |
| `GET /api/context/{layer}` | Context data by layer L1-L7 (query: `timeframe`) | | `GET /api/context/{layer}` | Context data by layer L1-L7 (query: `timeframe`) |
| `GET /api/decisions` | Decision log entries (query: `limit`, `market`) | | `GET /api/decisions` | Decision log entries (query: `limit`, `market`) |
| `GET /api/pnl/history` | P&L history time series |
| `GET /api/scenarios/active` | Today's matched scenarios | | `GET /api/scenarios/active` | Today's matched scenarios |
| `GET /api/pnl/history` | P&L history over time |
| `GET /api/positions` | Current open positions | | `GET /api/positions` | Current open positions |
## Telegram Commands ## Telegram Commands

View File

@@ -1,96 +1,75 @@
<!-- <!--
Doc-ID: DOC-PLAN-082 Doc-ID: DOC-PLAN-082
Version: 1.0.0 Version: 1.1.0
Status: draft Status: active
Owner: strategy Owner: strategy
Updated: 2026-02-28 Updated: 2026-03-01
--> -->
# 문서 재구조화 계획: 감사 → 실행 파이프라인 # 문서 재구조화 실행 현황
## Context ## 목적
80_implementation_audit.md는 v2/v3 구현 감사와 수익률 분석을 수행했으나, 여러 차례 리뷰를 거치면서 리뷰 이력/데이터 품질 논의/SQL 쿼리 등이 혼재되어 **실행 문서로 사용하기 어려운 상태**다. 문서 중복/드리프트/탐색 난이도를 줄여, 에이전트가 문서 기반으로 기획/설계/구현/검증을 일관되게 수행하도록 운영 규칙을 고정한다.
목표: 이 감사 결과를 바탕으로 **티켓 생성 → 개발 설계 → 구현/리뷰 → 검증 → 실환경 테스트**까지 일관되게 진행할 수 있는 문서 체계를 만든다. ## 적용 범위
## 변경 사항 - 루트 요약 문서: `README.md`, `CLAUDE.md`
- 운영 문서: `docs/architecture.md`, `docs/commands.md`, `docs/testing.md`, `docs/workflow.md`
- 실행 통제 문서군: `docs/ouroboros/*`
- 검증 자동화: `scripts/validate_docs_sync.py`, CI 워크플로우
### 1. 80_implementation_audit.md 정리 (감사 기록 문서) ## 완료 항목 (2026-03-01)
**역할**: 현재 상태의 팩트 기록. "무엇이 문제인가"에만 집중. ### 1) 문서 라우팅/역할 고정
정리 내용: - `docs/README.md` 신설
- Section 3: P&L 분석을 핵심 수치만 남기고 간결화 - 읽기 순서 + SSOT + 작성 규칙 명시
- 3.1(종합), 3.3(시장별), 3.4(통화 분리), 3.5(전략 진입분 분리), 3.6(무결성 결론) 유지
- 3.2 일별 손익: 주의 문구 제거, 본문으로 통합
- 3.7 데이터 품질: 핵심 결론만 남기고 세부 항목 제거
- 3.8 SQL: 별도 파일(`scripts/audit_queries.sql`)로 분리, 본문에서 참조만
- Section 6.1, 6.2 리뷰 반영 이력: 전부 제거 (git history로 추적 가능)
- Section 6 테스트: "재점검으로 확인" 항목을 "테스트 존재" 항목에 통합
- 신규 Section 7: 후속 문서 링크 (85_ 참조)
### 2. 85_loss_recovery_action_plan.md 신규 작성 (실행 계획 문서) ### 2) 요약 문서 중복 축소
**역할**: "어떻게 고칠 것인가". 티켓 생성부터 실환경 검증까지의 실행 청사진. - `README.md`, `CLAUDE.md`에 문서 진입점 추가
- 가변 수치/세부 동작의 직접 중복 기재를 축약하고 SSOT 문서 링크 중심으로 정리
구조: ### 3) 명령/테스트 문서 정합성 개선
```
## 1. 요약
- 목표: 손실 구간 탈출을 위한 7개 ROOT/5개 GAP 해소
- 성공 기준 (정량)
## 2. Phase별 작업 분해 - `docs/commands.md` 대시보드 API 목록 최신화(`pnl/history`, `positions` 포함)
### Phase 1: 즉시 파라미터/로직 수정 (손실 출혈 차단) - `docs/testing.md` 테스트 총량 확인 방식을 고정 수치 -> `pytest --collect-only -q`로 전환
각 항목마다:
- ROOT/GAP 참조
- Gitea 이슈 제목/설명 템플릿
- 변경 대상 파일 + 현재 동작 + 목표 동작
- 수용 기준 (acceptance criteria)
- 테스트 계획
- 의존성/차단 관계
### Phase 2: 데이터 정합성 + v2 실효화 ### 4) 동기화 자동 검증 + CI 게이트
(동일 형식)
### Phase 3: v3 세션 최적화 - `scripts/validate_docs_sync.py` 추가
(동일 형식) - `.gitea/workflows/ci.yml`, `.github/workflows/ci.yml``Validate docs sync` 단계 추가
- `docs/commands.md`에 동기화 검증 명령 추가
## 3. 검증 계획 ## 잔여 작업
- 단위 테스트 기준
- 통합 테스트 시나리오 (백테스트 파이프라인 활용)
- 실환경 검증: 소액 live 운용으로 직접 검증
(paper trading 제외 — 실환경과 괴리가 커 검증 신뢰도 부족)
- Phase별 실환경 투입 기준:
단위/통합 테스트 통과 → 소액 live → 모니터링 → 정상 확인 후 본운용
## 4. 의존성 그래프 ### A) SSOT 강제 범위 확장
- Phase 간 blocking 관계 - `README.md`/`CLAUDE.md`의 남은 동작 설명을 더 축약하고 상세는 `docs/architecture.md`로 일원화
- Phase 내 작업 순서 - `docs/testing.md`의 파일별 테스트 개수 스냅샷 자동 생성 여부 결정
## 5. 롤백 계획 ### B) 검증 규칙 고도화
- 각 Phase 실패 시 롤백 절차 - `validate_docs_sync.py`에 추가 패턴(중복 정책 문구/금지 숫자 표현) 확대
``` - 필요 시 `docs/architecture.md`를 API/모드 동작의 유일한 근거 문서로 명시
### 3. README.md 업데이트 ### C) 유지보수 운영화
- 릴리즈/스프린트 종료 시 문서 동기화 점검 체크리스트 정례화
- 문서 변경 PR 템플릿에 "SSOT 링크 업데이트 여부" 체크박스 추가 검토
- 85_ 문서 링크 추가 ## 검증 상태
## 작업 순서 - `python3 scripts/validate_docs_sync.py`: PASS
- `python3 scripts/validate_ouroboros_docs.py`: PASS
- `python3 scripts/validate_governance_assets.py`: PASS
1. 80_ 정리 (노이즈 제거, SQL 분리, 리뷰 이력 삭제) ## 운영 규칙
2. `scripts/audit_queries.sql` 작성 (80_에서 분리한 SQL)
3. 85_ 신규 작성 (실행 계획)
4. README.md 업데이트
## 작성하지 않는 것 - 문서 구조 변경 시 `docs/README.md`와 동기화 검증 규칙을 함께 갱신한다.
- 요약 문서는 "개요/진입점" 역할만 유지하고, 상세 사실/수치 정책은 SSOT 문서에만 기록한다.
- 가변 수치(테스트 개수, 엔드포인트 개수)는 자동 확인 명령 또는 SSOT 링크로 대체한다.
- 30_code_level_work_orders.md, 40_acceptance_and_test_plan.md 업데이트: 85_를 기반으로 실제 구현 시점에 업데이트 (지금은 실행 계획 수립까지만) ## 참조
- 01_requirements_registry.md: ROOT/GAP에서 파생되는 신규 REQ는 구현 착수 시 등록
- Gitea 이슈 생성: 85_ 문서 확정 후 별도 진행
## 검증 - 문서 허브: [docs/README.md](../../docs/README.md)
- 실행 문서 허브: [docs/ouroboros/README.md](./README.md)
- 80_: 감사 팩트만 남았는지, 리뷰 이력이 제거되었는지 확인 - 동기화 검증 스크립트: [`scripts/validate_docs_sync.py`](../../scripts/validate_docs_sync.py)
- 85_: Phase별 작업이 Gitea 이슈로 바로 전환 가능한 수준인지 확인
- 85_ 각 항목에 수용 기준과 테스트 계획이 포함되었는지 확인

View File

@@ -2,7 +2,13 @@
## Test Structure ## Test Structure
**998 tests** across **41 files**. `asyncio_mode = "auto"` in pyproject.toml — async tests need no special decorator. 테스트 총량은 지속적으로 변동된다. 최신 수치는 아래 명령으로 확인한다.
```bash
pytest --collect-only -q
```
`asyncio_mode = "auto"` in pyproject.toml — async tests need no special decorator.
The `settings` fixture in `conftest.py` provides safe defaults with test credentials and in-memory DB. The `settings` fixture in `conftest.py` provides safe defaults with test credentials and in-memory DB.

View File

@@ -0,0 +1,78 @@
#!/usr/bin/env python3
"""Validate lightweight documentation synchronization rules."""
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(".")
def read_text(path: Path, errors: list[str]) -> str:
if not path.exists():
errors.append(f"missing file: {path}")
return ""
return path.read_text(encoding="utf-8")
def main() -> int:
errors: list[str] = []
docs_index = ROOT / "docs" / "README.md"
readme = ROOT / "README.md"
claude = ROOT / "CLAUDE.md"
commands = ROOT / "docs" / "commands.md"
docs_index_text = read_text(docs_index, errors)
readme_text = read_text(readme, errors)
claude_text = read_text(claude, errors)
commands_text = read_text(commands, errors)
if docs_index_text and "Single Source of Truth" not in docs_index_text:
errors.append("docs/README.md: missing 'Single Source of Truth' section")
if readme_text and "docs/README.md" not in readme_text:
errors.append("README.md: missing docs/README.md routing link")
if claude_text and "docs/README.md" not in claude_text:
errors.append("CLAUDE.md: missing docs/README.md routing link")
# Prevent volatile hard-coded scale numbers in summary docs.
volatile_patterns: list[tuple[str, re.Pattern[str]]] = [
("README.md", re.compile(r"\b\d+\s*개 테스트\b")),
("README.md", re.compile(r"\b\d+\s*tests\s+across\b", re.IGNORECASE)),
("README.md", re.compile(r"\(\d+\s*개 API\)")),
("README.md", re.compile(r"\(\d+\s*API endpoints?\)", re.IGNORECASE)),
("CLAUDE.md", re.compile(r"\b\d+\s*tests\s+across\b", re.IGNORECASE)),
("CLAUDE.md", re.compile(r"\(\d+\s*API endpoints?\)", re.IGNORECASE)),
("docs/commands.md", re.compile(r"Run full test suite with coverage\s*\(\d+", re.IGNORECASE)),
]
text_by_name = {
"README.md": readme_text,
"CLAUDE.md": claude_text,
"docs/commands.md": commands_text,
}
for name, pattern in volatile_patterns:
text = text_by_name.get(name, "")
if text and pattern.search(text):
errors.append(f"{name}: contains volatile hard-coded scale text ({pattern.pattern})")
# Command doc should list all dashboard endpoints exposed by app.py.
for endpoint in ("/api/pnl/history", "/api/positions"):
if commands_text and endpoint not in commands_text:
errors.append(f"docs/commands.md: missing dashboard endpoint {endpoint}")
if errors:
print("[FAIL] docs sync validation failed")
for err in errors:
print(f"- {err}")
return 1
print("[OK] docs sync validation passed")
return 0
if __name__ == "__main__":
sys.exit(main())