# 容晟科技 結構化引用系統（Citation Schema）

> 靈感來自 **法律偵探（Lawsnote）**：把每一份「可被引用的資產」打上唯一 ID，
> 賦予結構化欄位，並建立雙向引用索引，達到「任何決策都能向上追溯、向下擴散」的知識網。

---

## 1. 設計目標

1. **唯一 ID**：每個 citable unit 有不重複的 ID，可被任何地方引用。
2. **結構化欄位**：用 YAML frontmatter 強制欄位（不能只靠 markdown 散文）。
3. **雙向引用**：A 引用 B 時，B 的詳情頁能反查「誰引用了我」（cited_by）。
4. **強型別關聯**：用 `relations:` 明確標示語意（cites / supersedes / refutes …），
   餵給 `build-knowledge.py` 產出 typed edges。
5. **可被搜尋**：所有欄位進入 `citation-index.json`，前端用 Lawsnote 風格條件搜尋。

---

## 2. 六種 Citable Unit 類型

| 類型 | ID 規則 | 對應法律世界 | 來源檔案 |
|------|---------|-------------|----------|
| `adr` | `ADR-NNN` | 「法規／命令」級決策 | `docs/decisions/ADR-*.md` |
| `case` | `CASE-{client-slug}[-NNN]` | 「判決」（已交付/進行中專案） | `knowledge/nodes/cases/*.md` |
| `est` | `EST-YYYY-MM[-NN]` | 「行政函示」（特定時點的估價判斷） | `knowledge/nodes/estimates/*.md` |
| `gotcha` | `GOTCHA-{stack}-NN` | 「裁判要旨」（踩坑教訓） | `knowledge/nodes/gotchas/*.md`（新建） |
| `mod` | `MOD-{name}` | 「學說／教科書」（可重用模組） | `knowledge/nodes/modules/*.md` |
| `dec` | `DEC-{area}-NNN` | 「會議結論」（內部決議） | `knowledge/nodes/decisions/*.md`（新建） |

ID 一律 ASCII，大寫，連字號分隔。slug 取小寫拉丁化（如 apex-gold、crm、esg）。

---

## 3. 共通 Frontmatter 欄位

所有 citable unit **必須** 至少包含：

```yaml
---
id: ADR-007                       # 唯一 ID（見上表 ID 規則）
title: 多租戶模組可移植性策略     # 顯示用標題
type: adr                         # 6 種之一：adr | case | est | gotcha | mod | dec
status: accepted                  # 狀態（見下表）
date: 2026-04-21                  # 主要時間點（YYYY-MM-DD）
tags: [多租戶, KV, namespace]     # 自由標籤
references: [MOD-CRM-SCHEDULE]    # 我引用了誰（向上）
cited_by: [CASE-AG-001]           # 誰引用了我（向下，可由腳本自動回填）
relations:                        # typed edges（餵給 build-knowledge.py）
  - rel: governs
    target: MOD-CRM-SCHEDULE
  - rel: applies_in
    target: CASE-AG-001
---
```

### 共通 status 列舉

| status | 含義 | 顯示色（侘寂禪意） |
|--------|------|-------------------|
| `draft` | 草稿，未定案 | `var(--muted2)` 灰 |
| `proposed` | 已提案，待審 | `var(--muted)` |
| `accepted` | 已採用 | `var(--text)` 深暖棕 |
| `active` | 進行中（case / est 用） | `#7B6E5E` |
| `deprecated` | 廢止 | 半透明 + 刪除線 |
| `superseded` | 被新版取代（搭配 `superseded_by`） | 半透明 |

---

## 4. 各類型專屬欄位

### 4.1 `adr` — 設計決策

```yaml
id: ADR-007
type: adr
status: accepted
deciders: [Eugene Lai]            # 決策人
context_summary: 一句話描述背景
decision_summary: 一句話描述決策
supersedes: []                    # 取代了哪些舊 ADR
superseded_by: ""                 # 被誰取代（單一 ID）
tags: [...]
references: [MOD-...]
cited_by: [CASE-...]
```

對應檔案：`docs/decisions/ADR-NNN-*.md`

### 4.2 `case` — 客戶案件 / 已交付專案

```yaml
id: CASE-AG-001
type: case
status: active                    # active | delivered | paused | lost
client: apex-gold                 # client slug
phase: design                     # discovery | design | build | uat | delivered
start_date: 2026-04-15
end_date: ""
estimate_ref: EST-2026-04         # 對應的估價單 ID
adrs_applied: [ADR-005, ADR-007]  # 套用了哪些 ADR
modules_used: [MOD-CRM-SCHEDULE, MOD-CRM-WORKFLOW]
gotchas_encountered: [GOTCHA-CF-01]
tags: [...]
```

對應檔案：`knowledge/nodes/projects/{client}-*.md` 或 `knowledge/nodes/cases/*.md`

### 4.3 `est` — 估價

```yaml
id: EST-2026-04
type: est
status: active                    # draft | active | accepted | rejected | expired
client: apex-gold
total_amount: 290000              # 含稅報價（NTD）
currency: NTD
mm_total: 1.78                    # 總人月
buffer: 1.2
quote_date: 2026-04-15
valid_until: 2026-05-15
plan: A                           # A | B | C （多方案時用）
adrs_referenced: [ADR-007]
modules_quoted: [MOD-CRM-WORKFLOW]
tags: [...]
```

對應檔案：`knowledge/nodes/estimates/*.md`

### 4.4 `gotcha` — 踩坑

```yaml
id: GOTCHA-CF-01
type: gotcha
status: accepted                  # 已驗證 / draft 待補
stack: cloudflare-workers         # cloudflare-workers | nextjs | kv | d1 | ...
severity: medium                  # low | medium | high | critical
symptom: CORS preflight 缺 X-Admin-Pin → 前端整段請求被瀏覽器擋
root_cause: Workers 預設 OPTIONS 回傳的 Access-Control-Allow-Headers 沒包含自定 header
fix_summary: 在 OPTIONS 回應加上 X-Admin-Pin
discovered_at: 2026-04-21
verified_in: [CASE-RSUN-CRM]
tags: [CORS, preflight, cloudflare]
references: []
cited_by: []
```

對應檔案：`knowledge/nodes/gotchas/{stack}-NN-*.md`（新目錄）

### 4.5 `mod` — 模組（可重用資產）

```yaml
id: MOD-CRM-SCHEDULE
type: mod
status: production                # candidate | production | deprecated
category: backend                 # frontend | backend | data | devops | ai
stack: [cloudflare-workers, kv]
visibility: private               # public | private（影響是否可被外部引用）
maturity: stable                  # experimental | beta | stable | mature
env_required: [BEARER_TOKEN]
depends_on: []
alternative_to: []
verified_in: [CASE-RSUN-CRM]
gotchas: [GOTCHA-CF-01]
governed_by: [ADR-002, ADR-007]   # 哪些 ADR 規範此模組
tags: [...]
```

對應檔案：`knowledge/nodes/modules/*.md`

### 4.6 `dec` — 內部決議（會議結論／快速決定）

```yaml
id: DEC-PRICING-001
type: dec
status: accepted
area: pricing                     # pricing | hiring | ops | client-ops | tooling
date: 2026-04-20
context: 一句話描述觸發背景
conclusion: 一句話結論
participants: [Eugene Lai]
adrs_promoted_to: ""              # 若此決議升格成正式 ADR，填 ADR ID
tags: [...]
references: []
cited_by: []
```

對應檔案：`knowledge/nodes/decisions/*.md`（新目錄）

---

## 5. relation 詞彙表（語意連結）

對應 `build-knowledge.py` 的 `RELATION_WEIGHT`，常用如下：

| relation | 用法 | 範例 |
|----------|------|------|
| `cites` | 一般引用 | EST → ADR |
| `supersedes` | 新版取代舊版 | ADR-008 supersedes ADR-007 |
| `refutes` | 反駁 / 推翻 | DEC refutes 早期 ADR |
| `extends` | 延伸補充 | ADR-007 extends ADR-005 |
| `governs` | 上位規範下位 | ADR governs MOD |
| `governed_by` | 下位被上位規範 | MOD governed_by ADR |
| `applies_in` | 抽象套用到具體 | ADR applies_in CASE |
| `derives_from` | 演化出 | EST-v2 derives_from EST-v1 |
| `depends_on` | 技術依賴 | MOD-A depends_on MOD-B |
| `verified_in` | 在某 case 中得到驗證 | MOD verified_in CASE |
| `interprets` | 解釋說明 | DEC interprets ADR |

`references` 與 `cited_by` 是「無語意」的方便欄位（等同於 `cites` / `cited_by`），
要表達特定語意請用 `relations:` 區塊。

---

## 6. 雙向索引產出流程

```
docs/decisions/ADR-*.md                  ┐
knowledge/nodes/projects/*.md            │
knowledge/nodes/estimates/*.md           ├─→  build-knowledge.py
knowledge/nodes/modules/*.md             │       │
knowledge/nodes/gotchas/*.md             │       ▼
knowledge/nodes/decisions/*.md           ┘    knowledge/graph.json（節點＋邊）
                                              knowledge/citation-index.json（純結構化檢索用）
                                              knowledge/search-index.json（全文）
```

`citation-index.json` 是 graph.json 的「結構化視圖」，
只保留 6 種 citable unit、所有結構化欄位、雙向 references / cited_by。
給 `/citation/` 頁的搜尋 UI 用。

---

## 7. 驗證規則（`scripts/validate-citations.py`）

每次 build 前 / pre-commit 跑：

1. **ID 唯一性**：所有 frontmatter `id` 不可重複。
2. **ID 格式**：必須符合對應 type 的正則。
3. **references 必須指向存在的 ID**（dangling reference 報 ERROR）。
4. **status 必須在列舉內**。
5. **type 必須是 6 種之一**。
6. **superseded_by 指向的目標必須真的 supersedes 自己**（雙向一致性）。
7. **cited_by 由腳本自動回填**（人類不必手寫，寫了會被覆蓋）。

不符合者 build 失敗，CI 阻擋 merge。

---

## 8. 實作里程碑

| 階段 | 內容 | 狀態 |
|------|------|------|
| Phase 1a | 本文件 | ✅ |
| Phase 1b | 把 ADR-001 ~ ADR-007 加上 frontmatter | 🔄 |
| Phase 1c | `scripts/validate-citations.py` | 🔄 |
| Phase 2a | `build-knowledge.py` 解析 references / cited_by | 🔄 |
| Phase 2b | 產出 `knowledge/citation-index.json` | 🔄 |
| Phase 3a | `/citation/` 結構化搜尋 UI | 🔄 |
| Phase 3b | 每個 ID 詳情頁 + 雙向引用 mini graph | 🔄 |

---

## 9. 維護守則

- 新增 citable unit → 產一個新 ID → 寫 frontmatter → commit
- 引用別人 → 寫進 `references:` 或 `relations:` → 對方 `cited_by` 由腳本自動更新
- 廢止 → 改 `status: deprecated` 或 `superseded_by: ADR-XXX`，不要刪檔
- 任何「我做過這個決定」「這個案子我們踩過坑」「這個估價我參考了那份估價」
  → 都應該變成一個帶 ID 的單元，方便未來反查
