# D · สัญญาข้อมูลสอง epoch และตัวคัดที่พักอย่างถูกเหตุ

**พื้นฐานก่อนทำ:** อ่าน [M01 สำรวจและทำแผนที่](/knowledge/drone-applications/survey-mapping/) เรื่อง reference/uncertainty และ [M08 สิ่งแวดล้อม](/knowledge/drone-applications/environment-monitoring/) เรื่องน้ำ/ฤดู/coverage; เขียน parser CSV ที่รักษาข้อความ `unknown`, ISO 8601 offset, `Decimal`, stable key และ unit ได้. แยก expected ของผู้แต่งจาก actual ที่ตนรัน.

**เป้าหมาย KSEC:** `APP-CSC-D-K01` นิยาม contract เวลา กรอบพิกัด datum น้ำ รุ่น checkpoint/สิทธิ์; `APP-CSC-D-S01` พิสูจน์ตัวคัด/เลขคณิตด้วยผลรันและกรณีผิด; `APP-CSC-D-E01` รักษา unknown/rights และไม่ยกระดับ local run เป็นผลสนาม; `APP-CSC-D-C01` ทวน issue/แก้/คืนฐานพร้อม retest. ดู [rubric](rubric.md).

1. เขียน **D-v0 interface** รับทุกคอลัมน์ของ `scenario.csv` พร้อมชนิด หน่วย required/unknown และ provenance. แยก `horizontal_frame=LOCAL-XY-v1` (เมตรท้องถิ่น), `vertical_datum=LOCAL-V-A/B` (ไม่มี transform), `tide_stage` และ `tide_level_m=unknown`. ห้าม parse unknown เป็น 0 หรือใช้ NOAA VDatum กับรหัสสมมติ. ออก output ที่มี source key + `source_row`, rule/model revision, raw delta, ขอบคำนวณแบบจำกัด, status/reason/next_check และสิทธิ์.
2. ตั้ง gate แบบ fail closed: key ซ้ำ/เวลาไม่มี offset/เวลา receive ก่อน observe/หน่วยผิด → reject or hold พร้อมเหตุ; คู่ไม่มี footprint หรือ x → no arithmetic; datum/tide mismatch หรือ checkpoint ไม่พอ → HOLD ข้อสรุป. CHK1 เป็น residual x ใน horizontal frame เดียว แต่ delta +0.50 ไม่ใช่ค่าปรับ x ของทุก zone. GCP1 เป็น input ของ model ไม่ใช่ validation. ห้าม export คำว่า “erosion” หรือ “safe” จาก `expected_status`.
3. รัน matrix ที่มีอย่างน้อย: 12 แถวเดิม; สลับ datum/น้ำแบบผิด; B1 x=`unknown`; CHK2-E1 หาย; GCP1 ถูกปลอมเป็น checkpoint; `0.40` เป็น `0` หรือหน่วยผิด; เวลาไร้ offset; revision ใหม่/duplicate key; epoch สลับ; offline/retry และการส่งออกเกินสิทธิ์. สำหรับ baseline ทวน A `−3.00`, C `−1.50`, CHK1 `+0.50`, 5 แถว HOLD, B ไม่มีค่า. เทียบ actual ต่อ `expected.csv` พร้อม input/rule hash, command, Python/runtime version, เวลา, exit status และ diff. **การเขียน test plan อย่างเดียวไม่ผ่าน S01**.
4. เก็บแผน rollback/replay: baseline version, trigger เมื่อ QA หรือสิทธิ์ผิด, owner ของการคืน, state ของ package ที่ส่งไปและวิธีแจ้งผู้รับเมื่อมีผลผิด. ทดสอบคืนรุ่นแล้ว HOLD ยังอยู่สำหรับ datum/tide/coverage/CHK. ให้ reviewer ทักอย่างน้อยสองประเด็น เก็บคำตอบ/เหตุแก้ D-v1 และ retest; ถ้าไม่มี reviewer ให้ `awaiting_review` ไม่แต่งการทวน.

สคริปต์ `scripts/verify-coastal-change-fixture.py` ใน repository เป็นเพียง **local_author_run ของผู้เขียน** เพื่อทวนชุดแจก ไม่ใช่โค้ด/ผลรันผู้เรียน. ผู้เรียนอาจใช้หลักตรวจเดียวกัน แต่ต้องส่งคำสั่ง ผลจริง และ diff ของตนแยก. ไม่มี WebODM/อากาศยาน/VDatum ไทย/ข้อมูลสนามที่รันในกรณีนี้.
