---
x-i18n:
    generated_at: "2026-07-19T18:04:22Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 90c6c85a837448f4e5ceccdccf73489db801ad502cbbb2f3eb04d6aff7e902f0
    source_path: plan/swarms.md
    workflow: 16
---

# Swarms — การกระจายงานไปยังเอเจนต์และการประสานงานในโหมดโค้ด

สถานะ: จัดส่งแล้ว — ถูกแทนที่ด้วย `docs/tools/swarm.md` เอกสารนี้ยังคงไว้เป็น
บันทึกการออกแบบการนำไปใช้งาน

## 1. คืออะไรและทำไมจึงต้องมี

**swarm** คือซับเอเจนต์จำนวนมากที่ได้รับการประสานงานอย่างกำหนดผลลัพธ์แน่นอนจากสคริปต์
โหมดโค้ด: กระจายงานไปยังตัวอ่าน N ตัว ตรวจสอบข้อค้นพบแบบโต้แย้ง สังเคราะห์ผ่าน
ตัวจัดลำดับความสำคัญแบบมีสถานะ และวนซ้ำตามเกตการตัดสินใจ โฟลว์การควบคุม (`Promise.all`,
`while`, `if`) _ก็คือ_ การประสานงาน — โดยตั้งใจให้ **ไม่มี DSL แบบกราฟ
ไม่มีโหมดใหม่ และไม่มีพื้นผิวเครื่องมือระดับบนสุดใหม่**

โหมดโค้ดของ OpenClaw (QuickJS-WASI, snapshot/resume, คำขอผ่านบริดจ์) เป็น
รากฐาน การเรียกบริดจ์ที่พักไว้จะคงอยู่ผ่านสแนปช็อต VM การรีสตาร์ต Gateway และ
กลับมาทำงานต่อจากจุดที่หยุดไว้อย่างแม่นยำ — แข็งแกร่งกว่าการออกแบบที่เล่นเจอร์นัลซ้ำ โดย
ไม่มีข้อจำกัดด้านการกำหนดผลลัพธ์แน่นอนสำหรับสคริปต์

การตั้งชื่อ: ชื่อในผลิตภัณฑ์/เอกสารคือ **Swarm** ตัวระบุในโค้ดคงไว้ตามตัวอักษร:
API ฝั่งเกสต์ `agents.*`, การกำหนดค่า `tools.swarm`, คอลัมน์กลุ่ม `swarm`

## 2. การตัดสินใจ (ผู้ดูแล, 2026-07-17)

- ต้นทุน: บังคับใช้ขีดจำกัดจากการกำหนดค่า; งบประมาณโทเค็นต่อ swarm เป็นทางเลือก ไม่มีงบประมาณบังคับ
- การอนุมัติ: ลูกทำงานแบบ **ปิดเมื่อเกิดความล้มเหลว / ไม่โต้ตอบ** การดำเนินการที่ต้อง
  ได้รับอนุมัติจะถูกปฏิเสธ; การปฏิเสธจะถูกรายงานในผลลัพธ์ของลูก; สคริปต์
  เป็นผู้ตัดสินใจ ไม่มีพรอมต์รบกวนผู้ปฏิบัติงานจากการกระจายงาน
- v1 รองรับเฉพาะสคริปต์เฉพาะกิจที่โมเดลเขียน เวิร์กโฟลว์ที่บันทึก/ตั้งชื่อไว้ และจุดเข้า
  CLI/cron: ทำภายหลัง (มีโหมดโค้ดแบบ headless สำหรับ cron อยู่แล้ว)
- อัตลักษณ์ของลูก: ใช้เอเจนต์ผู้ปฏิบัติงานเฉพาะโดยค่าเริ่มต้นผ่านการกำหนดค่า `tools.swarm.defaultAgentId`
  (ตรวจสอบกับรายการอนุญาตเป้าหมายซับเอเจนต์ที่มีอยู่); เขียนทับต่อการสร้าง
  ด้วย `agentId` Core ไม่มีรหัสเอเจนต์แบบรวมมาให้; เอกสารแนะนำการกำหนดค่าเอเจนต์
  `worker` แบบกระชับ
- ไม่มีการเปลี่ยนแปลงซอร์ส Codex ฮาร์เนส Codex ใช้รูปแบบ spawn/wait (§8)

## 3. ภาพรวมสถาปัตยกรรม

```
สคริปต์โหมดโค้ด (QuickJS VM, Gateway)          สคริปต์ Codex V8 (กระบวนการ Codex)
  agents.run(...) ── การเรียกบริดจ์ที่พักไว้       tools.sessions_spawn / tools.agents_wait
        │                                                │ RPC ของ item/tool/call (แต่ละครั้ง ≤600s)
        ▼                                                ▼
             CORE (ไม่ขึ้นกับฮาร์เนส, รีโพนี้)
  sessions_spawn {collect:true, outputSchema, fastMode, groupId}
  agents_wait {ids, timeoutSeconds}
        │
  รีจิสทรีซับเอเจนต์ (SQLite): ระเบียนการเสร็จสิ้นของตัวรวบรวม, รหัสกลุ่ม swarm
        │
  ลูก = เซสชันซับเอเจนต์ทั่วไป (จำกัดตามเลน, การอนุมัติแบบปิดเมื่อเกิดความล้มเหลว)
        │
  sessions.changed SSE ──► จุดใน Control UI / แถบด้านข้าง / ข้อความสถานะช่องทาง
```

มีเจ้าของหลักหนึ่งเดียวสำหรับความหมายของ spawn/complete/settle (เครื่องมือ Core + รีจิสทรี)
การขนส่งสำหรับ await สองแบบ: QuickJS พักการเรียกบริดจ์ไว้อย่างไม่มีกำหนด (สแนปช็อต);
Codex สำรวจ `agents_wait` ผ่าน RPC ที่มีขอบเขต

## 4. เกตการกำหนดค่า (v1)

`tools.swarm` ใหม่ (ส่วนกลาง + การเขียนทับต่อเอเจนต์ โดยใช้รูปแบบการผสานเดียวกับ
`tools.codeMode`):

```jsonc
"tools": {
  "swarm": {
    "enabled": false,            // เกตหลัก, ค่าเริ่มต้นปิด
    "maxConcurrent": 8,          // จำนวนลูกที่ทำงานพร้อมกัน (ขีดจำกัดเลน swarm)
    "maxChildrenPerGroup": 50,   // จำนวนลูกที่ยังทำงานอยู่ต่อกลุ่ม swarm
    "maxTotalPerGroup": 200,     // จำนวนการสร้างตลอดอายุของกลุ่ม (แนวป้องกันการทำงานไม่สิ้นสุด)
    "waitTimeoutSecondsMax": 600,
    "defaultAgentId": ""         // ไม่บังคับ; รหัสเอเจนต์ลูกเมื่อ spawn ไม่ระบุ agentId
  }
}
```

- Zod: ยูเนียน `boolean | strict object` แบบเดียวกับ `CodeModeSchema`
  (`src/config/zod-schema.agent-runtime.ts`); `swarm: true` → `{enabled: true}`
- ประเภทใน `src/config/types.tools.ts` (ทั้งต่อเอเจนต์และ `tools` ระดับบนสุด),
  ป้ายกำกับใน `schema.labels.ts`, ความช่วยเหลือใน `schema.help.runtime.ts`
- ตัวช่วยการแก้ค่า `resolveSwarmConfig(cfg, agentId)` ที่สะท้อนรูปแบบ
  `resolveCodeModeConfig` (`src/agents/code-mode.ts:215`) พร้อมจำกัดตัวเลขทั้งหมดให้อยู่ในช่วง
- ผลของเกตเมื่อปิดใช้งาน: ไม่มีเครื่องมือ `agents_wait` ในแค็ตตาล็อก;
  พารามิเตอร์ `collect`/`outputSchema`/`fastMode`/`groupId` บน `sessions_spawn`
  จะถูกปฏิเสธพร้อมข้อผิดพลาดที่ชัดเจนซึ่งระบุคีย์การกำหนดค่า ไม่มีการเปลี่ยนแปลงพฤติกรรมอื่น
- `defaultAgentId` ได้รับการตรวจสอบผ่าน `resolveSubagentAllowedTargetIds`
  (`src/agents/subagent-target-policy.ts`); รหัสที่ไม่รู้จัก → ข้อผิดพลาดในการสร้าง ไม่ใช่การใช้ค่าทดแทน

## 5. Core: การสร้างในโหมดตัวรวบรวม + `agents_wait` (v1)

### 5.1 ส่วนเพิ่มเติมของ `sessions_spawn` (ทั้งหมดขึ้นกับการเปิดใช้งาน swarm)

- `collect: boolean` — เมื่อเป็นจริง การทำงานของลูกจะได้รับการลงทะเบียนด้วย
  `expectsCompletionMessage: false` และ **ระเบียนการเสร็จสิ้นของตัวรวบรวม**
  แทนการส่งประกาศ/การชี้นำ เครื่องมือส่งคืน `{ runId, sessionKey }`
  ทันที ไม่มีการผูกกับช่องทาง/เธรด
- `outputSchema: object` — JSON Schema ลูกจะได้รับเครื่องมือสังเคราะห์
  `structured_output` ที่เพิ่มต่อท้ายพื้นผิวเครื่องมือ; ส่วนเพิ่มเติมของพรอมต์ระบบ
  สั่งให้เรียกเครื่องมือนี้หนึ่งครั้งเท่านั้นพร้อมผลลัพธ์สุดท้าย เมื่อการตรวจสอบ
  ล้มเหลว ลูกจะได้รับการกระตุ้นให้ลองใหม่หนึ่งครั้ง; หลังจากนั้นระเบียนการเสร็จสิ้น
  จะมี `structured: undefined` พร้อมข้อความดิบและ `schemaError`
- `fastMode: true | "auto" | false` — ส่งผ่านไปยังแพตช์เซสชันลูก
  ควบคู่กับโมเดล/การคิดผ่าน `resolveSubagentModelAndThinkingPlan`
  (`src/agents/subagent-spawn-plan.ts`) โดยใช้แกน `FastMode` ที่มีอยู่
  (`src/shared/fast-mode.ts`) ไม่ระบุ = สืบทอด
- `groupId: string` — ตราประทับกลุ่ม swarm ค่าเริ่มต้นคือ
  `swarm:<requesterSessionKey>:<runId-of-requesting-run>` คงอยู่ใน
  ระเบียนรีจิสทรีและแถวเซสชันลูก ใช้สำหรับขีดจำกัด การแสดงรายการ การเก็บถาวร
  แบบกลุ่ม และจุดต่าง ๆ
- `label: string` มีอยู่แล้ว — แสดงในจุดต่าง ๆ และ `subagents list`
- รหัสเอเจนต์ลูก: `params.agentId` → มิฉะนั้น `tools.swarm.defaultAgentId` → มิฉะนั้น
  เอเจนต์ผู้ร้องขอ (พฤติกรรมที่มีอยู่)

### 5.2 การอนุมัติแบบปิดเมื่อเกิดความล้มเหลว

ลูกแบบตัวรวบรวมทำงานด้วยบริบทการอนุมัติแบบไม่โต้ตอบ: การเรียกเครื่องมือใด ๆ
ที่ต้องได้รับอนุมัติจากผู้ปฏิบัติงานจะได้รับผลเป็นการปฏิเสธแบบมีโครงสร้าง
(`approval_required`) ที่ลูกมองเห็น และคาดว่าลูกจะรายงาน
การติดขัดในผลลัพธ์ การนำไปใช้: ใช้ระบบนโยบายการอนุมัติ exec/เครื่องมือ
ที่มีอยู่ซ้ำ โดยบังคับใช้ตัวแก้ค่า `deny` สำหรับการทำงานของลูกในโหมดตัวรวบรวม
ไม่มีการส่งเหตุการณ์อนุมัติจากลูกแบบตัวรวบรวมไปยังพื้นผิวของผู้ปฏิบัติงาน

### 5.3 เครื่องมือ `agents_wait` (ใหม่, มีเกตควบคุม)

```
agents_wait({ ids: string[], timeoutSeconds?: number })
→ {
    completed: [{ runId, status: "done"|"failed"|"killed"|"timeout",
                  result: string, structured?: unknown, schemaError?: string,
                  sessionKey, label?, usage?: {inputTokens, outputTokens} }],
    pending: string[]
  }
```

- ส่งคืนทันทีเมื่อมีรหัส **อย่างน้อยหนึ่งรายการ** เสร็จสมบูรณ์ (ความหมายแบบ
  เสร็จก่อน/แข่งขันกัน ซึ่งทำให้สร้างไปป์ไลน์ได้) หรือเมื่อหมดเวลาพร้อม `completed: []`
- ค่าเริ่มต้นของ `timeoutSeconds` คือ 30 และถูกจำกัดไว้ที่ `waitTimeoutSecondsMax`
- ทำซ้ำได้โดยไม่เปลี่ยนผลลัพธ์: รหัสที่เสร็จสมบูรณ์แล้วจะส่งคืนระเบียนเดิมอีกครั้ง (ระเบียนจะ
  ถูกเก็บไว้จนกว่าจะเก็บกลุ่มถาวร) รหัสที่ไม่รู้จัก → รายการข้อผิดพลาดต่อรหัส ไม่ใช่การ throw
- ความเป็นเจ้าของ: เฉพาะเซสชันที่สร้างการทำงาน (หรือลำดับพาเรนต์ของเซสชันนั้น) เท่านั้นที่รอ
  การทำงานดังกล่าวได้ — กฎความเป็นเจ้าของเดียวกับ `wait` ในโหมดโค้ด (`code-mode.ts:1684`)
- รีจิสทรี: ระเบียนการเสร็จสิ้นอยู่ในที่เก็บ SQLite ของรีจิสทรีซับเอเจนต์
  ที่มีอยู่ (`subagent-registry.store.sqlite.ts`) — ฟิลด์ใหม่ ไม่มีที่เก็บใหม่ และไม่มี
  การเพิ่มเวอร์ชันสคีมา (เฉพาะคอลัมน์เพิ่มเติม; ดูข้อจำกัดใน §9)

### 5.4 การบังคับใช้ขีดจำกัด

- `maxConcurrent`: ลูกแบบตัวรวบรวมทำงานบนเลนซับเอเจนต์ที่มีอยู่ แต่
  นับแยกตามกลุ่ม swarm; การสร้างที่เกินขีดจำกัดจะเข้าคิวแบบ FIFO (ฝั่งโฮสต์ ใน
  เส้นทางการสร้าง — ส่งคืน runId ทันที และเริ่มทำงานเมื่อมีช่องว่าง)
- `maxChildrenPerGroup` / `maxTotalPerGroup`: การสร้างจะถูกปฏิเสธด้วยข้อผิดพลาดแบบมีชนิด
  เมื่อเกินค่า; ข้อความข้อผิดพลาดจะระบุคีย์การกำหนดค่า
- ความลึก: ลูกแบบตัวรวบรวมคงความหมายของ `DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH`
  (ลูกเป็นโหนดปลายทาง เว้นแต่กำหนดค่าการซ้อนอย่างชัดเจน)

## 6. สัญญาการทดสอบ (v1, เลน A)

- ยูนิต: การแก้ค่า/จำกัดช่วงการกำหนดค่า; การปฏิเสธโดยเกตเมื่อปิดใช้งาน; การใช้ค่าเริ่มต้น
  ของ groupId; การบังคับใช้ขีดจำกัด (เข้าคิว + ปฏิเสธ); ความหมายการแข่งขันของการรอ; การทำซ้ำ
  การรอโดยไม่เปลี่ยนผลลัพธ์; การปฏิเสธความเป็นเจ้าของ; การตรวจสอบเอาต์พุตแบบมีโครงสร้าง + กระตุ้นให้ลองใหม่ +
  เส้นทาง schemaError; การส่ง fastMode ไปยังแพตช์เซสชัน; การตรวจสอบ
  defaultAgentId
- การผสานรวม (vitest, รันไทม์โมเดลจำลอง): สร้างลูกแบบตัวรวบรวม 3 ตัว รอ
  ในลูป ยืนยันลำดับการเสร็จก่อนและการระบายขั้นสุดท้าย; การจำลอง
  การรีสตาร์ต Gateway: โหลดรีจิสทรีใหม่ → การรอแก้ผลจากการเสร็จสิ้นที่คงอยู่
- การทดสอบทั้งหมดอยู่ร่วมกับ `*.test.ts`; ไม่มีการเรียกโมเดลจริง

## 7. พื้นผิวฝั่งเกสต์ QuickJS (เลน B, หลัง Core)

- โกลบอลฝั่งเกสต์ติดตั้งใน `CONTROLLER_SOURCE`
  (`src/agents/code-mode.worker.ts:190-374`) และเพิ่มชื่อสงวนใน
  `code-mode-namespaces.ts`:
  - `agents.run(prompt, opts) → Promise<result|structured>` — รูปแบบย่อ:
    การสร้างตัวรวบรวม + การรอแบบพักไว้บนเมธอดบริดจ์เฉพาะ (`agentWait`)
    ซึ่งโฮสต์จะตัดสินผลเมื่อเสร็จสมบูรณ์ (ไม่มีการสำรวจ; ปลอดภัยต่อสแนปช็อต)
  - `agents.session(system, opts) → Promise<handle>`;
    `handle.send(input, opts) → Promise<...>`; `handle.close()` (v1.1 —
    จัดส่งหลัง run(); ใช้ `mode:"session"` + ระเบียนตัวรวบรวมต่อเทิร์น)
  - `phase(title)`, `log(message)` — การแจ้งเตือนผ่านบริดจ์แบบส่งแล้วไม่รอผล →
    เหตุการณ์ความคืบหน้าของ swarm
- เพิ่มเมธอดบริดจ์ใน `CodeModeBridgeMethod` (`code-mode.ts:91`):
  `agentSpawn`, `agentWait`, `swarmNote` โดย `agentSpawn`/`agentWait`
  ปลอดภัยต่อการเล่นซ้ำ **โดยโครงสร้าง**: คีย์การทำซ้ำโดยไม่เปลี่ยนผลลัพธ์ `(codeModeRunId, bridgeId)`
  ถูกเก็บไว้ในระเบียนรีจิสทรี; การรีสตาร์ตจะตัดสินผลซ้ำจากการเสร็จสิ้นที่คงอยู่
  และไม่สร้างซ้ำ
- การเรียกบริดจ์ `agentWait` ที่รอดำเนินการจะขยาย TTL ของสแนปช็อตการทำงาน (ชุด
  เอเจนต์ที่รอดำเนินการคือสัญญาณ; ไม่มีแฟล็ก)
- ไฟล์เสมือน `API.read("agents.d.ts")` อธิบายพื้นผิวแบบมีชนิด + รูปแบบ
  การกระจายงาน / เกต / รอบ (`createCodeModeApiVirtualFiles`,
  `code-mode-namespaces.ts:876`)

## 8. การฉายไปยังฮาร์เนส Codex (เลนภายหลัง)

- `sessions_spawn` (พร้อมพารามิเตอร์ใหม่) และ `agents_wait` ไหลผ่าน
  บริดจ์เครื่องมือแบบไดนามิกที่มีอยู่; ภายในสคริปต์โหมดโค้ด Codex ทั้งสองจะปรากฏเป็น
  `tools.*` โดยอัตโนมัติ (ตรวจสอบแล้ว: `codex-rs/code-mode/src/runtime/globals.rs:14-65`,
  `codex-rs/core/src/tools/spec_plan.rs:448-507`)
- `agents_wait` ได้รับคลาสหมดเวลาแบบยาวสำหรับเครื่องมือไดนามิก (ขีดจำกัด 600s;
  `extensions/codex/src/app-server/dynamic-tool-execution.ts:37-39`) และ
  ถูกทำเครื่องหมายว่าปลอดภัยต่อการหมดเวลา/เล่นซ้ำ
- คีย์กลุ่มสำหรับพาเรนต์ Codex: `swarm:<parentSessionKey>:<turnId>`
- ซับเอเจนต์ `spawn_agent` แบบเนทีฟของ Codex อยู่ร่วมกันได้; แถวมิเรอร์งานของซับเอเจนต์เหล่านั้นส่งข้อมูล
  ไปยังพื้นผิวความคืบหน้าเดียวกัน

## 9. การคงอยู่และการเก็บรักษา

- ไม่มีที่เก็บใหม่ ระเบียนรีจิสทรีขยายตาราง SQLite ของรีจิสทรีซับเอเจนต์
  ที่มีอยู่; ลูกเป็นแถว `sessions` ทั่วไป เพิ่มเฉพาะคอลัมน์
  — **การเปลี่ยนแปลงใด ๆ ที่ต้องเพิ่มเวอร์ชันสคีมา SQLite ต้องได้รับ
  การอนุมัติอย่างชัดเจนจากผู้ดูแลก่อน** (นโยบายรีโพ)
- รหัสกลุ่ม swarm อยู่ในระเบียนรีจิสทรี + ข้อมูลเมตาของเซสชันลูก
- การเก็บรักษา: ระเบียนตัวรวบรวมที่เสร็จสมบูรณ์จะคงอยู่จนถึง **การเก็บกลุ่มถาวร**:
  เมื่อการทำงานของพาเรนต์เสร็จสิ้น (หรือ TTL หมดอายุ) ลูกของกลุ่มจะถูกเก็บถาวร
  เป็นชุด (ขยายการกวาด `DEFAULT_SUBAGENT_ARCHIVE_AFTER_MINUTES`
  ที่มีอยู่ให้ทำงานแยกตามกลุ่ม)

## 10. พื้นผิวความคืบหน้า ("จุดต่าง ๆ") — เลนภายหลัง

- ทำงานโดยนัยและขับเคลื่อนโดยฮาร์เนส อนุมานจาก SSE `sessions.changed` ที่มีอยู่ +
  รีจิสทรี; บันทึก `phase`/`log` เพิ่มความหมาย ไม่มีการเรนเดอร์ที่ขับเคลื่อนโดยเอเจนต์
- Control UI: ตัวเรนเดอร์ `swarm` ในตระกูลวิดเจ็ตพื้นที่ทำงาน
  (`ui/src/lib/workspace/widgets/`) — ตารางจุดที่จัดกลุ่มตามเฟส บรรทัด
  ผู้บรรยาย สถานะ/ป้ายกำกับ/โมเดลต่อจุด; ทรีลูกในแถบด้านข้างไม่เปลี่ยนแปลง
- ช่องทาง: ข้อความสถานะที่แก้ไขและควบคุมอัตราหนึ่งข้อความต่อกลุ่ม (ปฏิบัติตาม
  `docs/concepts/streaming.md`; ห้ามส่งข้อความแยกต่อลูก)

## 11. หน้า Labs (Control UI, เลนอิสระ)

Settings → **Labs**: ตัวสลับฟีเจอร์ทดลอง โดยรายการแรกคือ **Code Mode**
และ **Swarm** แต่ละแถวประกอบด้วยชื่อ คำอธิบายหนึ่งบรรทัด ลิงก์เอกสาร และตัวสลับที่เชื่อมต่อ
ผ่าน RPC `config.patch` ที่มีอยู่ (merge-patch ตาม RFC 7396 — ตั้งค่า
`tools.codeMode.enabled` / `tools.swarm.enabled`) พร้อมคำแนะนำว่า "ต้องรีสตาร์ต"
เมื่อเกี่ยวข้อง ผู้ใช้ค้นพบได้ง่าย แต่ข้อความต้องระบุสถานะทดลอง
อย่างชัดเจน i18n: สตริงทั้งหมดผ่าน `en.ts` + ไปป์ไลน์ซิงค์ตามปกติ

## 12. ตำแหน่งการทำงาน (ภายหลัง)

- `placement` ให้เลือกเมื่อ spawn: `"local"` (ค่าเริ่มต้น) | `"cloud:<profile>"` ผ่าน
  การส่งต่อสภาพแวดล้อม worker ที่มีอยู่ (`sessions.dispatch`) ส่วนตำแหน่งการทำงานแบบพูล
  เพิ่มภายหลัง หาก child ของ SSH sandbox ในกล่องที่ใช้ร่วมกันพิสูจน์แล้วว่าไม่เพียงพอ
- VM ของ Orchestrator จะอยู่บน Gateway เสมอ ส่วน settle/dots/budget
  ไม่รับรู้ตำแหน่งการทำงาน

## 13. สิ่งที่ไม่ใช่เป้าหมาย

- ไม่มี DSL แบบกราฟ — ลำดับการควบคุมคือกราฟ (ตั้งใจออกแบบและมีเอกสารกำกับ)
- ไม่มีการเปลี่ยนแปลงซอร์สของ Codex และไม่ใช้ส่วนภายในของ Codex Code Mode ซ้ำ
- ไม่มีเวิร์กโฟลว์ที่บันทึกไว้/ตั้งชื่อใน v1 และไม่มีจุดเริ่มต้นผ่าน CLI
- ไม่มีการส่งต่อการอนุมัติของผู้ดำเนินการจากแต่ละ child ขึ้นมา
- ไม่มีการจัดเตรียมคลาวด์แบบ 1:1 ในระดับ fan-out
- ไม่มี compat shim สำหรับรันไทม์ในสถานะคงที่ Swarm เป็นพื้นผิวใหม่ที่มีการควบคุมการเปิดใช้

## 14. ระยะการสร้าง / การแบ่ง PR

1. **เลน A (core)**: การกำหนดค่า §4 + spawn/wait/caps/approvals ใน §5 + การทดสอบ §6
2. **เลน C (หน้า Labs)**: §11 — เป็นอิสระและรวมได้ก่อน
3. **เลน B (พื้นผิว QuickJS)**: §7 — หลังจากรวมสัญญาของ A แล้ว
4. ตัวเรนเดอร์ dots (§10), การฉายภาพ Codex (§8), `agents.session` (§7 v1.1),
   ตำแหน่งการทำงาน (§12), การเขียนเอกสารผู้ใช้ใหม่ — เป็น PR ติดตามผลตามลำดับนี้

แต่ละ PR: ไปป์ไลน์ CI ผ่านทั้งหมด, `$autoreview` สะอาด, ปิดไว้เป็นค่าเริ่มต้น และ main พร้อมเผยแพร่
