یک تغییر کوچک و بدون امضا در طرحواره (Schema) میتواند کل خط لولهٔ پرداخت یک شرکت را در چند دقیقه فلج کند. این هشدار جدی در راهنمای ۱۶ سپتامبر ۲۰۲۶ در وبسایت dev.to منتشر شد تا الگوی شکست رایجی را افشا کند که در آن عاملهای هوش مصنوعی (AI Agents) — شبیه دستیارهایی که با سرعت زیاد کار میکنند اما گاهی جزئیات حیاتی را فراموش میکنند — فیلدهای اجباری را به اختیاری تبدیل کرده و باعث عدم تطابق فاجعهبار در محیطهای استیجینگ (Staging) و عملیاتی (Production) میشوند.
به نقل از این گزارش، یک مورد شکست زمانی رخ داد که وبهوکهای پرداخت، تمام سفارشات امضا شده را رد کردند؛ دلیل آن ساده بود: یک پیشنویس در مسیر رایگان (free-lane draft)، فیلد tax_id را اختیاری کرده بود، در حالی که کلاینتهای عملیاتی هنوز این فیلد را اجباری میدانستند. در نتیجه، خطوط لولهٔ پرداخت متوقف شدند و اپراتورها مجبور شدند ساعتها برای یافتن این تفاوت کوچک (unsigned diff) در کد بگردند.
این بحران درست زمانی رخ میدهد که مفهوم Vibe Coding — یعنی تکیه بر وصلههای تولید شده توسط AI بدون تایید دقیق مهندسی — وارد جریانهای کاری حرفهای شده است. همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، مدلها در تحلیلهای محلی عالی هستند اما درک سیستمیک ندارند. آنها نمیدانند چه زمانی یک فیلد، در واقع یک «قرارداد» است که سرویسهای خارجی به آن وابستهاند. تصور کنید AI یک دیتابیس را تمیز میکند اما فراموش میکند که یک وبهوک شخص ثالث هنوز شکل قدیمی دادهها را میخواهد؛ نتیجه یک شکست خاموش است که فقط هنگام وقوع حادثه در محیط عملیاتی ظاهر میشود. این ترکیب از Vibe Coding و مهندسی در داخل یک شاخه آزمایشی (scratch branch) بیضرر است، اما به محض اینکه فراخوانهای خارجی به بایتهای کد وابسته شوند، بسیار هزینهبر میشود.
خطر ارزیابی چرخشی
مشکل اصلی، ایجاد یک حلقهٔ بازخورد است که در آن همان مدلی که وصله را مینویسد، آن را ارزیابی هم میکند. این ارزیابی چرخشی، حس امنیت کاذبی ایجاد میکند؛ عامل AI گزارش میدهد که تستها «سبز» هستند، اما محدودیتهای مصرفکنندگان خارج از مخزن کد را نادیده میگیرد.
در این حالت، بررسی داخلی عامل ممکن است یک تجزیه (parse) محلی تمیز را گزارش کند، اما فراخوانهای خارج از مخزن همچنان شکل قبلی دادهها را ارسال میکنند. این فراخوانها بدون هیچ پنجرهای برای نسخهبندی یا اعلام بازنشستگی (deprecation window) میشکنند و تیمهای پشتیبانی را با خطاهای مربوط به «پیلود نامعتبر» (invalid payload) رها میکنند، در حالی که هیچ مالک مشخصی برای این خطا وجود ندارد. این چالشها یادآور رویکردهای مقابله با توهمات در مستندات فنی است که در آن تبدیل نویسنده به کامپایلر برای جلوگیری از اختراعات مدلهای AI پیشنهاد شده بود.
تعریف تغییرات سطح قرارداد
برای جلوگیری از این قطعیها، مهندسان باید بین «تغییرات ساده در کامنتها» (comment churn) و «ویرایشهای سطح قرارداد» (contract-class edits) تفاوت قائل شوند. طبق گزارش dev.to، یک فایل زمانی «قرارداد» است که سیستمهای دیگر مجبور به پیروی از آن باشند. طرحوارههای مشترک بسیار بیشتر از چتهایی که آنها را پیشنهاد دادهاند عمر میکنند و حذف خاموش یک فیلد میتواند به حوادثی در سطح چندین سرویس منجر شود.
موارد زیر را به عنوان تغییرات سطح قرارداد در نظر بگیرید:
- فایلهای OpenAPI و اسناد JSON Schema تحت کنترل نسخه.
- مهاجرتهای دیتابیس (Database Migrations) و فایلهای مدل ORM تولید شده.
- فایلهای تعریف طرحواره در Protobuf، Avro یا GraphQL.
- قراردادهای مربوط به دادههای وبهوک که توسط شرکای خارجی مصرف میشوند.
- اسناد شرایط IAM که مجوزهای نوشتن تخریبی را صادر میکنند.
در مقابل، تغییر در فایل README یا آزمایش فرمت لاگ در یک سرویس داخلی، تغییر سطح قرارداد نیست؛ اما حذف یک فیلد اجباری، همیشه یک تغییر سطح قرارداد محسوب میشود.
پیادهسازی گیت قفل طرحواره
راهکار پیشنهادی، ایجاد یک گیت «بستهشده در صورت خطا» (fail-closed) است. این مکانیزم که از طریق یک اسکریپت Node.js اجرا میشود، هر تغییری در مسیرهای قرارداد را که از منابع «رایگان» (free-tier) یا «سرورهای پیشنویس» (scratch-server) آمده باشد، رد میکند. این اسکریپت مسیرهای خاصی مانند contracts/ ، migrations/ ، tools/schema/ و فایلهای openapi.yaml یا openapi.yml را هدف قرار میدهد.
به جای اعتماد به تایید خودکار AI، سیستم یک «داجس» (Digest) امضا شده میطلبد. یک بازبین انسانی یا یک جاب (Job) مورد اعتماد باید هش SHA256 تغییر پیشنهادی را در فایل schema.lock.json بنویسد. اگر هش فایل در حال اجرا با هش قفل شده یا یک هش در انتظار (pending digest) مطابقت نداشته باشد، گیت با یک کد غیرصفر خارج شده و ادغام (Merge) را مسدود میکند. برای مثال، یک تفاوت قراردادی در مسیر رایگان باید با کد ۳ خارج شود، که این دقیقاً هدف اصلی این گیت است. این مدل نظارت انسانی بر ادغامها مشابه سیستم گیتهای انسانی در MonkeyCode است که برای توقف خودکار توهمات در مستندات فنی به کار گرفته شده است.
جریان کاری ارتقاء
۱. پیشنویس: عامل AI یک طرحواره کاندید را روی سرور پیشنویس ایجاد میکند (که به عنوان free-tier برچسب خورده است).
۲. اعتبارسنجی: تیم، نمونههای واقعی JSON (consumer fixtures) را روی هش در انتظار اجرا میکند. یک نمونه سفارش حداقلی ممکن است شامل order_id ، customer_id ، tax_id و total_cents باشد. اگر این نمونهها شکست بخورند، هش در انتظار بلافاصله حذف میشود؛ نمونهها نباید با استفاده از همان مدل رایگان اصلاح شوند.
۳. امضا: مالک انسانی با ابزاری مثل sign_pending.js هش SHA256 را به نقشه pending در فایل قفل اضافه میکند.
۴. اجرا: گیت تایید میکند که منبع تغییر (PATCH_ORIGIN) اکنون یک منبع مورد اعتماد است (مثلاً human-lock) و هش با قفل مطابقت دارد. تنها پس از این مرحله است که هش در نقشه اصلی files ثبت میشود.
چراغهای قرمز برای بازبینها
مهندسان باید در صورت مشاهده هر یک از این پرچمها، ارتقاء کد را رد کنند:
- تبدیل یک کلید اجباری به اختیاری بدون افزایش نسخه (version bump).
- حذف مقادیر Enum بدون بازهٔ زمانی مستند برای بازنشستگی.
- نیاز به تولید وصله جدید توسط AI برای بازگشت (Rollback) به جای استفاده از یک بازگشت پین شده (pinned revert).
- تستهایی که فقط «قابلیت تجزیه» (Parse) فایل را میسنجند و نه تطابق آن با نمونههای مصرفکننده.
- زمانی که تفاوت (diff) مسیرهای قرارداد، مهاجرتها یا طرحوارههای ابزار را لمس میکند در حالی که منبع آن
free-tierیاscratch-serverاست. - زمانی که همان مدل، هم وصله را نوشته و هم تستها را طراحی کرده است.
- زمانی که مرحله اجرا (apply) فاقد چکسامِ قفل قبلی است.
- تغییر در مفاهیم مربوط به احراز هویت، پول یا معناشناسی حذف دادهها.
- زمانی که فرآیند سرور رایگان، جابِ اجرا (apply job) را نیز مدیریت میکند.
- زمانی که وصله مسیر رایگان، شماره نسخه را برای تایید خودکار افزایش میدهد.
وجود یک پرچم برای مسدود کردن ارتقاء کافی است؛ وجود دو پرچم به این معناست که شاخه باید به حالت پیشنویس (scratch) بازگردد.
جدول تصمیمگیری برای تایید ادغام
برای حفظ ثبات، تیمها باید از یک جدول تصمیمگیری در کنار باکس ادغام استفاده کنند:
- کامنت در فایل موقت: مجاز (منبع رایگان: مجاز / قفل مورد اعتماد: اختیاری).
- تغییر نام تست واحد محلی: مجاز (منبع رایگان: مجاز / قفل مورد اعتماد: اختیاری).
- ویرایش فیلد اجباری در JSON Schema ابزار: فقط پیشنویس (قفل مورد اعتماد: اجباری / منبع رایگان: رد شده).
- مهاجرت SQL یا تغییر مدل ORM: فقط پیشنویس (قفل مورد اعتماد: اجباری / منبع رایگان: رد شده).
- حذف متد یا مسیر در OpenAPI: فقط پیشنویس (قفل مورد اعتماد: اجباری / منبع رایگان: رد شده).
- کاهش مقادیر Enum در وضعیت وبهوک: فقط پیشنویس (قفل مورد اعتماد: اجباری / منبع رایگان: رد شده).
- خط زمانی حادثه یا رکورد حسابرسی: رد شده (قفل مورد اعتماد: اجباری).
- بایتهای مربوط به Secret، توکن یا سیاست IAM: رد شده (قفل مورد اعتماد: اجباری).
جایگزینهای راهبردی
برای تیمهایی که به دنبال رویکردی سختگیرانهتر هستند، پیشنهاد میشود به جای حذف خاموش فیلدها از نسخه ۱، یک سند «نسخه ۲» منتشر کنند. شماره نسخهها باید توسط مالک قفل مدیریت شود، نه عامل پیشنویس. افزایش نسخه از ۱ به ۲ در مسیر رایگان، همچنان یک قرارداد بدون امضا محسوب میشود. مسیر درست این است که نسخه ۲ را به عنوان یک فایل جدید عرضه کرده و نسخه ۱ را طبق یک تقویم مشخص بازنشسته کنید.
علاوه بر این، کارهای برگشتناپذیر مانند مهاجرتهای دیتابیس فقط باید روی رانرهای امضا شده و غیررایگان اجرا شوند. یک سرور پیشنویس میتواند میزبان امنی برای عاملهای یکبارمصرف باشد، اما هرگز نباید عملیات migration apply یا cluster apply را اجرا کند. بازگشتها (Reverts) باید از طریق پین کردن چکسامها مدیریت شوند، نه با درخواست از مدل برای «لغو تغییرات». این رویکرد برای جلوگیری از سقوط دیتابیسها حیاتی است، مشابه آنچه در تحلیل دمپهای زمانی و کاتالوگهای زنده برای حل شکستهای بررسی SQL توسط AI بررسی کردیم.
معیارهای خروج و حاکمیت
تیمها باید در صورت وقوع هر یک از موارد زیر، استفاده از مسیر رایگان برای کارهای قراردادی را کاملاً متوقف کنند:
- تغییر یک فیلد اجباری بدون افزایش نسخه متناظر.
- شکست دو مصرفکننده در یک نمونه (fixture) مشابه طی یک هفته.
- اشتراک میزبان بین جابِ اجرا (apply job) و جابِ پیشنویس (draft job).
- فقدان متادیتای منبع (Origin metadata) در بیش از یک ادغام.
- وقوع حادثهای که نیاز به بازگشت طرحواره داشته اما هیچ نسخهای برای بازگشت وجود نداشته است.
- زمانی که مدلی که تفاوت را نوشته، تستها را نیز بهروزرسانی کرده است.
- جابجایی شماره نسخهها در همان کامیتِ پیشنویس.
پس از خروج از مسیر رایگان، مسیرهای قراردادی باید در فایل CODEOWNERS منجمد شوند. برای مثال، مسیرهای /contracts/ ، /migrations/ و /tools/schema/ باید به @schema-lock-owners اختصاص یابند. این لیست باید کوتاه و فعال نگه داشته شود، زیرا یک فایل CODEOWNERS خالی، در واقع یک قفل نیست.
محدودیتها و دامنه
این رویکرد محدودیتهای خاصی دارد. اسکریپت به متغیر محیطی PATCH_ORIGIN اعتماد میکند؛ یک جاب با برچسب اشتباه میتواند سیاست را دور بزند. برابری چکسام ثابت میکند که مالک قفل بایتها را دیده است، اما ایمنی معنایی (Semantic Safety) را تضمین نمیکند. علاوه بر این، اعتبارسنجی نمونهها ممکن است خطاهای رفتاری مانند گرد کردن اعداد یا تغییرات منطقه زمانی را نادیده بگیرد، که همچنان نیازمند تستهای دامنه (domain tests) هستند.
این سیستم جایگزینی برای بکآپ یا اسکنرهای امنیتی نیست، بلکه برای تیمهایی است که مصرفکنندگان خارجی، مهاجرتهای دیتابیس یا وبهوک دارند. برای پروتوتایپهای تکنفره یا طرحوارههایی که هرگز از دفترچه یادداشت شخصی خارج نمیشوند، این حجم از پیچیدگی لازم نیست.
معنای این تحول برای توسعهدهندگان مدرن، بازگشت به نسخهبندی صریح است. عصر «پرامپت بزن و دعا کن» برای زیرساختها به پایان رسیده و جای خود را به مدل ترکیبی میدهد که در آن AI پیشنهاد میدهد و انسان امضا میکند. این یعنی در حالی که «حس و حال» کد توسط AI هدایت میشود، قراردادها یک قطعیت مهندسی باقی میمانند.
گام بعدی شما
- پوشههای
contracts/وmigrations/خود را بازرسی کنید و فایلهایی که در حال حاضر توسط عاملها بدون چکسام امضا شده توسط انسان ویرایش میشوند را شناسایی کنید. - برای اکتشاف و ایدهپردازی از مسیر رایگان (Free Lane) استفاده کنید، اما قفل امضا شده را فقط در یک جاب مورد اعتماد یا توسط یک انسان نگه دارید.
- یک لیست کوتاه از
@schema-lock-ownersدر فایلCODEOWNERSتعریف کنید تا هیچ تغییر قراردادی بدون تایید آنها منتشر نشود.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو