Risk 분류 규칙
Fascia의 모든 Tool 스펙은 배포 전에 Risk Engine(리스크 엔진)에 의해 평가됩니다. Risk Engine은 Flow 그래프를 분석하고, 안전하지 않은 패턴을 식별하며, Tool의 배포 가능 여부를 결정하는 Risk Level(리스크 레벨)을 할당합니다.
Risk Level
Green -- 배포 가능
Tool이 Green Risk Level을 받으려면 다음 조건이 모두 충족되어야 합니다:
- Entity 액션만 사용합니다 (create, update, transition, soft-delete) -- 원시 SQL 쓰기가 없어야 합니다.
- 모든 쓰기 작업을 감싸는 명시적
transaction경계 노드가 존재해야 합니다. - 읽기 전용이 아닌 모든 작업에 멱등성 키가 있어야 합니다.
- 무제한 쿼리가 없어야 합니다 -- 모든
read노드에 페이지네이션 또는 명시적 제한이 포함되어야 합니다. - 외부 호출이 없거나, 또는 모든 외부 호출이 트랜잭션 경계 바깥에 위치해야 합니다.
배포: 허용됩니다. Green Tool은 추가 절차 없이 배포할 수 있습니다.
Yellow -- 확인 필요
Tool이 Yellow Risk Level을 받는 조건은 다음 중 하나라도 감지되는 경우입니다:
| 조건 | 설명 |
|---|---|
| 상태 전이 중 외부 호출 | Entity 상태 전이 과정에서 payment, email, sms, httpRequest 노드가 사용됩니다. |
| External 노드에 재시도 미설정 | External 노드 (payment, email, sms, httpRequest)에 retry 노드가 설정되어 있지 않습니다. |
| 높은 행 영향도 | 단일 쓰기 작업이 100개 이상의 행에 영향을 미칩니다. |
| 멱등성 키 누락 | 쓰기 작업에 입력에서 도출된 멱등성 키가 없습니다. |
| 명시적 제한 없는 읽기 | read 노드에 페이지네이션이나 행 제한이 없어 전체 테이블 스캔의 위험이 있습니다. |
| External 노드에 타임아웃 미설정 | External 노드에 timeout 노드가 설정되어 있지 않습니다. |
배포: 확인 후 허용됩니다. 사용자가 각 Yellow 경고를 검토하고 명시적으로 확인해야 합니다. 확인 내역은 감사 로그에 기록됩니다.
Red -- 차단
Tool이 Red Risk Level을 받는 조건은 다음 중 하나라도 감지되는 경우입니다:
| 조건 | 설명 |
|---|---|
| 원시 쓰기 | Entity 추상화 레이어 없이 SQL이 실행됩니다 (검증 및 감사를 우회). |
| 무제한 업데이트 | WHERE 절이 없거나 행 제한이 없는 UPDATE 작업입니다. |
| 롤백 없는 결제 | 실패에 대한 보상 또는 롤백 메커니즘이 없는 payment 노드입니다. |
| 트랜잭션 경계 누락 | 명시적 transaction 경계 노드 바깥에 쓰기 작업이 존재합니다. |
| 하드 삭제 | 소프트 삭제(deletedAt 타임스탬프) 대신 영구 삭제를 시도합니다. |
| 트랜잭션 내부의 부작용 있는 외부 호출 | payment, email, sms, httpRequest 노드가 transaction 경계 내부에 위치합니다. 트랜잭션이 롤백되어도 외부 부작용은 되돌릴 수 없습니다. |
| 상태 머신 없는 쓰기 | write 노드가 상태 머신이 정의되지 않은 Entity를 대상으로 합니다. |
| 순환 의존성 | Flow 그래프에 순환이 포함되어 있습니다 (유효한 DAG가 아님). |
배포: 차단됩니다. Red Risk Tool은 어떤 상황에서도 배포할 수 없습니다. Risk 분석을 통과하기 전에 문제를 해결해야 합니다. Red 신호는 확인하거나 무시할 수 없습니다.
자동 수정 제안
Risk Engine이 리스크 신호를 감지하면, 구체적인 해결 방법을 제 시합니다:
| 신호 | 권장 수정 방법 |
|---|---|
| 트랜잭션 누락 | 모든 write 노드를 transaction 경계 노드로 감쌉니다. |
| 트랜잭션 내 외부 호출 | 외부 호출을 트랜잭션 경계 바깥으로 이동합니다. 롤백 시나리오를 처리하기 위한 보상 Flow를 추가합니다. |
| 재시도 누락 | 최대 3회 시도, 지수 백오프가 설정된 retry 노드를 추가합니다. |
| 무제한 업데이트 | 업데이트 범위를 지정하기 위해 WHERE 조건을 추가하거나, 명시적 행 제한을 추가합니다. |
| 롤백 없는 결제 | 보상 Flow를 추가합니다 (예: 후속 실패 시 자동 환불). |
| 멱등성 키 누락 | 입력 필드의 해시에서 도출되는 idempotencyKey를 추가합니다. |
| 하드 삭제 | 행을 삭제하는 대신 deletedAt 타임스탬프를 설정하는 소프트 삭제로 변환합니다. |
| 타임아웃 누락 | 외부 호출을 감싸는 기본 30초의 timeout 노드를 추가합니다. |
이러한 제안은 설계 단계에서 Chat Studio와 Flow Studio에 표시됩니다. Safety Agent는 사용자가 승인하면 많은 수정을 자동으로 적용할 수 있습니다.
Risk 에스컬레이션
| 레벨 | 배포 정책 | 필요한 사용자 조치 |
|---|---|---|
| Green | 자유롭게 배포 가능 | 없음 |
| Yellow | 확인 후 배포 가능 | 사용자가 각 경고를 검토하고 수락해야 합니다. 확인 내역은 감사 로그에 기록됩니다. |
| Red | 배포 차단 | 사용자가 모든 Red 신호를 수정해야 합니다. Red 신호는 확인하거나 무시할 수 없으며 -- 구조적으로 해결해야 합니다. |
평가 흐름
Risk Engine은 다음 순서로 Tool 스펙을 평가합니다:
- 구조적 검증 -- Flow 그래프가 단일 시작 노드를 가진 유효한 DAG이며, 고아 노드가 없는지 확인합니다.
- Red 신호 스캔 -- Red 조건을 검사합니다. 발견되면 Tool은 즉시 Red로 분류됩니다.
- Yellow 신호 스캔 -- Yellow 조건을 검사합니다. Red 신호 없이 발견되면 Tool은 Yellow로 분류됩니다.
- Green 확인 -- Red 또는 Yellow 신호가 감지되지 않으면 Tool은 Green으로 분류됩니다.
Risk Level은 Tool 스펙의 riskLevel 필드에 기록됩니다. 이 필드는 Risk Engine이 설정하며, 수동으로 재정의할 수 없습니다.
예시
Green Tool
데이터를 읽고, 트 랜잭션 내에서 쓰기를 수행하며, 멱등성 키가 있는 단순 CRUD Tool입니다:
[Read Customer] --> [Transaction] --> [Write Order] --> [Assert Invariant]
- 모든 쓰기가 트랜잭션 경계 내부에 있습니다.
- 외부 호출이 없습니다.
- 입력에서 도출된 멱등성 키가 있습니다.
- 읽기에 명시적 제한이 있습니다.
결과: Green -- 안전하게 배포 가능합니다.
Yellow Tool
확인 이메일을 보내지만 재시도가 설정되지 않은 예약 Tool입니다:
[Transaction] --> [Write Reservation] --> [Email Confirmation]
- 쓰기가 트랜잭션 내부에 있습니다 -- 양호합니다.
- 이메일 노드가 트랜잭션 바깥에 있습니다 -- 양호합니다.
- 이메일 노드에
retry가 설정되지 않았습니다 -- Yellow 신호입니다. - 이메일 노드에
timeout이 설정되지 않았습니다 -- Yellow 신호입니다.
결과: Yellow -- 사용자가 재시도 및 타임아웃 누락을 확인해야 합니다.
Red Tool
트랜잭션 내부에서 결제를 처리하는 결제 Tool입니다:
[Transaction] --> [Write Order] --> [Payment Charge] --> [Commit]
- 결제 노드가 트랜잭션 경계 내부에 있습니다. 결제가 성공한 후 트랜잭션이 롤백되면, 결제를 자동으로 되돌릴 수 없습니다.
결과: Red -- 배포가 차단됩니다. 결제 노드를 트랜잭션 바깥으로 이동하고 보상 Flow를 추가해야 합니다.
관련 문서
- Tool 스펙 스키마 --
riskLevel필드와 Flow 그래프 구조를 정의합니다 - Policy 스펙 스키마 -- Policy는 Risk 규칙과 함께 안전성을 강제합니다
- 시스템 아키텍처 -- Risk Engine이 빌드 단계에서 어떻게 작동하는지 설명합니다