# งานตั้งเวลา — JUJU 0.6.0

JUJU มี scheduler ภายใน ใช้คำสั่ง `juju schedule` หรือ `juju cron`
ไม่ติดตั้ง system cron, launchd หรือบริการพื้นหลังให้อัตโนมัติ
**ต้องเปิด `juju` / `juju start` แบบ HTTP ในโปรเจกต์นั้นอยู่**
STDIO ให้เสนอ/จัดการตารางได้ผ่าน IPC แต่ไม่เริ่ม scheduler
เมื่อเครื่องหลับ เซิร์ฟเวอร์หยุด หรือสลับไปอีกโปรเจกต์ จะไม่รันงานของโปรเจกต์เดิม

## การอนุมัติงานตั้งเวลา

การใช้งาน MCP ปกติใช้สิทธิ์ connection และ trust mode ของโปรเจกต์
ส่วนตารางต้องได้รับการอนุมัติแยกโดยเจ้าของ ตารางเริ่มเป็น pending เสมอ ไม่มี MCP tool สำหรับ approve
แม้ใช้ trusted/bypass ก็ไม่ทำให้ pending table รันเอง

ตารางผูกกับ root identity, คำสั่ง, cwd, cron, timezone, timeout,
sandbox/network, expiry และ security policy ขณะเสนอ โดยมี SHA-256 digest
การเปลี่ยนรายละเอียดให้ยกเลิกของเดิมแล้วเสนอและอนุมัติใหม่ ไม่มี silent edit

## ตัวอย่าง: รัน test วันละครั้ง

ใน terminal ของโปรเจกต์ ตั้ง saved trust ก่อนเสนอ:

```bash
juju trust --mode trusted --yes
juju
```

เปิด terminal อีกหน้าในโปรเจกต์เดียวกัน แล้วสร้าง pending schedule:

```bash
juju schedule create \
  --name "Daily tests" \
  --command "npm test" \
  --cron "0 9 * * *" \
  --timezone "Asia/Bangkok" \
  --expires "2026-09-17T23:59:00+07:00"
```

**เปลี่ยนวันหมดอายุเป็นวันในอนาคตไม่เกิน 30 วันจากวันนี้** ตัวอย่างใช้วันของ release
เลือกเวลาจริงของคุณ Cron มี 5 ช่อง: นาที ชั่วโมง วันที่ เดือน วันในสัปดาห์
ใช้ cron-parser 5.10.0 กับ IANA timezone; ไม่รองรับ seconds field ใน JUJU

ค่าเริ่มต้น sandbox ต้องเปิดและปิด network; ถ้าเครื่องไม่มี sandbox จะไม่รันแบบไร้ sandbox แทน
งานติดตั้ง dependencies อาจต้อง `--network`
หากตั้งใจรันด้วยสิทธิ์ OS โดยไม่มี sandbox ให้ระบุ `--no-sandbox` ตอนเสนอ
shell และ package scripts สามารถรัน arbitrary code ได้; directory guard ไม่ใช่ sandbox

ตรวจเนื้อหาจริงก่อนอนุมัติ:

```bash
juju schedule show sched_ID
juju schedule approve sched_ID --digest sha256:DIGEST_FROM_REVIEW
juju schedule list
```

หรือเปิด Private config > **Scheduled commands** ตรวจคำสั่ง พาธ เวลา และ expiry
ติ๊กยืนยันว่าอนุญาตแม้ไม่ได้เปิดแชต แล้วกด **อนุมัติงานตั้งเวลา**
ต้องมี saved trust เป็น trusted; `juju --bypass` อย่างเดียวไม่ใช่ standing schedule consent
ถ้าเปลี่ยน trust หลังเสนอ ต้องเสนอใหม่เพราะ digest ผูก policy version

AI ที่มีสิทธิ์ workspace และ exec scope เสนอได้ผ่าน `schedule_propose`
ส่ง spec เดียวกันรวม workspaceId/workspaceEpoch
แต่ผลยัง pending จนเจ้าของอนุมัติ ถ้า OAuth grant หรือ client exec ACL ของผู้เสนอ
ถูกถอน ตารางจะไม่เริ่มรอบถัดไป และเปลี่ยนสถานะเป็น paused เมื่อถึงรอบนั้น
ตารางที่สร้างโดย local CLI ใช้ owner authority ไม่ผูก OAuth ของแชต

## ดูผลและหยุด

```bash
juju schedule history sched_ID
juju schedule revoke sched_ID
```

history คืนกำหนดเวลา, launch/skip status, jobId และข้อมูล job ที่บันทึกจริง
รวม exitCode/status ถ้ามี สำหรับ log ขณะ process ยังเปิด ใช้ job_output ผ่าน MCP
ภายใต้สิทธิ์อ่านของ connection; logs มีเพดานตามปกติ ไม่อ้างว่าเก็บ log ครบตลอดไป
หลัง restart history/exitCode ยังอยู่ แต่ตัวอ่าน spool เดิมไม่ได้ restore ในรุ่นนี้

revoke ปิดรอบอนาคตและยกเลิก owned running job ของตารางนั้น
ถ้าต้องปิดทั้งหมดใช้ `juju kill` ซึ่งหยุด server/jobs แต่เก็บตารางและ OAuth ไว้
หากต้องการไม่ให้ตารางกลับมารันหลังเปิดใหม่ ต้อง revoke ตารางก่อน

## การเริ่มระบบใหม่และความซ้ำ

- SQLite เก็บ pending/approved/paused/revoked, spec/digest, next due และประวัติ
- ก่อน spawn จอง (scheduleId, dueAt) ด้วย transaction และ unique key
- ถ้า process crash หลังจอง ไม่รันรอบที่สถานะไม่แน่นอนซ้ำ
  history อาจคง `claimed`; job เดิมอาจเป็น interrupted_on_restart
- รอบที่ผ่านไประหว่างปิดระบบหรือช้ากว่า 60 วินาทีจะถูก skip ไม่ catch up
- งานเดียวกันรอบก่อนยังรันอยู่: skip รอบใหม่ ไม่เข้าคิวซ้อน
- เวลาเครื่องถอยหลังไม่ทำให้ due slot เดิมรันซ้ำ; ไม่รับประกัน real-time scheduling
- มี job concurrency, runtime และ log caps ของ JUJU; launch ที่ติดเพดานไม่ retry อัตโนมัติ
- เปลี่ยน root identity หรือ security policy: pause ต้องเสนอและอนุมัติใหม่
- ตารางหมดอายุ: หยุดรอบใหม่และ cancel งานของตารางที่ยังรันอยู่

**Digest ของคำสั่งไม่ได้ตรึงโค้ดทั้งโปรเจกต์** `npm test` ใช้ scripts, tests และ
installed dependencies ที่มีอยู่ ณ เวลารัน รุ่นนี้ไม่มี revision-pinning mode
ใช้กับโปรเจกต์ที่ไว้ใจ หรือให้เจ้าของกำหนด workflow ที่ตรึง revision เอง

## สถานะการทดสอบ

มี automated fixture สำหรับ approval/digest, execution จริง, overlap, revoke,
expiry, restart/missed/uncertain ticks, shared-SQLite duplicate claim,
policy/grant changes และ invalid cron/timezone/path
การรันหลายวันจริง, DST ใน timezone ต่าง ๆ และการพักเครื่อง macOS จริงเป็น
MANUAL_NOT_RUN; ดู TEST_REPORT และ MANUAL_ACCEPTANCE
