تصور کنید خط لولهی CI شما وضعیت «سبز» را گزارش میکند، اما عامل هوش مصنوعی در واقع حتی یک خط کد را هم اصلاح نکرده است. این کابوس هر توسعهدهندهای است. این شکست خاموش به این دلیل رخ میدهد که اکثر عاملها وقتی انسانی برای کلیک روی دکمهی «تأیید» حضور ندارد، بهصورت پیشفرض تمام درخواستهای ابزار (Tool Calls) را رد میکنند.
به نقل از مستندات Claude Code، اگر یک اجرای claude -p در محیط CI به ابزاری برسد که نیاز به تأیید دارد، آن درخواست رد شده و برنامه طبق روال مستندات حالت بدونسر (Headless) ادامه مییابد. نتیجه این است که عامل ممکن است در پایان پیام دهد «تستهای ناپایدار (Flaky) اصلاح شدند»، در حالی که هیچ تغییری در کد رخ نداده و Job شما با یک Diff خالی، سبز میشود. Gemini CLI نیز دقیقاً همین رفتار را بهطور عمدی دارد؛ هر قانونی که در حالت تعاملی نیاز به پرسش از کاربر داشته باشد، در حالت غیرتعاملی بهطور خودکار «رد» (Deny) تلقی میشود. این رویکرد امنیتی یادآور سیاستهای سختگیرانهی Verax است که از طریق قوانین «رد پیشفرض»، دسترسی عاملها به ابزارها را محدود میکند تا از اجرای دستورات ناخواسته جلوگیری شود.
ادغام عاملها در گردشکارهای خودکار نیازمند عبور از چتهای تعاملی است. توسعهدهندگان اکنون به سمت «حالت بدونسر» (Headless Mode) — یعنی اجرای عاملها از طریق پرچمهای CLI برای خودکارسازی تستها و رفع باگها — حرکت میکنند. اما طبق بررسیها تا ۱۷ اکتبر ۲۰۲۶، هر شرکت سازنده این انتقال را به شکل متفاوتی پیاده کرده است که اغلب تلههایی ایجاد میکند که منجر به Diffهای خالی و مثبتهای کاذب میشود. هر CLI عامل، نسخهی خاص خود از این تله را دارد.

راهنمای سریع حالت بدونسر
برای اینکه مطمئن شوید عامل واقعاً کد را اجرا میکند، باید از پرچمهای خاصی استفاده کنید. بر اساس مستندات رسمی سازندگان، دستورات اصلی برای اجرای بدونسر و پرچمهای مرتبط با آنها عبارتاند از:
- Claude Code: از
claude -p "..."همراه با--output-format jsonیاstream-jsonاستفاده میکند. پرچمهای کلیدی شامل--allowedToolsبرای تعیین ابزارهای مجاز،--permission-modeو همچنین--continueیا--resume <id>برای زنجیرهسازی اجراها است. - Codex: از دستور
codex exec "..." --json(در قالب JSONL) یا-o <file>بهره میبرد. برای دسترسیهای نوشتاری از--sandbox workspace-writeاستفاده میکند و برای ادامه کار ازcodex exec resume --lastیا وارد کردن<id>بهره میبرد. - Gemini CLI: از
gemini -p "..." --output-format jsonیاstream-jsonاستفاده میکند. این ابزار از--approval-modeو قوانین Policy بهره میبرد و برای تداوم اجرا از--resume latestاستفاده میکند. - Copilot CLI: از
copilot -p "..." --output-format json(در قالب JSONL) یا-sاستفاده میکند. پرچمهای--allow-toolو--deny-toolبرای کنترل دسترسی و--continueیا--resume=<id>برای ادامه اجرا به کار میروند. - OpenCode: از طریق
opencode run "..." --format jsonاجرا میشود. دسترسیها در فایلopencode.jsonیا از طریق پرچم--autoمدیریت میشوند و برای بازگشت به جلسه از-cیا-s <id>استفاده میکند.
نکات حیاتی Gemini CLI
در مورد Gemini CLI باید به یک هشدار نسخهای بسیار مهم دقت کنید. مستندات این ابزار صراحتاً بیان میکند که در ۱۸ ژوئن ۲۰۲۶، این CLI برای کاربران Google One و کاربران طرحهای رایگان با Antigravity CLI جایگزین شد. اگر حساب شما منتقل شده است، دستور چاپ در ابزار جدید به agy -p تغییر یافته است. نسخهی ۱.۱.۸ از Antigravity CLI خروجیهای ماشینخوان را از طریق --output-format و --json-schema معرفی کرد. نکته قابل توجه این است که خطاهای مربوط به استفاده از print-mode با کد وضعیت ۲ (exit status 2) خارج میشوند؛ در حالی که در نسخهی ۱.۳.۴، آخرین خطایی که پیشتر با کد ۰ (موفقیت) بسته میشد، اصلاح شد.
مدلهای دسترسی و ردهای خاموش
بزرگترین ریسک در حالت بدونسر، شکاف دسترسی است. پنج عامل، پنج مدل دسترسی متفاوت؛ و برخی بدون اینکه به شما بگویند، درخواست را رد میکنند.
جزئیات Claude Code:
- حالتها: شما باید یک حالت (Mode) را صراحتاً پاس دهید. اگر هیچ حالتی تنظیم نشود، از یک حالت شروع داخلی استفاده میکند که «میتواند auto باشد».
- نوشتن: پرچم
acceptEditsاجازه نوشتن در فایل را میدهد، اما دستورات Shell که خارج از مجموعه read-only هستند، همچنان نیاز به یک ورودی در--allowedToolsدارند. - محیط CI: حتماً پرچم
--bareرا در CI اضافه کنید. بدون آن، یک جلسه-pسعی میکند هوکهای موجود در.claude/settings.jsonرا اجرا کرده و سرورهای.mcp.jsonرا بدون دیالوگ اعتماد (Trust Dialog) متصل کند. حالت Bare این موارد را نادیده گرفته و لاگینهای اشتراکی را رد میکند، بنابراین بهANTHROPIC_API_KEYنیاز دارد. - مثال:
claude --bare -p "Fix the failing test in auth" --permission-mode acceptEdits --allowedTools "Bash(npm test *)" --output-format json > result.json. توجه داشته باشید که عبارتBash(npm test *)با دستور سادهیnpm testنیز مطابقت دارد. - اعتبارسنجی: برای جلوگیری از شکست خاموش، از دستور
jq -e '.permission_denials | length == 0' result.jsonاستفاده کنید تا اگر هر درخواستی رد شد، Job شما با خطا متوقف شود؛ زیرا هر دو ساختار موفقیت و خطا، یک آرایهpermission_denialsرا حمل میکنند.
جزئیات Codex:
- سندباکس: بهصورت پیشفرض در یک سندباکس فقط-خواندنی (Read-only) اجرا میشود. برای تغییر در مخزن کد، باید از
--sandbox workspace-writeیا--approve-for-meبرای بررسی خودکار استفاده کنید. - دسترسی: پرچم
danger-full-accessرا فقط در محیطهای کاملاً کنترلشده فعال کنید. پرچم قدیمی--full-autoدیگر پشتیبانی نمیشود. - نیازمندیها: Codex انتظار یک مخزن Git را دارد؛ برای نادیده گرفتن این بررسی از
--skip-git-repo-checkاستفاده کنید. - امنیت: مستندات هشدار میدهند که از تنظیم
OPENAI_API_KEYیاCODEX_API_KEYبه عنوان متغیرهای سطح Job در گردشکارهایی که کدهای کنترلشده توسط مخزن را اجرا میکنند، خودداری کنید.
جزئیات Gemini CLI:
- حالتهای تأیید: پرچم
--approval-modeمقادیرdefault،auto_edit،yoloیاplanرا میپذیرد. - منسوخ شدنها: هر دو پرچم
--yoloو--allowed-toolsمنسوخ شدهاند و دومی جای خود را به موتور سیاستگذاری (Policy Engine) داده است. - موتور سیاستگذاری: قوانین در فایل
~/.gemini/policies/ci.tomlتعریف میشوند و میتوانند دستورات را فقط زمانی که هیچ ترمینالی متصل نیست مجاز کنند. برای مثال، قانونی باtoolName = "run_shell_command"،commandPrefix = "npm test"،decision = "allow"وinteractive = falseفقط در حالت بدونسر اعمال میشود.
جزئیات Copilot CLI:
- منطق: قوانین رد (Deny) حتی وقتی
--allow-allفعال باشد، برنده هستند. پرچم--allow-all(که نام مستعار--yoloرا دارد) معادل است با ترکیب--allow-all-tools --allow-all-paths --allow-all-urls. - تعامل: از
--no-ask-userاستفاده کنید تا عامل برای سوالات شفافساز، اجرای برنامه را متوقف نکند. - مثال:
copilot -p "Fix the failing test in auth" -s --allow-tool='write, shell(npm:*)' --deny-tool='shell(npm publish)' --no-ask-user. - تله ورودی: اگر همزمان با پاس دادن
-pورودی را Pipe کنید، ورودی Pipe شده نادیده گرفته میشود.
جزئیات OpenCode:
- پیشفرضها: برعکس بقیه، «اکثر دسترسیها بهصورت پیشفرض مجاز هستند». فقط
doom_loopوexternal_directoryبهصورت پیشفرض نیاز به پرسش دارند و خواندن فایلهای.envرد میشود. - حفاظها: از یک قانون Deny در
opencode.jsonاستفاده کنید. برای مثال، تنظیمbashرویaskو تنظیمgit push *یاrm *رویdeny. - اتوماسیون: پرچم
--autoهر درخواستی که صراحتاً رد نشده باشد را تأیید میکند. بدون--auto،یک درخواست Ask در حالت بدونسر مستند نشده است و باید به عنوان وضعیت نامعلوم تلقی شود. - پرامپت: در دستور
opencode run،پرچم-pبه معنای--password(برای basic-auth) است، نه پرامپت. پرامپت باید به عنوان آرگومان موقعیتی (Positional Argument) پاس داده شود.

تحلیل خروجیها و کدهای خروج
خروجیهای استاندارد اغلب با لاگهای پیشرفت آلوده هستند و یافتن جواب نهایی را برای اسکریپتهای CI سخت میکنند.
- Claude Code: با
--output-format jsonیک شیء JSON شامل نتیجه،session_idو تخمین هزینه سمت کلاینت (total_cost_usd) برمیگرداند. افزودن--json-schemaپاسخ را درstructured_outputقرار میدهد. - Codex: لاگهای پیشرفت به stderr میروند و فقط پیام نهایی به stdout میرود. حالت
--jsonخروجی stdout را به JSONL تبدیل میکند (ازthread.startedتاturn.completedیاturn.failed). پرچم-oپیام نهایی را در یک فایل مینویسد. - Gemini CLI: در حالت JSON مقادیر
response،statsو یک شیء اختیاریerrorرا برمیگرداند. - Copilot CLI: آمار و تزئینات را اضافه میکند مگر اینکه
-sبرای دریافت «فقط پاسخ عامل» پاس داده شود.--output-format jsonخروجی JSONL تولید میکند. - OpenCode: با
--format jsonرویدادهای «JSON خام» را صادر میکند. ساختار آن در صفحه CLI توصیف نشده است، بنابراین قبل از تجزیه (Parsing)، نسخه را ثابت (Pin) کنید.
شناسههای جلسه (Session IDs) اجازه زنجیرهسازی اجراها را میدهند. برای Claude: ابتدا id=$(claude -p "Start a review" --output-format json | jq -r '.session_id') و سپس claude -p "Continue that review" --resume "$id". برای Codex: ابتدا codex exec "review the change" و سپس codex exec resume --last "fix the race conditions".
کدهای خروج (Exit Codes) بهطور متناقضی مستند شدهاند. Claude Code در موفقیت ۰ و در شکست مقدار غیرصفر برمیگرداند (SIGTERM مقدار ۱۴۳ میدهد). خروجی JSON از is_error و زیرمجموعههایی مثل error_max_turns استفاده میکند. Gemini CLI از کدهای ۰ (موفق)، ۱ (خطای عمومی/API)، ۴۲ (خطای ورودی) و ۵۳ (اتمام محدودیت Turn) استفاده میکند. Codex یک کد خروج برای شکست در استارت سرور MCP الزامی دارد؛ در غیر این صورت باید رویدادها را بخوانید. Copilot CLI کدهای خروج را برای workflow run ارائه میدهد، نه برای -p. OpenCode هیچ اشارهای به کدهای خروج برای run نکرده است.
برای فرار از تله «Diff خالی»، دو بررسی را پیاده کنید. برای Codex، در صورت شکست یک Turn، Job را متوقف کنید: jq -s -e 'all(.[]; .type != "turn.failed")' events.jsonl. برای هر عاملی، اگر هیچ فایلی تغییر نکرد، خطا بدهید: if [ -z "$(git status --porcelain)" ]; then echo "agent changed nothing" >&2; exit 1; fi.
جایگزین: انسان در حلقه (Human-in-the-Loop)
برای کارهایی که نمیتوان کاملاً خودکار کرد، ابزارهایی مثل Hermes IDE راهکار میانی هستند. من Hermes را به عنوان یک اپلیکیشن دسکتاپ برای macOS، ویندوز و لینوکس ساختهام — نه به عنوان یک CI Runner. این ابزار Claude Code، Codex، Antigravity CLI، Gemini CLI، GitHub Copilot CLI و OpenCode را اجرا میکند، هر کدام در یک ترمینال واقعی با رابط کاربری مجزا، تا تنظیمات و قوانین دسترسی هر عامل بدون تغییر اعمال شود. این رویکرد در تضاد با معماریهای کاملاً خودکار است؛ برای مثال، مایکروسافت در Foundry مکانیزمی را پیاده کرده است که عاملها را برای تأیید انسانی بهطور نامحدود متوقف میکند تا کنترل دقیقتری بر خروجیها داشته باشد.

در Hermes، شیت New task (با ⌘N) شامل یک انتخابگر عامل است. هر جلسه وضعیتی را نشان میدهد: در حال کار (working)، نیاز به تأیید (needs approval)، پرسش از شما (asked you)، انجام شد (done)، خطا (error) یا بیکار (idle). اینباکس توجه (Attention Inbox) تعداد عاملهایی که منتظر شما هستند را میشمارد و ⌘I (یا Ctrl+Shift+I در ویندوز/لینوکس) شما را به عاملی که طولانیترین زمان انتظار را داشته منتقل میکند. شما در ترمینال خود آن عامل پاسخ میدهید. Hermes هرگز به جای شما به یک درخواست دسترسی پاسخ نمیدهد.
این ساختار اجازه میدهد Codex را روی orders-types و Claude Code را روی orders-api بهطور همزمان و هر کدام در یک worktree مجزای hermes/ اجرا کنید. هر تسک میتواند شاخه (Branch) و worktree مخصوص خود را داشته باشد تا عاملها یک checkout واحد را ویرایش نکنند. Hermes رایگان است، تحت لایسنس BSL 1.1 در دسترس است و هیچ وابستگی رسمی به Anthropic، OpenAI، Google، GitHub، OpenCode یا Nous Research ندارد.
تحلیل: شکاف قابلیت اطمینان
این پراکندگی در طراحی CLI نشاندهنده یک تنش بنیادی در هوش مصنوعی عاملمحور است: توازن بین خودمختاری (Autonomy) و ایمنی (Safety). سازندگان با قرار دادن «رد» به عنوان پیشفرض در حالت بدونسر، کاربران را از خطاهای خودکار فاجعهبار محافظت میکنند، اما بار قابلیت اطمینان را بهطور کامل بر دوش توسعهدهنده میاندازند. در محیطهای حساستر، این لایههای حفاظتی حتی سختگیرانهتر میشوند؛ چنانکه سیستم Styx با استفاده از تایید بیومتریک، مانع از استقرار تصادفی عاملهای کدنویس در محیط Production میشود تا ریسکهای عملیاتی به حداقل برسد.
برای متخصصان، این بدان معناست که یک عامل هوش مصنوعی در CI در حال حاضر یک «وابستگی غیرقابل اطمینان» (Unreliable Dependency) است. برخلاف یک کامپایلر قطعی (Deterministic)، یک عامل میتواند به دلیل محدودیتهای نرخ (Rate Limits)، تایماوتها یا یک رد دسترسی خاموش شکست بخورد. کتاب System Design Pocket Guide: Fundamentals بلوکهای سازنده اصلی برای طراحی حول چنین وابستگیهایی را پوشش میدهد. این کتاب یکی از ۸ کتاب کوتاه در سری Pocket Guides for Developers است که موضوعاتی چون عاملها، RAG، پرامپتها، مشاهدهپذیری (Observability)، رویدادها، پایگاههای داده و طراحی سیستم را بررسی میکند.
برای ساخت خط لولههای تابآور، باید خروجی عامل را به عنوان یک «پیشنهاد» در نظر بگیرید و نه یک «واقعیت». اعتبارسنجی وضعیت واقعی سیستم فایل (Diff) تنها راه تضمین این است که عامل، کار درخواستی را واقعاً انجام داده است.




گفتگو