ConstructiCat Logo
CodeBust.
Browse section ▾

الإعدادات المكتوبة بشكل مباشر.

يقوم مساعدو الذكاء الاصطناعي بكتابة القيم الخاصة بالبيئة — مثل روابط URL، والمنافذ، والمسارات، وفترات انتهاء الصلاحية، والمفاتيح، والأرقام السحرية — مباشرة في منطق الكود بدلاً من قراءتها من ملف الإعدادات أو البيئة، وذلك لأن القيمة الحرفية هي الرمز التالي الأكثر احتمالاً للظهور، كما يفتقر النموذج إلى الوعي بوجود طبقة الإعدادات الحالية لديك.

##Signs and Symptoms

يميل مساعد الذكاء الاصطناعي إلى إصدار قيمة حرفية معقولة في المكان الذي ينبغي أن يوضع فيه مرجع لمتغير. يعمل الكود في العرض التوضيحي، لذا تنجو هذه الرائحة من المراجعة ما لم تبحث عنها خصيصاً.

العلامات المميزة:

  • نقاط نهاية، ومنافذ، ومسارات، وفترات مهلة مدمجة (inline) متناثرة في منطق الأعمال بدلاً من تجميعها في موديول الإعدادات: مثل http://localhost:3000، أو /tmp/cache، أو 5432، أو setTimeout(..., 30000).
  • أرقام/سلاسل نصية سحرية لا تشير إلى ثابت مسمى — مثل عدد مرات إعادة المحاولة، أو أحجام الصفحات، أو حدود معدل الاستخدام، أو حدود ميزات النظام.
  • تكرار نفس القيمة الحرفية عبر ملفات متعددة لأن النموذج أعاد توليدها بدلاً من استيراد ثابت موجود (وهو ما يمثل نمط GitClear المتمثل في "ارتفاع النسخ/اللصق وانخفاض إعادة الهيكلة" بشكل مصغر).
  • بيانات اعتماد / مفاتيح مكتوبة بشكل مباشر — مثل رموز واجهة برمجة التطبيقات المميزة، أو مفاتيح التشفير، أو سلاسل مصادقة Basic المنسوخة من بيانات التدريب.
  • تجاهل كود جديد بالكامل لكائن إعدادات config.ts / .env / الإعدادات الحالي والموجود مسبقاً.
  • قيم مخصصة لبيئة معينة: ككتابة رابط URL لبيئة اختبار أو معرف حساب تجريبي مباشرة في مسار يُشحن لاحقاً إلى بيئة الإنتاج.
// 🚩 AI-generated: every knob is a literal, dev values baked in
export async function syncOrders() {
  const res = await fetch("https://api.staging.acme.dev/v1/orders", {
    headers: { Authorization: "Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc" },
    signal: AbortSignal.timeout(30000),
  });
  const orders = (await res.json()).slice(0, 50); // لماذا 50؟
  for (let i = 0; i < 3; i++) { /* retry 3x... why 3? */ }
}

سطر Authorization يمثل انتهاكاً تكتشفه أدوات مثل gitleaks/Semgrep؛ بينما تمثل قيم مثل الرابط، و 30000، و 50، و 3 روائح للقيم السحرية؛ ورابط api.staging.acme.dev هو قيمة تطوير على وشك الوصول إلى الإنتاج.

##Reasons for the Problem

لماذا تنتجها النماذج؟

  • القيمة الحرفية هي الرمز التالي الأعلى احتمالاً. بالنظر إلى استدعاء fetch(، فإن الإكمال الأرخص الذي يلبي متطلبات التوجيه المباشر هو سلسلة نصية لرابط URL محدد، وليس config.apiBaseUrl. يتطلب حل المرجع معرفة أن الرمز موجود في مكان آخر؛ بينما لا يتطلب إصدار قيمة أي معرفة مسبقة. تقوم النماذج بالتحسين لإنتاج مقطع كود معقول محلياً وقابل للتشغيل.
  • مجموعة بيانات التدريب عبارة عن مقاطع كود برمجية قائمة بذاتها. تضع الدروس البرمجية، وأمثلة ملفات README، وإجابات Stack Overflow قيمها بشكل مدمج (inline) حتى تعمل بشكل مستقل ومستقر. لقد تعلم النموذج أن "كود الأمثلة الجيد" يحتوي على قيم مباشرة — وهو عكس النظافة والتنظيم المطلوب في كود الإنتاج.
  • غياب سياق المستودع / نافذة سياق محدودة. عادةً لا يكون النموذج قد قرأ مجلد config/ الخاص بك، أو مخطط المتغيرات البيئية، أو ملف الثوابت، وبالتالي لا يمكنه إعادة استخدامها. يربط تقرير GitClear هذا مباشرة بارتفاع نسبة تكرار الأكواد: المساعدون "أقل احتمالاً لاقتراح إعادة استخدام دالة مماثلة... ويعود ذلك جزئياً إلى حجم السياق المحدود"، مع نمو الكتل المكررة المكونة من 5 سطور أو أكثر بمعدل ~8 أضعاف في عام 2024 بينما انخفضت السطور المعاد هيكلتها ("المنقولة") من ~24% إلى ~9.5%.
  • التملق / الانحياز للإجابة على الأمر الموجه. عندما يُطلب من النموذج "إضافة مزامنة للطلبات"، فإنه يقدم شيئاً يعمل الآن؛ أما فصل الإعدادات وتصديرها فهو عمل إضافي لن يتطوع للقيام به ما لم يُطلب منه ذلك بوضوح.
  • تاريخ انتهاء التدريب (Training-cutoff staleness). غالباً ما تكون القيم المباشرة المضمنة عبارة عن قيم متقادمة — مثل نقاط نهاية قديمة، أو إصدارات واجهات برمجة تطبيقات مهملة، أو منافذ افتراضية، أو ثوابت تشفير ضعيفة (مثل MD5، والمفاتيح المكتوبة مباشرة). وجدت Ox Security أن 62% من الأكواد المولدة بالذكاء الاصطناعي تُشحن مع مشكلات، وتنسب المفاتيح/الأسرار/المسارات المكتوبة مباشرة إلى أنماط "تم تعلمها من قواعد كود قديمة... مع [غياب] تام للوعي بتطور معايير الأمان".

لماذا يسبب ضرراً؟

  • قابلية الصيانة — الجراحة بالبندقية (Shotgun Surgery). يعني تغيير مهلة زمنية واحدة أو رابط URL أساسي واحد البحث عن كل قيمة حرفية مكررة عبر قاعدة الكود بأكملها؛ وفي حال إغفال واحدة، ينحرف السلوك بصمت في مواقع الاستدعاء.
  • الصحة عبر بيئات التشغيل المختلفة. قد يتم شحن رابط URL لبيئة اختبار (staging) أو معرف حساب تطوير مكتوب مباشرة في المنطق إلى بيئة الإنتاج الفعلي؛ وتنحرف الحدود الرقمية السحرية التي لا تحمل اسماً عن القيم التي يجب أن تعكسها وتتزامن معها.
  • الأمان. الرموز المميزة أو المفاتيح المكتوبة بشكل مباشر هي تسريبات لبيانات الاعتماد — وبمجرد تضمينها وحفظها في التزامات git فإنها تعيش في تاريخ التغييرات للأبد. وجدت ورقة بحثية حول كود بناء المشاريع (2601.16839) مسارات/روابط مكتوبة بشكل مباشر وبيانات اعتماد خطيرة للغاية تتكرر في ملفات البناء المولدة بالذكاء الاصطناعي.
  • عبء المراجعة والديون التقنية. يجب على المراجعين التحقق من مصدر كل قيمة حرفية مباشرة. تشير دراسة روائح كود الذكاء الاصطناعي (arXiv 2509.20491) إلى أن النماذج تتعامل مع "القيم الحرفية داخل النطاق" بشكل جيد ولكنها تواجه صعوبة في الحالات الحساسة للقيمة حيث تعتمد الصحة على حدود رقمية تنتشر عبر دوال مساعدة — وهي بالضبط القيم المكتوبة مباشرة التي يجب على البشر الآن مراجعتها يدوياً. ووفقاً لمقابلة Stack Overflow مع إينو رييس من Factory، فإن الجودة الأساسية للكود هي "الإشارة الوحيدة" لمعرفة ما إذا كان الوكلاء البرمجية يسرعون عمل الفريق أم يبطئونه — وتآكل هذه الجودة يحدث بسبب انتشار القيم المكتوبة مباشرة.

##Treatment

تكتيكات المراجعة وصياغة الأوامر

  • وجه النموذج إلى طبقة الإعدادات الخاصة بك: "اقرأ ملف src/config.ts وملف .env.example؛ استخدم config.* / process.env لكل رابط URL، ومنفذ، ومهلة، وبيانات اعتماد. لا تقدم قيماً حرفية مباشرة". تكتب النماذج القيم مباشرة لأنها لا تعرف بوجود الثابت المسمى — لذا قم بتسميته وإرشاده إليه.
  • احظر القيم السحرية صراحة: "لا تستخدم أرقاماً أو سلاسل نصية سحرية — استخرج ثوابت مسماة". ثم اطلب منه تشغيل الأمر eslint --rule no-magic-numbers وماسح الأسرار (gitleaks/Semgrep) وإصلاح ما يتم تمييزه من أخطاء. وفقاً لتوجيهات Factory، اربط أدوات الفحص/المسح في الحلقة التكرارية حتى يصحح الوكيل البرمجي نفسه بدلاً من الاعتماد على المراجعة البشرية.
  • وفر مخططاً لمتغيرات البيئة (مثل zod/envalid/.env.example) بحيث يجد النموذج مكاناً يضع فيه القيم بدلاً من تخمينها.
  • ابحث في الفروقات (diffs) الجديدة عن كلمات مثل http، و localhost، وقيم IP، و Bearer ، والأرقام المجردة في معاملات الاستدعاء قبل الدمج.

إعادة الهيكلة — حدد الحركات الكلاسيكية:

  • استبدال الرقم السحري بثابت رمزي (Replace Magic Number with Symbolic Constant) للحدود والأعداد والأحجام.
  • استخراج الدالة / استخراج موديول الإعدادات (Extract Function / Extract Config Module) لتجميع خيارات التحكم في مكان واحد محدد النوع ومتحقق من صحته.
  • نقل الإعدادات إلى البيئة (12-factor) لأي شيء يختلف باختلاف البيئة أو يمثل سراً؛ ولا تقم أبداً بحفظ الأسرار في التزامات الكود.
// config.ts — single, validated source of truth
import { z } from "zod";
const env = z.object({
  ORDERS_API_BASE_URL: z.string().url(),
  ORDERS_API_TOKEN: z.string().min(1),
  ORDERS_TIMEOUT_MS: z.coerce.number().default(30_000),
  ORDERS_PAGE_SIZE: z.coerce.number().default(50),
  ORDERS_MAX_RETRIES: z.coerce.number().default(3),
}).parse(process.env);
export const config = env;
// ✅ after: references, not literals — one place to change, secret out of source
import { config } from "./config";
export async function syncOrders() {
  const res = await fetch(`${config.ORDERS_API_BASE_URL}/v1/orders`, {
    headers: { Authorization: `Bearer ${config.ORDERS_API_TOKEN}` },
    signal: AbortSignal.timeout(config.ORDERS_TIMEOUT_MS),
  });
  const orders = (await res.json()).slice(0, config.ORDERS_PAGE_SIZE);
  for (let i = 0; i < config.ORDERS_MAX_RETRIES; i++) { /* ... */ }
}

إذا تم تسريب سر بالفعل في التزام كود سابق، فقم بتغييره واستبداله فوراً — فحذف السطر لا يطهر تاريخ سجلات git.

##Detected by