운영 런북 (runbook)
설계서 §13.4(환경 분리)·§14(품질·운영). 실제 운영 도입은 §17 확정 항목을 마친 뒤 판단한다.
관리자는 같은 내용을 포털 안에서도 읽을 수 있습니다 —
/admin/manual(관리자 매뉴얼). 사용자용 절차는/manual입니다. 문구의 원천은shared/manual.ts하나이고(manual.md), 이 런북은 화면 밖 작업(초기 배포·DB·백업)의 기준입니다.
0. 운영 배포 최소 설정
NODE_ENV=production 에서는 Mock 설정이 차단되므로(§13.4) 아래 세 값이 반드시 필요합니다.
NODE_ENV=production
AUTH_MODE=directory # PortalConsole 위임 인증
PROCESS_ADAPTER=contract # 기존 프로세스 포탈 읽기 전용 연계
# 저장소(§13.1) — 운영에서는 필수다. 없으면 시작을 막는다(재시작마다 데이터가 사라지는 것을 막는다).
DATABASE_URL=postgresql://<user>:<password>@<host>:5432/agent_center
MIGRATE_ON_START=false # 단일 인스턴스(개발서버 포함)는 true 로 두면 배포가 간단하다. 미적용 상태로 기동하면 시작을 막는다.
# 중앙 인증(PortalConsole)
PORTAL_CONSOLE_ORIGIN=https://portal-console.example.internal
PORTAL_CONSOLE_PORTAL_ID=agent-center
PORTAL_CONSOLE_SESSION_SECRET=<자체 생성 서명 키 — 아래 설명>
PORTAL_CONSOLE_REGISTRATION_TOKEN=<콘솔이 발급한 등록 시크릿> # 자동 등록(§17)
APP_ORIGIN=https://agent-center.example.internal # 자동 등록에는 필수PORT는 호스팅 플랫폼이 주입하는 값을 그대로 씁니다.DATABASE_URL이 있으면 PostgreSQL 저장소를, 없으면 인메모리 저장소를 씁니다(개발 전용). 운영에서 값이 없으면 시작이 실패합니다.APP_ORIGIN은 비워 두면 요청 헤더(x-forwarded-proto/x-forwarded-host)에서 유도합니다. 고정 도메인 배포에서는 명시하세요(콜백 URL 이 이 값으로 만들어집니다). 자동 등록을 켜면 필수입니다 — 등록 본문의baseUrl·redirectUris가 이 값으로 만들어집니다.PORTAL_CONSOLE_REGISTRATION_TOKEN을 주면 기동 시POST {PORTAL_CONSOLE_ORIGIN}/api/internal/portal-registrations로 포털을 등록하고 API 키를 발급받습니다. 실패하면 운영에서는 시작을 중단합니다(등록 없이는 로그인이 동작하지 않습니다). 값을 주지 않으면 자동 등록을 건너뜁니다.PORTAL_CONSOLE_SESSION_SECRET은 PortalConsole 이 발급하는 값이 아니라 포털이 직접 만드는 세션 서명 키입니다. 자기 세션 쿠키(agent_center_directory_session)를 HMAC-SHA256 으로 서명하고 로컬에서 검증하는 데만 쓰이며, PKCE 코드 교환 본문에도 들어가지 않습니다(server/adapters/identity/directorySession.ts). 비어 있으면 시작이 실패합니다.- 32바이트 이상 무작위를 넣으세요:
node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))" - 세션을 서버에 저장하지 않으므로 모든 인스턴스가 같은 값이어야 하고, 값을 바꾸면 전원 재로그인입니다.
- 개발 스택은
ProcessCenter/docker-compose.dev.yml의local-dev-*값을 그대로 씁니다 — 운영에는 그 값을 쓰지 않습니다(환경마다 다른 값, 유출 시 세션 위조로 이어짐). PORTAL_JWT_SECRET이 이미 있으면 그 값이 대신 쓰입니다.
- 32바이트 이상 무작위를 넣으세요:
- 배포 전 확인:
pnpm verify:full→pnpm build→ 마이그레이션 →node dist/index.js→GET /api/health.
아직 남은 외부 작업 (§17)
| 대상 | 필요한 것 | 현재 상태 |
|---|---|---|
| PortalConsole | PORTAL_CONSOLE_REGISTRATION_TOKEN 발급(등록 시크릿) | 자동 등록 구현됨(server/adapters/identity/portalRegistration.ts) — 세션 서명 키는 자체 생성이므로 콘솔에 요청할 것이 없다 |
| PortalConsole | 사용자 권한 claim(검토 역할) 노출 | 미확정 — 그 전까지 DIRECTORY_ROLE_ASSIGNMENTS 로 부여 |
| 기존 프로세스 포탈 | 읽기 전용 프로세스 노드 API(§9.1 계약) | 미제공 — 어댑터 클라이언트는 구현되어 기동하고, 조회 시점에 503 으로 드러남(§9.4) |
1. 환경 변수
로컬에서는 .env.example 을 .env 로 복사해 쓴다(.env 는 커밋하지 않는다). 서버 기동 시 .env 가 로드되고, 이미 주입된 환경변수가 우선하므로 배포에서는 배포 환경 값이 이긴다.
cp .env.example .env # 로컬 개발용| 변수 | 값 | 설명 |
|---|---|---|
NODE_ENV | development / production | 운영에서 Mock 설정 시 시작 실패 |
PORT | 기본 3000 | API 서버 포트 |
APP_ORIGIN | 예: https://agent-center.example | 콜백 URL 구성용(끝 슬래시 없음) |
CORS_ORIGINS | 쉼표 구분 | 프론트·API가 다른 오리진일 때만 |
DATABASE_URL | PostgreSQL URL | drizzle 명령에도 필수 |
DATABASE_DIALECT | postgres | 설계서 §13.1 |
AUTH_MODE | mock / directory / local | mock 은 개발 전용, local 은 미구현 |
PORTAL_CONSOLE_ORIGIN | 콘솔 오리진 | directory 모드 필수 |
PORTAL_CONSOLE_PORTAL_ID | 기본 agent-center | 콘솔 등록 식별자 |
PORTAL_CONSOLE_CLIENT_ID | 기본 = portalId | 포털 식별자와 다를 때만 |
PORTAL_CONSOLE_SESSION_SECRET | 세션 서명 키(자체 생성) | directory 모드 필수, 기본값 없음. 콘솔이 발급하는 값이 아니다 — §0 참고 |
PORTAL_JWT_SECRET | 대체 서명 키 | PORTAL_CONSOLE_SESSION_SECRET 대신 사용 가능 |
PORTAL_CONSOLE_CALLBACK_PATH | 기본 /auth/callback | 배포 리라이트에 맞춰 조정 |
PORTAL_CONSOLE_SESSION_TTL_MS | 기본 28800000 | 세션 수명(8시간) |
PORTAL_CONSOLE_API_KEY | 콘솔이 발급한 포털 API 키 | 공통 관리자 메뉴 공급(규약 §1). 없으면 로컬 시드로 폴백하며 관리자 셸은 정상 표시 |
PORTAL_CONSOLE_MENU_TTL_MS | 기본 900000(15분) | 공통 관리자 메뉴 캐시 TTL. 만료된 조회에서만 콘솔을 다시 호출 |
DIRECTORY_ADMIN_ROLES | 기본 ADMIN,VIEWER | portalAdmin 사용자 역할 |
DIRECTORY_DEFAULT_ROLES | 기본 VIEWER | 일반 사용자 역할 |
DIRECTORY_ROLE_ASSIGNMENTS | JSON | 중앙 식별자별 역할 부여(임시 브리지) |
PROCESS_ADAPTER | mock / contract | mock 은 개발 전용 |
PROCESS_PORTAL_BASE_URL | ProcessCenter 오리진 | contract 모드 필수(끝 슬래시 없음) |
PROCESS_TAXONOMY_CODE | 분류 축(L1 루트 노드 code) | contract 모드 필수. mock 은 group-ax-v1(합성) 기본. 원본이 이 값을 분류체계로 해석하므로 운영 값은 ProcessCenter 와 합의(dev 실측 예: L1-000001) |
PROCESS_PORTAL_API_KEY | 소비자 서비스 키 | contract 모드 필수. ProcessCenter 의 PROCESS_NODE_CONSUMERS_JSON 에 process:read·process:access 두 스코프로 등록해야 한다(스코프가 없으면 권한 판정 호출이 403). 키는 브라우저에 내려가지 않는다 |
PROCESS_SYNC_INTERVAL_MS | 기본 900000(15분) | 증분 동기화 주기 |
PROCESS_FULL_RECONCILE_INTERVAL_MS | 기본 86400000(24시간) | 전체 대조 주기 |
AI_ENABLED | false(기본) | 근거 기반 답변 기능 플래그(규약 §2-7). true 이면 아래 세 값이 필수다 — 없으면 기동 실패 |
MODEL_GATEWAY_URL | ModelGateway 오리진 | AI_ENABLED=true 필수(끝 슬래시 없음) |
MODEL_GATEWAY_SERVICE_TOKEN | 서버 간 서비스 토큰 | AI_ENABLED=true 필수. ModelGateway 의 MODEL_GATEWAY_SERVICE_TOKEN 과 같은 값. 브라우저에 내려가지 않는다 |
MODEL_GATEWAY_MODEL | 게이트웨이 허용 모델 | AI_ENABLED=true 필수(예: gw-default). /v1/models 로 허용 목록을 확인한다 |
MODEL_GATEWAY_TIMEOUT_MS | 기본 20000 | 생성 타임아웃. 검색은 즉시, 답변은 근거 문서 독해 뒤에 온다 |
EXPLORE_SERVICE_TOKEN | 게이트웨이와 공유하는 서비스 토큰 | 미설정이면 어댑터 경로(POST /api/explore/v1/search)가 503 이다(셸 검색은 영향 없음). ExploreGateway 의 PORTAL_SERVICE_TOKENS_JSON["agent-center"] 와 같은 값 |
EXPLORE_GATEWAY_URL | ExploreGateway 오리진 | 설정하면 질문(§14 answer)이 게이트웨이 → 중앙 RAG 로 먼저 간다(정본). 미설정이면 이 포털 색인 답변이 유일한 경로다. 설정 시 아래 두 값이 필수 — 없으면 기동 실패 |
EXPLORE_GATEWAY_AUDIENCE | 기본 explore-gateway | 위임 토큰 audience. 콘솔 소비자 등록의 delegationAudiences 에 포함되어야 한다 |
AGENT_CENTER_SERVICE_CLIENT_SECRET | 콘솔이 이 소비자에게 준 시크릿 | 위임 토큰 발급(경로 B). 브라우저에 내려가지 않는다. 콘솔 PORTAL_CONSOLE_TOKEN_CONSUMERS_JSON 의 clientId: "agent-center" 항목과 같은 값 |
NPM_TOKEN | GitHub Packages 토큰 | @hohyun94 패키지 설치 시(현재는 vendor/ 사용) |
시작 가드: NODE_ENV=production 에서 AUTH_MODE=mock 또는 PROCESS_ADAPTER=mock 이면 시작 실패(§13.4, AT-32). 운영에서 Mock 으로 자동 전환하지 않는다.
1-1. 통합 답변(§14) 연계 등록
게이트웨이 경유 답변은 콘솔이 발급한 위임 토큰으로 호출된다(경로 B — PortalConsole/docs/delegation-token-contract.md). 콘솔에 이 포털을 소비자로 등록한다.
[
{
"clientId": "agent-center",
"clientSecret": "<AGENT_CENTER_SERVICE_CLIENT_SECRET 과 같은 값>",
"audience": "ui-center-theme",
"scopes": [],
"delegationAudiences": ["explore-gateway"],
"delegationScopes": ["search:read"]
}
]delegationAudiences·delegationScopes밖의 요청은 거절된다 — 위임은 좁히기만 한다(권한 상승 금지).- 여기 쓰는
clientSecret은PORTAL_CONSOLE_SESSION_SECRET(세션 서명 키)과 다른 값이다. 세션 키는 콘솔이 발급하지 않는다. - 검색 어댑터(게이트웨이 → 이 포털)와 답변 아웃바운드(이 포털 → 게이트웨이)는 다른 창구다: 전자는
EXPLORE_SERVICE_TOKEN+ ExploreGatewayPORTAL_SERVICE_TOKENS_JSON["agent-center"], 후자는 위 소비자 등록 +EXPLORE_GATEWAY_URL. 둘 다 설정하면 상단 검색의 검색·답변이 모두 중앙 연계로 동작한다.
2. 자주 쓰는 명령
pnpm install # 의존성 설치
pnpm dev # 개발 서버(3000)
pnpm check # 타입 검사
pnpm test # 단위 테스트
pnpm verify:full # 로컬 게이트(test + check + build)
pnpm build # 클라이언트 빌드 + 서버 번들(dist/)
pnpm start # dist/index.js 실행(운영)
pnpm db:generate # drizzle 마이그레이션 생성
pnpm db:migrate # 마이그레이션 적용
pnpm verify:process-integration # 실행 중인 ProcessCenter v2 에 실 HTTP 로 연계 계약 확인(아래 §2-1)2-1. 프로세스 연계 실 확인 (contract 모드)
단위 테스트는 목 응답으로 계약을 고정한다. 실제 상대 서비스가 같은 계약을 지키는지는 별도로 확인한다.
# 전제: ProcessCenter 가 떠 있고, 이 키가 PROCESS_NODE_CONSUMERS_JSON 에 등록되어 있어야 한다
# (레거시 AGENT_CENTER_API_KEY 를 쓰면 두 스코프로 자동 승격된다)
export PROCESS_PORTAL_BASE_URL=http://127.0.0.1:3900
export PROCESS_PORTAL_API_KEY=<소비자 키>
export PROCESS_TAXONOMY_CODE=L1-000001
pnpm verify:process-integration확인 항목: 게시본만 오는지 · code 식별자(대리 키 미노출) · sourceVersion · pathCodes · resolve 404 · 권한 판정 응답 · 잘못된 키 401. 종료 코드 0 통과 · 1 계약 위반 · 2 실행 불가(설정 누락/연결 실패).
2-2. 통합 탐색 어댑터 실 확인 (ExploreGateway 연계)
pnpm test 는 어댑터 계약을 목 요청으로 고정한다. 게이트웨이가 같은 헤더·본문으로 부를 수 있는지는 실 호출로 확인한다(계약: ExploreGateway/docs/adapter-onboarding.md §3).
# 전제: EXPLORE_SERVICE_TOKEN 이 게이트웨이의 PORTAL_SERVICE_TOKENS_JSON["agent-center"] 와 같은 값
curl -sS -X POST "http://127.0.0.1:3000/api/explore/v1/search" \
-H "authorization: Bearer $EXPLORE_SERVICE_TOKEN" \
-H "content-type: application/json" \
-H "x-explore-subject-id: demo-user-viewer" \
-H "x-explore-org-id: demo-org-education" \
-H "x-explore-roles: VIEWER" \
-d '{"query":"런북","limit":20}'확인 항목: 토큰 없음·불일치 401 · 주체 헤더 누락 400 · 빈 질의·201자 질의 400 · 정상 200(results[].portalId="agent-center") · EXPLORE_SERVICE_TOKEN 미설정 503.
권한은 역할을 바꿔 같은 질의를 두 번 보낸다 — x-explore-roles 가 없거나 VIEWER 면 관리자 매뉴얼 절(/admin/manual)이 결과 자체로 만들어지지 않아야 한다(§4.2 — 가려진 것을 "없음"과 구분해 알려 주지 않는다).
2-3. 근거 기반 답변 실 확인 (ModelGateway 연계)
pnpm test 는 게이트웨이 호출을 fetch 대역으로 고정한다(tests/unit/modelGateway.test.ts). 실 게이트웨이가 같은 토큰·모델을 받는지는 실 호출로 확인한다.
# 전제: AI_ENABLED=true · MODEL_GATEWAY_URL · MODEL_GATEWAY_SERVICE_TOKEN · MODEL_GATEWAY_MODEL 설정
# MODEL_GATEWAY_SERVICE_TOKEN 이 게이트웨이의 값과 같아야 한다.
# 1) 게이트웨이가 이 토큰을 받는가 (기대: 200)
curl -sS -H "authorization: Bearer $MODEL_GATEWAY_SERVICE_TOKEN" "$MODEL_GATEWAY_URL/v1/health"
# 2) 이 모델이 허용 목록에 있는가 (기대: MODEL_GATEWAY_MODEL 포함)
curl -sS -H "authorization: Bearer $MODEL_GATEWAY_SERVICE_TOKEN" "$MODEL_GATEWAY_URL/v1/models"
# 3) 생성 경로·귀속 헤더가 같은 모양인가 (기대: OpenAI 호환 응답)
curl -sS -X POST "$MODEL_GATEWAY_URL/v1/chat/completions" \
-H "authorization: Bearer $MODEL_GATEWAY_SERVICE_TOKEN" \
-H "content-type: application/json" \
-H "x-portal-id: agent-center" \
-H "x-purpose: explore-answer" \
-d "{\"model\":\"$MODEL_GATEWAY_MODEL\",\"messages\":[{\"role\":\"user\",\"content\":\"한 단어로만 답해줘: 확인\"}]}"화면 확인: 포털 셸 검색창(Ctrl/⌘ K)에서 질의를 제출하면 이 질문에 근거 문서로 답변 버튼이 보인다(미구성이면 보이지 않는다). 관리자 셸도 같은 창구를 쓴다 — 관리자 매뉴얼·관리자 메뉴가 같은 색인에 있으므로 관리자 셸에서 같은 질의를 넣어도 결과·답변이 같아야 한다(D-072). 관리자 「연계·동기화」의 「근거 기반 답변」 배지가 구성됨인지도 함께 본다.
확인 항목:
- 근거가 없는 질의는 답변이 아니라 결과만 온다(
NO_EVIDENCE— 모델을 부르지 않는다). - 미구성·게이트웨이 장애는 503
EXPLORE_ANSWER_UNAVAILABLE이며 빈 답변으로 위장하지 않는다. - 답변의 인용은 검색 결과 상위 근거와 일치한다(모델이 말한 출처를 옮기지 않는다).
- 역할을
VIEWER로 낮추면 관리자 매뉴얼 근거가 답변·인용 어디에도 없다(§4.2 — 프롬프트 단계에서 걸린다). - 게이트웨이 로그·사용량에
x-purpose=explore-answer로 비용이 귀속된다(없으면 미분류로 기록된다).
3. 배포
pnpm verify:full통과 확인(로컬 게이트).pnpm build→dist/public(SPA) +dist/index.js(API).- 마이그레이션 적용 —
DATABASE_URL을 주입한 상태에서pnpm db:migrate. 여러 인스턴스를 올리기 전에 한 번 수행한다. 단일 인스턴스(개발서버 포함)라면MIGRATE_ON_START=true로 기동해도 된다. 이미지에는drizzle/migrations가 포함되어 있다.- 적용하지 않고 기동하면 시작이 중단된다:
데이터베이스에 마이그레이션이 적용되지 않았습니다(없는 테이블: agents, …). 배포 단계에서 pnpm db:migrate 를 실행하거나, 단일 인스턴스라면 MIGRATE_ON_START=true 로 기동하세요(설계서 §13.1).
- 적용하지 않고 기동하면 시작이 중단된다:
- 환경 변수를 배포 환경에 주입(
DATABASE_URL,APP_ORIGIN,AUTH_MODE,PROCESS_ADAPTER). - 기동 후
GET /api/health확인. - 적용된 공용 UI 버전 확인 — 브라우저 devtools 콘솔에서
document.documentElement.dataset.pfUiVersion을 읽는다(예:0.6.158). vendor tarball 을 갱신했는데 값이 그대로면 재빌드·재설치가 빠진 것이다.
/api/health 응답 예:
{ "ok": true, "authMode": "mock", "processAdapterKind": "mock", "demoData": true, "aiEnabled": false }4. 관측·헬스에 포함할 것 (§14 관측성)
- 중앙 연동(PortalConsole·프로세스 원본) 상태와 마지막 성공 시각
- DB 연결, 동기화 Worker 상태·커서, 실패 격리 건수
- 매핑 원본 신선도(FRESH/STALE/UNAVAILABLE) 분포
- 게시 차단 사유(재검토 필요·원본 확인 실패)
5. 장애 대응 요약 (§9.4·§14.3)
| 상황 | 동작 |
|---|---|
| 원본 프로세스 API 장애 | 카탈로그 조회는 마지막 캐시로 제공 가능. 제출·승인·게시의 원본 검증은 보류하고 503 + 재시도 안내 |
| 권한 조회 시스템 장애 | 만료된 권한으로 접근 허용 금지. AUTHORIZATION_SOURCE_UNAVAILABLE |
| 동기화 부분 실패 | 불량 레코드 격리·기록. 불완전 작업의 커서를 성공 지점으로 확정하지 않는다 |
| 동시 편집 | ETag 충돌(412) 반환. 마지막 저장으로 덮어쓰지 않음 |
| 게시 직전 원본 변경 | 재검증으로 차단 |
| 원본 장애 | 게시된 Agent의 자동 폐기·자동 중지로 이어지지 않는다 |
중앙 로그인이 /?auth_error=로그인 요청이 만료되었거나 유효하지 않습니다… 로 무한 반복 | 브라우저가 state 쿠키를 저장하지 못한 경우다. /api/auth/login 응답 헤더를 확인한다 — Max-Age=0 이면 즉시 삭제된 것이다(res.cookie 의 maxAge 단위는 밀리초이며, 초 단위 값을 넘기면 0초가 된다). 서버 로그의 [directory-gateway] callback rejected: … 도 같은 원인을 가리킨다. |
| 콘솔 화면에 "등록되지 않았거나 허용되지 않은 포털 callback 주소입니다" | 콘솔의 포털 등록 redirect_uris 가 APP_ORIGIN + PORTAL_CONSOLE_CALLBACK_PATH 와 문자열 완전 일치하지 않다(콘솔은 https 만 허용, localhost 만 http 예외). 콘솔 관리자 화면의 포털 설정에서 https://<agent-center 주소>/auth/callback 을 등록·정정한다. |
| 콘솔 화면에 "이 계정은 해당 포털에 등록되어 있지 않습니다" | 등록은 정상이고 접속 권한이 없다. 콘솔에서 해당 계정을 portal_access_assignments(agent-center)에 지정한다. |
| 관리자 셸의 "사용자·역할" 항목이 사라짐 | 공급 주체는 중앙이다. 콘솔이 items: [] 를 반환하면 그대로 반영한다(포털이 항목을 되살리지 않는다). 콘솔의 PORTAL_ADMIN_MENU_JSON 또는 내장 시드에 agent-center 항목이 있는지 확인한다. 서버 로그의 중앙이 공통 관리자 메뉴를 0건 반환했습니다 가 이 경우다. |
| 공통 관리자 메뉴가 갱신되지 않음 | PORTAL_CONSOLE_MENU_TTL_MS(기본 15분)가 지나야 다시 받는다. 즉시 반영이 필요하면 재기동하거나 TTL 을 줄인다. 서버 로그의 공통 관리자 메뉴 갱신 실패 — 마지막 성공 응답(…)으로 계속합니다 는 마지막 캐시로 동작 중이라는 뜻이다(포털 기능 장애가 아니다). |
로그인 문제는 아래 두 명령으로 배포된 값 그대로 확인한다(문서·추측 대신 응답 헤더를 본다).
# 1) 포털: state 쿠키가 실제로 살아 있는가 (기대: Max-Age=600 / 문제: Max-Age=0)
curl -sS -D - -o /dev/null "https://<agent-center 주소>/api/auth/login" | grep -i "set-cookie: agent_center_oauth_state"
# 2) 콘솔: 이 client_id·redirect_uri 조합이 등록되어 있는가 (기대: "valid":true)
curl -sS "https://<콘솔 주소>/api/trpc/centralAuth.authorizeStatus?input=%7B%22json%22%3A%7B%22clientId%22%3A%22agent-center%22%2C%22redirectUri%22%3A%22https%3A%2F%2F<agent-center 주소>%2Fauth%2Fcallback%22%7D%7D"6. 보안·감사 (§14.1)
- 객체별 권한은 서버에서 검사한다. 화면 버튼 숨김으로 권한을 대체하지 않는다.
- 등록 링크는 허용 스킴·내부 도메인 정책으로 검증한다. 미리보기를 위해 임의 URL에 서버가 접근하지 않는다.
- 감사 이벤트: 생성·수정·검토·게시·중지·폐기·책임자 변경·권한 변경·동기화 실패.
- 감사 로그의 비밀정보·개인정보는 마스킹한다. 일반 관리 화면에 감사 이력 삭제 버튼을 두지 않는다.
- 보존 기간은 사내 정책 확정 전까지 임의 값을 사실처럼 구현하지 않는다.
7. 아직 구현되지 않은 것 (운영 전 필수)
- 동기화 Worker·변경 영향 파이프라인 (§9.2·§9.3)
- 폐기 검토 흐름(
review_requestkind=RETIREMENT)과 새 버전 작성 - 알림 수신자 해석(디렉터리 연계로 검토자 목록 조회)
- 관리자 화면의 편집 기능 — 정책 편집(사내 값 확정 §17), 감사 보존 정책, 사용자 원장 편집(콘솔 소유). 화면 4종 자체는 조회 전용으로 구현되어 있다(D-010)
- 공통 관리자 메뉴 저장·저작 계층(L3b) — 공급 경로는 열려 있고, 콘솔의 메뉴 저장소·저작 화면·감사가 남았다(PortalConsole
docs/portal-admin-menu-supply.md) - E2E(Playwright)
AUTH_MODE=local(포털 자체 계정) —mock과directory만 구현되어 있습니다- (외부 §17) 프로세스 원본 API 3경로의 운영 값 — 어댑터와 상대측 API 는 구현되어 있고, 남은 것은
taxonomyId로 쓸 L1 확정과 서비스 키 발급입니다 - (외부) ModelGateway 배포와
purpose매핑 — 근거 기반 답변(규약 §2-7)의 포털 쪽 경로·검증은 구현되어 있고, 남은 것은 게이트웨이 기동·서비스 토큰 공유·purpose매핑(쿼터)입니다. 미구성이면 셸은 질문 버튼을 켜지 않습니다(검색은 정상) - (외부 §17) 중앙 권한 claim(검토 역할) 노출 — 그 전까지
DIRECTORY_ROLE_ASSIGNMENTS로 부여합니다 - (외부 §17) PortalConsole 의 등록 시크릿 발급 — 자동 등록 코드는 준비되어 있습니다
운영 도입 전 §17 "실제 연계 전에 확정할 항목"을 담당자와 마친다.