# 설계서: 전체 벡터 접근 역할의 ALL predicate 정규화 (#573)

> **상태**: Implemented · QA passed
> **작성**: [AI] Architect · **최종수정**: 2026-06-30
> **추적성** — Redmine: #573 · 선행 기능: #558, #570, #572
> · 구현 파일: `32_dds_vector_tag_setup.sql`, `38_agent_ords_vector_all_permission_normalization.sql`, `29_agent_ords_vector_search_ords.sql`, `OrdsProbeService`
> · 테스트: `OrdsProbeServiceTest`, `GuidedFlowTemplateTest`, `mvn test`, 운영 vector probe

## 1. 목적

기본 벡터 접근은 역할 기반 whitelist다. 기본 역할(10·20·30)에 `CB_VECTOR_SEARCH_DOCUMENTS / SELECT / ALLOW / ALL`을 저장하고, 그 역할을 가진 사용자는 전체 벡터 청크를 조회한다. 역할 권한이 없는 사용자는 VPD의 fail-closed predicate `1 = 0`으로 차단한다.

`TAG`, 부서, 소유자 같은 행 조건은 관리자가 **ALL rule이 없는 제한 역할**에 실제로 등록했을 때만 추가한다. 기본 예제 역할에 임의의 TAG rule을 넣지 않는다.

| 역할 | permission rule | VPD predicate | effective SQL 권한 조건 |
|---|---|---|---|
| `HR_DEPT_ROLE` | `ALL` | `1 = 1` | 조건 생략 |
| `FIN_SELF_ROLE` | `ALL` | `1 = 1` | 조건 생략 |
| `ALL_DOC_ROLE` | `ALL` | `1 = 1` | 조건 생략 |
| 관리자가 TAG rule을 준 역할 | `TAG: ...` | TAG OR | `AND (REGEXP_LIKE(...))` |
| 권한 없음 | allow rule 없음 | `1 = 0` | `AND (1 = 0)` |

## 2. 범위

- 초기화 SQL에서 기본 역할 10·20·30의 개별 TAG rule을 제거하고 `ALL` rule을 보장.
- 이미 설치된 DB를 위한 idempotent migration SQL 제공 및 운영 적용.
- vector ORDS/백오피스 effective SQL trace에서 predicate가 `1 = 1`이면 `AND` 절을 출력하지 않음.
- 특정 TAG role의 `REGEXP_LIKE` filter와 fail-closed `1 = 0`은 유지.

## 3. 인수조건

- [x] 기본 whitelist 역할 사용자(`이에이치알`, `박파이넨스`, `김어드민`)의 VPD predicate가 정확히 `1 = 1`이다.
- [x] 기본 whitelist 역할의 vector effective SQL에 `REGEXP_LIKE`와 `AND (1 = 1)`이 없다.
- [x] 관리자가 TAG rule을 실제로 부여한 역할만 해당 TAG predicate를 포함한다.
- [x] 기본 역할 10·20·30의 기존 vector TAG rule은 migration 후 제거되고 ALL rule은 각 한 개만 존재한다.
- [x] 권한 없는 사용자 결과는 기존 fail-closed semantics를 유지한다.
- [x] SQL trace에 Bearer 원문·임베딩 숫자가 포함되지 않는다.

## 4. 구현 흐름

```text
whitelist role
  → CB_PERMISSION (CB_VECTOR_SEARCH_DOCUMENTS / SELECT / ALLOW)
  → CB_PERMISSION_RULE (ALL)
  → CB_AGENT_DOC_VPD_FILTER = 1 = 1
  → vector effective SQL: base VECTOR_DISTANCE query only
```

기존 기본 역할의 TAG rule은 현재 fixture의 태그만 허용할 뿐 이후 추가되는 청크를 불필요하게 막는다. 기본 whitelist는 `ALL` rule로 유지하고, 제한이 필요한 역할에만 명시적 행 rule을 부여한다.

## 5. 검증

- `vectorEffectiveSql(..., "1 = 1")`가 `AND (1 = 1)`을 만들지 않는 단위 테스트.
- setup/migration source가 role 30의 ALL rule과 TAG rule 정리를 포함하는 템플릿/소스 테스트.
- `mvn test`.
- 운영 smoke: `tempUserId=101`, `102`, `103`으로 vector `/probe`를 실행해 모두 `VPD predicate = 1 = 1`, `REGEXP_LIKE` 없는 effective SQL, `SCORE` Top-K를 확인한다. 권한 없는 별도 사용자는 `1 = 0`인지 확인한다.

## 6. 구현·QA 결과

- `38_agent_ords_vector_all_permission_normalization.sql`을 운영 DB에 적용해 기본 role 10·20·30의 legacy TAG rule을 제거하고 `ALL` rule을 보장했다.
- ORDS vector handler(29)를 재등록하고 백오피스를 배포했다.
- `mvn test`: 59 tests, 0 failures.
- 운영 `/probe` smoke(2026-06-30): `이에이치알(101)`, `박파이넨스(102)`, `김어드민(103)` 모두 `1 = 1 (ALL: 추가 행 필터 없음)` 및 `WHERE d.embedding IS NOT NULL ORDER BY score`를 반환했다. 세 결과에 `REGEXP_LIKE`와 `AND (1 = 1)`은 없었다.
- 권한 없는 역할의 VPD 함수 경로는 변경하지 않아 기존 `1 = 0` fail-closed 동작을 유지한다.
