# S5-D · นักพัฒนา: สัญญาข้อมูลคำขอและหลักฐานรับมอบ

**ก่อนทำ:** อ่าน [M09](/knowledge/drone-applications/field-logistics/), [M10](/knowledge/drone-applications/communications-support/), [รวมระบบ](/knowledge/integration/) และ [ทดสอบ](/knowledge/testing/). K ต้องรู้ composite key, event/revision และความหมายสถานะ; S ต้องอ่าน CSV และรัน/บันทึก verifier; E ไม่แต่งผลจริงหรือเอา `sent` แทน `received`; C ต้องเก็บ change/retest/rollback. หากยังไม่พร้อม ให้ทำตัวอย่าง duplicate ของ MSG-A ด้วยมือก่อน

**โจทย์:** เสนอ data contract สำหรับการอ่าน [scenario.csv](scenario.csv) 16 แถวและออก expected ตาม [CSL-RULE-v1](readme.md). ไม่มีระบบ CPX, อุปกรณ์หรือข้อมูลภาคสนาม. [expected.csv](expected.csv) เป็น oracle ของผู้เขียน ไม่ใช่ผลรันของผู้เรียน

1. เขียน D-v0 ระบุ 19 input fields, ชนิด/enum/หน่วย/ค่า unknown, composite key `(scenario_id, record_id, revision)` กับ `source_row` สำหรับ duplicate, แยก request/stock/allocation/recipient/airspace/message/goods receipt
2. ระบุกฎ version: Q-A/v0→v1, STOCK-A/v0→v1, MSG-A/v0 ซ้ำสองแถวและ v1 ที่ส่งแล้ว; ไม่ลบ history และไม่ถือ retry เป็น receipt. วางกฎหมดอายุ STOCK-A เวลา 09:00 และห้าม PLAN-A 09:05 ใช้ stale confirmation
3. ทำ test matrix อย่างน้อย normal, unknown recipient, requested-only stock, duplicate, stale confirmation, offline queued, sent-without-received, blank goods receipt, cross-request double allocation และ rollback. ระบุ expected outcome และ evidence level ของทุก test
4. หากรันโค้ดจริง เก็บ command, เวลา, exit, input SHA-256, raw output และ diff กับ expected; หากไม่ได้รันให้ `actual=NOT_RUN` และอย่าให้ `APP-CSL-D-S01` ผ่าน. ทดสอบ mutation ที่เปลี่ยน `valid_until`, `recipient` และ revision แล้วคืน baseline พร้อมหลักฐาน retest
5. รับคำทักอย่างน้อยสองข้อ ทำ D-v1 และ issue/change record ที่มี owner, เหตุแก้, version และผล retest. Contract ต้องไม่สร้างสถานะ `authorized`, `delivered`, `accepted` จากข้อมูลสอน

**ชิ้นงาน:** D-v0/v1, schema/contract, test matrix, actual-run record ถ้ามี, mutation/rollback log. ใช้ [rubric](rubric.md) ตรวจ `APP-CSL-D-K01/S01/E01/C01`. ผู้เขียนรัน verifier ในเครื่องแยกจากผลผู้เรียน; P5 ยัง `NOT_RUN`
