چند هفته پیش نتایج اولیه Project Glasswing را منتشر کردیم، که بررسی می‌کرد چه اتفاقی می‌افتد وقتی frontier security models را روی یک enterprise codebase نشانه می‌رویم. در آن گزارش نشان دادیم که سازوکارهای دفاعی چطور خود را تطبیق می‌دهند تا زیرساخت و مشتری‌ها را در برابر تهدیدهای ناشی از frontier AI محافظت کنند. ecosystemِ AI همچنان سریع حرکت می‌کند — توسعه‌دهندگانی که همه‌چیز را حولِ یک مدل متمرکز کرده‌اند قبلاً تجربه کرده‌اند که وقتی آن مدل در دسترس نباشد یا مدلِ قوی‌تری جایگزین شود چه رخ می‌دهد.

این تغییرات بازار یک پیام روشن را تقویت می‌کند: آینده‌ی agentic workflows با یک مدل منفرد، یک prompt، یا یک single-agent session پیدا نخواهد شد. برای رفتن از یک «skill» محلی امنیتی به یک pipeline اسکن پیوسته و fleet-wide، معماری باید طوری باشد که models به‌عنوان اجزای قابل‌تعویض رفتار شوند. اتکای صرف به یک مدل پوشش دفاعی را محدود می‌کند چون همان سیستم مسیرهای کد را از لنز یکسانی می‌بیند؛ راه حل این است که مدل‌ها به‌طور مرتب جابجا و cross-tested شوند. 🔁

با تغییر مدل‌ها در طول pipeline — مثلاً استفاده از یک مدل برای کشف اولیه و یک مدل کاملاً متفاوت برای validation — می‌توانیم مطمئن شویم که آسیب‌پذیری‌ها توسط مجموعه‌های متفاوتی از منطق بررسی می‌شوند. علاوه بر این، یک harness در مقیاس enterprise باید فراتر از مخازن ایزوله ببیند و وابستگی‌های cross-repo را ردیابی کند تا از هزاران کاندید خام، صفی از موارد قابل‌اعتماد و triaged برای رفع به‌دست آید. 🛠️

این نوشته یک نگاه عملی به ساخت آن لایه‌ی model-agnostic ارائه می‌دهد، با تمرکز بر مدیریت state controls، کاهش false positives و هماهنگی end-to-end triage در مقیاس.

دو اعتراض که بهتر است اول پاسخ داده شوند:

1) «چرا از subagents استفاده نکنیم به‌جای یک harness؟» Subagents مفیدند و نقطه شروع خوبی‌اند، اما security analysis نیازمند صدها تحقیق جداگانه است که باید بین اجراها باقی بمانند، context window مشترک نداشته باشند، و بعداً قابل‌rescope و cross-reference باشند. این نیاز به persistence، deduplication، resumability و در نهایت fleet-wide dependency tracing دارد — که همگی مسائل orchestration هستند و یک prompt به تنهایی نمی‌تواند آن‌ها را حل کند.

2) «آیا این مطلب صرفاً تبلیغ frontier models است؟» خیر. رویکرد ما حول harness می‌چرخد، نه مدل. برای کشف vulnerability ما از هر frontier model که آن کار را بهتر انجام دهد استفاده می‌کنیم. وقتی مدل‌های مختلف را روی یک هدف می‌گذاریم، هرکدام سهم متفاوتی از باگ‌ها را پیدا می‌کنند. آنچه می‌ماند و دوام می‌آورد خود harness است. اگر سیستم خودتان را می‌سازید، از روز اول آن را model-agnostic طراحی کنید تا آزاد باشید هر مدلی را به‌کار ببرید.

همه‌چیز با یک skill شروع شد

ما با یک security-audit skill حدوداً ۴۵۰ خطی کار را روی یک repo واحد شروع کردیم و prompts را تا زمانی تنظیم کردیم که باگ‌های واقعی ظاهر شوند. بعداً orchestration را اضافه کردیم که تبدیل به plumbing کل سیستم شد. ارزش واقعی در خود prompts است؛ prompts ما هنوز سناریوهای attacker، کلاس‌های باگ و anti-patternها را تقریباً بدون تغییر حمل می‌کنند. 🔎

این skill برای اجرای یک ۷-فاز audit در یک session نوشته شده بود: سه agent تحقیق موازی برای تدوین architecture.md؛ یک Hunter per class attack که می‌کوشد کد را بشکند؛ adversarial validators برای نقض هر finding؛ بازنویسی یافته‌های زنده به صورت human-readable vulnerability report؛ خروجی گرفتن به عنوان findings.json بر اساس یک schema و یک بررسی مکانیکی روی آن فایل؛ و در نهایت یک agent جدید که هر finding را مستقل بازتأیید می‌کند. یافته‌های بازتأییدشده به ingest API ارسال می‌شوند.

آن skill تقریباً به‌صورت مستقیم به harness تبدیل شد: Recon ↔ Recon، Hunters ↔ Hunt، Validators ↔ Validate، گزارش ↔ Report، بررسی مکانیکی روی findings.json ↔ Mechanical validation، و agent تازه ↔ Independent validation.

اما skill محدودیت‌هایش را نشان داد. یک اجرای منفرد در بهترین حالت حدود نیمی از باگ‌هایی را که با چند اجرای ترکیبی پیدا می‌شوند آشکار می‌کرد و تمایل داشت به باگ‌های ساده‌تر گرایش پیدا کند. وقتی فرآیند شما عملاً «ده بار اجرا کن و دستی diff بگیر» می‌شود، باید به harness واقعی فکر کنید. ⚠️

در جریان توسعه skill با سه دیوار برخورد کردیم:

– Context exhaustion: پس از مدتی context window پر می‌شود و مدل شروع به cannibalize کردن حافظه‌ی خودش می‌کند و یافته‌هایی را که ساعت‌ها دنبالشان بوده فراموش می‌کند. ما این گلوگاه را با externalizing state حل کردیم و LLM را به‌عنوان یک stateless compute engine در نظر گرفتیم.

– Persistence: یک crash وسط اجرا یعنی شروعِ مجدد. از دست دادن ساعت‌ها کار به‌خاطر یک خطای rate-limit یا قطع اتصال خیلی پرهزینه است. بنابراین persistence لازم است.

– Cross-repo reasoning: یک session محدود به یک repo نسبت بین برنامه‌هایی که از آن استفاده می‌کنند را نمی‌بیند، و تعداد ضعف‌هایی که وقتی این رابط‌ها را بررسی می‌کنید ظاهر می‌شود معمولا قابل‌توجه است.

نکته عملی: یک harness واقعی اما حداقلی متشکل از سه مرحله Recon، Hunt و Validate است که در یک database نگهداری می‌شوند، و یک Validator جدا که نمی‌تواند خودش finding ثبت کند. تا وقتی فقط یک repo مهم دارید، از cross-repo tracing صرف‌نظر کنید. تا وقتی واقعاً در نویز غرق نشده‌اید، از یک Deduplication agent اختصاصی صرف‌نظر کنید. ابتدا با یک skill در محیط توسعه خودتان شروع کنید، prompts را خوب کنید، و مرحله معماری بعدی را فقط وقتی کمبود آن واقعا سرعتتان را کم می‌کند اضافه کنید.

کدبندی skill به صورت pipeline

بیشتر مطالب درباره AI security که می‌بینید روی یک repo یا benchmark کاستوم متمرکز است؛ اجرای entire fleet با cross-repo tracing چیزی نیست که زیاد مستند شده باشد. کدبیس ما ترکیبی از زبان‌های متعدد — Rust، Go، C، Lua، TypeScript، Python — و انواع configها و contextهای دیگر است. بنابراین باید چیزی جدید طراحی می‌کردیم که برای ما کار کند. تبدیل اولین run به یک fleet scanner که بتواند ۱۲۸ repo مجزا را پوشش دهد و وابستگی‌های مرتبط را خودکار پیدا و پرس‌وجو کند، حدود شش هفته طول کشید.

کدبندی بیشتر مکانیکی بود: هر فاز از skill را به یک agent مجزا بردیم، پشت آن یک database گذاشتیم و یک orchestrator جلویش گذاشتیم. نگاشت تقریباً یک‌به‌یک بود. کل fleet روی یک harness واحد اجرا می‌شود بدون tuningِ per-language و می‌تواند وابستگی بین repoها را trace کند. با واگذاری syntax به مدل، سیستم language-agnostic می‌ماند؛ تمایز اصلی در توانایی trace وابستگی‌ها بین repoها است. harness خودش اهمیتی نمی‌دهد که دارد به C pointers نگاه می‌کند یا یک فایل TypeScript؛ تمرکز روی منطق سطح بالای security orchestration است که امکان scale روی صدها codebase را فراهم می‌کند.

روال تحقیق vulnerability در دو مرحله

ما یک چارچوب عملیاتی دو مرحله‌ای ساخته‌ایم: Vulnerability Discovery Harness (VDH) و Vulnerability Validation System (VVS).

VDH موتور کشف ماست که به‌صورت پروأکتیو codebaseها را اسکن می‌کند تا مسائل امنیتی احتمالی را بیرون بکشد. وقتی باگ‌ها وارد VVS می‌شوند — سیستمی که می‌تواند از چند harness تغذیه شود — مراحل Deduplication، Judgment و نهایتاً Fixing را طی می‌کنند.

ما برای VDH از یک مدل استفاده می‌کنیم و برای VVS از مدل کاملاً متفاوتی؛ به این ترتیب مدل‌ها عملاً همدیگر را دوبل چک می‌کنند. مزیت امنیتی روشن است: مجبور کردن Model B (VVS) برای قضاوت خروجی Model A (VDH) باعث می‌شود یافته توسط مجموعه‌ی متفاوتی از وزن‌های منطقی و داده‌های آموزشی ارزیابی شود — یک third-party adversarial که وظیفه‌اش stress-test assumptions مدل A است. ✅

عملیاتی هم سود دارد: با درنظر گرفتن model providers به‌عنوان commodities قابل‌تعویض، تحمل تغییرات در temperature، caching و inference budgets ساده‌تر می‌شود. به‌جای ساختن سیستمی که به رفتار پیش‌بینی‌شده یک مدل وابسته است، harness ما به‌گونه‌ای طراحی شده که نوسانات downstream را تحمل کند بدون اینکه بشکند.

Stage 1: Vulnerability Discovery Harness (VDH)

در پست اول درباره اینکه هر agent/مرحله برای چه کاری است گفتیم؛ اینجا درباره چسب بین مراحل و چند جزئیاتی که تعیین می‌کنند آیا سیستم کار می‌کند یا نه صحبت می‌کنیم.

Agent/Stage — نقش اصلی — زیرعامل‌ها / ابزارها:

– Recon: نقشه‌برداری از معماری هدف و مشخص‌کردن threat vectors. سه Recon sub-agent موازی architecture.md را می‌نویسند. 📦

– Hunt: اجرای attack per class، جمع‌آوری fragments و پروب کردن binaries. این مرحله siblings می‌سازد (بسته به مدل بین ۹٪ تا ۲۰٪ کارهای fleet-wide را انجام می‌دهند) و با ابزار Wishlist تعامل می‌کند.

– Validate: بررسی مکانیکیِ finding و سپس تلاش adversarial برای نقض آن قبل از اینکه filed شود. این مرحله دو پاس اجرا می‌شود: ابتدا checksِ plain code برای schema/path، سپس یک agentِ ایزوله سعی می‌کند یافته را نقص کند.

– Gapfill: برای هر cell پوشش‌نیافته (area × attack-class) کارهای hunt جدید enqueue می‌کند تا coverage را پر کند.

– Dedup: شناسایی و ادغام کردن موارد مشابه تا نویز کاهش یابد؛ این بخش زمانی حیاتی می‌شود که حجم یافته‌ها زیاد است.

جمع‌بندی نهایی: اگر می‌خواهید یک سیستم دفاعی مقیاس‌پذیر برای codebaseهای enterprise بسازید، کلید کار یک harness model-agnostic است که state را بیرون از LLM نگه دارد، persistence و ability to re-verify فراهم کند، و cross-repo dependency tracing را در لایه‌ای بالاتر انجام دهد. از یک skill در محیط توسعه شروع کنید، prompts را به‌خوبی بسنجید، سپس به‌صورت مرحله‌ای و حسب نیاز orchestration و اجزای پایگاه‌داده را اضافه کنید.🛡️