애플리케이션 정의 기준 94 HTTP routes + 1 WebSocket. FastAPI 자동 문서 route(/docs, /redoc, /openapi.json, OAuth redirect)를 포함하면 HTTP route는 98개다. 인증은 DASHBOARD_PASSWORD 설정 시 쿠키 기반 세션 (dash_session). /, /static/*, /login, /features, /landing/ops, /landing/team, /landing/executive, /api/auth/login, /api/auth/me, /api/health, /metrics, /api/ingest, /api/codex-collector.py 는 인증 우회.
프로젝트 기준과 문서 우선순위는 AGENTS.md를 따른다. 이 문서는 인터페이스 계약과 호출 예시에 집중한다.
이 문서와 별개로 FastAPI 가 자동 생성하는 라이브 스펙이 있습니다:
| URL | 용도 |
|---|---|
http://localhost:8617/docs |
Swagger UI — 브라우저 인터랙티브 탐색, 요청 시도 |
http://localhost:8617/redoc |
ReDoc — 더 읽기 좋은 문서 뷰 |
http://localhost:8617/openapi.json |
OpenAPI 3.1 스펙 JSON — 외부 통합 / 클라이언트 코드 생성 |
외부 툴에서 이 대시보드 API 를 호출하려면 openapi.json 을 가져와
원하는 언어의 client generator 에 넣으면 됩니다. 예:
curl -s http://localhost:8617/openapi.json | jq '.paths | keys' | head| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /login |
로그인 페이지 HTML (인증 우회) |
| GET | / |
공개 랜딩 페이지 (인증 우회) |
| GET | /landing/ops |
Ops 대상 공개 랜딩 페이지 (인증 우회) |
| GET | /landing/team |
Team 대상 공개 랜딩 페이지 (인증 우회) |
| GET | /landing/executive |
Executive 대상 공개 랜딩 페이지 (인증 우회) |
| POST | /api/auth/login |
로그인. Body: {password}. 성공 시 dash_session 쿠키 발급 (HMAC 서명, 만료 내장). Rate limit: 5회/분/IP |
| POST | /api/auth/logout |
로그아웃 (dash_session 쿠키 삭제) |
| GET | /api/auth/me |
현재 인증 상태 확인. 응답: {authenticated, auth_required} |
| GET | /features |
Feature Reference HTML 페이지 (인증 우회) |
운영 확인은 기본 포트 8617 기준으로 수행한다.
# 1. 프로세스가 0.0.0.0:8617 에 바인딩됐는지 확인
ss -ltnp | grep 8617
# 2. 로그인 강제 여부 확인
curl http://127.0.0.1:8617/api/auth/me
# 3. 비로그인 상태에서 보호 API 거부 확인
curl -i http://127.0.0.1:8617/api/statsDASHBOARD_PASSWORD가 설정된 런타임이면/api/auth/me에서auth_required가true여야 한다.- 같은 네트워크의 다른 기기에서는
http://<서버IP>:8617로 접속해 로그인 화면이 보이는지 확인한다. - 비로그인 상태의
/api/stats는401 Unauthorized또는{"error":"unauthorized"}를 반환해야 한다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/health |
헬스체크 (인증 우회) |
| GET | /metrics |
Prometheus 메트릭 (인증 우회) |
| GET | /api/stats |
전체/오늘 통계 (모델 집계는 messages 기반 → synthetic $0) |
| GET | /api/usage/periods |
일/주/월 사용량 + 이전 기간 대비 증감 |
| GET | /api/usage/hourly?hours=N |
시간별 (KST) |
| GET | /api/usage/daily?days=N |
일별 (KST) |
| GET | /api/forecast?days=N |
월말 forecast + 일/주간 burn-out 호환 payload. Codex usage 메타데이터가 없으면 비용 필드는 0 |
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/sessions |
sort/order, search, project, model, pinned_only, date_from/to, cost_min/max, tag, include_subagents, node |
| GET | /api/sessions/search?q=k |
FTS5 전문 검색 (선두 와일드카드 차단, 매칭 토큰 하이라이트) |
| GET | /api/sessions/{id} |
상세 — subagent_count/cost, duration, stop_reason, parent_tool_use_id, task_prompt, tags |
| GET | /api/sessions/{id}/messages |
대화 (limit/offset, subagent는 sidechain 필터 우회) |
| GET | /api/sessions/{id}/message-position?message_id=N |
특정 메시지의 0-based offset 반환 (검색 결과 → 해당 페이지 점프용). 응답: {position, total, message_id} |
| GET | /api/sessions/{id}/subagents |
spawn한 subagent 목록 + duration |
| GET | /api/sessions/{id}/chain?depth=N |
Codex 보수적 재귀 chain. 루트 세션 + 저장소에서 명시적으로 증명되는 agent-run 자식만 포함 |
| DELETE | /api/sessions/{id} |
preview → confirm |
| POST / DELETE | /api/sessions/{id}/pin |
핀 토글 |
| POST | /api/sessions/{id}/tags |
태그 저장 (콤마 구분) |
Codex 전용 인덱스(codex_projects, codex_sessions, codex_messages)를 조회하는 라우트다. 기존 /api/sessions 집계와 분리되어 메시지 검색, 리플레이, 타임라인 복기를 Codex 기준으로 제공한다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/search/messages?q=k |
Codex 메시지 전문 검색. project, role, limit 지원 |
| GET | /api/search/messages/{message_id}/context?window=N |
특정 Codex 메시지 주변 문맥 조회 |
| GET | /api/codex/stats |
Codex 저장소 기반 전체/오늘 통계 payload |
| GET | /api/codex/models |
Codex 메시지 기반 모델 집계 |
| GET | /api/codex/projects |
Codex 프로젝트 목록 집계 |
| GET | /api/codex/projects/top |
Codex 프로젝트 TOP 목록과 최근 메시지 preview |
| GET | /api/codex/projects/{name}/stats?path= |
Codex 프로젝트 상세 요약/세션/모델/일별 집계 |
| GET | /api/codex/projects/{name}/messages?path=&limit=&offset=&order= |
Codex 프로젝트 전체 메시지 스트림 |
| GET | /api/sessions/{id}/replay |
Codex 세션 리플레이 페이로드 조회 |
| GET | /api/codex/sessions?limit=N |
최신 Codex 세션 목록 |
| GET | /api/codex/sessions/table?page=&per_page= |
대시보드 표 형태의 Codex 세션 목록 |
| GET | /api/codex/sessions/{id} |
Codex 세션 상세 payload |
| GET | /api/codex/sessions/{id}/messages?limit=&offset= |
Codex 세션 메시지 목록 |
| GET | /api/codex/usage/periods |
Codex 저장소 기반 일/주/월 사용량 payload |
| GET | /api/codex/usage/hourly?hours=N |
Codex 저장소 기반 시간별 메시지 집계 |
| GET | /api/codex/usage/daily?days=N |
Codex 저장소 기반 일별 메시지 집계 |
| GET | /api/codex/forecast?days=N |
Codex 저장소 기반 forecast payload |
| GET | /api/codex/plan/usage |
Codex 저장소 기반 예산 사용량 payload |
| GET | /api/timeline/summary?limit=N&date_from=&date_to= |
최근 Codex 이벤트 + 세션 요약 |
| GET | /api/usage/summary |
Codex 세션/메시지/역할 사용량 요약 |
| GET | /api/agents/summary?limit=N |
Codex agent 실행 요약 |
GET /api/sessions/{id}/chain 은 Codex-only conservative recursion 으로 동작한다.
- 루트 노드는 요청한 세션이다.
- 1단계 자식은 해당 세션에 저장된
role='agent'메시지들이다. - 더 깊은 단계는 Codex 저장소 안에서 부모-자식 관계가 명시적으로 증명될 때만 확장한다.
- legacy
sessions/messages를 이용한 텍스트 매칭 복원이나 추론 연결은 수행하지 않는다.
즉, 응답 shape는 유지하지만 트리를 과장하지 않고 “확실히 증명되는 연결만 표시”하는 것이 계약이다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/subagents |
agent_type/parent/search 필터 + sort/order |
| GET | /api/subagents/stats |
by_type, by_stop_reason, top_by_cost/duration, parents_with_most_subs, by_type_and_stop_reason |
| GET | /api/subagents/heatmap |
agent_type × project 2D 집계 |
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/timeline?date_from=D&date_to=D |
Gantt 용 세션 목록 (start/end, cost, model, project). include_subagents, limit, node |
| GET | /api/timeline/heatmap?days=N |
요일×시간 7×24 행렬 (메시지 수, 호환 비용). 기본 90일 |
| GET | /api/timeline/hourly?date=YYYY-MM-DD |
특정 일자 시간별 (0~23) 프로젝트×세션 집계. include_subagents. 슬롯별 projects/sessions/message_count/cost_usd/tokens 반환 |
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/models |
모델별 분석 (sort/order, page/per_page) |
| GET | /api/projects |
path 기반 그룹 + session/subagent 카운트 분리 (sort/order, page/per_page) |
| GET | /api/projects/top?limit=N |
프로젝트 TOP N. Codex usage 메타데이터가 없으면 비용 정렬 값은 0 |
| GET | /api/projects/{name}/stats |
?path= 모호성 해소, sessions 배열 포함 |
| GET | /api/projects/{name}/messages |
프로젝트 전체 대화 취합 (limit/offset/order, ?path=) |
| DELETE | /api/projects/{name} |
preview → confirm (?path= 필요 시) |
| GET | /api/tags |
전체 태그 + 사용 카운트 (page/per_page) |
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/plan/detect |
rateLimitTier 자동 감지 |
| GET / POST | /api/plan/config |
예산 조회/저장 (daily ≤ weekly 검증) |
| GET | /api/plan/usage |
일/주간 사용량 vs 예산 + 잔여 시각 |
| GET | /api/export/csv |
CSV 23 컬럼 (tags, stop_reason, parent_tool_use_id, duration, agent_type/description 포함) |
| WS | /ws |
실시간 (init / batch_update / scan_progress / scan_complete, ping 30s). 쿠키 세션 인증 (dash_session) |
관리자 UI의 "내보내기/Admin" 뷰에서 사용되는 라우트. 모든 admin 액션은 admin_audit 테이블에 {action, actor_ip, status, detail} 로 기록된다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/admin/backup |
DB 백업 (_write_lock + sqlite3.backup(), 10개 유지). 감사 action=backup |
| DELETE | /api/admin/retention |
오래된 세션 삭제. ?older_than_days=N&confirm=true. preview → confirm 2단계. 감사 action=retention |
| POST | /api/admin/db-compact |
WAL checkpoint + incremental vacuum 기반 DB 공간 회수. 감사 action=db_compact |
| GET | /api/admin/db-size |
DB 파일 크기 (bytes / MB) |
| GET | /api/admin/status |
가동시간, 스키마 버전, DB·WAL 크기, 세션·메시지·subagent·원격노드·audit 카운트, Codex ingest 상태 (source_kind=codex, indexed_sessions, indexed_messages), watcher 상태·큐·추적 파일 수 |
| GET | /api/admin/audit?limit=100&action= |
감사 로그 조회 (최근순, action 필터) |
| GET | /api/admin/retention/schedule |
보존 스케줄 설정 조회 — {enabled, interval_hours, older_than_days, last_run_at, last_result, next_run_at} |
| PUT | /api/admin/retention/schedule |
스케줄 갱신 (enabled/interval_hours/older_than_days). 감사 action=retention_schedule_update. 내장 asyncio 루프가 60초마다 확인하여 due 시 자동 실행 (action=retention_scheduled) |
Linux codex-zone의 project registry, production wiki, raw snapshot 자동화를
대시보드 관리 화면에서 조작하는 보호 API다. 인증 우회 목록에 포함하지 않는다.
기본 경로는 환경변수로 바꿀 수 있다.
| 환경변수 | 기본값 |
|---|---|
CODEX_ZONE_ROOT |
/data/projects/codex-zone |
CODEX_GOVERNANCE_REPO_DIR |
$CODEX_ZONE_ROOT/codex-project-mgmt |
CODEX_PROJECTS_REGISTRY |
$CODEX_ZONE_ROOT/projects.yaml |
CODEX_ZONE_WIKI_DIR |
$CODEX_ZONE_ROOT/wiki |
CODEX_ZONE_RAW_DIR |
$CODEX_ZONE_ROOT/raw |
CODEX_ZONE_AUDIT_DIR |
$CODEX_ZONE_WIKI_DIR/audit |
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/governance/summary |
registry project 목록, 경로 존재 여부, wiki/raw/audit count와 최신 audit metric, sync/check/track script 상태 |
| GET | /api/governance/wiki/index |
wiki/index.md 본문과 파일 메타데이터 |
| GET | /api/governance/wiki/page?path=<rel> |
wiki 내부 markdown 파일 조회. .., 절대 경로, 비-.md 파일 차단 |
| GET | /api/governance/audit/latest |
wiki/audit/zone-audit-latest.md 본문, 파일 메타데이터, 상단 metric 파싱 결과 |
| POST | /api/governance/check |
allowlist된 scripts/wiki-check.sh 실행. 감사 action=governance_check |
| POST | /api/governance/sync |
allowlist된 scripts/project-sync.sh 실행. 감사 action=governance_sync |
| POST | /api/governance/track |
allowlist된 scripts/zone-track.sh 실행. sync/check/audit를 한 번에 수행하고 감사 action=governance_track |
| POST | /api/governance/projects |
신규 project를 projects.yaml에 append하고 선택적으로 sync 실행. 감사 action=governance_project_add |
| GET | /api/governance/lifecycle/runs?project_id=<id> |
등록된 project의 docs/lifecycle/runs/*.json snapshot 목록 조회 |
| POST | /api/governance/lifecycle/preview |
lifecycle-redesign-start.sh <project_id> --topic <topic> --json 실행. write 없이 preview하고 감사 action=governance_lifecycle_preview |
| POST | /api/governance/lifecycle/write |
confirm: true 필요. lifecycle-redesign-start.sh <project_id> --topic <topic> --write --json 실행 후 같은 run id를 lint하고 감사 action=governance_lifecycle_write |
| POST | /api/governance/lifecycle/lint |
lifecycle-lint.sh <project_id> --run <run_id> --json 실행. 감사 action=governance_lifecycle_lint |
POST /api/governance/projects body:
{
"id": "purecvisor-windows-edge",
"path": "purecvisor-windows-edge",
"title": "Purecvisor Windows Edge",
"kind": "project",
"summary": "Windows Server 전용 Purecvisor Edge client.",
"wiki": true,
"sync_after": true
}POST /api/governance/lifecycle/preview body:
{
"project_id": "codex-dashboard",
"topic": "governance-lifecycle-runs"
}POST /api/governance/lifecycle/write body:
{
"project_id": "codex-dashboard",
"topic": "governance-lifecycle-runs",
"confirm": true
}POST /api/governance/lifecycle/lint body:
{
"project_id": "codex-dashboard",
"run_id": "2026-05-03-governance-lifecycle-runs"
}제약:
id는[A-Za-z0-9][A-Za-z0-9_.-]{0,79}형식.path는 zone root 기준 상대 경로만 허용한다.wiki는 registry의 wiki 생성/동기화 여부를 지정한다.- 중복
id또는 중복path는409로 거부한다. - 스크립트 실행은
project-sync.sh,wiki-check.sh,zone-track.sh만 allowlist한다. - lifecycle script 실행은 별도 allowlist로
lifecycle-redesign-start.sh,lifecycle-lint.sh만 허용한다. - lifecycle script는 dashboard의
CODEX_ZONE_ROOT를--zone-dir로 명시해 dashboard 검증과 script target resolution을 같은 zone 기준으로 맞춘다. 현재 lifecycle 실행은CODEX_PROJECTS_REGISTRY=$CODEX_ZONE_ROOT/projects.yaml형태만 지원한다. - lifecycle write는 등록된 project만 대상으로 하며
confirm: true없이는 거부한다. - lifecycle 감사 로그는 project id, topic, run id, return code, duration, created/error/warning count 같은 summary만 저장하고 전체 stdout/stderr는 저장하지 않는다.
project-sync.sh,wiki-check.sh실행 제한 시간은 60초,zone-track.sh는 180초이며 stdout/stderr는 잘라서 응답한다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/ingest |
원격 Codex collector 에이전트가 JSONL 레코드 전송. X-Ingest-Key 헤더 인증. Body: {node_id, file_path, records[]} (인증 우회) |
| GET | /api/codex-collector.py |
codex_collector.py 스크립트 다운로드 (원격 서버 설치용, 인증 우회) |
| GET | /api/nodes |
등록된 노드 목록 (local 포함) + 세션/메시지 카운트 |
| POST | /api/nodes |
노드 등록. Body: {node_id, label?}. 응답에 일회성 ingest_key 포함 |
| DELETE | /api/nodes/{node_id} |
노드 등록 해제 (수집된 데이터는 유지) |
| POST | /api/nodes/{node_id}/rotate-key |
ingest key 재발급 |
/metrics 응답에 포함되는 주요 시리즈:
http_requests_total{method,path,status}— 라우트 템플릿 기반 (cardinality bounded)http_request_duration_seconds— 히스토그램 10 buckets (0.005s~5s)dashboard_ws_connections— 활성 WebSocket 게이지dashboard_scan_files_total{phase}— initial / event / polldashboard_new_messages_total— watcher 가 ingest 한 새 메시지 카운터dashboard_file_retries_total{outcome}— retry / gave_updashboard_{sessions,messages}_total게이지 +dashboard_db_size_bytes
미들웨어 순서: metrics(외부) → auth(내부) → route. 401 도 카운트된다.
# 인증이 설정된 경우 먼저 로그인 (쿠키 저장)
curl -c cookies.txt -X POST http://localhost:8617/api/auth/login \
-H 'Content-Type: application/json' -d '{"password":"codex2026"}'
# 이후 요청에 쿠키 첨부 (-b cookies.txt)
curl -b cookies.txt -s http://localhost:8617/api/stats | jq .
curl -b cookies.txt -s 'http://localhost:8617/api/sessions?per_page=10&pinned_only=true' \
| jq '.sessions[]|{project_name,model,total_cost_usd,tags}'
curl -s 'http://localhost:8617/api/forecast?days=14' | jq .
curl -s 'http://localhost:8617/api/subagents/stats' | jq '.by_type_and_stop_reason'
curl -s 'http://localhost:8617/api/sessions/<sid>/chain?depth=4' | jq .
curl -o codex-usage.csv http://localhost:8617/api/export/csv
curl -s http://localhost:8617/metrics | grep dashboard_
# Governance / Wiki
curl -b cookies.txt -s http://localhost:8617/api/governance/summary | jq '.project_count'
curl -b cookies.txt -s -X POST http://localhost:8617/api/governance/check | jq .