# ชุดฝึก S1 น้ำท่วมและการส่งข้อมูลเพื่อการช่วยเหลือ

**ระดับหลักฐาน:** `scenario.csv` = `synthetic_training_data`; `expected.csv` = `expected_training_result` ตามกฎ `CSF-RULE-v1`. ไม่มีภาพต้นทาง, พิกัดโลก, ผลบิน, ผลพบคน, ผลผู้เรียนหรือผลตรวจภาคสนาม. ภาพประกอบบทเป็นภาพสร้างเพื่อสอนและไม่ใช่หลักฐานของแถว CSV. ผู้ตรวจเฉพาะสาขา `not_assigned`; งานสนาม `pending_field_review`.

เปิดไฟล์ CSV ด้วย UTF-8 และกำหนดทุกคอลัมน์เป็นข้อความก่อนนำเข้าโปรแกรมตารางคำนวณ เพื่อรักษา offset, `unknown`, ศูนย์นำหน้า และ `v0/v1`. เก็บ `scenario.csv` ต้นฉบับแบบอ่านอย่างเดียว. ชุดนี้มี **7 ไฟล์**: `scenario.csv`, `expected.csv`, `readme.md`, `beginner.md`, `operator.md`, `developer.md`, `rubric.md`. อ่านบทที่ [/knowledge/drone-applications/case-studies/flood-response/](https://drone.pk-research.work/knowledge/drone-applications/case-studies/flood-response/).

## คำขอและขอบเขตสมมติ

`request_id=REQ-CSF-01`. ผู้ประสานเหตุสมมติ `INCIDENT` ต้องเลือก **จุด/พื้นที่ที่จะขอผู้มีหน้าที่ตรวจต่อ** ภายใน `2026-10-13T10:40:00+07:00`. ส่งสถานะรอบแรกภายในเวลานั้น โดยใช้ snapshot ที่รับข้อมูลไม่เกิน `2026-10-13T10:20:00+07:00` (`cutoff`). `PUBLIC` เป็นผู้รับสรุปที่ต้องลดรายละเอียดตามสิทธิ์; `INCIDENT` เป็นผู้รับรายการจำกัดสิทธิ์. ทั้งสองเป็นบทบาทสมมติ ไม่ใช่หน่วยงานจริง. พื้นที่ `Z-A` ถึง `Z-D` เป็นเพียงรหัสช่องกระดาษ ไม่มีรูปทรง ขนาด พิกัด ระดับน้ำ หรือระบบอ้างอิงโลก. `local_frame=CSF-PAPER-v1`; datum/CRS/epoch โลก = `unknown`.

คำตอบที่รับได้คือรายการ “เสนอให้ตรวจต่อ” กับเหตุ, ประวัติแถวและข้อค้าง, ผู้รับผิดชอบ และสถานะส่งต่อ. ห้ามแปล `candidate_check` เป็น “มีน้ำแน่”, “พบคน”, “ถนนผ่านได้” หรือ “ปลอดภัย”. ไม่มีค่าความแม่นยำ/ความครอบคลุมร้อยละที่คำนวณได้.

## พจนานุกรมคอลัมน์ `scenario.csv`

สิบคอลัมน์แรกคงลำดับตาม `docs/drone-applications-case-study-contract.md` ใน repository. ค่าข้อความ `unknown` คือข้อมูลที่ไม่ทราบ ไม่ใช่ศูนย์หรือช่องให้เติมเอง.

| คอลัมน์ | ความหมายและขอบค่า |
|---|---|
| `scenario_id` | `TRAIN-CSF-01` ทุกแถว; รหัสแบบฝึก ไม่มีสถานที่จริง |
| `record_id` | รหัสสิ่งสังเกตเชิงตรรกะ `R01`–`R11`; `R01` มีประวัติสองรุ่น, `R11` เป็นคีย์ซ้ำผิด |
| `observed_at` | เวลาเกิดข้อสังเกต ISO 8601 พร้อม offset; `unknown` ที่ R04 หมายถึงไม่มีเวลา ห้ามใช้ `received_at` แทน |
| `source` | `SYN-RGB`, `SYN-SAT`, `SYN-GROUND` เป็นแหล่งแต่งขึ้นทั้งสิ้น; ไม่มีภาพดาวเทียม/โดรน/รายงานภาคพื้นแนบ |
| `revision` | `v0/v1`; R01v1 แก้คำอธิบายจาก v0 และ supersede v0 เฉพาะในโจทย์; เก็บทั้งคู่ |
| `coverage` | `partial`=เห็นเพียงบางส่วน, `point`=รายงานจุด, `none`=ไม่มีส่วนใช้ได้; ไม่มีพื้นที่/ตัวหารให้คิดเปอร์เซ็นต์ |
| `uncertainty` | ทุกแถว `unknown` เพราะไม่มีวิธีวัดเชิงปริมาณ; ไม่เติม 0 |
| `status` | `unverified`, `stale`, `superseded`, `conflict`, `hold` เป็นสถานะที่ผู้แต่งกำหนด; `conflict` คือดูเหมือนขัดกันแต่ยังไม่มี footprint พอเทียบจุด ไม่ใช่ field verification |
| `rights` | `incident_only` ส่งรายการให้ INCIDENT, `restricted` จำกัดรายละเอียดสัญญาณ R07 ให้ INCIDENT, `unknown` พักการส่งออกตามกติกา; ไม่มีสิทธิ์ส่ง raw row ต่อ PUBLIC ในชิ้นงานฝึก |
| `recipient` | `INCIDENT`, `PUBLIC` หรือ `unknown`; ผู้รับ unknown ต้องพัก. ชื่อบทบาทไม่แปลว่ารับไฟล์แล้ว |
| `zone_id` | รหัสช่องกระดาษ Z-A–Z-D ไม่ใช่พิกัดหรือ polygon |
| `observation` | คำบรรยายสั้นของสิ่งที่รายงาน; `possible_person_signal_unconfirmed` ไม่ใช่ผลพบคน |
| `received_at` | เวลาข้อมูลเข้าชุดโจทย์ ไม่ใช่เวลา `received` ของผู้รับรายงาน |
| `related_record_id` | R05/R06 ชี้คู่ที่ดูเหมือนขัดกันใน Z-B แต่ไม่มี footprint พอพิสูจน์ว่าเป็นจุดเดียวกัน; R01 ชี้ประวัติตน; `unknown` คือไม่มีความสัมพันธ์ที่ทราบ |

คีย์ตรรกะคือ `(scenario_id,record_id,revision)`; R11v0 ปรากฏสองบรรทัดเหมือนกันและ **ทั้งคู่ต้องพัก**. `expected.csv` เพิ่ม `source_row` เป็นเลขบรรทัดจริงรวม header เพื่อชี้สองบรรทัดที่ใช้คีย์เดียวกัน โดยไม่เปลี่ยนนิยามคีย์. `input_revision` คือรุ่นต้นทาง, `rule_revision= v1` คือรุ่นกฎนี้, `expected_status` คือ disposition, `reason` คือเหตุ, `next_check` คืองานต่อ; ไม่มีแถว expected ที่เป็นผลรัน.

ไฟล์ต้นฉบับสังเคราะห์นี้เผยแพร่ให้ดาวน์โหลดได้เพื่อการเรียน. `rights` เป็น **กติกาการจัด package ในแบบฝึก** ไม่ใช่มาตรการควบคุมการเข้าถึงไฟล์ดาวน์โหลดหรือหลักฐานว่ามีข้อมูลบุคคลจริง. ผู้เรียนต้องแสดงการกรอง output ตามบทบาท แม้ทุกคนอ่าน fixture ต้นฉบับได้.

## กฎ `CSF-RULE-v1` สำหรับ expected

ประเมินทุกบรรทัดต้นทางโดยไม่ลบหรือรวมแถว. ลำดับเหตุหลัก: **คีย์ซ้ำ → superseded → เวลาใช้ไม่ได้/เข้าหลัง cutoff → คู่ขัดแย้ง → เก่า → ไม่มี coverage → สิทธิ์/ผู้รับไม่ชัด → candidate_check**. หากมีหลายปัญหาให้บันทึกทั้งหมดในข้อค้าง แม้ expected ให้เหตุหลักหนึ่งค่า.

1. คีย์ซ้ำทุก occurrence = `hold_duplicate`; R01v0 เป็นประวัติ `superseded`, ไม่ใช่ duplicate. รุ่นใหม่ต้องมีประวัติการแทนที่ที่อธิบายได้; หากไม่ชัดให้ `hold_conflict` แทนการเลือกเลขรุ่นสูงเอง.
2. เวลา `observed_at` และ `received_at` ต้องมี offset, ไม่เป็น `unknown`, `observed_at ≤ received_at ≤ cutoff`. แถวหลัง cutoff = `hold_late` สำหรับฉบับถัดไป; ห้ามใช้เวลา ingest เป็นเวลา observe.
3. freshness สอน = อายุ 0–45 นาที **รวมขอบ** วัด `cutoff - observed_at`. เก่ากว่านั้น = `hold_stale`; ค่านี้เป็นกติกาแบบฝึก ไม่ใช่เกณฑ์ฉุกเฉินจริง. R03 อายุ 89 นาที.
4. `coverage=none` ต้องพัก. `partial` หรือ `point` ใช้เพียงเสนอการตรวจ ไม่อนุมานครอบคลุมทั้งช่อง. R05/R06 อยู่ Z-B และคำบรรยายดูเหมือนขัดกัน แต่ไม่มี footprint/พิกัดย่อยพิสูจน์ว่าเป็นจุดเดียวกัน จึง `hold_conflict` เพื่อขอ footprint และการทวนอิสระ ไม่ตัดสินว่าข้อมูลหนึ่งผิด.
5. `rights=unknown` หรือ `recipient=unknown` ต้องพักการส่งออก. `incident_only/restricted` ห้ามส่ง raw row ให้ PUBLIC. R07 เป็น `candidate_check` ใน package INCIDENT เท่านั้นพร้อมคำว่าไม่ยืนยัน; PUBLIC ได้เพียงสรุปว่า “มีข้อค้างที่ผู้รับผิดชอบกำลังทวน” หากผู้รับอนุมัติข้อความนั้น.
6. `candidate_check` แปลว่าข้อมูลพอ **จัดคิวตรวจต่อ** ภายใต้สิทธิ์สมมติ; ไม่รับรองข้อสังเกต. ผล expected คือ R01v1, R02v0, R07v0 จำนวน 3 บรรทัด; อีก 10 บรรทัดเป็นประวัติ/hold. Z-D ไม่มี candidate ใช้ได้.

## ร่องรอยการตรวจ

ค่าคาดหวังตามไฟล์เป็นงานเขียนของผู้แต่ง ไม่ใช่ผลผู้เรียน. การตรวจไฟล์ในเครื่องให้บันทึกเวลา, คำสั่ง, รุ่น Python/โปรแกรม, SHA-256 ของ `scenario.csv` และ `expected.csv`, exit status และความต่างที่พบใน **บันทึก local_author_run แยกต่างหาก**; ไม่แก้ `expected.csv` ให้ตามผลโปรแกรมที่ผิด. เมื่อไม่มี log ให้ `local_author_run=NOT_RUN`. `learner_result=NOT_RUN` และ `field_verified_result=NOT_RUN` จนเกิดหลักฐานจริง; B/O/D = 0/0/0. ผู้ทวนเฉพาะสาขา `not_assigned`, `pending_field_review`.

ใช้ `python -c "import hashlib,pathlib; [print(p.name,hashlib.sha256(p.read_bytes()).hexdigest()) for p in map(pathlib.Path,('scenario.csv','expected.csv'))]"` ในโฟลเดอร์ชุดฝึก หรือ `sha256sum scenario.csv expected.csv` บน Linux. Hash ใช้ยืนยันว่าไฟล์ที่ตรวจคือฉบับเดียวกับที่ผู้เรียนเปิด ไม่ใช่รับรองความจริงของข้อสังเกต. เก็บไฟล์ต้นฉบับ/รุ่น rule แล้วทำงานในสำเนา.
