ใน CLAUDE.md ของเว็บนี้ ผมเขียนไว้ว่าห้ามใช้ migrate:fresh agent ทำตามเกือบทุกครั้ง แต่คำว่าเกือบก็พอให้ฐานข้อมูลหายได้ guideline จึงเป็นแค่คำแนะนำ ส่วนเรื่องที่พลาดแล้วเสียหายต้องกันไว้ด้วยสิ่งที่ไม่ต้องพึ่งความจำของ agent
ผมแบ่งรั้วเป็นสี่ชั้น เรียงจากใกล้ตัว agent ที่สุดไปถึง production
| ชั้น | กันอะไร | ทำงานเมื่อไหร่ |
|---|---|---|
| test | โค้ดที่ทำงานผิด ฐานข้อมูลที่โดนล้าง | agent รันเองระหว่างทำงาน |
| hook | โค้ดที่ไม่เป็นระเบียบ คำสั่งที่อันตราย | ก่อนรันคำสั่ง และทุกครั้งที่ agent จบงาน |
| CI | ทุกอย่างที่หลุดจากสองชั้นแรก | ทุก push ก่อน deploy |
| สิทธิ์ | การเขียนข้อมูลบน production, secret | ตลอดเวลา |
test ต้องเร็วพอให้ agent รันเองทุกครั้ง
agent จะรัน test บ่อยแค่ไหนขึ้นกับว่า test ใช้เวลานานเท่าไหร่ ถ้ารันทีละหลายนาที agent ก็รันน้อยลง หรือรันแค่บางไฟล์แล้วบอกว่าผ่าน
ผมจัดฐานข้อมูลสำหรับ test ด้วย snapshot ที่ commit ไว้ และ DatabaseTransactions แทนการรัน migration ใหม่ทุกครั้ง แล้วรัน test แบบขนาน ส่วนผลของ test ที่ยาว Laravel PAO ย่อให้ agent อ่านได้โดยไม่เปลือง context
โปรเจกต์ของผมสั่ง DB::prohibitDestructiveCommands() ไว้ทุก environment ตามค่าที่ตั้งตั้งแต่วันแรก คำสั่งอย่าง migrate:fresh จะแค่เตือนแล้วจบโดยไม่แตะฐานข้อมูล ถึง agent จะลืมกฎก็ล้างฐานข้อมูลไม่ได้
hook จัดโค้ดให้ทุกครั้งที่ agent จบงาน
hook ของ Claude Code คือคำสั่งที่เราตั้งให้รันเองตามจังหวะ เช่น ก่อน agent รันคำสั่ง หรือตอน agent จบงานแต่ละรอบ ผมตั้งไว้สามตัว
{
"hooks": {
"Stop": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/laravel-quality.sh" }] }],
"PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/block-broad-kill.py" }] }],
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/session-status-reminder.sh" }] }]
}
}
ตัวที่ช่วยมากที่สุดคือ hook ตอนจบงาน ทุกครั้งที่ agent แก้ไฟล์เสร็จหนึ่งรอบ hook จะรัน Rector แล้ว Pint กับไฟล์ PHP และ ESLint แล้ว Prettier กับไฟล์ JS เฉพาะไฟล์ที่ session นั้นแก้ และเฉพาะโปรเจกต์ที่มีไฟล์ตั้งค่าของเครื่องมือนั้น เรื่องสไตล์ที่เคยต้องเขียนเป็นกฎยาว ๆ ก็มาอยู่ตรงนี้แทน รายละเอียดของเครื่องมือแต่ละตัวอยู่ในโพสต์เรื่อง lint, formatter และ static analysis
hook ปฏิเสธคำสั่งที่พังทั้งเครื่อง
hook ก่อนรันคำสั่งผมตั้งขึ้นหลังเหตุการณ์หนึ่งในเดือนตุลาคม 2569 agent จะหยุด process ที่ค้างอยู่ตัวเดียว แต่สั่ง pkill -f ด้วยคำค้นสั้น ๆ คำว่า cat บน macOS -f จับคำนี้ในทุก path ที่มีคำว่า Application, Location หรือ Notification ผลคือแอปราว 80 ตัวปิดพร้อมกัน ทั้งเบราว์เซอร์ LINE และตัวแอป Claude เอง ผมเห็นเหมือน Mac ปิดตัวเอง
เรื่องนี้เกิดสองครั้ง ตอนนี้ hook ปฏิเสธ pkill, killall และ kill แบบกว้างทุกตัวในทุกโปรเจกต์ agent ต้องหา PID ที่แน่นอนแล้วสั่ง kill ทีละตัว
Matt Pocock มี skill ที่ตั้ง hook แบบเดียวกันกับคำสั่ง git ที่ย้อนไม่ได้ อย่าง git push --force, git reset --hard หรือ git clean ถ้าเพิ่งเริ่มตั้ง hook กันคำสั่งอันตราย ชุดนี้เป็นจุดเริ่มที่ดี
CI เป็นด่านสุดท้ายก่อน deploy
ทุก push ต้องผ่าน GitHub Actions ก่อน deploy ใน CI มี test ทั้งชุด Pint, Rector, ESLint และ Prettier เฉพาะไฟล์ที่เปลี่ยน PHPStan ทั้งโปรเจกต์ และ gitleaks ที่หา secret ที่หลุดเข้า commit
ทั้งผมและ agent ไม่ deploy จากเครื่องตัวเอง ทางเดียวที่โค้ดขึ้น production ได้คือผ่าน CI ถ้า agent พลาดอะไรที่ hook และ test ในเครื่องไม่จับ CI จะจับได้อีกรอบ และ agent ที่ push ต้องเฝ้า CI จนผ่าน ไม่ใช่ push แล้วจบ
Superpowers มี skill ชื่อ verification-before-completion ที่ห้าม agent บอกว่างานเสร็จหรือ test ผ่าน ถ้ายังไม่ได้รันคำสั่งตรวจในรอบนั้นจริง ๆ ปัญหาเดียวกับที่ CI ของผมกันไว้ คือ agent ที่บอกว่าผ่านทั้งที่ยังไม่ได้รัน
agent อ่าน production ได้ แต่เขียนเองไม่ได้
agent ช่วยไล่ปัญหาบน production ได้ดีมาก ถ้าเห็นข้อมูลจริง แต่ผมไม่อยากให้ agent มีสิทธิ์เขียน
- ฐานข้อมูล production agent ต่อผ่าน SSH tunnel ด้วย user ที่อ่านได้อย่างเดียว เล่าไว้ในวิธีให้ AI อ่านฐานข้อมูล production อย่างปลอดภัย
- คำสั่งบนเซิร์ฟเวอร์ อ่าน log และดูไฟล์ได้เอง แต่การเขียนหรือรัน artisan ที่เปลี่ยนข้อมูล ต้องถามผมในแชทก่อนทุกครั้ง
- secret อย่าง API key ไม่ผ่านแชทเลย ผมพิมพ์ใน terminal ที่ซ่อนข้อความ ค่าเก็บใน Keychain ของ macOS แล้วส่งเข้าคำสั่งเป็น environment variable agent ใช้ได้โดยไม่เห็นค่า ส่วน
.envของ production เข้ารหัสเก็บไว้ใน git
รั้วแทนการอ่านทุกบรรทัด
Jason McCreary เล่าไว้ในสี่ขั้นที่เขาปล่อยงานให้ AI agentว่าสิ่งที่ทำให้เขาเลิกรีวิวโค้ดได้ คือรั้วที่ตั้งไว้ตั้งแต่ก่อนมี AI ของผมก็คล้ายกัน ส่วนที่ต่างคือรั้วหลายตัวของผมเกิดขึ้นหลังมี AI เพราะ agent ทำบางอย่างที่คนไม่ค่อยทำ อย่างสั่ง pkill แบบกว้าง หรือบอกว่า test ผ่านทั้งที่รันไม่ครบ
ถ้าจะเริ่มตั้งรั้วเอง ผมว่าเริ่มจากเรื่องที่พลาดแล้วย้อนไม่ได้ก่อน คือฐานข้อมูล การ deploy และ secret แล้วค่อยเพิ่มตัวอื่นทุกครั้งที่ agent ทำอะไรที่ไม่อยากให้เกิดซ้ำ






