# Milestone: 사용자별 OpenAI-compatible 토큰 측정 MVP

## 위치

- Roadmap: [ROADMAP.md](../../../ROADMAP.md)
- Phase: [PHASE.md](../PHASE.md)

## 목표

OpenAI-compatible 호출의 토큰 사용량을 IOP bearer token 기준으로 외부 principal id 또는 내부 alias에 귀속하고, Prometheus metric으로 노출해 사용자별 사용량과 ROI 판단의 1차 근거를 볼 수 있게 한다.
외부 호출 표면은 OpenAI-compatible 표준 field와 `Authorization: Bearer <token>`만 사용하며, `metadata.user`나 provider token/provider identity를 사용자 입력 또는 사용자-facing 사용량 표면에 추가하지 않는다.
IOP는 완성된 사용자/테넌트 관리 시스템을 소유하지 않고, 별도 사용자/테넌트 프로젝트와 연결될 `principal_ref`를 token mapping으로 보관하는 얇은 인증/귀속 레이어만 가진다.
1차 MVP는 측정에 집중하고, 사용자별 token 제한과 비용/모델 가격 비교는 측정 데이터가 안정화된 뒤 후속 축으로 진행한다.

## 상태

[완료]

## 승격 조건

- 없음: 사용자 검토에서 1차 범위가 OpenAI-compatible bearer-token 기반 Prometheus metering과 얇은 principal-token 매핑으로 확정되었고, 완성된 사용자/테넌트 관리, Control Plane 대시보드, request-level ledger, Loki 로그, 사용자별 제한, 비용/모델 가격 비교는 후속으로 분리되었다.

## 구현 잠금

- 상태: 해제
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/operational-observability-provider-management/usage-token-log-ops-mvp/SDD.md)
- SDD 사유: 1차는 OpenAI-compatible request/response body, Edge-Node proto, Control Plane API를 바꾸지 않지만, IOP token alias 매핑과 Prometheus metric schema라는 운영 계약을 고정해야 한다.
- 잠금 해제 조건:
  - [x] SDD 잠금이 해제되어 있다.
  - [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
  - [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
  - [x] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다.
- 결정 필요: 없음

## 범위

- OpenAI-compatible HTTP 호출 중 현재 provider/runtime usage를 관측할 수 있는 경로의 토큰 사용량 측정
- IOP bearer token 또는 그 secret reference를 `principal_ref`, 내부 alias, token reference로 매핑하는 운영 경계
- 프로젝트용 운영 skill이 `principal_ref` 또는 내부 id를 입력받아 raw token을 생성하고, tracked 문서/config에는 raw token 없이 token reference 또는 hash와 alias만 남기는 경계
- pure `passthrough` 응답 body를 바꾸지 않고 Edge 내부에서 usage frame, provider-reported usage, 완료 이벤트를 관측해 metric으로 집계하는 경로
- Prometheus counter 기반 사용자별 token usage metric과 request count/status metric
- token type: `input`, `output`, provider가 별도 보고한 `reasoning`, provider가 별도 보고한 `cached_input`
- reasoning token을 provider가 별도 보고하지 않는 경우 token 추정 없이 `unavailable`로 취급하고, 필요 시 reasoning 관측 여부와 reasoning character count만 보조 metric으로 남기는 기준
- Grafana dashboard/query를 1차 조회 표면으로 두고 Control Plane/Client 대시보드는 만들지 않는 운영 경계
- 사용자별 제한은 2차 후속 축으로 분리하되, 1차 metric label과 rollup이 제한 정책에 재사용될 수 있게 하는 기준

## 기능

### Epic: [ops-usage] Usage and Log Operations

운영자가 OpenAI-compatible token 사용량을 외부 principal id 또는 내부 alias 단위로 빠르게 확인하기 위한 Prometheus/Grafana 중심 capability를 묶는다.

- [x] [identity-scope] OpenAI-compatible 호출 주체는 `metadata.user`가 아니라 IOP bearer token의 운영 매핑으로 판별하고, IOP는 사용자/테넌트 모델이 아닌 `principal_ref` 참조값만 소유하는 기준이 정리되어 있다.
- [x] [token-alias] Edge-owned 운영 설정 또는 secret reference에서 `token_ref -> principal_ref/internal_alias` 매핑을 관리하고, Grafana에는 내부 alias와 token reference만 노출하는 기준이 정리되어 있다.
- [x] [token-issue-skill] 프로젝트용 운영 skill이 `principal_ref` 또는 내부 id를 등록하면 raw IOP token을 생성하고, raw token은 한 번만 운영자에게 전달하며, tracked 파일에는 token reference 또는 hash만 남기는 기준이 정리되어 있다.
- [x] [openai-scope] 1차 측정 범위가 OpenAI-compatible 호출로 제한되고, CLI usage status, A2A, local-only adapter usage, request-level ledger는 후속 범위로 분리되어 있다.
- [x] [passthrough-safe] pure `passthrough` 응답 body에는 IOP sideband field/event를 추가하지 않고, Edge 내부 관측만으로 usage metric을 emit하는 기준이 정리되어 있다.
- [x] [token-breakdown] `input`, `output`, provider-reported `reasoning`, provider-reported `cached_input` token type과 provider-reported/unavailable source 표시 기준이 정리되어 있다.
- [x] [reasoning-observed] provider가 reasoning token을 별도 보고하지 않으면 token 추정치를 만들지 않고, reasoning 관측 여부와 character count만 보조 metric으로 남기는 기준이 정리되어 있다.
- [x] [prometheus-metrics] Prometheus metric 이름과 label cardinality 기준이 정리되어 있다. request_id, session_id, raw token, raw prompt/response, provider token은 label에 넣지 않는다.
- [x] [grafana-surface] Control Plane/Client dashboard를 만들지 않고 Grafana dashboard/query를 1차 조회 표면으로 쓰는 기준이 정리되어 있다.
- [x] [limit-followup] 사용자별 token 제한은 2차 후속 축으로 분리하고, 1차 metric이 daily/monthly warn/reject 정책에 재사용될 수 있는 기준이 정리되어 있다.

## 완료 리뷰

- 상태: 통과
- 요청일: 2026-07-10
- 완료 근거: 같은 Milestone task group의 archive `complete.log` 3개가 PASS `Roadmap Completion`으로 기능 Task 9개를 확인했고, 기존 완료 Task `token-issue-skill`은 [openai-usage-token-issue/SKILL.md](../../../../agent-ops/skills/project/openai-usage-token-issue/SKILL.md)와 관련 git evidence로 확인했다. 종료 감사에서 관련 코드/계약/spec/test를 재확인했고 남은 차단 항목은 없다.
- 완료 evidence:
  - [identity_alias_auth complete.log](../../../../agent-task/archive/2026/07/m-usage-token-log-ops-mvp/01_identity_alias_auth/complete.log) - `identity-scope`, `token-alias`
  - [usage_metrics complete.log](../../../../agent-task/archive/2026/07/m-usage-token-log-ops-mvp/02+01_usage_metrics/complete.log) - `openai-scope`, `passthrough-safe`, `token-breakdown`, `reasoning-observed`, `prometheus-metrics`
  - [grafana_rollup_docs complete.log](../../../../agent-task/archive/2026/07/m-usage-token-log-ops-mvp/03+02_grafana_rollup_docs/complete.log) - `grafana-surface`, `limit-followup`
- 종료 감사:
  - Spec sync: updated - [openai-compatible-surface.md](../../../../agent-spec/input/openai-compatible-surface.md), [provider-pool-config-refresh.md](../../../../agent-spec/runtime/provider-pool-config-refresh.md), [edge-node-execution.md](../../../../agent-spec/runtime/edge-node-execution.md), [index.md](../../../../agent-spec/index.md)
  - 검증: `go test -count=1 ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/node/internal/adapters/openai_compat ./apps/node/internal/adapters/vllm` PASS
  - 검증: `rg --fixed-strings "sum by (principal_alias, token_type)" docs/openai-usage-grafana.md`와 daily/monthly `increase()` query 확인 PASS
  - 참고: `go test -count=1 ./...`는 local root filesystem `/tmp` 공간 부족과 `/config` mount의 `mkdir -m 0000` 동작 때문에 환경성 실패가 있었고, Milestone 직접 범위 테스트는 통과했다.
- 남은 차단 항목: 없음
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: `sync-milestone-workstate`와 `complete-milestone` 기준으로 SDD gate, 관련 파일/git evidence, spec sync, Phase/current 라벨을 함께 확인했다.

## 범위 제외

- 결제, chargeback, 조직 IAM, 장기 retention 정책의 상세 구현
- 사용자 CRUD, tenant/org 모델, RBAC, SSO/OIDC, 초대/탈퇴 같은 완성된 사용자/테넌트 관리
- Claude Opus, Gemma4 공식/내부 가격 비교와 ROI 금액 산출
- 사용자별 token 제한의 warn/reject enforcement 구현
- Control Plane 또는 Client 기반 usage dashboard 구현
- request-level ledger 저장소, Loki 연동, 요청별 상세 감사/디버깅 조회
- 모든 로그 schema와 audit schema 확정
- provider routing 또는 inference adapter 구현
- `metadata.user` 또는 OpenAI-compatible request body 확장으로 사용자를 식별하는 방식
- 사용자-facing 운영 표면에 provider token 또는 provider identity를 노출하는 방식
- hidden reasoning token을 provider가 보고하지 않는 경우의 추정 token 산출 또는 완전 정확한 복원

## 작업 컨텍스트

- 관련 경로: `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/openai_compat`, `apps/node/internal/adapters/vllm`, `packages/go/observability`, `packages/go/config`, `configs/edge.yaml`, `proto/iop/runtime.proto`, [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md)
- 표준선(선택): OpenAI-compatible 호출 주체 식별은 `Authorization: Bearer <token>`에서 온 IOP token을 Edge-owned 운영 매핑으로 `principal_ref`와 내부 alias에 연결해 처리한다. `metadata.user`는 사용하지 않는다.
- 표준선(선택): IOP는 사용자/테넌트 source of truth가 아니며, `principal_ref`는 별도 사용자/테넌트 프로젝트 또는 dev-corp 운영 id에 대한 foreign-key-like 참조값이다.
- 표준선(선택): token 발급은 프로젝트용 운영 skill로 보조할 수 있지만 raw token은 tracked roadmap/docs/config/log/metric에 남기지 않고 operator에게 1회 전달한다.
- 완료 근거(`token-issue-skill`): [openai-usage-token-issue/SKILL.md](../../../../agent-ops/skills/project/openai-usage-token-issue/SKILL.md)와 [project rules.md](../../../../agent-ops/rules/project/rules.md)에 raw token 1회 전달, tracked 파일 raw token 미저장, `token_ref`/`principal_ref`/alias 매핑 절차가 등록되어 있다.
- 표준선(선택): provider token과 provider identity는 사용자 입력 표면이나 사용자-facing usage dashboard에 노출하지 않는다. 내부 진단이 필요하면 user usage metric과 분리한다.
- 표준선(선택): pure `passthrough`는 provider-original response body를 유지하고, IOP usage metric은 Edge 내부 관측으로만 emit한다.
- 표준선(선택): token count는 provider-reported 값을 우선하며, missing reasoning token은 추정하지 않고 unavailable로 둔다. 단, reasoning stream/content를 관측한 사실과 character count는 token이 아닌 보조 metric으로 남길 수 있다.
- 표준선(선택): Prometheus label은 low-cardinality 값만 사용한다. 후보는 `edge_id`, `principal_ref`, `principal_alias`, `token_ref`, `model_group`, `endpoint`, `response_mode`, `token_type`, `usage_source`, `status`이며, request/session/raw token/raw payload는 label로 쓰지 않는다.
- 표준선(선택): Grafana가 1차 대시보드이며 Control Plane/Client usage dashboard는 후속 필요가 생길 때만 검토한다.
- 선행 작업: Control Plane과 Client 운영, OpenAI-compatible usage 응답, CLI usage checker
- 후속 작업: 사용자별 token 제한 enforcement, 요청 실행 로그와 Usage Ledger 기반, 운영 리포트, audit retention, 가격 baseline/ROI 비교, 품질 기반 routing/fallback 고도화
- 확인 필요: 없음
