Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions decisions/0028-versioning-for-tool-response-contracts.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ADR-0028: contract ที่ส่งผ่าน tool response — กฎ versioning สำหรับช่องทางที่ประกาศไปไม่ถึงผู้รับ

**Status:** **Accepted** (2026-09-07)
**อัปเดต:** 2026-09-07 — บันทึกนาฬิกาเรือนที่สาม (ข้อเท็จจริงที่ผู้ขอวัดได้หลัง deploy) · ปิดข้อค้างเรื่องคีย์ที่ถูกลบไปแล้ว · กติกาถูก implement และยืนยันจากฝั่งผู้ใช้แล้ว
**อัปเดต:** 2026-09-07 — บันทึกนาฬิกาเรือนที่สาม (ข้อเท็จจริงที่ผู้ขอวัดได้หลัง deploy) · ปิดข้อค้างเรื่องคีย์ที่ถูกลบไปแล้ว · กติกาถูก implement และยืนยันจากฝั่งผู้ใช้แล้ว · **หดคำกล่าวอ้างเรื่องหน้าต่าง rollout ให้เท่ากับหลักฐาน** ตามที่ผู้ขอทักมาใน `seq 17`
**Date:** 2026-09-07
**Depends on:** [ADR-0006](0006-contract-versioning.md) · [ADR-0011](0011-conformance-automation.md) · [ADR-0027](0027-toolid-transformation-must-be-deterministic.md)
**Blocking:** `contracts/mcp/v1` (ยังไม่แตะ) · คำขอจาก [`ai-collaboration-mcp`](https://github.com/monthop-gmail/ai-collaboration-mcp)
Expand Down Expand Up @@ -33,10 +33,18 @@ waiting_for_you { handoffs, tasks } → waiting_for_you { unaccepted, in
```text
ผลลัพธ์ของ tool สร้างสด → เปลี่ยนเมื่อ isolate ที่รับคำขอนั้นเป็นตัวใหม่
description/schema ค้างที่ client → เปลี่ยนเมื่อ client เชื่อมต่อใหม่ ซึ่งไม่มีใครรู้ว่าเมื่อไหร่
ช่วง rollout isolate เก่ากับใหม่ตอบพร้อมกัน → สองรูปมีชีวิตพร้อมกันชั่วขณะ
ช่วง rollout หลัง deploy จบ ยังมีคำขอที่ได้รูปเก่า → สองรูปถูกเสิร์ฟพร้อมกันได้
```

**เรือนที่สามเพิ่มเข้ามาหลังเคาะ และเป็นการวัดของฝั่งผู้ขอเอง ไม่ใช่ข้อสันนิษฐานของเรา** — เดิม `seq 13` ระบุว่าผลลัพธ์ *"เปลี่ยนพร้อมกันหมดทุก client ตั้งแต่วินาทีที่ deploy จบ"* และ ADR ฉบับแรกอ้างประโยคนั้น · ตอน deploy กติกานี้จริง เขายิง `get_workspace_context` ทันทีหลัง deploy จบแล้ว **ยังไม่มีฟิลด์ `contract`** ยิงซ้ำอีกไม่กี่วินาทีถัดมาจึงได้ครบ แล้วถอนประโยคเดิมของตัวเองใน `seq 15`
**เรือนที่สามเพิ่มเข้ามาหลังเคาะ และเป็นการวัดของฝั่งผู้ขอเอง ไม่ใช่ข้อสันนิษฐานของเรา** — เดิม `seq 13` ระบุว่าผลลัพธ์ *"เปลี่ยนพร้อมกันหมดทุก client ตั้งแต่วินาทีที่ deploy จบ"* และ ADR ฉบับแรกอ้างประโยคนั้น · ตอน deploy กติกานี้จริง เขายิง `get_workspace_context` ทันทีหลัง `wrangler deploy` รายงานว่าจบ แล้ว **ยังไม่มีฟิลด์ `contract`** ยิงซ้ำอีกไม่กี่วินาทีถัดมาจึงได้ครบ แล้วถอนประโยคเดิมของตัวเองใน `seq 15`

> **ขอบเขตของหลักฐาน — อ่านให้ตรงกับที่วัดมา** (`seq 17`)
>
> สิ่งที่หลักฐานรองรับคือ **หน้าต่างนั้นมีอยู่จริง** เท่านั้น
>
> สิ่งที่ **ยังไม่รู้และ ADR ฉบับนี้ไม่อ้าง**: หน้าต่างกว้างเท่าไหร่ (สังเกตครั้งเดียว ไม่ได้จับเวลา) · ขึ้นกับอะไรบ้าง (ไม่ได้ทำซ้ำหลาย deploy ไม่ได้ยิงจากหลาย region) · เป็นพฤติกรรมของ Workers ทั่วไปหรือของ deployment รูปแบบนี้โดยเฉพาะ · และ **กลไกเบื้องหลังคืออะไร** — คำว่า *isolate* ที่ใช้กันในกระทู้เป็นคำอธิบายที่น่าเชื่อ ไม่ใช่สิ่งที่วัดได้
>
> ฉบับก่อนหน้าของ ADR นี้เขียนว่า *"isolate เก่ากับใหม่ตอบพร้อมกัน → สองรูปมีชีวิตพร้อมกันชั่วขณะ"* ซึ่ง **ยืนยันกลไกและความกว้างเกินกว่าที่หลักฐานรองรับ** · ผู้ขอทักมาเอง และถูก — ADR ที่ทั้งใบยืนอยู่บนหลักว่าอย่ารายงานสิ่งที่เชื่อว่าจริงแทนสิ่งที่อ่านมาจริง จะละเมิดหลักของตัวเองในย่อหน้าที่ตั้งใจบันทึกความซื่อตรงไม่ได้

**ข้อนี้ไม่ได้ลดน้ำหนักของคำตอบ แต่เพิ่ม** — กติกาที่พึ่งการประกาศต้องถูกทั้งสามเรือนจึงจะรอด ส่วนกฎห้ามลบไม่ต้องถูกสักเรือน เพราะทุกรูปที่มีชีวิตอยู่ในช่วงนั้นมีคีย์เก่าครบเหมือนกัน

Expand Down Expand Up @@ -143,9 +151,10 @@ ADR นี้ **ขยายกฎของ [ADR-0006](0006-contract-versioning.
* **ทะเบียนคีย์ที่รอลบต้องอยู่ฝั่ง server** ไม่ใช่ที่ [`contracts/README.md`](../contracts/README.md) ของเรา เพราะไม่ใช่ contract ที่เราถือ — เราถือแค่กฎ
* **ปิดแล้ว — คีย์ที่ถูกลบเมื่อ 7 ก.ย. ไม่คืน · จุดเริ่มของกฎคือ `contract 2`** · เจ้าของ server เคาะไม่คืน และเหตุผลที่ตัดสินคือข้อที่ **ฝั่งเรามองข้าม**: `waiting_for_you.total` เป็นคีย์ที่ *ยังอยู่แต่ความหมายเปลี่ยน* (เดิมนับซ้ำได้ `2` ตอนนี้ไม่นับซ้ำได้ `1`) ซึ่งกฎข้อ 1 ท่อน *ห้ามเปลี่ยนความหมาย* ห้ามไว้เหมือนกัน — **การคืนแค่ `handoffs`/`tasks` จึงไม่ได้ทำให้ถูกกฎ ต้องคืน `total` แบบเดิมด้วย ซึ่งเท่ากับคืนบั๊กที่ทั้งสองทีมเห็นพ้องกันว่าผิด** · ตอนเราเสนอให้คืน เรานับแต่คีย์ที่หายไป ไม่ได้นับคีย์ที่ยังอยู่แต่ความหมายเปลี่ยน ทั้งที่กฎที่เราเขียนเองครอบทั้งสอง · ข้อยกเว้นครั้งเดียวนี้บันทึกไว้ที่ README และ NOTES ของ server แล้ว **ตั้งแต่ `2` เป็นต้นไปกฎมีผลเต็ม**
* **กติกาถูก implement และยืนยันจากฝั่งผู้ใช้แล้ว** — `agent-platform` ยิงเทียบเองในฐานะ client ที่ไม่ได้อยู่ในการ deploy: `description` ที่ client ถืออยู่ขึ้นต้นว่า `contract 2` และ `get_workspace_context` ที่ยิงสดคืน `contract: 2` · **ตรงกัน** · ฝั่ง server ทำเป็น wrapper ของ `registerTool` ไม่ใช่เขียนเลขในข้อความของแต่ละ tool — เหตุผลเดียวกับ [ADR-0027](0027-toolid-transformation-must-be-deterministic.md) คือกฎที่ต้องอาศัยความจำของคนเขียนจะถูกละเมิดทันทีที่คนเปลี่ยน
* **ยังไม่ปิด:** **ความกว้างของหน้าต่าง rollout** — `ai-collaboration-mcp` เสนอวัดให้เป็นเรื่องเป็นราวในรอบ deploy ถัดไป (ยิงถี่ตั้งแต่ก่อน deploy จนหลัง) · จนกว่าจะมีผล ข้อนี้เป็น *การมีอยู่* ไม่ใช่ *ปริมาณ* และไม่มีกฎข้อใดใน ADR นี้ขึ้นกับตัวเลขนั้น
* **ยังไม่ปิด:** ที่ทางของเลข contract ใน `mcp/v1` — รอ consumer รายแรกที่ pin ตามหลักเดียวกับ mapping record ใน [ADR-0027](0027-toolid-transformation-must-be-deterministic.md)
* ยังไม่มีใครตอบได้ว่า **ค่ายไหนถือ schema เวอร์ชันไหนอยู่** — ภายใต้ D ข้อนี้เลิกเป็นเรื่องคอขาดบาดตาย เพราะคนที่ถือของเก่าก็ยังทำงานได้ แต่ยังเป็นข้อจำกัดที่ต้องบันทึก

## Sources

`dis-7c741dbb` ใน [`ai-collaboration-mcp`](https://github.com/monthop-gmail/ai-collaboration-mcp) workspace — `seq 7` (การเปลี่ยนรูป `waiting_for_you`) · `seq 10` (agent-platform ทักว่าเป็น breaking change ที่ไม่มีเวอร์ชัน) · `seq 12` (รับข้อเสนอ + คำถามสามข้อ) · `seq 13` (ข้อจำกัดสามข้อที่วัดมาเอง) · `seq 15` (รับกติกาทั้งชุด · เคาะไม่คืนคีย์ · ถอนประโยคเรื่อง deploy ของตัวเอง) · `seq 16` (agent-platform รับว่ามองข้าม `total`) · [ADR-0006](0006-contract-versioning.md) นิยาม breaking + Deprecation + Compatibility · [`contracts/README.md`](../contracts/README.md) เกณฑ์รับ contract ใหม่ 4 ข้อ · MCP `notifications/tools/list_changed`
`dis-7c741dbb` ใน [`ai-collaboration-mcp`](https://github.com/monthop-gmail/ai-collaboration-mcp) workspace — `seq 7` (การเปลี่ยนรูป `waiting_for_you`) · `seq 10` (agent-platform ทักว่าเป็น breaking change ที่ไม่มีเวอร์ชัน) · `seq 12` (รับข้อเสนอ + คำถามสามข้อ) · `seq 13` (ข้อจำกัดสามข้อที่วัดมาเอง) · `seq 15` (รับกติกาทั้งชุด · เคาะไม่คืนคีย์ · ถอนประโยคเรื่อง deploy ของตัวเอง) · `seq 16` (agent-platform รับว่ามองข้าม `total`) · `seq 17` (ขอบเขตของหลักฐานเรื่องหน้าต่าง rollout · กติกาการขยับเลข) · [ADR-0006](0006-contract-versioning.md) นิยาม breaking + Deprecation + Compatibility · [`contracts/README.md`](../contracts/README.md) เกณฑ์รับ contract ใหม่ 4 ข้อ · MCP `notifications/tools/list_changed`
Loading