# AP 그라운딩 가이드

**LLM에게 이 문서를 통째로 붙여 넣으세요.** 응용 프로파일(AP)과 원문 PDF를 받은 모델이
공개 아카이브 사이트(스타터킷)에 **그대로 실리는** Turtle을 내도록 규칙을 못 박은 문서입니다.

---

## 1. 이 문서의 쓰임

세 가지를 함께 LLM에게 줍니다.

| 무엇 | 어디서 | 무엇을 말하는가 |
|---|---|---|
| ① **기술규칙 TTL** | 「응용 프로파일」 화면 → **Turtle 내보내기** | 어느 클래스를 어느 속성으로 기술하는가 (SHACL `sh:NodeShape` — `sh:targetClass`·`sh:path`·`sh:minCount`/`sh:maxCount`·`sh:nodeKind`·`sh:class`) |
| ② **원문 PDF** | 구술총서 등 기술 대상 | 사실의 출처 |
| ③ **이 문서** | 같은 화면의 「AP 그라운딩 가이드」 | 산출물이 **화면에서 성립하기 위한** 형식 계약 |

①은 *무엇을 쓸 수 있는가*를 말하고, 이 문서는 *어떻게 적어야 화면에 뜨는가*를 말합니다.
둘은 겹치지 않으므로 **둘 다** 주어야 합니다.

### 붙여 넣을 프롬프트 (예)

> 첨부한 AP 기술규칙 TTL과 구술총서 PDF를 읽고, 아래 「AP 그라운딩 가이드」의 규칙을 지켜
> 구술기록 아카이브에 적재할 수 있는 Turtle 한 장을 만들어 줘. 컬렉션 이름은 「○○ 구술」로 해 줘.
> PDF에 없는 사실은 만들지 말고, 각 개체에 근거 쪽수를 `dcterms:source` 로 달아 줘.

---

## 2. 반드시 지킬 것

소비자(스타터킷)는 이 규칙들을 **검사하지 않습니다.** 어기면 오류가 아니라 화면이 조용히 빕니다.

### 2.1 네임스페이스 — 문자열이 정확히 일치해야 한다

```turtle
@prefix ric:  <http://archives.nanet.go.kr/id/> .                  # 모든 개체 IRI가 이 안에
@prefix rico: <https://www.ica.org/standards/RiC/ontology#> .      # https · '#' 로 끝난다
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix geo:  <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix schema: <https://schema.org/> .                            # https — http:// 는 전멸한다
```

- 개체(주어·IRI 목적어)는 **전부** `ric:` 안에 있어야 합니다. 지역명은 `agent-`·`rec-`·`place-`·`event-`·`col-` 처럼
  사람이 읽을 수 있는 슬러그로 짓습니다(한글도 유효하지만 공백·`/`·문장부호는 쓰지 마세요).
- 접두를 선언하든 전체 IRI로 쓰든 상관없습니다 — 소비자는 확장된 IRI를 비교합니다. **철자만 맞으면 됩니다.**

### 2.2 개체마다 `rdf:type` 은 표준 클래스 **정확히 1개**

화면이 그리는 표준 클래스는 아래 **12종**뿐입니다. 이 목록 밖의 타입만 가진 개체는 노드가 되지 못하고,
그 개체에 닿는 관계도 함께 사라집니다.

| 클래스 | 화면 표기 | 클래스 | 화면 표기 |
|---|---|---|---|
| `rico:Person` | 인물 | `rico:Record` | 기록 |
| `rico:CorporateBody` | 단체 | `rico:RecordSet` | 기록집합 |
| `rico:Position` | 직위 | `rico:Instantiation` | 구현체 |
| `rico:Event` | 사건 | `rico:Rule` | 규칙 |
| `rico:Activity` | 활동 | `skos:Concept` 또는 `rico:Concept` | 개념 |
| `rico:Place` | 장소 | `skos:ConceptScheme` | 개념체계 |

> 소비자는 클래스 IRI의 `#` 뒤 **지역명만** 봅니다. 그래서 `rico:Concept` 과 `skos:Concept` 이 똑같이 「개념」으로
> 그려집니다. 반대로 네임스페이스를 잘못 적어도(`http://…RiC/ontology#`처럼 http로) 지역명은 그대로라
> 이 자리에서는 통과합니다 — 다만 **관계 술어**의 네임스페이스는 문자열로 검사하므로 그쪽은 전멸합니다(2.7).

> **구현체(`rico:Instantiation`)의 「파일」 구획은 여러분이 만드는 것이 아닙니다.** 개체 상세에 PDF 뷰어와
> 「파일 내려받기」가 붙는 것은 발행 시스템이 **파일 사본을 함께 내보내면서** 주소·형식·썸네일
> (`schema:contentUrl`·`encodingFormat`·`thumbnailUrl`)을 파생 트리플로 달아 주기 때문입니다.
> 파일 없이 경로 문자열만 적으면 깨진 링크가 됩니다 — 산출물에 넣지 마세요.

### 2.3 이름은 클래스가 정하는 술어에

| 개체 | 이름 술어 |
|---|---|
| 기록(`rico:Record`·`rico:RecordSet`) | `rico:title` |
| 개념·개념체계 | `skos:prefLabel` |
| 그 밖 전부(인물·단체·직위·사건·활동·장소·규칙) | `rico:name` |

**`rdfs:label` 은 이름 자리가 아닙니다.** 소비자는 `rdfs:label` 값을 **사진 출처 크레딧**으로 읽습니다.
여기에 인물 이름을 넣으면 이름 자리에는 URI 꼬리가 뜨고 사진 출처 자리에 사람 이름이 박힙니다.
(사진 출처를 적을 때의 관례는 `"Wikimedia Commons · <출처> · 2008 촬영"` — 4자리 촬영 연도를 포함시킵니다.)

### 2.4 리터럴은 **평문** — 언어태그도 자료형도 붙이지 않는다

```turtle
rico:name "정세균"              # ✓
rico:name "정세균"@ko           # ✗ 이름으로 찾는 질의가 전부 0건이 된다
rico:beginningDate "2016-06-09"^^xsd:date   # ✗
```

다국어 이름이 필요하면 언어태그가 아니라 `skos:altLabel` 로 냅니다.

### 2.5 날짜는 세 정밀도까지

`YYYY` · `YYYY-MM` · `YYYY-MM-DD` 만 씁니다. 이 셋은 사전순이 곧 시간순이라 정렬이 성립하고,
앞 4자를 연도로 잘라 쓰는 코드가 안전해집니다. 어기면 **두 가지 다른 일**이 일어납니다.

- **앞 4자가 숫자로 안 읽히면 연표에서 조용히 탈락합니다** — `"ca. 1972"`·`"단기 4305"` 는 `NaN`,
  `"78.3"` 은 78.3 이라 「1900년 이후」 검사에 걸립니다. (1900년 이하 실제 연도도 같은 이유로 배제됩니다.)
- **앞 4자만 맞으면 연표에는 뜨는데 순서가 어긋납니다** — `"1997년 3월"`·`"1997.03.15"` 는 연도를 1997로
  제대로 잡지만, 인물 페이지의 재임·연표 정렬은 **문자열 사전순**이라 ISO 값과 섞이는 순간 순서가 뒤집힙니다.
  이쪽이 더 나쁩니다. 값이 화면에 보이니까 틀린 줄을 모릅니다.

### 2.6 좌표는 십진 문자열, 술어는 `geo:long`(`lon` 아님)

```turtle
ric:place-jeonju a rico:Place ; geo:lat "35.8242" ; geo:long "127.1480" .
```

지도는 **`geo:lat` 이 있는지만** 보고 장소를 셉니다. 그래서 값이 못 쓰는 것이어도 「곳」 수에는 그대로
들어가고, 마커를 만드는 단계에서만 깨집니다 — 수치가 그럴싸해 보여서 늦게 발견되는 사고입니다.

- 도분초 표기나 쉼표 소수점은 숫자 변환에서 `NaN` 이 됩니다.
- `geo:long` 대신 `geo:lon` 을 쓰면 경도가 아예 안 잡힙니다. 그래도 「곳」 수에서는 빠지지 않습니다.

### 2.7 관계 술어는 5개 네임스페이스, 목적어는 그래프 안의 타입 있는 개체

관계망에 그려지려면 **셋 다** 참이어야 합니다.

1. 술어가 다음 다섯 중 하나로 시작한다 —
   `https://www.ica.org/standards/RiC/ontology#` · `http://www.w3.org/2004/02/skos/core#` ·
   `http://xmlns.com/foaf/0.1/` · `https://schema.org/` · `http://archives.nanet.go.kr/voca#`
2. 목적어가 리터럴이 아니라 **IRI** 다.
3. 간선 **양끝이 모두** 위 12종 타입을 가진 개체다.

`dcterms:`·`prov:`·`oa:`·`owl:` 술어는 관계가 되지 않습니다(그래도 유용합니다 — 2.10 참조).

### 2.8 컬렉션 — `col-` 접두 + `rico:RecordSet` + 갈라지는 소속 술어

```turtle
ric:col-○○-구술 a rico:RecordSet ; rico:title "○○ 구술" .

ric:rec-1     rico:isOrWasIncludedIn ric:col-○○-구술 .   # 기록만
ric:agent-1   rico:isOrWasSubjectOf  ric:col-○○-구술 .   # 인물·사건·장소·개념…
```

술어가 갈리는 이유는 취향이 아니라 도메인입니다 — `isOrWasIncludedIn` 의 domain 이 `Record` 라
인물을 그리로 이으면 도메인 위반입니다. `isOrWasSubjectOf` 는 domain 이 `Thing` 이라 무엇이든 걸 수 있습니다.

소비자는 `RecordSet` **이면서** 지역명이 `col-` 로 시작하는 노드만 컬렉션으로 인정하고,
그 노드와 소속 간선을 화면에서 걷어냅니다. `col-` 을 빠뜨리면 컬렉션이 걷어내지지 않고
**모든 개체가 달라붙은 거대 허브**가 되어 관계망의 상위 노드 선정이 통째로 왜곡됩니다.

### 2.9 역속성은 한 방향만

RiC-O가 `owl:inverseOf` 로 짝지은 9쌍입니다. 같은 사실을 양쪽으로 적으면 개체 상세의 연결 목록에
**같은 관계가 두 줄**로 뜹니다(오류는 나지 않습니다).

`hasCreator`↔`isCreatorOf` · `hasAuthor`↔`isAuthorOf` · `hasOrHadSubject`↔`isOrWasSubjectOf` ·
`occupiesOrOccupied`↔`isOrWasOccupiedBy` · `hasOrHadPosition`↔`existsOrExistedIn` ·
`isOrWasMemberOf`↔`hasOrHadMember` · `includesOrIncluded`↔`isOrWasIncludedIn` ·
`hasOrHadInstantiation`↔`isOrWasInstantiationOf` · `isOrWasParticipantIn`↔`hasOrHadParticipant`

**어느 쪽을 남길지는 자유가 아닙니다.** 인물 페이지는 인물에서 **나가는** 방향만 읽습니다:

| 사실 | 반드시 이 방향 |
|---|---|
| 인물이 맡은 직위 | `인물 rico:occupiesOrOccupied 직위` |
| 인물이 참여한 사건 | `인물 rico:isOrWasParticipantIn 사건` |
| 인물과 관련된 장소 | `인물 rico:isAssociatedWithPlace 장소` |
| 구술자 | `기록 rico:hasCreator 인물` (기록 → 인물) |

역방향으로만 적으면 전기 한 줄·인물 연표·관련 장소 카드가 통째로 빕니다.

### 2.10 `prov`·`oa`·`dcterms` 는 관계망 **밖의 층**이다

근거를 남기는 것은 권장됩니다 — 다만 그 트리플을 `rico:`/`skos:`/`foaf:`/`schema:` 술어로 내지 마세요.
그러면 근거 간선이 관계망에 섞여 성좌가 뭉개집니다. 출처는 `dcterms:source "구술총서 p.114"` 처럼
관계망 밖 네임스페이스로 답니다. 이 층은 화면에 그려지지 않지만 검수와 질의에서 살아 있습니다.

### 2.11 구술자(`rico:hasCreator` 를 받는 인물)는 컬렉션당 **한 명**

원문(코퍼스)에는 화자 구분이 없어서, 한 컬렉션에 구술자가 둘 이상이면 두 사람 모두에게 같은 인용문이
「자기 구술」로 달립니다 — 오귀속이 오류 없이 발생합니다.

---

## 3. 어기면 화면에서 무엇이 조용히 비는가

「조용히」가 핵심입니다. 아래 중 **적재 실패로 소리를 내는 것은 첫 줄 하나뿐**입니다.

| 어긴 것 | 화면에서 일어나는 일 |
|---|---|
| Turtle 문법 오류 | **유일하게 시끄러운 실패** — 사이트 전체가 「적재 실패」로 멈춘다(올리기 경로에서는 그 파일만 거부) |
| `rdf:type` 누락 / 12종 밖 타입만 | 그 개체가 **모든 화면에서 사라진다**. 목록·검색·지도·연표·관계망 어디에도 없고, 그 개체에 닿던 간선도 함께 소멸 |
| `rdf:type` 이 표준 2개 이상 | 색·도형·유형 분류가 **발행마다 흔들린다**(첫 행 승자, 비결정) |
| 이름 술어 없음 | 이름 자리에 **URI 꼬리**(`pos-0`·`auth-68-…`)가 그대로 노출된다. 노드·간선·연결 수는 그대로라 관계망에는 남지만, 사람이 읽을 수 없는 점이 된다 |
| 이름을 `rdfs:label` 에 넣음 | 이름 자리는 URI 꼬리, **사진 출처 자리에 사람 이름**이 박힌다 |
| 리터럴에 `@ko` / `^^xsd:…` | 이름 정확일치 질의가 전부 **0건**. 질의 화면의 예제가 통째로 죽는다 |
| (규칙대로 해도) 이름이 `rico:title`·`skos:prefLabel` | 화면은 전부 정상. 다만 질의 화면의 **중심성 카드**는 `rico:name` 만 세므로 기록·개념이 그 순위에만 안 나온다 — 그 카드 하나의 한계이니 **여러분의 TTL에서 우회하려 들지 마라**. `rico:name` 으로 옮기면 §2.3을 어긴다 |
| 날짜의 앞 4자가 숫자가 아님 (`"ca. 1972"`·`"78.3"`) | 그 사건이 **연표에서만** 조용히 빠진다(다른 화면에는 그대로 있어 눈치채기 어렵다) |
| 날짜가 앞 4자만 맞음 (`"1997년 3월"`·`"1997.03.15"`) | 연표에는 **제 연도로 뜨는데** 인물 페이지의 재임·연표 정렬(문자열 사전순)에서 순서가 뒤집힌다 — 값이 보여서 더 안 들킨다 |
| 좌표가 도분초·쉼표 소수점 / `geo:lon` 으로 적음 | 지도는 `geo:lat` 유무만 보므로 **지도 화면의 「곳」 수에는 그대로 들어가고** 마커 생성만 깨진다 |
| 관계 술어가 5개 밖 네임스페이스 | 그 관계가 **관계망에서 통째로 안 보인다**. 개체는 남아 외톨이 점이 된다 |
| `http://schema.org/`(http) | schema 관계 **전멸** |
| 간선 목적어가 리터럴 / 그래프 밖 IRI | 그 간선이 **소거**된다 |
| 컬렉션에 `col-` 접두 없음 | 컬렉션이 걷어내지지 않아 **모든 점이 붙은 거대 허브**가 생기고 상위 노드 선정이 왜곡된다 |
| 인물을 `isOrWasIncludedIn` 으로 컬렉션에 이음 | **화면에는 아무 일도 안 일어난다** — 소비자는 두 술어를 똑같이 소속으로 받고 도메인을 검사하지 않는다. 그래서 거짓 진술만 조용히 남는다(§2.8). 이 줄은 화면이 아니라 **그래프의 정확성** 문제다 |
| 관계를 역방향으로만 단언 | 인물 페이지의 전기·연표·장소 카드가 **통째로 빈다** |
| 역속성 양방향 단언 | 연결 목록에 **같은 관계가 두 줄** |
| `skos:inScheme` 없는 개념 | 주제 화면 목록에 **아예 안 뜬다**(요약 숫자에는 잡혀서 수가 안 맞아 보인다) |
| `skos:ConceptScheme` 개체가 하나도 없음 | 개념이 아무리 많아도 주제 목록이 **빈다** |
| `skos:narrower` 만 씀 | 개념 계층이 통째로 안 잡힌다 — 계층은 `skos:broader`(하위→상위) 방향만 읽는다 |
| 구술자가 두 명 이상 | 두 사람 모두에게 **같은 인용문**이 자기 구술로 달린다 |

---

## 4. 커스텀 클래스를 쓸 때

기관 고유 어휘(`nara:` — `http://archives.nanet.go.kr/voca#`)처럼 표준 밖 클래스를 쓸 수 있습니다.
**대체가 아니라 병기**입니다:

```turtle
ric:org-national-assembly-20 a rico:CorporateBody, nara:AssemblyTerm ;
    rico:name "제20대 국회" .
```

표준 타입을 빼면 그 개체가 유형별 화면(지도·연표·관계망·홈 색인)에서 통째로 사라집니다.
**대장의 유형은 근사, 정확한 유형은 커스텀 클래스** — 둘을 함께 냅니다.

### 주의 ① 지역명이 표준 12종과 겹치면 오분류된다

소비자는 네임스페이스를 보지 않고 `#` 뒤 지역명만으로 클래스를 판정합니다.
그래서 `nara:Person` 같은 이름을 만들면 그 커스텀 타입이 **표준 타입 후보로 인정되어**
한 개체에 표준 후보가 둘이 되고, 그때는 정말로 첫 행 승자(비결정)가 됩니다.

> **규칙: `Person`·`CorporateBody`·`Position`·`Event`·`Activity`·`Place`·`Record`·`RecordSet`·
> `Instantiation`·`Rule`·`Concept`·`ConceptScheme` 과 같은 이름의 커스텀 클래스를 만들지 않는다.**

### 주의 ② 커스텀 술어는 프로파일에 등재해야 의미가 산다

`http://archives.nanet.go.kr/voca#` 술어는 관계망 간선 필터에 **들어 있습니다**(2.7의 다섯째).
다만 질의 화면이 자동으로 얹는 접두 목록에는 없으므로, 질의할 때는 전체 IRI로 물어야 합니다:

```sparql
SELECT ?s ?n WHERE { ?s a <http://archives.nanet.go.kr/voca#AssemblyTerm> ; rico:name ?n }
```

---

## 5. 최소 예시 — 이대로 내면 반드시 성립한다

인물 1 · 장소 1 · 기록 1 · 컬렉션 1. 위 규칙을 전부 지킨 가장 작은 유효한 형태입니다.

```turtle
@prefix ric:     <http://archives.nanet.go.kr/id/> .
@prefix rico:    <https://www.ica.org/standards/RiC/ontology#> .
@prefix geo:     <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix dcterms: <http://purl.org/dc/terms/> .

# ① 컬렉션 — col- 접두 + rico:RecordSet + rico:title
ric:col-보기-구술 a rico:RecordSet ;
    rico:title "보기 구술" .

# ② 기록 — 이름은 rico:title, 소속은 isOrWasIncludedIn, 구술자는 기록 → 인물 방향
ric:rec-boki-1 a rico:Record ;
    rico:title "보기 구술 1차 면담" ;
    rico:beginningDate "2024-03-11" ;
    rico:scopeAndContent "예시용 1차 면담 녹취." ;
    dcterms:source "예시 파일 — 실제 기록 아님" ;
    rico:hasCreator ric:agent-boki ;
    rico:isOrWasIncludedIn ric:col-보기-구술 .

# ③ 인물 — 이름은 rico:name, 소속은 isOrWasSubjectOf, 장소는 인물에서 나가는 방향
ric:agent-boki a rico:Person ;
    rico:name "홍길동" ;
    rico:generalDescription "예시용 구술자입니다." ;
    dcterms:source "예시 파일 — 실제 인물 아님" ;
    rico:isAssociatedWithPlace ric:place-boki ;
    rico:isOrWasSubjectOf ric:col-보기-구술 .

# ④ 장소 — 좌표는 십진 문자열, 술어는 geo:long
ric:place-boki a rico:Place ;
    rico:name "예시 장소" ;
    geo:lat "35.8242" ;
    geo:long "127.1480" ;
    dcterms:source "예시 파일 — 실제 장소 아님" ;
    rico:isOrWasSubjectOf ric:col-보기-구술 .
```

이 예제에는 사건(`rico:Event`)이 없어 **연표 화면은 비어 있는 것이 정상**입니다.
연표를 채우려면 `rico:Event` 개체에 `rico:beginningDate` 를 붙이면 됩니다.

스타터킷 저장소의 `examples/sample-upload.ttl` 도 같은 형태의 본보기입니다.

---

## 6. 스타터킷에 적재하는 법

### 길 A — 컬렉션 화면에서 **TTL 올리기** (권장)

공개 사이트의 **컬렉션** 화면에 「TTL 올려 컬렉션 더하기」 칸이 있습니다. 만든 `.ttl` 을 그대로 올리면
컬렉션이 하나 늘어납니다. 이 길로 하면 발행본을 건드리지 않습니다.

- 파일은 **올린 브라우저에만** 남습니다(localStorage). 다른 사람은 발행본만 봅니다.
- 문법이 깨진 파일은 얹지 않고 오류 줄을 보여 줍니다 — 본 그래프는 손상되지 않습니다.
- **컬렉션 이름을 직접 적을 수 있습니다.** 적으면 그 이름으로 모으고, 파일 안의 컬렉션 개체는 목록에서 뺍니다.
  비우면 파일 안의 `rico:RecordSet` 이름을, 그것도 없으면 **파일 이름**으로 컬렉션을 만들어 개체들을 잇습니다
  (그래도 2.8을 지켜 파일 안에 컬렉션을 넣어 두는 편이 낫습니다 — 그래야 두 길에서 같은 모양이 됩니다).
- **사이트가 컬렉션을 대신 만들어 줄 때 소속에 들어가는 것은 `rdf:type` 이 있고 IRI가
  `http://archives.nanet.go.kr/id/` 로 시작하는 주어뿐입니다.** 타입 없는 개체나 다른 네임스페이스에
  세운 개체는 소속에서 **조용히 빠져** 컬렉션을 골라도 화면에 안 나옵니다. §2.1·§2.2를 지키면 걸리지 않습니다.
- 여러 팀이 같은 이름을 올려도 지역명에 `-2`·`-3` 이 붙어 섞이지 않습니다.
- 사이트의 `data/ontology.rdf` 에 **등재되지 않은 술어**가 있으면 경고만 하고 싣습니다.
  (그 파일은 사이트에 실린 프로파일 사본이라 방금 내보낸 프로파일보다 낡았을 수 있습니다 —
  `geo:`·`skos:`·`rdfs:` 술어가 경고에 뜨는 것은 이 때문이며, 화면 동작에는 지장이 없습니다.)

### 길 B — 발행본 `data/graph.ttl` 을 통째로 교체

사이트의 `data/graph.ttl` 을 만든 파일로 갈아끼우고 새로고침합니다. 팀 전체가 같은 것을 봅니다.
이 길에서는 컬렉션 개체(2.8)를 **반드시** 파일 안에 넣어야 합니다 — 만들어 주는 사람이 없습니다.

### 함께 나가지 않는 것

- **원문(`data/corpus/…`)** — 「언어」 화면과 인용문·「오늘의 목소리」가 읽는 자료입니다.
  LLM 산출 TTL에는 들어 있지 않으므로 **그 화면만 빕니다**(「원문 없음」이라고 정직하게 표시됩니다).
  나머지 화면은 전부 정상입니다.
- **이미지(`assets/media/…`)** — `foaf:depiction` 은 사이트 루트 기준 상대경로 문자열이고,
  그 파일이 실제로 있어야 뜹니다. 파일 없이 경로만 적으면 썸네일만 빠집니다(화면은 깨지지 않습니다).

---

## 7. 한계 — 이 길과 그라운더의 차이

- **LLM 산출물은 검수가 필요합니다.** 이 문서는 *형식*을 보증할 뿐 *사실*을 보증하지 않습니다.
  PDF에 없는 인물·날짜·좌표를 모델이 지어내도 TTL은 완벽하게 유효합니다. 반드시 원문과 대조하세요.
  근거 쪽수(`dcterms:source`)를 개체마다 달게 하면 대조가 기계적으로 가능해집니다.
- **여기 적힌 계약은 검사되지 않습니다.** 올리기 경로의 문법 검사와 AP 술어 경고가 전부입니다.
  나머지는 전부 §3의 「조용한」 실패입니다.
- **온톨로지 그라운더로 뽑으면 이 계약이 자동으로 지켜집니다.** 발행이 클래스별 이름 술어를 붙이고,
  이름 없는 개체를 대장 레이블로 메우고, 컬렉션 개체와 소속 술어를 합성하고, 평문 리터럴을 보장하고,
  검수 관문(승인·live·미회수)을 개체와 트리플에 같게 적용합니다. 대신 원문을 시스템에 넣고
  검수를 거쳐야 합니다. **LLM 그라운딩은 빠르고 검수가 사람 몫, 그라운더는 느리고 계약이 코드 몫입니다.**
