Tool: bash, bash_bg — รันคำสั่ง shell จริง ไม่ใช่ allow-list คำสั่งจำกัด

ภาพประกอบ: Tool: bash, bash_bg — รันคำสั่ง shell จริง ไม่ใช่ allow-list คำสั่งจำกัด

bash คือ tool หลักสำหรับงานระบบ: รันสคริปต์ ตรวจ process/disk/memory, ค้นหา, build และ test ส่วน bash_bg คือคู่หูสำหรับงานที่รันนานเกิน timeout ของ bash เอง สำหรับการเปลี่ยน Git metadata ให้ใช้ git ซึ่งมีขอบเขตแคบกว่า shell

ต่างจาก agent-lite ตรงไหน

bash ของ ENDEAVOR AGENT LITE ใช้ allow-list คำสั่ง เข้มงวด — อนุญาตแค่ ~20 คำสั่งอ่านอย่างเดียว (cat, find, grep, ls ฯลฯ) เพราะโมเดล 2B ที่ควบคุมมันไม่น่าเชื่อถือพอจะปล่อยอิสระ

bash ของ Endeavor Hands ไม่มี allow-list คำสั่งแบบตายตัว — เพราะ ChatGPT เป็นผู้ตัดสินใจเรียกคำสั่ง ไม่ใช่โมเดลขนาดเล็กในเครื่อง สิ่งที่ควบคุมแทนคือขอบเขตของผลกระทบ ผ่าน macOS sandbox-exec และตัวตรวจการลบไฟล์ รันคำสั่งไหนก็ได้ แต่ path ระบบและ path อ่อนไหวถูก deny, workspace กับ /tmp ถูก allow อย่างชัดเจน และ path อื่นที่ไม่ได้อยู่ใน deny-list ยังต้องถือว่าอยู่นอกการรับประกันเชิง allow-list

Sandbox profile: allow default, deny เฉพาะที่อันตราย

จากซอร์สโค้ดจริงใน _build_sandbox_profile():

(allow default)
(deny file-write*
  (subpath "/etc") (subpath "/usr") (subpath "/System") (subpath "/Library")
  (subpath "~/Desktop") (subpath "~/Documents") (subpath "~/Downloads")
  (subpath "~/.ssh") (subpath "~/.aws") (subpath "~/.gnupg") ...
)
(deny file-read* (subpath "~/.ssh") (subpath "~/.aws") (subpath "~/.gnupg") ...)
(allow file-write* (subpath "{workspace}") (subpath "/private/tmp"))
(allow file-read*  (subpath "{workspace}"))
(deny file-write-unlink (subpath "{workspace}"))

Policy เริ่มจาก allow default (ตรงข้ามกับ allow-list ของ agent-lite ที่เริ่มจาก deny) แล้ว deny การเขียนไปยัง path อันตรายและโฟลเดอร์ผู้ใช้ทั่วไป จากนั้นallow เขียน workspace กับ /tmp ต่อท้าย — เพราะ macOS sandbox profile ใช้กติกา last-match-wins กฎ allow ที่มาทีหลังจึงชนะกฎ deny ก่อนหน้าเฉพาะในขอบเขตที่ตรงกัน สุดท้ายมีกฎ deny file-write-unlink ปิดท้ายเฉพาะเจาะจงกับ workspace — แก้ไฟล์ในนั้นได้ แต่ลบไฟล์ในนั้นไม่ได้ แม้จะเขียนได้ก็ตาม (unlink เป็น operation คนละแบบจาก write) จึงต้องจำไว้ว่า sandbox นี้เป็น deny-list ไม่ใช่ allow-list ครอบจักรวาล

GUI scripting ผ่าน bash ถูกบล็อก — ใช้ computer แทน

osascript ที่เรียก System Events (GUI scripting) ถูก sandbox บล็อกโดยตั้งใจ — error code -10004 จะโผล่มาพร้อม hint อัตโนมัติจาก _classify_bash_error():

GUI scripting via osascript is blocked by this tool’s sandbox — use the computer tool for clicking/typing/keystrokes instead.

เหตุผลตรงตาม docstring ของ tool เอง: ❌ switch to Chrome → osascript keystroke/cmd+tab tricks ✅ → open -a "Google Chrome" (หรือใช้ computer) — เพราะ computer มี guardrail เฉพาะสำหรับ UI action (ปฏิเสธ password field, ปฏิเสธ action ที่ดูเหมือนลบ) ที่ osascript ผ่าน bash ไม่มี

คำสั่งระดับแอปที่ sandbox-safe และยังใช้ผ่าน bash ได้ตามปกติ: open -a "App", open <path|URL>, pbcopy/pbpaste, osascript -e 'display notification ...', ปรับ volume — เพราะเป็น one-shot ไม่ใช่การจำลองคลิก/พิมพ์แบบ interactive

แก้ปัญหาจากสัญญาณจริง ไม่ใช่เดาจากข้อความคำสั่ง

_classify_bash_error() แนบ hint ตามหลักฐานจริงจากผลรัน ไม่ใช่เดาจากคำในคำสั่ง (คอมเมนต์ในซอร์สบอกตรงๆ ว่า “a wrong hint is worse than no hint”):

  • returncode == 127 → “command not found — check spelling, or use an absolute path”
  • returncode == 126 → “permission denied executing that file”
  • error message มี Operation not permitted / Permission denied / Read-only file system → “write/access denied by the sandbox — only workspace/ and /tmp are writable”

bash_bg — งานพื้นหลังสูงสุด 5 งานพร้อมกัน

bash_bg มี 4 action: start (spawn ภายใต้ sandbox เดียวกับ bash, stdout/stderr redirect ไปไฟล์ log ใต้ Endeavor_Hands/work/, คืน job_id ทันทีไม่รอจบ), status (running/exited + log 2,000 ตัวอักษรล่าสุด), list, kill (ส่ง SIGTERM ก่อน แล้ว SIGKILL หลัง 3 วินาทีถ้ายังไม่ตาย) — จำกัดสูงสุด 5 job พร้อมกัน เหมาะกับ dev server (npm start, uvicorn), ดาวน์โหลดไฟล์ใหญ่, build/install ที่นานเกิน timeout ของ bash เดี่ยวๆ งานที่จบใน 2-3 วินาทีให้ใช้ bash ตรงๆ ไม่ต้องผ่าน bash_bg

Output cap และการกันสั่งซ้ำโดยไม่ตั้งใจ

ผลลัพธ์เกิน 10,000 ตัวอักษรถูกตัดและบันทึกฉบับเต็มเป็นไฟล์ใต้ Endeavor_Hands/work/ พร้อม marker [bash] truncated: ... บอก path ให้เปิดอ่านต่อ — marker วางไว้ต้นข้อความ (marker_first) เพื่อไม่ให้ชั้นตัดข้อความรอบสองของ MCP ตัด marker ทิ้งไปโดยไม่รู้ตัว ส่วนคำสั่ง echo ล้วนๆ ที่ไม่มี redirect/pipe/variable จะถูกกลืนเป็นผลลัพธ์ว่างเปล่าไปเลย — เพราะโมเดลมักใช้ echo "..." เป็นแค่ข้อความประกาศขั้นตอน ไม่ใช่คำสั่งที่ต้องเห็นผลจริง

ใช้ git แทน bash เมื่อจะเปลี่ยน repository

การรัน git status หรือ git diff แบบอ่านอย่างเดียวผ่าน bash ยังทำได้ แต่ add, commit และ push ควรใช้ git โดยตรง เพื่อให้ระบบตรวจ repo อยู่ใน workspace, รับ path แบบ explicit, ปิด hook/signing ที่ไม่จำเป็น และปฏิเสธ force-push/การลบ source file การแยกนี้ลดผลกระทบจาก shell ที่รันคำสั่งได้กว้างโดยไม่ทำให้ความสามารถตรวจ repository หายไป

ทำไมเรื่องนี้ถึงสำคัญ

bash คือ tool ที่เสี่ยงที่สุดใน Endeavor Hands เพราะรันคำสั่งอะไรก็ได้ตามตัวอักษร การออกแบบเลือกเปิดกว้างที่ระดับคำสั่ง (เพราะไว้ใจ ChatGPT มากกว่าที่ agent-lite ไว้ใจโมเดล 2B) แล้วปิดที่ระดับผลกระทบต่อไฟล์แทนผ่าน sandbox-exec ระดับ OS — เป็นจุดตัดสินใจด้านสถาปัตยกรรมที่ต่างจาก agent-lite โดยตรง ไม่ใช่แค่รายละเอียดย่อย

อ่านเพิ่มเติม

ความคิดเห็น

กำลังโหลดความคิดเห็น...