아키텍처 결정 이력
2026-08-20 · UI Center의 역할 분리
결정: 공통 UI 배포 작업대는 DirectoryService 관리자 화면에서 분리해 UI Center 독립 웹서비스로 운영한다.
이유: 공통 UI 패키지 버전, 릴리스 메타데이터, 포털별 적용·검증 상태는 중앙 운영 도구로서 별도 화면과 릴리스 수명주기가 필요하다.
영향: DirectoryService는 사용자·조직·권한 원장과 UI Center 연동 설정을 유지한다. UI Center는 공통 UI 패키지·테마·배포 상태를 표시하고 관리한다.
후속 조치: UI Center 전용 읽기·쓰기 권한과 중앙 로그인 기반의 쓰기 작업 보호를 구현한다.
2026-08-20 · 배포 워크플로 이관 구현
결정: 공통 UI 릴리스 승인·포털 구독·적용 요청의 활성 운영 화면은 UI Center가 담당하고, DirectoryService는 포털 URL·관리형 클라우드 전달 대상·관리형 Key 및 배포 원장 API를 담당한다.
이유: 공통 UI의 릴리스 수명주기와 포털 인증·전달 설정은 서로 다른 운영 관심사다. UI Center에서는 중앙 로그인 관리자만 ui:read·ui:write 권한을 사용하는 배포 작업을 실행한다.
영향: DirectoryService의 일반 좌측 메뉴에서는 공통 UI 배포 탭을 제거하고, 로그인 사용자 정보 바로 위의 독립 UI Center 바로가기로 전환한다. 포털 URL 등록과 자격증명 전달은 현황 우선의 단일 포털 연동 설정 화면에서 관리한다.
2026-08-20 · 공통 기능은 통합 운영이 아닌 Asset 제공
결정: 일반게시판·첨부파일 같은 공통 기능은 중앙 런타임 서비스와 중앙 DB로 통합하지 않는다. 기본 소스·예제·테스트·적용 문서를 제공하는 버전 관리 Asset으로 운영한다.
이유: 포털마다 게시판 필드, 승인 절차, 화면, 보존 정책과 운영 요구가 다르다. 하나의 통합 게시판은 각 포털 요구를 제약하거나 지나치게 복잡해질 수 있다.
영향: 각 포털은 게시판 DB·소스·운영을 독립적으로 소유한다. 공통 Asset 저장소는 출발점과 개선된 기준 버전을 제공할 뿐, 포털의 런타임과 직접 결합하지 않는다.
후속 조치: 게시판·첨부파일 기본 Asset 구조와 포털별 인계·선택적 업그레이드 기준을 정의한다.
2026-08-20 · 데이터 분리 원칙 재정의
결정: 공통 게시판 DB를 별도 인스턴스나 별도 사용자로 만들지 않는다. 게시판 데이터는 적용 포털의 DB에 저장한다.
이유: 공통 기능의 최종 모델이 중앙 운영 서비스가 아니라 소스 Asset 제공으로 정리됐기 때문이다.
영향: DB 인스턴스 통합 여부는 각 포털의 기존 운영 환경 판단으로 남는다. DirectoryService의 사용자·조직 원장은 계속 중앙 API를 통해 참조한다.
후속 조치: 공통 Asset의 사용자·조직 연동 예시를 DirectoryService API 기반으로 제공한다.
2026-08-20 · 공통 UI 표준 템플릿과 자유 레이아웃 경계
결정: 공통 UI의 표준 템플릿은 로그인 화면, 로그인 후 좌측 메뉴, 우측 프레임 상단바, 히어로 영역까지로 한정한다. 히어로 아래는 공통 좌우 여백을 제외하고 포털과 하위 페이지가 자유롭게 소유하는 업무 레이아웃으로 운영한다.
이유: 모든 포털에서 일관된 진입 경험과 탐색 규칙을 유지하면서도, 업무 화면의 정보 구조·데이터 밀도·승인 절차·도메인 기능이 고정 템플릿에 제약받지 않도록 하기 위함이다.
영향: 공통 UI 패키지는 로그인, 좌측 메뉴, 상단바, 히어로 및 버튼·타이포그래피·첨부파일·게시판·폼 같은 재사용 컴포넌트를 제공한다. 각 포털은 히어로 아래의 그리드·섹션·업무 흐름·도메인 데이터 표현을 자체 소스로 구현한다.
후속 조치: 신규 포털과 화면 개편 시 공통 UI 템플릿 및 포털 자유 레이아웃 가이드를 적용 검토 기준으로 사용한다.
2026-09-13 · UI플랫폼 재편 범위와 RAG 소유자
결정: UiCenter를 UI플랫폼으로 개명·재편하되 책임은 표현 규칙(공통 UI 패키지·테마·릴리스·배포·런타임 설정) 전용으로 유지하고, AI 기능은 관장하지 않는다. RAG(문서 색인·벡터 검색·근거 기반 응답)는 별도 RAGCenter를 두지 않고 ExploreGateway가 소유한다.
이유: AI 기능에는 프론트엔드 없이 도는 것(배치 색인·요약 생성·정합성 점검 등)이 상당수 있어, 화면·표현 규칙을 소유하는 UI플랫폼이 AI 런타임까지 관장하면 책임과 릴리스 수명주기가 섞인다. 또한 RAG의 본질적 행위는 "색인된 문서에 대한 검색 실행과 근거 기반 응답"이며, 이는 이미 검색 실행·조합을 소유한 ExploreGateway의 책임과 같은 계열이다.
영향: ExploreGateway가 다중 포털 검색 조합과 문서 색인·벡터 검색·근거 기반 응답을 함께 소유한다. 벡터 저장은 애플리케이션 서비스가 아니라 PostgreSQL+pgvector 또는 외부 벡터 DB가 담당하고, 계약은 portal-foundation의 @hohyun94/portal-ai(provider·VectorStore)에 유지한다. LLM 완성(요약·번역·정합성)은 검색과 무관한 범용 기능이므로 별도 모델 게이트웨이(후속) 가 모델·키·비용·감사를 소유하고, 소비 포털은 그 주소로 호출한다. FileStore의 발행 대상 명칭은 RAGCenter에서 ExploreGateway 색인 API로 교체한다.
후속 조치: docs/SERVICE_BOUNDARIES.md의 RAGCenter 언급을 ExploreGateway 기준으로 정리하고, FileStore·ProcessCenter 문서의 발행 대상·소유자 표기를 함께 갱신한다. 모델 게이트웨이 도입 시 소비 포털의 PRIVATE_LLM_URL을 게이트웨이 주소로 교체한다.
정정(2026-09-13): 아래 "서비스 경계 정정" 항목에서 확인된 대로 RAGCenter는 별도 서비스로 존재하며 문서 인덱스·RAG·citation을 소유한다. 위 결정 중 "별도 RAGCenter를 두지 않는다"는 부분은 그 항목으로 대체된다.
2026-09-13 · 포털 메뉴 구조의 소유자
결정: 포털 메뉴 구조(메뉴 트리·퀵링크·그룹 접근 규칙)는 각 포털이 소유한다. UI플랫폼은 메뉴 데이터를 저장·배포하지 않고, 공통 메뉴 UX 규칙과 컴포넌트만 제공한다.
이유: 메뉴는 포털의 화면 구조·업무 동선·라우팅·권한과 직접 엮여 있어 포털마다 체계가 다르다. 중앙에서 소유하면 포털 화면 개편마다 UI플랫폼 릴리스가 필요해져 릴리스 수명주기가 묶이고, 테마·릴리스처럼 중앙화할 이득이 크지 않다. ARCHITECTURE.md의 "개별 포털이 화면과 DB를 소유한다" 원칙과도 일치한다.
영향: ProcessCenter의 portalMenu·portalGroups(및 portal_menu_items·portal_quick_links·portal_menu_audits·portal_user_groups·portal_group_members·portal_group_permissions)는 현행 포털 소유를 유지한다. UI플랫폼은 메뉴 데이터 API를 제공하지 않으며, 포털은 공통 메뉴 최적화 가이드(COMMON_UI_TEMPLATE_GUIDE.md)를 참고해 자체 메뉴를 구성한다.
후속 조치: 경계 문서(SERVICE_BOUNDARIES.md)와 역할 표(ARCHITECTURE.md)에 포털 소유를 명시했다. 테마 정책은 계속 UI플랫폼 소유(themePolicyGateway 구독)이므로, 메뉴와 혼동하지 않도록 두 항목을 함께 관리한다.
2026-09-13 · 모델 게이트웨이 이름·범위 확정
결정: LLM 완성(요약·번역·정합성 등)의 모델 접근·키·쿼터·비용·감사를 담당하는 서비스를 **ModelGateway(모델 게이트웨이)**로 확정한다. OpenAI 호환 인터페이스를 유지해 소비 포털은 환경변수 교체만으로 이전한다.
이유: UI플랫폼은 AI를 관장하지 않고, ExploreGateway는 검색·색인을 소유한다. 남은 "모델 접근" 축을 별도 서비스로 두면 키·쿼터·비용·감사를 한 곳에서 일관되게 관리할 수 있다. 이름은 ExploreGateway와 짝을 이루면서 공용 라이브러리 @hohyun94/portal-ai(ai-core)와 충돌하지 않는 ModelGateway로 정했다(AiGateway·Ai-Core·LlmGateway 기각).
영향: 소비 포털은 PRIVATE_LLM_URL을 게이트웨이 주소로 바꾸고 키를 게이트웨이로 이전한다(코드 변경 0). 이어서 귀속 헤더(x-portal-id·x-purpose·x-actor)를 추가하면 비용·감사 귀속이 활성화된다. 감사는 요청·응답 본문을 저장하지 않고 메타데이터만 기록한다.
후속 조치: 범위·인터페이스·미해결 항목은 docs/MODEL_GATEWAY_SCOPE.md에서 관리한다. 저장소 생성 시 서비스 표준 레이아웃(헬스·인증·감사·Dockerfile.dev)을 적용하고, 소비 포털의 P1(주소 교체)·P2(귀속 헤더)를 순차 진행한다.
2026-09-13 · 모델 게이트웨이 운영 정책(프롬프트·폴백·임베딩·토큰)
결정: ① 프롬프트 내용은 각 포털 소유(게이트웨이는 purpose·모델·감사·쿼터만) ② 모델 폴백은 CLOUD 한정 옵션(MODEL_GATEWAY_FALLBACK_URL)으로 1회 재시도, ON_PREM 금지 ③ 임베딩도 게이트웨이 경유로 통일 ④ 서비스 토큰은 소비자별 정적 + 다중 동시 유효로 무중단 회전.
이유: 프롬프트 내용은 업무 규칙이므로 중앙 표준화하면 포털별 요약·번역 요구를 제약한다(선행 결정 "AI 적용 결정 = 각 포털"). 모델 폴백은 가용성과 데이터 반출 정책이 충돌하는 지점이라 CLOUD에만 허용한다. 임베딩을 게이트웨이로 모으면 키·쿼터·감사가 한 지점에서 관리되고, 토큰이 하나뿐이면 회전 시 다운타임이 생긴다.
영향: ModelGateway는 토큰 목록(MODEL_GATEWAY_SERVICE_TOKENS)·폴백 URL을 환경변수로 받고, ProcessCenter는 임베딩 호출도 게이트웨이를 우선 사용한다(미설정 시 기존 직접 호출 폴백). 폴백 사용 시 응답 헤더 x-upstream-fallback: true로 표시된다.
후속 조치: 배포 환경에 MODEL_GATEWAY_SERVICE_TOKENS(2개) 주입 절차를 문서화한다. 프롬프트 표준화가 필요해지면 포털별 purpose 등록 방식으로 검토한다.
2026-09-13 · 서비스 경계 정정 (RAGCenter · ExploreGateway 공존)
결정: 문서 인덱스·RAG·citation은 RAGCenter(기존 Python 서비스)가 소유하고, ExploreGateway는 다중 포털 탐색 실행 조합(포털 어댑터 오케스트레이션)만 소유한다. 포털은 ExploreGateway가 호출하는 탐색 어댑터를 제공한다.
이유: 실사 결과 ExploreGateway(control plane catalog·Scope 기반 어댑터 선택·정규화)와 RAGCenter(문서 파이프라인·청킹·인덱싱·pgvector RLS 검색·스트리밍 답변·감사·PII·평가)가 이미 분리된 서비스로 존재했다. 같은 날 앞선 결정("별도 RAGCenter를 두지 않는다")은 저장소 실사를 반영하지 못한 것이므로 정정한다. ExploreGateway 경계 문서도 문서 인덱스·RAG·citation = RAGCenter로 명시하고 있다.
영향: FileStore의 발행 대상 표기는 RAGCenter로 원복한다. ProcessCenter는 게이트웨이에 질의하는 대신 어댑터(POST /api/explore/v1/search, 서비스 토큰 + x-explore-subject-id)를 제공하며, 이 역할은 이미 server/remoteExplore.ts에 구현되어 있다. RAG 답변은 RAGCenter로 연동한다(연동 전까지 PC 로컬 구현 유지).
후속 조치: ProcessCenter/docs/EXPLORE_ADAPTER_CONTRACT.md·explore-adapter.openapi.json으로 어댑터 계약을 문서화했다. RAGCenter API 계약 확인 후 PC의 rag 경로 연동 계획을 수립한다.
2026-09-13 · 플랫폼 명칭 규칙 확정 (Center = 소비 포털 · 기능 접미사 = 플랫폼 서비스)
결정: 소비 포털은 …Center(ProcessCenter · GuideCenter), 플랫폼 서비스는 기능 접미사(PortalConsole · UiPlatform · FileStore · RagService · ModelGateway · ExploreGateway)로 통일한다. 이전 이름 DirectoryService(제품 표기 Portal Control Center) → PortalConsole, UiCenter → UiPlatform, AssetStore → FileStore, RAGCenter → RagService 로 저장소·폴더·패키지·compose 서비스·컨테이너명을 변경했다. 기준 문서는 docs/PLATFORM_NAMING.md다.
이유: "Center"가 소비 포털과 플랫폼 서비스에 섞여 쓰여 서비스 성격(사용자 제품인지 플랫폼인지)이 이름만으로 드러나지 않았고, "Asset"이 파일 원본 저장소와 공통 UI 자산에 중복 사용되어 혼란을 만들었다.
영향: 저장소·폴더·패키지명·dev compose(서비스 키·컨테이너명·빌드 컨텍스트·서비스 간 호스트명·loopback 전달자 대상)가 새 이름을 쓴다. 데이터·계약 식별자(DB directory_service·ui_center·file_store와 file_store_* 테이블, API 경로 /api/directory/v1/*·/api/file-store/v1/*, 토큰 audience·포털 ID ui-center·ui-center-theme·file-store·rag-center, 환경변수 접두 DIRECTORY_*·UI_CENTER_*·FILE_STORE_*·RAG_CENTER_*, 배포 서비스명)는 호환을 위해 유지하며 근거를 명칭 문서 §3에 기록했다.
후속 조치: 2차 — 환경변수 접두 개편(구 이름 별칭 1릴리스 병행) · 배포 서비스명·도메인 · PF 어댑터 패키지명(@hohyun94/portal-filestore)과 vendor 재배포. 3차 — 문서 본문·코드 심볼·CSS 클래스 전면 치환, RagService Python 모듈명(ragcenter), 토큰 audience·포털 ID 동시 배포 릴리스, PF 네임스페이스(@portal-foundation/* vs @hohyun94/*) 통일.
2026-09-14 · AI 운영 표면과 AI 기능 레지스트리
결정: AI를 사용하는 공통기능(요약·번역·정합성·영역 추론·RAG·실시간 번역 등) 의 목록·세팅·사용량을 PortalConsole(제어평면 콘솔) 한 곳에서 관리한다. 중심 엔티티는 고정 enum이 아니라 열린 AI 기능(purpose) 레지스트리이고, 각 기능은 완성 연결(ModelGateway) 과 선택적 검색 연결(ExploreGateway·RagService) 을 가지며, 도입에 필요한 능력(예: streaming) 을 함께 기록한다. 규격은 docs/AI_FEATURE_REGISTRY.md, 게이트웨이 쪽 결정은 docs/MODEL_GATEWAY_SCOPE.md §9·§8-7이다.
이유: AI를 쓰는 기능은 계속 늘어나는데(번역 → 실시간 번역, 요약 → 영역 추론, 검색 → RAG), 기능을 고정 목록으로 두면 확장마다 서비스·스키마·화면을 함께 고쳐야 한다. 화면을 서비스별로 각각 만들면(게이트웨이 + 검색 + 색인) 관리자가 여러 곳을 오가고, "어느 포털에 어떤 AI 기능이 적용됐는지"를 볼 단일 지점이 사라진다. 사용자·조직·포털·접근권한을 이미 소유한 PortalConsole가 정책·적용 현황·사용량을 통합해 보는 것이 제어평면 역할과 일치한다.
영향: 서비스 경계는 그대로 유지한다(ModelGateway=완성, ExploreGateway·RagService=검색·색인, portal-foundation=계약·유틸 Asset). 게이트웨이는 UI를 갖지 않으며(MODEL_GATEWAY_SCOPE §8-7) 콘솔 서버가 서버 간 토큰으로 각 서비스 관리 API를 호출한다. 공통기능 구현은 2026-08-20 결정("공통 기능은 통합 운영이 아닌 Asset 제공")대로 Asset으로 제공하고, 중앙 런타임은 모델 접근·색인에만 둔다. RAG는 ModelGateway 소유가 아니며 wiring.model + wiring.retrieval을 함께 가진 기능으로 기록한다. 스트리밍 기능은 capabilities: ["streaming"]으로 등록하고, MODEL_GATEWAY_SCOPE §8-8 보류를 재개한 뒤 활성화한다.
후속 조치: 포털 카탈로그의 고정 capabilities(["search","answer"])를 기능 레지스트리로 승격 · RagService ↔ ExploreGateway 경계(권장 A안) 확정 · RagService·ExploreGateway의 콘솔용 관리·상태 API 계약 · 레지스트리 저장 위치 확정.
2026-09-14 · 플랫폼 비전·가치 사슬 확정
결정: 플랫폼의 방향을 "데이터 → 지식 → 의미 → 성과" 가치 사슬로 고정한다. 노스 스타는 "흩어진 데이터를 의미망(온톨로지·지식 그래프)으로 승화하고, AI가 그 위에서 의미를 도출해 각 포털의 비즈니스 성과로 이어지게 하는 기반"이다. 플랫폼은 데이터 → 지식 → 의미까지를 책임지고, 의미 → 성과는 각 포털이 낸다. 전문은 docs/PLATFORM_VISION.md.
이유: 각 축(제어·표현·의미·저장·검색·완성·업무)의 결정이 개별적으로 쌓여 있어 "왜 이 구조인가"를 한 곳에서 볼 기준이 없었다. AI 기능 레지스트리(2026-09-14)와 데이터·온톨로지 논의를 거치면서 개별 결정들이 하나의 사슬로 수렴함을 확인했다.
영향: 새 원칙을 만들지 않고 기존 결정을 정합 표로 묶는다 — 업무는 각 포털 소유, 공통기능은 Asset(템플릿), 표현은 portal-foundation 원천 + UiPlatform 통제, 서비스는 분리·표면은 통합(PortalConsole), 모델은 연결 대상(기능은 purpose만 인다), 플랫폼은 업무 로직을 실행하지 않는다. 함께 기록한 것: AI 계층 3층(모델 연결 → 공통기능 → 포털 기능)과 purpose 귀속, 데이터 3형태(정형·비정형·관계)와 문서에 담긴 지식, 온톨로지 양방향(표준 정의 + 데이터 추출).
후속 조치: PLATFORM_VISION.md §9의 미해결 결정(온톨로지 범위·소유자·그래프 저장·생성 방식, RagService ↔ ExploreGateway 경계)을 순차 확정하고, 결정 시 이 로그와 본 문서를 함께 갱신한다.
2026-09-14 · 플랫폼 문서 라이브러리(생성 문서 축적·조회) 소유권
결정: 플랫폼이 만드는 설계·결정·규격 문서를 한 곳에 축적해 조회하는 "문서 라이브러리" 를 둔다. 보관은 오브젝트 스토리지(R2, platform-docs/ 프리픽스 — 콘솔이 이미 쓰는 PROFILE_STORAGE_* 구성 공유), 조회 표면(메뉴) 은 PortalControlCenter 관리자 메뉴가 소유하고, 검색·질의는 후속으로 RagService·ExploreGateway 색인에 태운다.
이유: 플랫폼 문서가 저장소(UiPlatform/docs)에만 있어 운영자·개발자가 열람·검색하기 어렵다. 별도 포털이나 새 앱을 만들면 2026-08-20 결정("공통 기능은 중앙 런타임 통합이 아닌 Asset 제공")과 충돌하고 운영 표면이 중복된다. 제어평면 콘솔이 이미 관리자 인증·권한·메뉴·감사를 소유하므로, 2026-09-14 "운영 표면은 PortalConsole 한 곳" 결정과 같은 방식으로 콘솔 메뉴 한 곳에 붙이는 것이 일관적이다. 보관을 FileStore가 아니라 오브젝트 스토리지 프리픽스로 두는 이유는, 콘솔이 portal-media/에서 이미 같은 방식(오브젝트 키 파생 목록 + 서명 URL 조회)을 쓰고 있어 새 스키마·새 서비스가 필요 없기 때문이다.
영향: PortalControlCenter에 관리자 메뉴 문서 라이브러리를 추가한다. 게시는 관리자(또는 CI가 전용 토큰으로) 수행하고, 목록은 오브젝트 키 규약 platform-docs/{docId}/{version}/{file}에서 파생한다(별도 테이블 없이 첨부파일 재고와 같은 방식). 문서 조회는 서명 URL(만료 10분)로 열람·다운로드한다. 오브젝트 스토리지가 구성되지 않은 환경에서는 로컬 파일시스템(PORTAL_CONSOLE_DOC_LIBRARY_PATH, 기본 var/doc-library)으로 폴백해 즉시 게시·조회할 수 있게 하고, R2를 설정하면 같은 키 규약으로 이관한다.
후속 조치: 문서 게시 자동화 완료 — UiPlatform scripts/publish-docs.mjs와 .github/workflows/publish-docs.yml이 docs/** 변경 시 HTML/PDF를 만들어 콘솔 API(POST /api/library/v1/documents, 전용 게시 토큰)로 게시한다. 남은 것: RagService 색인 연동(자연어 질의) · 보관 위치를 중앙 파일 원본(FileStore) 관리로 이관할지 검토.
2026-09-14 · 온톨로지 범위·소유·저장·생성 확정
결정: 가치 사슬의 지식 단계를 여는 온톨로지의 범위·소유·저장·생성 방식을 확정한다. 전문은 docs/ONTOLOGY_SCOPE.md. (1) 범위 — 문서·프로세스에 실제 등장하는 개념·관계·용어로 한정하고, 데이터 공급원은 ProcessCenter 업무프로세스 정의 + GuideCenter 사내정책문서 + 사내 비정형 문서로 한다. 개별 업무의 산출물(결재 건·실행 결과 보고서·회의록 등 인스턴스)은 범위 밖이며 수용 여부는 다음 단계에서 결정한다. (2) 정형 처리 — 프로세스 종류(게시본·노드·승인)는 온톨로지 개념으로 정의하고 개별 프로세스 정의는 참조 노드로 둔다(방식 2). (3) 소유 — 분할 소유: 표준 스키마·용어팩은 portal-foundation Asset(@hohyun94/portal-ai 하위, 커지면 @hohyun94/portal-ontology), 운영 표면(용어·개념·후보 승인)은 PortalConsole 관리자 메뉴 온톨로지, 실데이터는 각 소유자, 실행(추출·색인)은 ModelGateway·RagService/ExploreGateway. (4) 저장·색인 — 중앙 그래프 DB를 신설하지 않고 어댑터 수집(각 소유자 원본 유지) + 기존 색인을 쓴다. glossary는 개념 용어 중심으로 확장하고 번역은 선택 필드로 내린다. (5) 생성 — 수동 뼈대 + 자동 살(제안 → 승인): 표준 등록(사람) → 추출(자동, ontology.extract) → 승인(사람) → 색인 반영 → 용어팩 버전 배포. 관계 유형은 7종 고정(isA·partOf·belongsTo·appliesTo·references·requiresRole·precedes)이고, 범위 진입은 사람·표준이 판정하며 자동은 후보만 낸다. (6) 유입 경로 — 정책·비정형 문서의 정본은 FileStore이며 추출·검색은 FileStore 색인을 단일 입력으로 받는다. Document Library는 "플랫폼 생성 문서" 전용을 유지한다(역할 확장 없음).
이유: 데이터·정의·정책은 쌓이는데 의미망이 없어 AI가 매 질문마다 문맥을 처음부터 다시 읽고 있었다. 씨앗(glossary 번역 용어)·코퍼스(문서 라이브러리·FileStore)·연결(ModelGateway)·소비자(RagService/ExploreGateway)는 이미 운영 중이므로 정의만 확정하면 지식 단계를 열 수 있다. 범위를 "실제 등장하는 것"으로 한정하고 자동은 후보만 내게 한 이유는 근거 없는 추측이 지식으로 굳는 것을 막기 위함이며(전사 온톨로지 선제 정의 배제), 후보에는 evidence(근거 문서)가 필수다. 개별 업무 산출물을 범위 밖으로 둔 이유는 그것이 각 포털의 업무 데이터이기 때문이다 — "플랫폼은 업무 데이터를 소유하지 않는다" 원칙과 일치한다. 분할 소유를 택한 이유는 스키마·용어팩이 포털이 버전으로 받아 쓰는 Asset이어야 하고(2026-08-20), 운영 표면은 콘솔 한 곳이어야 하기 때문이다(2026-09-14). 그래프 DB를 신설하지 않은 이유는 지금 필요한 것이 "어휘·관계의 일관성"이지 대규모 그래프 질의가 아니기 때문이며, 재검토 조건(다단계 관계 질의·수만 건 조회 지연)을 문서에 명시했다.
영향: PortalConsole에 관리자 메뉴 온톨로지를 추가하고 glossary를 개념 용어 중심으로 확장한다(번역은 선택 필드). portal-foundation @hohyun94/portal-ai가 온톨로지 스키마·용어팩 배포 단위가 된다. 정책·비정형 문서는 FileStore에 정본을 두고 색인을 경유해 추출되며, Document Library의 역할은 플랫폼 문서 전용으로 유지된다(사내 문서의 정본이 아니다). 각 포털은 자기 데이터를 계속 소유하고 플랫폼은 정의·보관·검증 표면만 갖는다. 새 AI 기능 ontology.extract(개념·관계·용어 후보 추출)가 레지스트리에 등록된다.
후속 조치: RagService ↔ ExploreGateway 경계(§9-5, 권장 A안) 확정 · 추출 품질 측정 기준 · 승인 화면의 근거 문서 링크 · 색인 재발행 시점(즉시/배치) · 개별 업무 산출물 수용 여부(다음 단계) · 포털 카탈로그 capabilities → 기능 레지스트리 승격.
2026-09-15 · 검색 경계 확정 — 오케스트레이션은 ExploreGateway, 색인·RAG는 RagService
결정: PLATFORM_VISION.md §9-5 의 RagService ↔ ExploreGateway 경계를 A안으로 확정한다. 다중 포털 탐색 조합 실행은 ExploreGateway, 문서 색인·검색·RAG·citation 은 RagService 가 소유한다. 전문과 콘솔용 관리·상태 API 계약 초안은 docs/SEARCH_SCOPE.md.
이유: 세 저장소의 실제 라우트를 읽어 검증했다. RagService 가 POST /api/v1/search·/api/v1/chat/stream·/api/v1/questions/embedding 과 관리 API(/api/v1/admin/overview·operations·settings·tuning/recommendations·documents/{id})를 소유하고, ExploreGateway 는 POST /api/explore/v1/search 로 조합 실행만 한다 — A안이 실제 경계와 일치한다. 또한 RagService 는 디렉터리가 서명한 JWT(audience rag-center, scope rag:admin)를 검증하므로 콘솔이 이미 서명 주체인 점을 그대로 쓸 수 있고(새 토큰 체계 불필요), 색인 입력이 파일 경로 기반 배치(BatchDocumentJob{path, metadata})라 FileStore 가 원본을 두고 경로를 넘기는 비전 §6-2 흐름과 맞는다.
영향: 콘솔은 각 서비스에 브라우저로 붙지 않고 서버 간 호출로만 접근한다(게이트웨이와 같은 원칙 — MODEL_GATEWAY_SCOPE §8-7). AI 기능 레지스트리의 retrieval 능력은 "경계 확정"으로 올라가고, 문서 라이브러리·정책·비정형 문서가 같은 색인을 공유해 자연어 질의와 온톨로지 추출 입력(ontology.extract)을 함께 얻는다.
후속 조치: 관리·상태 API 계약 초안 완료(SEARCH_SCOPE.md §6) · 공유 스토리지 경로 규약(FileStore 원본 ↔ RagService 읽기 경로) · 색인 재발행 시점(승인 즉시 vs 배치) · 콘솔 사용량 뷰에 색인 지표 연결 · ontology.extract 입력 연결.
2026-09-15 · 저장 라우팅 확정 — 포털별 파일 보관은 FileStore가 소유, 운영 표면은 콘솔
결정: 포털별 비정형 파일을 어느 저장소(백엔드)에 어떤 정책으로 둘지는 FileStore가 소유한다. 운영 표면은 Portal Control Center 관리자 메뉴가 가지며, 콘솔은 서버 간 호출로만 백엔드·정책을 조회·등록·진단한다(브라우저는 FileStore에 직접 붙지 않는다). 실제 API 계약·검증·콘솔 화면 설계는 docs/FILE_STORE_SCOPE.md.
이유: FileStore 소스를 읽어 이미 구현돼 있음을 확인했다 — StorageBackend(provider CLOUDFLARE_R2·AMAZON_S3·S3_COMPATIBLE·LOCAL_VOLUME, bucket·endpoint·secretRef·localRoot)와 ConsumerStoragePolicy(포털별 backendId·pathPrefix·maxBytes·allowedContentTypes·retentionDays·encryptionRequired·ragPublishAllowed·read/write), 객체 키 {pathPrefix}/{consumerId}/{assetId}/{fileName}, 라우팅 createStorage, 관리 API(PUT /admin/backends/:id·POST /admin/backends/validate·test-connection·PUT /admin/consumer-policies/:id). secretRef는 ${secretRef}_ACCESS_KEY_ID·${secretRef}_SECRET_ACCESS_KEY 환경변수 접두로만 해석해 키가 DB·화면에 남지 않는다. 반면 콘솔은 문서 라이브러리를 자기 앱의 단일 버킷에만 넣고 있어, 앱 환경변수 미설정 시 로컬 파일시스템으로 폴백해 재배포마다 문서가 사라졌다. 즉 새 모델을 만들 필요가 없고 운영 표면만 연결하면 된다. 표면을 콘솔 한 곳으로 모으는 것은 이미 확정된 서비스 분리 · 표면 통합 원칙을 따른 것이며, 포털별 파일을 포털별 정책으로 분리하는 것이 특정 포털의 파일이 다른 포털의 저장소 사고에 휩쓸리지 않게 하는 방법이다.
영향: PortalConsole에 관리자 메뉴 파일 보관(FileStore) 을 추가한다 — 저장 백엔드 탭(목록·등록·검증·R2 연결 실측·비활성화), 포털별 정책 탭(백엔드 라우팅·보존·허용 형식·RAG 발행 허용), 진단 탭(콘솔이 이미 저장하는 fileStoreConsumerId·fileStoreMappingId·fileStoreBaseUrl와 FileStore 정책의 불일치 표시). 콘솔 서버는 FILE_STORE_BASE_URL·FILE_STORE_ADMIN_TOKEN·FILE_STORE_SERVICE_TOKEN(모두 서버 전용)로 호출하고, 화면에는 secretRef 이름만 표시한다. FileStore의 권한 게이트 작업(계정·admin:manage·cleanup·감사)은 FileStore /admin 화면이 계속 담당하며 콘솔로 복제하지 않는다. LOCAL_VOLUME 백엔드는 볼륨 마운트가 없으면 재배포 시 파일이 사라진다는 경고를 화면에 고정한다.
후속 조치: 콘솔 파일 보관 데스크 구현(다음 작업) · 공유 스토리지 경로 규약과 RagPublisher 실연결(현재 로그 스텁) 결정 — 결정 전까지 ragPublishAllowed는 끈 상태 유지 · 문서 라이브러리 보관을 FileStore 소비자로 이관할지 검토 · 콘솔 앱 스토리지 환경변수 점검을 백엔드 진단으로 일반화.
2026-10-11 · 용어집 중앙화와 번역 — 표기의 정본은 원장, 번역 실행은 콘솔
결정: 표기(용어)의 정본은 PortalConsole 용어 원장(directoryGlossaryTerms) 하나로 두고, AI 번역은 번역 팩(승인 용어만)을 입력으로 쓴다. 번역 실행도 콘솔의 중앙 번역 서비스(POST /api/directory/v1/translation, 스코프 translation:invoke)가 맡는다 — 포털은 콘텐츠 파이프라인(무엇을 번역할지·작업 큐·버전·발행·번역 메모리)만 유지한다. 온톨로지 팩(개념·관계)과 번역 팩(표기)은 분리한다. 계약 문서는 PortalConsole/docs/TRANSLATION_PACK.md.
이유: 소비 포털이 늘면 같은 단어를 포털마다 다르게 옮겨 AI 번역이 매번 흔들린다 — 콘텐츠를 만들 때 정확한 단어를 먼저 알려주는 것이 용어집을 만드는 목적이다. ProcessCenter 용어집의 중앙 승격은 이미 완료됐고(directory_glossary_repository 가 원장 read-through, 2026-10-04 개정), GuideCenter 에도 원장 클라이언트가 있어 배선이 짧았다. 반대로 번역기를 포털마다 두면 프롬프트 규칙까지 갈라지므로 실행도 한 곳으로 모았다. 온톨로지는 "무엇을 뜻하고 무엇과 이어지는가"이고 용어집은 "어떻게 부르는가"라 계층이 다르다 — 개념 없는 번역 전용 용어가 대부분이므로 한 팩으로 합치지 않았다.
영향: 번역은 원장 승인 용어를 먼저 쓰고(중앙 실행) 로컬 용어는 보조로 병합하며, 원장이 설정되지 않았거나 닿지 않아도 GUIDE_TRANSLATION_PROVIDER=local 폴백·자동 폴백으로 번역이 멈추지 않는다. 프롬프트 규칙(구조·링크·코드·숫자·placeholder·제품명·ID 보존, 용어집 우선)은 GuideCenter·콘솔이 같은 문장을 쓴다. 용어 등록 API 는 소속(scope)을 받고 생략하면 호출 포털 소속으로 저장하며, 수정에서 생략하면 기존 소속을 유지한다(소속이 사라지면 팩에서 조용히 빠진다). 표준 표기는 시드 스크립트(pnpm seed:glossary, 플랫폼 표기 ko↔en 38개)로 한 번에 넣는다.
후속 조치: glossary:write 키로 원장 시드 실행(로컬·배포) · 각 포털이 자기 업무 용어를 자기 scope(process-center 등)로 등록 · @hohyun94/portal-ai 소스 저장소가 준비되면 번역 모듈(프롬프트·provider)을 라이브러리로 승격해 콘솔·포털의 중복 구현 제거 · 최소 1회 실연결 확인.
2026-10-16 · 온톨로지 소유 이관 — 원장은 OntologyService, 콘솔은 등록·런처
결정: 온톨로지·용어사전(개념·용어·관계·컨텐츠 연결)의 원장(표·감사·팩 발행·REST/tRPC)을 새 플랫폼 서비스 OntologyService 로 이관한다. PortalConsole 은 포털 등록(PLATFORM_SERVICE)과 셸 레일 하단 런처만 남긴다. 경로·응답 스키마·scope 이름(glossary:read·glossary:write)은 유지해 소비자 3곳(ProcessCenter·DocumentLibrary·GuideCenter)이 주소만 바꾼다. 번역 실행은 콘솔에 남긴다(2026-10-11 유지) — 콘솔 중앙 번역 서비스(POST /api/directory/v1/translation, scope translation:invoke)가 지식 서비스의 승인 용어를 서버 간 호출로 읽어 번역 팩을 만든다(표기·정의는 복제하지 않는다). 확정(2026-10-16): 서비스 이름 OntologyService · 배포 주소 ontology.rlab.monster · 과거 감사 이력은 새 서비스로 복사한다.
이유: 지식망은 업무 데이터가 아니라 플랫폼 자산인데(2026-09-14) 원장이 콘솔 DB·관리자 화면에 있고, 지식 로드맵(추출 ontology.extract · 색인 재발행 · 승인 이력 · 품질지표)은 관리자 메뉴와 수명주기가 다르다. 용어사전 편집 표면도 콘솔 온톨로지 데스크와 ProcessCenter 전문용어사전 두 곳으로 갈려 있다(둘 다 같은 원장 호출 — terminologyService.ts → directorySyncService.createCentralGlossaryTerm). 2026-09-15 결정의 "서비스 분리 · 표면 통합" 중 표면을 콘솔 한 곳에 두는 부분만 개정한다 — 서비스 분리(소유) 원칙은 유지·강화된다. 2026-10-11의 "표기의 정본은 원장"도 그대로다(원장의 위치만 콘솔 DB → 지식 서비스 DB).
영향: ONTOLOGY_SCOPE.md §3·§4·§5·§6·§8 표기 개정 · SERVICE_BOUNDARIES.md 온톨로지 행 교체 · 콘솔 온톨로지 탭 제거 + 레일 하단 런처 · 소비자 env ONTOLOGY_BASE_URL 신설(DIRECTORY_BASE_URL 폴백) · 콘솔이 지식 서비스 REST 소비자로 추가(서버 간 호출).
후속 조치: 이관 절차·검증·롤백은 PortalConsole docs/ontology-ownership-move-plan.md(P0~P5) · 감사 이력 연속성 — 2026-10-16 확정: 과거 directory_audit_logs(entity_type=ONTOLOGY) 행을 새 서비스로 복사(표·컬럼·봉투 키 동일) · ProcessCenter 전문용어사전 편집 표면 단일화 · ONTOLOGY_SCOPE.md §8 미결 2건(공유 스토리지 경로 규약 · 색인 재발행 시점)은 추출·색인 연결 전에 확정.
2026-10-16 · 파일 보관 표면 전환 — 콘솔 데스크 대신 FileStore 런처
결정: 2026-09-15 결정의 "운영 표면 = PortalConsole 관리자 메뉴" 부분을 개정한다. 포털별 저장 라우팅의 소유는 FileStore 그대로이고, 콘솔 관리자 메뉴의 파일 보관(file-store) 탭은 없앤다. 대신 등록된 file-store 포털 주소를 셸 레일 하단 런처로 새 창에서 연다(UiPlatform 바로가기와 같은 방식 — 클래스 .platform-launch · URL 검증 lib/platformLaunchLink.ts getPlatformLaunchUrl · 조건은 enabled + 절대 HTTPS URL). 저장 백엔드·정책·자격증명은 FileStore 자체 /admin(로컬 관리자 세션)이 원천이다.
이유: FileStore /admin 이 권한 게이트(계정·admin:manage·cleanup)를 이미 소유해 콘솔 데스크와 운영 화면이 중복됐고, 콘솔이 서버 간 프록시로 들고 있던 백엔드 목록·정책은 FileStore 화면과 갈릴 수 있었다. 표면을 줄이는 방향은 2026-09-15 의 취지와 같다 — 다만 통합 지점이 콘솔 데스크가 아니라 FileStore 자체 화면이다(온톨로지 이관과 같은 원칙: 소유는 서비스, 콘솔은 등록·런처).
영향: PortalConsole docs/FILE_STORE_DESK.md(탭 제거 안내) · docs/portal-console-admin-menu.md(메뉴 9 → 8, 부가 진입점 표에 FileStore 행) · 런처 클래스 이름을 플랫폼 중립 .platform-launch 로 정리(舊 .ui-center-launch) · 콘솔 화면 자산(FileStoreDesk·fileStoreDesk.css·nav.fileStore)과 서버 fileStore* 경로는 되돌리기 쉽게 유지.
후속 조치: 콘솔 서버의 FILE_STORE_* 프록시 경로 유지/폐기 결정 · 운영자 브라우저에서 FileStore /admin 접근 경로 실측(권한 게이트는 로컬 관리자 세션만 허용) · 문서 라이브러리 보관을 FileStore 소비자로 이관할지 계속 검토(2026-09-15 후속 유지).