# CPX P3-02: การส่งข้อความ การเชื่อมกลับ และการหยุดข้ามฝ่าย

วันที่ 7 ตุลาคม 2026 · เว็บ 1.17.2 · ต้นแบบหน้าฝึกเดิม 1.16.28

## ขอบเขต

ชุดนี้ผ่านการตรวจระหว่างพัฒนาในเครื่อง: กรณีหลัก F09–F12 สี่กรณีและตัวตรวจข้อมูล/ฐานอีกสองกรณี รวมกับ P3-01 เป็น 15 กรณี ไม่ข้ามกรณีใด ใช้ Node.js 22.23.1 และ SQLite กับภารกิจ ตัวตน และ peer สมมติที่ host สร้าง ไม่มีการเปิดห้องฝึกหลายคนบนคลาวด์

## พฤติกรรมที่ตรวจผ่าน interface

| กรณี | สิ่งที่ต้องตรวจในเครื่อง | ชั้นที่ยังต้องตรวจต่อ |
|---|---|---|
| F09 | ผู้รับบันทึกแล้วแต่คำตอบหาย ส่งซ้ำคืนหลักฐานเดิม ไม่เพิ่มบันทึกหรือผลซ้ำ เปลี่ยนเนื้อหา/ID ถูกปฏิเสธ การส่งถึงไม่ยืนยันรับภารกิจ | การยืนยัน peer จริง การส่งสถานะภารกิจข้าม owner แบบสด และ transport บนคลาวด์ |
| F10 | ข้อความลำดับอนาคตอยู่ใน pending ไม่ใช้สรุปสถานะจนเติมช่องว่างครบ แยกลำดับเฉพาะผู้รับจากเลขคำสั่งผู้ส่ง | HTTP/Queues และการเรียงลำดับในระบบจริง |
| F11 | เปิดฐานเดิมอีกครั้ง อ่าน snapshot ที่มีสิทธิ์ล่าสุด ตรวจ policy ปัจจุบันใหม่ และไม่ส่ง draft อัตโนมัติ | WebSocket reconnect, hibernation และ policy กระจายจริง |
| F12 | EXCON อยู่ใน stopping จน owner ตาม manifest บันทึก fence และยืนยันครบ ฝ่าย offline ยัง unconfirmed คำสั่งใหม่ที่ใช้ epoch เก่าถูกปฏิเสธหลัง fence บันทึกเดิมยังอยู่ | stop propagation, crash และ Durable Objects storage จริง |

## ความหมายของสถานะ

การส่งถึงในชั้น transport หมายถึงฐานข้อมูลผู้รับบันทึก envelope และหลักฐานรับไว้แล้ว ยังไม่ใช่การรับข้อความโดยผู้ฝึกหรือการรับภารกิจ ฝ่ายยังต้องจอง จัดแผน ตรวจทรัพยากร และรอ N-C ยืนยันทีมหลักตามกติกาเดิม

`sourceSequence` อ้างเลขคำสั่งที่ผู้ส่งบันทึก ส่วน `deliverySequence` เรียงเฉพาะคู่ผู้ส่ง–ผู้รับ คำสั่งที่ส่งไปฝ่ายอื่นจึงไม่สร้างช่องว่างปลอม หากข้อความของผู้รับมาถึงผิดลำดับ ต้องแสดงว่ารอเติม ไม่เดาสถานะจากข้อมูลลำดับอนาคต

การหยุดฝึกมีสองช่วง: EXCON บันทึกคำสั่งหยุดและ epoch ใหม่ แล้วรอแต่ละ owner บันทึก fence พร้อมเลขบันทึกสุดท้าย สถานะ stopped ต้องรอทุกฝ่ายยืนยัน ฝ่ายที่ยังติดต่อไม่ได้ต้องอยู่ในรายการรอยืนยัน การหยุดนี้ไม่ลบประวัติการปฏิบัติงาน

หากข้อความถูกบันทึกไว้ขณะที่ยังขาดลำดับก่อนหน้า หลักฐานเดิมจะระบุ delivery-pending และการส่งซ้ำคืนหลักฐานเดิม เมื่อเติมช่องว่างครบ ผู้ส่งต้องอ่านหลักฐานสถานะปัจจุบันก่อนยืนยัน received ใน outbox จึงไม่ยืนยันจากหลักฐาน pending ที่เก็บไว้ก่อนหน้า

## วิธีตรวจและข้อจำกัด

```text
node --test tools/cpx-cloud-feasibility/*.test.mjs
node --test tools/cpx-local/*.test.mjs
```

การตรวจรวมโดยผู้ประสานผ่าน 15 กรณี ต้นแบบเดิมผ่าน 147 กรณี ก่อนเพิ่มพฤติกรรมครบ assertion ของ F09–F12 ล้มเหลวทั้งสี่กรณีตามช่องว่างของ implementation แล้วผ่านหลังแก้ มีการตรวจซ้ำว่าข้อมูล JSON ที่ใช้ object ร่วมกันต้องหยุดตรวจตามเพดานรวม และเลขลำดับขนาดใหญ่ไม่ทำให้สร้างรายการช่องว่างทีละเลข

กรณีหยุดฝึกปิดฐานของ N-D-B ก่อนส่งคำสั่งหยุด แล้วเปิดฐานกลับมา บันทึก fence และปฏิเสธคำสั่งเก่าที่รอส่ง บันทึก coordinator มีหนึ่งคำสั่งหยุดและเจ็ด ACK ส่วน journal เดิมของ N-C ยังมีคำสั่งที่ commit ก่อนหยุดหนึ่งรายการ คืนผลเดิมได้เมื่อผู้ส่งยังมีสิทธิ์ปัจจุบัน ชุดทดลองนี้ปิดคำสั่งใหม่ทั้งหมดหลัง fence ไม่ใช่ขั้นตอนหยุดโดรนในเหตุจริง

การทดสอบ F04 เดิมยังตรวจ SQLite contention จริง: ผู้เขียนคนแรกยังถือ lock และไม่ commit ขณะคำสั่งคู่แข่งได้ ERR_SQLITE_ERROR/errcode 5 หลังรอ 5544.1 ms แล้ว retry คำสั่งเดิมได้ REVISION_CONFLICT เวลานี้เป็น busy timeout ในเครื่อง ไม่ใช่ latency ของ Cloudflare

ฐานข้อมูลชั่วคราวแยกจากต้นแบบและหลักฐานเดิม ใช้การปิด/เปิด connection กับจุดแทรกข้อผิดพลาด ไม่อ้างว่าเป็นการทดสอบ process kill ระหว่างเขียน ไฟดับ หรือ lifecycle ของ Cloudflare ตัวตน/peer/policy เป็น fixture ในเครื่อง ไม่ใช่ JWT หรือบัญชีจริง Node แจ้งว่า SQLite เป็น experimental feature

รูปแบบ OwnerJournal ของ P3-02 เป็น schema 2 ต้องใช้ฐานทดลองใหม่ การตรวจฐาน schema เก่าจำลองพบว่าปฏิเสธโดยข้อมูลไฟล์ยังตรงทุก byte ไม่มีการ migrate อัตโนมัติ หากตรวจหลักฐาน P3-01 ให้ใช้ source รุ่น 1.17.1 ที่ตรึงไว้ ไม่ใช้ harness ใหม่นี้แก้ฐานเก่า

บันทึก transport แยกจาก reducer ภารกิจเดิม การพิสูจน์ผลธุรกิจใช้ข้อความจาก observation prefix ที่ตรึงไว้ แล้วส่งคำสั่งธุรกิจอย่างชัดเจน การอัปเดต projection ด้วยเหตุการณ์ใหม่จากฝ่ายอื่นแบบสดยังต้องออกแบบและตรวจต่อ ผล P3-02 จึงมี coverage รวมเป็น PARTIAL ไม่ใช่ผลตรวจรับระบบหลายฝ่ายครบวงจร

แบบบันทึกคลาวด์ F01–F16 ยังเป็น NOT_RUN ทุกกรณี ผลในเครื่องและการ deploy เว็บไม่แทนการซักซ้อมกับผู้ใช้ การตรวจด้านการบิน หรือการตรวจรับเหตุจริง การตรวจ source ด้านสิทธิ์เป็น security-audit guidance เท่านั้น ยังไม่มี OS-enforced audit sandbox จึงไม่อ้างผล dev tests เป็นการตรวจรับความปลอดภัย

## ฐานวิจัยและงานถัดไป

Cloudflare Queues อาจส่งซ้ำและไม่รับประกันลำดับ จึงใช้ ID/เนื้อหาตรวจซ้ำและลำดับของผู้รับเป็นสัญญาที่ CPX ออกแบบเพิ่ม ([Delivery guarantees](https://developers.cloudflare.com/queues/reference/delivery-guarantees/), [How Queues works](https://developers.cloudflare.com/queues/reference/how-queues-works/))

Durable Objects มี API สำหรับเก็บ attachment ของ WebSocket เพื่อฟื้นข้อมูล connection หลัง hibernation ผลการเปิด SQLite ใหม่ในชุดนี้ต้องตรวจซ้ำบน API จริง ([Use WebSockets](https://developers.cloudflare.com/durable-objects/best-practices/websockets/))

งานต่อไป P3-03 ตรวจข้อมูลสรุปและ watermark หลักฐานตามสิทธิ์ และ coordinated restore จากนั้นตรวจการส่งสถานะภารกิจแบบสดและ Cloudflare ใน P3-04 เมื่อยืนยัน issuer/login กติกาถอนสิทธิ์ retention วงเงิน และสิทธิ์บัญชี ก่อนซักซ้อมและตรวจรับขอบเขตกับผู้ใช้จริง
