# S3 · ใบงาน D นักพัฒนา: สัญญาชุดกล้องและการคืนฐาน

เวลาแนะนำ 90–120 นาที · ใช้ CSV แต่งในเครื่อง · ชิ้นงาน data/camera contract, test ledger และ change/rollback record. ไม่มีไฟล์ภาพจริง จึงทดสอบ parser และกฎ metadata เท่านั้น; ห้ามอ้างว่าทดสอบ optical performance, ระบบอากาศยานหรือภาคสนามแล้ว.

## ความพร้อมก่อนเริ่มและ KSEC

- **K ก่อน:** อ่าน ISO time offset, composite key, `unknown`, version และหน่วยได้; ทวน [C01 ชุดกล้อง](/knowledge/drone-applications/cases/inspection-camera/) และ [การทดสอบ](/knowledge/testing/). **K ที่ฝึก:** อธิบาย schema input/output/error, ความต่าง CAM-A/CAM-B และเส้นแบ่งระบบ/นักบิน/ผู้ตรวจ (`APP-CSS-D-K01`).
- **S ก่อน:** แยก expected จาก actual และทำสำเนา baseline. **S ที่ฝึก:** ทดสอบ baseline/invalid/boundary/before–after/rollback โดยเก็บ hash คำสั่ง เวลา exit และ diff ที่รันจริง (`APP-CSS-D-S01`).
- **E ก่อน:** ติดป้าย synthetic/author/learner/field และเช็กสิทธิ์ส่งออก. **E ที่ฝึก:** ปฏิเสธ claim โครงสร้างและการแชร์ rights unknown ไม่เติม calibration ที่หาย (`APP-CSS-D-E01`).
- **C ก่อน:** รับ issue พร้อมหลักฐานและทำ review log. **C ที่ฝึก:** แก้แล้วทวนกรณีผิด คืน CAM-A baseline และแสดงผลหลังคืน (`APP-CSS-D-C01`).

## สัญญาอินเทอร์เฟซที่ต้องเขียน

Input ใช้ header 24 ช่องของ `scenario.csv` และคีย์ `(scenario_id,record_id,revision)`, เก็บ `source_row` ตามบรรทัดจริง. ห้าม normalize `unknown` เป็น 0 หรือ `none`. Contract กล้องมี `camera_config`, `camera_calibration`, ช่วงรุ่น/เวลาที่ใช้, การจับคู่ asset/member/view/angle/scale และ provenance ของภาพต้นทาง **ถ้ามีในระบบจริง**. ใน fixture นี้มีเพียงคำบรรยาย `SYN-PHOTO`, จึงต้องแสดง `image_binary = NOT_PROVIDED`. Output อย่างน้อย `source_row`, `rule_revision`, `expected_status`, `reason`, `next_check`, `evidence_level=synthetic_training_data` และ `claim_limit`. Error ต้องเก็บแถวต้นทางและเหตุ เช่น duplicate key, observed time missing/inverted, camera config unknown, rights unknown, calibration unknown, bad recipient. ไม่มีผล "safe" ใน enum.

## ทดสอบการเปลี่ยนและคืนฐาน

1. ทำสำเนา `scenario.csv`/`expected.csv` เป็น baseline; บันทึก SHA-256 และผล parse 14 แถว. ผลที่ระบุใน expected เป็น oracle ของโจทย์ ไม่ใช่ actual.
2. รันกฎ `CSS-RULE-v1` กับทุก source row และเทียบ exact status/reason; บันทึก script/commit หรือไฟล์กฎ, command, timestamp, exit, raw output, diff. หากยังไม่รันให้ actual เป็น `NOT_RUN`.
3. ทดสอบ R08/v0 → v1: v0 ต้องคง history, v1 ชัดขึ้นแต่ `CAM-B/unknown` ยัง `hold_camera_change`. R11/CAM-A ก่อนกับ R12/CAM-B หลังห้ามรายงานการเปลี่ยนขนาด/สภาพจากภาพเพียงอย่างเดียว.
4. Mutation: เปลี่ยน R03 เป็น `readable` ทั้งที่ light insufficient; ซ้ำ composite key; ลบ observed_at; ตั้ง received ก่อน observed; ลบ member/scale; เปลี่ยน `camera_calibration` เป็น `CAL-A-v1` โดยไม่ใส่หลักฐาน; rights unknown แล้ว export. ระบบต้อง HOLD หรือคืน error มีเหตุ ไม่ fallback เป็น accepted.
5. Rollback: คืน input และ config CAM-A สำเนาฐาน, รันซ้ำ 14 แถว, เปรียบ hash/ผลกับ baseline และตรวจว่า R08/v1/R12 ยัง HOLD เมื่ออยู่ในชุดข้อมูลเดิม. ถ้าระบบจริงแก้ metadata CAM-B แล้วต้องมีหลักฐาน calibration ใหม่และทดสอบใหม่; ห้ามเปลี่ยน expected เดิมเพื่อทำให้ผ่าน.

## บันทึกการแก้

ตารางขั้นต่ำ `issue_id | source_row | version_before/after | finding | owner | test_command | input_hash | exit | observed_result | expected_diff | reviewer_comment | rollback_trigger | rollback_result`. บันทึก `D-v0 → D-v1` และทวนกับ [rubric.md](rubric.md). โชว์ว่าการทดสอบ parser ผ่านไม่ใช่การรับรองกล้อง/ทักษะผู้ควบคุม/การวินิจฉัยวิศวกรรม. ผลผู้เรียนและภาคสนามยัง `NOT_RUN`.
