> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lynxops.co/llms.txt
> Use this file to discover all available pages before exploring further.

# 이슈 후보 접수

> 방화벽, 반복 동작, 복구 신호를 서버의 비동기 검토 대상으로 전송합니다.

로컬 실행 환경에서 이슈가 될 수 있는 동작을 찾으면 `POST /openapi/v1/issue-records`를 호출합니다. 이 기록을 보냈다고 해서 즉시 이슈가 만들어지는 것은 아닙니다.

서버는 먼저 원본 기록을 저장합니다. 이후 백그라운드 작업이 관련 실행, 해결 여부, 비슷한 기존 이슈를 확인합니다. 검토 결과에 따라 새 이슈를 만들거나 기존 이슈의 발생 횟수를 늘립니다.

## 탐지 요청 예시

```bash theme={null}
curl --request POST \
  --url https://api.lynxops.co/openapi/v1/issue-records \
  --header "X-API-Key: $LYNX_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "sdkInstanceId": "python-worker-01",
    "clientRecordId": "record_01JZQ4A8C2",
    "recordKind": "DETECTION",
    "detectionType": "TOOL_BLOCKED",
    "runId": "run_01JZQ3VY4K",
    "sessionId": "session_customer_42",
    "eventId": "evt_tool_04",
    "agentId": "support-agent",
    "policyId": "17",
    "promptVersionId": "c1821bc3-bf1e-46ef-b210-b9376a41cd0c",
    "detectedAt": 1784808000000,
    "payload": {
      "toolName": "delete_customer_data",
      "tools": ["search_customer", "delete_customer_data"],
      "riskSignals": ["destructive-action"]
    },
    "evidence": {
      "decision": "BLOCK"
    }
  }'
```

## 필드

| 필드                | 필수  | 설명                                               |
| ----------------- | --- | ------------------------------------------------ |
| `sdkInstanceId`   | 예   | 고정된 클라이언트 식별자입니다. 이벤트의 `clientId`와 같은 값을 권장합니다.  |
| `clientRecordId`  | 예   | 기록의 중복 방지 키입니다. 재시도할 때 같은 값을 사용합니다.              |
| `recordKind`      | 예   | `DETECTION` 또는 `RECOVERY`입니다.                    |
| `detectionType`   | 예   | `TOOL_BLOCKED`, `LOOP_DETECTED` 같은 고정된 탐지 종류입니다. |
| `runId`           | 아니요 | 관련 외부 Run ID입니다.                                 |
| `sessionId`       | 아니요 | 관련 외부 Session ID입니다.                             |
| `eventId`         | 아니요 | 관련 이벤트의 중복 방지 키입니다.                              |
| `agentId`         | 예   | 외부 시스템의 고정 Agent ID입니다.                          |
| `policyId`        | 아니요 | 판단에 사용한 정책입니다.                                   |
| `promptVersionId` | 아니요 | 실행에 사용한 Lynx 프롬프트 버전 UUID입니다.                    |
| `detectedAt`      | 예   | 밀리초 단위 Unix 시간입니다.                               |
| `payload`         | 아니요 | 탐지 판단에 사용한 구조화된 정보입니다.                           |
| `evidence`        | 아니요 | 이슈 후보를 뒷받침하는 근거입니다.                              |

요청 본문은 256 KiB 이하여야 합니다.

## 접수 응답

```json theme={null}
{
  "recordId": "7295695e-1960-43b5-9924-003d7163d0db",
  "status": "RECEIVED",
  "isNew": true
}
```

상태는 `RECEIVED`, `EVALUATING`, `DECIDED`, `FAILED` 중 하나입니다. `isNew: false`는 같은 `sdkInstanceId`와 `clientRecordId`가 이미 접수됐다는 뜻입니다.

이 응답은 원본 기록이 저장됐다는 의미이며 최종 이슈 생성 결과가 아닙니다. 이후 평가를 기다리느라 고객 요청을 막지 마세요.

## Fingerprint와 유사 이슈 묶기

클라이언트는 구조화된 사실을 전달하고, 어떤 이슈와 묶을지는 서버가 판단합니다. 서버는 탐지 종류, 정책, 실패한 도구, 사용된 도구 집합, 판단 사유, 모델 같은 안정적인 정보를 정규화한 뒤 SHA-256으로 해싱합니다.

발생할 때마다 무작위 fingerprint를 만들지 마세요. 같은 상황을 일관되게 묶을 수 있도록 탐지 이름과 도구 식별자를 고정해서 사용하세요.

## 복구 기록

탐지한 상태가 끝났다는 근거가 생기면 `recordKind: "RECOVERY"`인 새 기록을 보냅니다. 복구 기록에는 새로운 `clientRecordId`를 사용하고 가능한 경우 같은 Run 또는 Session을 연결하세요.

복구 여부도 비동기로 검토됩니다. 복구 기록이 이슈를 바로 닫는 것은 아닙니다.

<Warning>
  근거에는 도구 인자, 모델 응답, 로그가 들어갈 수 있습니다. 탐지를 설명하는 데
  필요한 최소한의 정보만 보내고, 큐에 넣기 전에 비밀값을 마스킹하세요.
</Warning>
