# Quy Trình 02 — Điều Phối Translator Dịch Tiểu Sử Alahan (V1)

> **Dành cho Architect** — thiết lập & giám sát cron job điều phối translator
> Dự án: 013-tieu-su-cac-bac-alahan | Cập nhật: 2026-06-23 | Phiên bản: **1.0** (Việt only, prose)

---

## I. NGUYÊN LÝ CỐT LÕI

```
┌─────────────────────────────────────────────────────────────┐
│           KIẾN TRÚC V1 — TRANSLATOR 2-PHASE (PROSE)          │
│                                                              │
│  TRANSLATOR AI (Gemini 3 Flash, 2 LLM CALLS)                 │
│  ├─ PHASE 1 (1 call): exec python → chọn batch + source     │
│  │                    + SQLite glossary lookup               │
│  │                    + ĐỌC context-summary batch trước       │
│  └─ PHASE 2 (1 call): write+write+exec, TẤT CẢ CÙNG LÚC    │
│                       vi-only + context-summary              │
│                       + update progress                      │
│                                                              │
│  CHIẾN LƯỢC: Việt only — file-by-file — prose translation   │
│  KHÔNG merge-bilingual — KHÔNG song ngữ                      │
│  TOKEN: ~40-50K/batch (~$0.03/batch với Gemini 3 Flash)     │
│  lightContext: true → bỏ system prompt files                 │
│  🌉 BRIDGE: context-summary nối câu đứt giữa các batch       │
└─────────────────────────────────────────────────────────────┘
```

### Khác biệt so với Vinaya (02A):

| Vinaya (02A) | Tiểu Sử Alahan (02) | Lý do |
|-------------|---------------------|------|
| Block `---` separator | File-by-file (3 trang/batch) | Prose, không có cấu trúc kệ |
| merge-bilingual.py | KHÔNG dùng | Việt only |
| Song ngữ Myanmar+Việt | CHỈ tiếng Việt | Yêu cầu dự án |
| Thuật ngữ Luật tạng | Thuật ngữ tiểu sử/Alahan | Khác thể loại |
| 22 batch | 225 batch | Sách dài hơn |

---

## II. KIẾN TRÚC

```
┌──────────────────────────────────────────────────────┐
│                 ARCHITECT (giám sát)                  │
│  • 1 cron job tieu-su-translator (every 15min)       │
│  • 1 cron job tieu-su-translate-monitor (every 30min)│
│  • QA hậu kiểm: check output length, format          │
│  • Cập nhật SQLite glossary khi cần                   │
└──────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────┐
│     TRANSLATOR AI (Gemini 3 Flash, 2 LLM CALLS)       │
│  ┌──────────────────────────────────────────┐        │
│  │ PHASE 1: exec python                      │        │
│  │   • Chọn batch pending từ progress JSON   │        │
│  │   • Đọc source từ edited/gemini-flash/    │        │
│  │   • SQLite glossary lookup                │        │
│  │   • Đọc context-summary batch trước        │        │
│  │   → In source + glossary + trunc. prev    │        │
│  └──────────────────────────────────────────┘        │
│  ┌──────────────────────────────────────────┐        │
│  │ PHASE 2: ALL TOOLS IN 1 RESPONSE          │        │
│  │   • Ghép câu đứt từ batch trước (nếu có)  │        │
│  │   • write → vi-only/{BATCH}-vi.md         │        │
│  │   • write → context-summary/{BATCH}-...   │        │
│  │     (bao gồm câu đứt nếu có)              │        │
│  │   • exec → update progress JSON           │        │
│  │   ⚠️ KHÔNG merge-bilingual                 │        │
│  │   ⚠️ KHÔNG tạo text report riêng!         │        │
│  └──────────────────────────────────────────┘        │
│  ⚡ 2 LLM CALLS ~40-50K token, ~$0.03/batch          │
│  🌉 Câu đứt được nối qua context-summary             │
└──────────────────────────────────────────────────────┘
```

---

## III. CẤU TRÚC THƯ MỤC

```
013-tieu-su-cac-bac-alahan/
├── edited/gemini-flash/                       # Source files (Myanmar đã hiệu đính)
│   ├── output-1-to-3.md
│   ├── output-4-to-6.md
│   └── ... (225 files)
│
├── ver-1/Gemini-3-Flash/
│   ├── progress.json                           # Tiến độ pipeline
│   │
│   ├── vi-only/                                # Translator output (Việt only)
│   │   ├── output-1-to-3-vi.md
│   │   ├── output-4-to-6-vi.md
│   │   └── ...
│   │
│   └── context-summary/                        # Context summaries
│       ├── output-1-to-3-context-summary.md
│       └── ...
│
└── guide/
    ├── 02-Dich-Tieu-Su-Alahan.md               # File này
    └── TRANSLATOR-GUIDE-TIEU-SU.md             # Guide cho translator
```

---

## IV. THIẾT LẬP CRON JOBS

### 📋 Progress JSON

Đã tạo sẵn tại `ver-1/Gemini-3-Flash/progress.json`:

```json
{
  "batches": [
    {"name": "output-1-to-3", "source": "edited/gemini-flash/output-1-to-3.md", "status": "pending"},
    {"name": "output-4-to-6", "source": "edited/gemini-flash/output-4-to-6.md", "status": "pending"},
    ...
    {"name": "output-97-to-99", "source": "edited/gemini-flash/output-97-to-99.md", "status": "pending"}
  ]
}
```

> 225 batch — mỗi batch = 3 trang Myanmar đã hiệu đính.

---

### Cron 1: `tieu-su-translator` (Translator — mỗi 15 phút, 2 LLM calls)

```bash
openclaw cron add \
  --name tieu-su-translator \
  --every 15m \
  --session isolated \
  --agent translator \
  --model openrouter/google/gemini-3-flash-preview \
  --light-context true \
  --message 'Bạn là Translator Agent dịch Tiểu Sử Alahan Myanmar → Việt — TỐI ƯU 2 LLM CALLS.

═══════════════════
QUY TẮC DỊCH (theo guide)
═══════════════════

1. Đọc guide chung: /home/tuan-nguyen/.openclaw/workspace/obsidian/huong-dan/Translator-Myanmar-Vi.md
2. Đọc guide đặc thù: /home/tuan-nguyen/.openclaw/workspace/013-tieu-su-cac-bac-alahan/guide/TRANSLATOR-GUIDE-TIEU-SU.md

Đây là sách TIỂU SỬ CÁC BẬC A LA HÁN — văn xuôi Phật học, kể chuyện cuộc đời các bậc thánh tăng.
Dịch mượt mà, tự nhiên, giữ tinh thần nguyên tác.
TUYỆT ĐỐI CHỈ DỊCH TIẾNG VIỆT — không giữ chữ Myanmar, không song ngữ.

Format output:
  ✍️ Văn xuôi tiếng Việt tự nhiên, trang trọng
  ✍️ Giữ cấu trúc đoạn văn, xuống dòng hợp lý
  ✍️ Pāḷi: Việt trước, Pāḷi trong ngoặc sau
  ✍️ Tránh Hán-Việt cổ
  ✍️ Thuật ngữ: tra SQLite glossary

Từ khóa đặc thù tiểu sử:
  - အရဟံ / Arahant → A-la-hán / bậc Ứng Cúng
  - ရဟန္တာ → bậc A-la-hán
  - မထေရ် → Trưởng lão / Đại đức
  - သာသနာဝင် → lịch sử giáo pháp
  - ဈာန် → thiền / tầng thiền
  - အဘိညာဉ် → thắng trí / thần thông
  - ပဋိပတ္တိ → thực hành / pháp hành

═══════════════════
PHASE 1: CHẠY SCRIPT NÀY (1 LLM call)
═══════════════════

```python
import json, os, sqlite3
from datetime import datetime, timezone, timedelta

PROJ = "/home/tuan-nguyen/.openclaw/workspace/013-tieu-su-cac-bac-alahan"
VER = "ver-1/Gemini-3-Flash"
tz = timezone(timedelta(hours=7))

# P1: Chọn batch pending
with open(f"{PROJ}/{VER}/progress.json") as f:
    data = json.load(f)

vi_dir = f"{PROJ}/{VER}/vi-only"
ctx_dir = f"{PROJ}/{VER}/context-summary"

for b in data["batches"]:
    name = b["name"]
    vi_path = f"{vi_dir}/{name}-vi.md"
    ctx_path = f"{ctx_dir}/{name}-context-summary.md"

    if b["status"] == "in_progress":
        # Check if all outputs exist → mark done
        if os.path.exists(vi_path) and os.path.exists(ctx_path):
            b["status"] = "done"
            b["completed_at"] = datetime.now(tz).isoformat()
            print(f"RECOVER:{name}")
        else:
            # Check if stuck (>15 min)
            started = datetime.fromisoformat(b.get("started_at", "2000-01-01T00:00:00+07"))
            if (datetime.now(tz) - started).total_seconds() > 900:
                b["status"] = "pending"
                print(f"STUCK:{name}")
            else:
                print(f"SKIP:{name}")
                exit()
        with open(f"{PROJ}/{VER}/progress.json", "w") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)

# Find next pending
target = None
for b in data["batches"]:
    name = b["name"]
    vi_path = f"{vi_dir}/{name}-vi.md"
    if b["status"] == "pending":
        target = b
        break
    # Also pick up incomplete batches
    if b["status"] != "done" and not os.path.exists(vi_path):
        target = b
        break

if target is None:
    print("ALL_DONE")
    exit()

target["status"] = "in_progress"
target["started_at"] = datetime.now(tz).isoformat()
BATCH = target["name"]
SOURCE = target["source"]
print(f"BATCH:{BATCH}")
print(f"SOURCE:{SOURCE}")

with open(f"{PROJ}/{VER}/progress.json", "w") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

# P2: Đọc source
src_path = f"{PROJ}/{SOURCE}"
with open(src_path) as f:
    source = f.read()

# P3: SQLite glossary
conn = sqlite3.connect("/home/tuan-nguyen/.openclaw/workspace/data/myanmar_pali_viet_terms_vec.db")
cur = conn.cursor()
cur.execute("SELECT pali, vietnamese, desc_vi, category FROM terms ORDER BY category, id")
glossary = [(r[0], r[1], r[2], r[3]) for r in cur.fetchall()]
conn.close()
print(f"GLOSSARY:{len(glossary)} terms loaded")
for pali, vi, desc, cat in glossary:
    print(f"  [{cat}] {pali} → {vi}" + (f" | {desc}" if desc else ""))

# P4: Đọc context-summary batch trước → kiểm tra câu đứt
prev_idx = None
for i, b in enumerate(data["batches"]):
    if b["name"] == BATCH:
        prev_idx = i - 1
        break

if prev_idx is not None and prev_idx >= 0:
    prev_name = data["batches"][prev_idx]["name"]
    prev_ctx_path = f"{PROJ}/{VER}/context-summary/{prev_name}-context-summary.md"
    if os.path.exists(prev_ctx_path):
        with open(prev_ctx_path) as f:
            prev_ctx = f.read()
        if "## Câu đứt chuyển batch" in prev_ctx:
            idx = prev_ctx.index("## Câu đứt chuyển batch")
            truncated = prev_ctx[idx:].strip()
            print(f"TRUNCATED_PREV:{prev_name}")
            print(truncated)
        else:
            print("TRUNCATED_PREV:NONE")
    else:
        print("TRUNCATED_PREV:NONE (no context file)")
else:
    print("TRUNCATED_PREV:NONE (first batch)")

print("---SOURCE_START---")
print(source)
print("---SOURCE_END---")
```

═══════════════════
PHASE 2: 1 RESPONSE — GỌI TẤT CẢ TOOL CÙNG LÚC
═══════════════════

⚠️ TUYỆT ĐỐI: PHASE NÀY PHẢI HOÀN THÀNH TRONG ĐÚNG 1 RESPONSE.
   GỌI TẤT CẢ TOOL SONG SONG TRONG CÙNG 1 LƯỢT.
   Mỗi response thêm = +30K token lãng phí → TUYỆT ĐỐI TRÁNH.

⚠️ KHÔNG tạo text báo cáo riêng sau khi tool chạy xong.
   Tool results (write + exec) tự thông báo kết quả.
   Cron delivery sẽ tự announce.
   Chỉ gọi tool, không thêm text!

Nếu Phase 1 in "ALL_DONE": KHÔNG làm gì hết.
Nếu Phase 1 in "SKIP:{name}": KHÔNG làm gì hết.
Nếu Phase 1 in "STUCK:{name}": KHÔNG làm gì hết (monitor sẽ chạy lại).

Khi Phase 1 in "BATCH:{tên_batch}" và "SOURCE:{đường_dẫn}":
   → Đọc SOURCE (giữa ---SOURCE_START--- và ---SOURCE_END---)
   → Đọc GLOSSARY đã load
   
   ⚠️ QUAN TRỌNG: Kiểm tra output Phase 1 có dòng "TRUNCATED_PREV:{batch_name}" không:
     → Nếu CÓ (có câu đứt từ batch trước): GHÉP phần câu đứt (chữ Myanmar) 
       VÀO ĐẦU SOURCE trước khi dịch. Điều này đảm bảo câu bị đứt được 
       dịch liền mạch cùng phần tiếp theo ở batch hiện tại.
     → Nếu "TRUNCATED_PREV:NONE": dịch bình thường.
   
   → Dịch TOÀN BỘ sang tiếng Việt
   → Format: văn xuôi Việt tự nhiên, giữ cấu trúc đoạn văn
   
   ⚠️ KIỂM TRA CUỐI BATCH: ~200 ký tự cuối cùng của source
     → Nếu câu cuối bị đứt (không có dấu ။ hoါ၊):
       + KHÔNG DỊCH câu đó — chỉ dịch đến trước câu đứt
       + LƯU câu đứt vào context-summary (mục "Câu đứt chuyển batch")
     → Nếu câu cuối hoàn chỉnh (có dấu kết): dịch bình thường

   → SAU ĐÓ, GỌI ĐỒNG THỜI TẤT CẢ CÁC TOOL SAU TRONG 1 RESPONSE:
      (thay BATCH bằng tên batch thật từ output Phase 1)

   [TOOL 1] write:
     path: /home/tuan-nguyen/.openclaw/workspace/013-tieu-su-cac-bac-alahan/ver-1/Gemini-3-Flash/vi-only/{BATCH}-vi.md
     content: toàn bộ bản dịch Việt (văn xuôi, tự nhiên, trang trọng)

   [TOOL 2] write:
     path: /home/tuan-nguyen/.openclaw/workspace/013-tieu-su-cac-bac-alahan/ver-1/Gemini-3-Flash/context-summary/{BATCH}-context-summary.md
     content: context-summary markdown
     # Tóm tắt Bối cảnh — Tiểu Sử Alahan
     > Sau batch: {BATCH}
     ## Nội dung đã dịch đến nay
     [≤200 từ: chủ đề chính, nhân vật, sự kiện, thuật ngữ đặc biệt]
     ## Batch vừa hoàn thành
     - Nội dung chính: [1-2 câu]
     - Số trang: X-Y
     
     ## Câu đứt chuyển batch (nếu có)
     [Nếu cuối batch có câu Myanmar bị đứt giữa chừng → ghi NGUYÊN VĂN Myanmar vào đây]
     [Nếu không có câu đứt → ghi "Không có"]

   [TOOL 3] exec:
     command: python3 -c "
import json
from datetime import datetime, timezone, timedelta
PROJ = '/home/tuan-nguyen/.openclaw/workspace/013-tieu-su-cac-bac-alahan'
VER = 'ver-1/Gemini-3-Flash'
BATCH = '{BATCH}'
with open(f'{PROJ}/{VER}/progress.json') as f: data = json.load(f)
for b in data['batches']:
    if b['name'] == BATCH:
        b['status'] = 'done'
        b['completed_at'] = datetime.now(timezone(timedelta(hours=7))).isoformat()
        break
with open(f'{PROJ}/{VER}/progress.json', 'w') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)
print('OK')
"

   → DONE. 3 tool trên là đủ. KHÔNG thêm text báo cáo!' \
  --timeout-seconds 600 \
  --delivery "announce,telegram,412242443"
```

**Cấu trúc payload:**
```json
{
  "lightContext": true,
  "timeoutSeconds": 600,
  "model": "google/gemini-3-flash-preview"
}
```

---

### Cron 2: `tieu-su-translate-monitor` (Architect — mỗi 30 phút)

```bash
openclaw cron add \
  --name tieu-su-translate-monitor \
  --every 30m \
  --session isolated \
  --agent architect \
  --model deepseek/deepseek-v4-flash \
  --light-context true \
  --message '## Tiểu Sử Alahan Monitor

```python
import json, os, glob
from collections import Counter
PROJ = "/home/tuan-nguyen/.openclaw/workspace/013-tieu-su-cac-bac-alahan"
VER = "ver-1/Gemini-3-Flash"
with open(f"{PROJ}/{VER}/progress.json") as f: data = json.load(f)
c = Counter(b["status"] for b in data["batches"])
n_vi = len(glob.glob(f"{PROJ}/{VER}/vi-only/*.md"))
n_ctx = len(glob.glob(f"{PROJ}/{VER}/context-summary/*.md"))
print(f"Done={c.get(\"done\",0)} InProg={c.get(\"in_progress\",0)} Pend={c.get(\"pending\",0)}")
```

Report 1 dòng kết quả. Nếu ALL DONE → disable cả 2 cron.' \
  --timeout-seconds 300 \
  --delivery "announce,telegram,412242443"
```

> ⚠️ Monitor cron bắt đầu disabled — chỉ enable khi pipeline đang chạy.

---

## V. SQLITE GLOSSARY

**Database:** `/home/tuan-nguyen/.openclaw/workspace/data/myanmar_pali_viet_terms_vec.db`

| Table | Columns | Mô tả |
|-------|---------|-------|
| `terms` | `id, pali, myanmar, vietnamese, desc_vi, desc_pali, category` | Thuật ngữ Pāḷi-Myanmar-Việt |

### Load nhanh (dùng trong Phase 1):
```python
import sqlite3
conn = sqlite3.connect('/home/tuan-nguyen/.openclaw/workspace/data/myanmar_pali_viet_terms_vec.db')
cur = conn.cursor()
cur.execute('SELECT pali, vietnamese, desc_vi, category FROM terms ORDER BY category, id')
glossary = [(r[0], r[1], r[2], r[3]) for r in cur.fetchall()]
```

---

## VI. GIÁM SÁT CHI PHÍ

| Mục | Giá trị |
|-----|--------|
| Model | Gemini 3 Flash Preview |
| Token/batch (ước tính) | ~40-50K |
| LLM calls/batch | 2 |
| Chi phí/batch | ~$0.03 |
| Tổng 225 batch | **~$6.75** |
| Input price | $0.50/M token |
| Output price | $3.00/M token |

---

## VII. SPAWN THỦ CÔNG (dự phòng)

Khi cần chạy 1 batch riêng lẻ (không qua cron):

```js
sessions_spawn({
  agentId: "translator",
  task: "<prompt từ guide: đọc TRANSLATOR-GUIDE-TIEU-SU.md + source file>",
  model: "google/gemini-3-flash-preview",
  mode: "run"
})
```

---

## VIII. TỔNG KẾT

```
V1 — VIỆT ONLY, PROSE, FILE-BY-FILE

  TRANSLATOR AI (2 LLM CALLS)              ARCHITECT
  ┌──────────────────────────┐            ┌──────────────┐
  │ PHASE 1: exec python     │            │ Giám sát 30ph │
  │  • Chọn batch + source   │            │ QA hậu kiểm   │
  │  • SQLite glossary       │            │ Fix sự cố     │
  │  • Đọc ctx-summary trước │            └──────────────┘
  ├──────────────────────────┤
  │ PHASE 2: 1 RESPONSE      │
  │  • Ghép câu đứt (nếu có) │
  │  • write vi-only file    │
  │  • write context-summary │
  │  • exec update progress  │
  │  ⚠️ KHÔNG merge-bilingual│
  │  ⚠️ KHÔNG text report!   │
  │ GỌI TẤT CẢ CÙNG LÚC      │
  │ ~40-50K token            │
  └──────────────────────────┘
```

> **Khác biệt chính từ Vinaya (02A→02):**
> 1. KHÔNG `---` block separator — dịch file-by-file (prose)
> 2. KHÔNG merge-bilingual.py — Việt only
> 3. KHÔNG song ngữ — CHỈ tiếng Việt
> 4. 225 batch (nhiều hơn Vinaya 22 batch)
> 5. Thuật ngữ tiểu sử/Alahan thay vì Luật tạng

> 📖 **File liên quan:**
> - `guide/TRANSLATOR-GUIDE-TIEU-SU.md` — Guide đặc thù cho translator
> - `edited/gemini-flash/output-*.md` — Source files (225 batch)
> - `obsidian/huong-dan/Translator-Myanmar-Vi.md` — Guide chung Myanmar→Việt
