diff --git a/backend/src/main/java/gc/mda/kcg/domain/ai/DetectionModel.java b/backend/src/main/java/gc/mda/kcg/domain/ai/DetectionModel.java
new file mode 100644
index 0000000..36a4e5c
--- /dev/null
+++ b/backend/src/main/java/gc/mda/kcg/domain/ai/DetectionModel.java
@@ -0,0 +1,53 @@
+package gc.mda.kcg.domain.ai;
+
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.OffsetDateTime;
+
+/**
+ * detection_models 엔티티 (V034, Phase 1-1).
+ *
+ * prediction 의 탐지 모델 카탈로그 — model_id 가 PK. 런타임 파라미터는
+ * 별도 {@link DetectionModelVersion} 에 버전별로 보관.
+ */
+@Entity
+@Table(name = "detection_models", schema = "kcg")
+@Getter
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+@Builder
+public class DetectionModel {
+
+ @Id
+ @Column(name = "model_id", length = 64, nullable = false)
+ private String modelId;
+
+ @Column(name = "display_name", length = 200, nullable = false)
+ private String displayName;
+
+ @Column(name = "tier", nullable = false)
+ private Integer tier;
+
+ @Column(name = "category", length = 40)
+ private String category;
+
+ @Column(name = "description", columnDefinition = "text")
+ private String description;
+
+ @Column(name = "entry_module", length = 200, nullable = false)
+ private String entryModule;
+
+ @Column(name = "entry_callable", length = 100, nullable = false)
+ private String entryCallable;
+
+ @Column(name = "is_enabled", nullable = false)
+ private Boolean isEnabled;
+
+ @Column(name = "created_at", updatable = false)
+ private OffsetDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private OffsetDateTime updatedAt;
+}
diff --git a/backend/src/main/java/gc/mda/kcg/domain/ai/DetectionModelController.java b/backend/src/main/java/gc/mda/kcg/domain/ai/DetectionModelController.java
new file mode 100644
index 0000000..8a7bfef
--- /dev/null
+++ b/backend/src/main/java/gc/mda/kcg/domain/ai/DetectionModelController.java
@@ -0,0 +1,119 @@
+package gc.mda.kcg.domain.ai;
+
+import gc.mda.kcg.permission.annotation.RequirePermission;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Detection Model Registry 운영자 API (Phase 3 MVP).
+ *
+ * 경로: /api/ai/detection-models
+ *
+ *
엔드포인트 (MVP 8종)
+ *
+ * - GET / — 모델 카탈로그 목록 (tier, model_id 정렬)
+ * - GET /{modelId} — 단건 상세
+ * - GET /{modelId}/dependencies — DAG 선행 의존성 목록
+ * - GET /{modelId}/versions — 버전 목록 (최신순)
+ * - GET /{modelId}/versions/{versionId} — 버전 상세 (params 포함)
+ * - POST /{modelId}/versions — 새 DRAFT 버전 생성
+ * - POST /{modelId}/versions/{versionId}/activate — DRAFT → ACTIVE(role)
+ * - POST /{modelId}/versions/{versionId}/archive — ACTIVE/DRAFT → ARCHIVED
+ *
+ *
+ * 범위 밖 (후속 PR)
+ * - promote-primary (SHADOW/CHALLENGER → PRIMARY), enable 토글,
+ * metrics / compare / runs 조회.
+ *
+ * 권한
+ * 모든 READ: {@code ai-operations:detection-models} READ.
+ * 쓰기(create/activate/archive): 각각 CREATE/UPDATE 권한. ADMIN / OPERATOR 역할 보유.
+ * 모든 쓰기 액션은 {@code @Auditable} 로 감사로그 자동 기록.
+ */
+@RestController
+@RequestMapping("/api/ai/detection-models")
+@RequiredArgsConstructor
+public class DetectionModelController {
+
+ private static final String RESOURCE = "ai-operations:detection-models";
+
+ private final DetectionModelService modelService;
+ private final DetectionModelVersionService versionService;
+
+ // ── 모델 카탈로그 ────────────────────────────────────────────────
+ @GetMapping
+ @RequirePermission(resource = RESOURCE, operation = "READ")
+ public List list() {
+ return modelService.list().stream()
+ .map(DetectionModelResponse::from)
+ .toList();
+ }
+
+ @GetMapping("/{modelId}")
+ @RequirePermission(resource = RESOURCE, operation = "READ")
+ public DetectionModelResponse get(@PathVariable String modelId) {
+ return DetectionModelResponse.from(modelService.get(modelId));
+ }
+
+ @GetMapping("/{modelId}/dependencies")
+ @RequirePermission(resource = RESOURCE, operation = "READ")
+ public List