কোনো ফিচার শিপ হওয়ার ছয় মাস পর একটি রিপোজিটরি খুললেও অনেক কিছু পুনর্গঠন করা যায়। আপনি আর্কিটেকচার ট্রেস করতে পারেন, স্কিমা পরীক্ষা করতে পারেন, টেস্ট পড়তে পারেন, আর ঠিক কোন লাইনগুলো বদলেছে তা দেখতে পারেন।
যেটা সাধারণত পুনর্গঠন করা যায় না, তা হলো সেই কথোপকথন, যা ওই লাইনগুলোকে প্রয়োজনীয় করে তুলেছিল।
কোড আপনাকে বলবে না যে একটি ভ্যালিডেশন রুল আছে, কারণ একজন গ্রাহক বিকৃত এক্সপোর্ট পাঠান। এটি ব্যাখ্যা করবে না যে একটি অদ্ভুত রিট্রাই পলিসি ডাউনস্ট্রিম সিস্টেমে ডুপ্লিকেট ট্রানজ্যাকশন ঠেকায়। এটি দেখাবে না যে অ্যাক্সেসিবিলিটি টেস্টের পর আরও পরিষ্কার ইন্টারফেসটি বাতিল করা হয়েছিল, বা কোনো সার্ভিস বাউন্ডারি ইঞ্জিনিয়ারিং পছন্দের বদলে চুক্তিগত সীমাবদ্ধতার প্রতিফলন।
কোডের ইতিহাস সংরক্ষণে Git অসাধারণ। কিন্তু উদ্দেশ্য সংরক্ষিত থাকে তখনই, যখন একটি দল সচেতনভাবে সেই উদ্দেশ্য লিখে রাখে এবং তা ইমপ্লিমেন্টেশনের সঙ্গে যুক্ত রাখে।
এই ফাঁক সবসময়ই সফটওয়্যার ইঞ্জিনিয়ারিংয়ের অংশ ছিল। AI কোডিং টুলগুলো এটিকে আরও দৃশ্যমান করে। একটি সিস্টেম রিপোজিটরির প্রতিটি ফাইল পড়তে পারে, প্রতিটি সিম্বল অনুসরণ করতে পারে, এবং প্রযুক্তিগতভাবে বিশ্বাসযোগ্য একটি প্যাচ তৈরি করতে পারে—তবু তাও ভুল সমস্যার সমাধান করতে পারে।
সমস্যা এই নয় যে কোড বিভ্রান্তিকর। কোড কেবল আরও সংকীর্ণ একটি প্রশ্নের উত্তর দিচ্ছে।
ইঞ্জিনিয়ারিং সত্যের পাঁচটি স্তর
অর্থবহ বেশিরভাগ সফটওয়্যার পরিবর্তন পাঁচটি ভিন্ন স্তরের প্রমাণের ওপর নির্ভর করে।
- উদ্দেশ্য — ব্যবহারকারী, গ্রাহক, বা ব্যবসা কী ফলাফল চাইছে? এটি কোনো স্পেসিফিকেশন, টিকিট, সাপোর্ট কথোপকথন, বা মিটিং নোটে থাকতে পারে।
- সীমাবদ্ধতা — কী ভাঙা চলবে না? কম্প্যাটিবিলিটির প্রতিশ্রুতি, সিকিউরিটি বাউন্ডারি, নিয়মকানুন, চুক্তি, বাজেট, এবং ডেডলাইন প্রায়ই রিপোজিটরির বাইরে থাকে।
- ইমপ্লিমেন্টেশন — আজ সিস্টেমটি কীভাবে কাজ করছে? কোড, টেস্ট, স্কিমা, ডিপেনডেন্সি, এবং ডিপ্লয়মেন্ট কনফিগারেশন এই স্তরটি দেয়।
- রানটাইম প্রমাণ — বাস্তব সিস্টেমে কী ঘটছে? লগ, ট্রেস, মেট্রিক্স, প্রোডাকশন ডেটা, এবং ইনসিডেন্ট রিপোর্ট এমন ধারণার বিরোধিতা করতে পারে, যা কোডে যুক্তিসঙ্গত মনে হয়।
- সিদ্ধান্তের ইতিহাস — বর্তমান পদ্ধতিটি কেন বেছে নেওয়া হয়েছিল? পুল রিকোয়েস্ট, ডিজাইন আলোচনা, বাতিল করা বিকল্প, এবং আগের ইনসিডেন্টগুলোতে এর উত্তর থাকে।
তৃতীয় স্তরে রিপোজিটরি সবচেয়ে শক্তিশালী। এতে অন্যগুলোর কিছু অংশ থাকে, কিন্তু সেগুলোকে সম্পূর্ণভাবে উপস্থাপন করার মতো যথেষ্ট খুব কমই থাকে।
এটি গুরুত্বপূর্ণ, কারণ সফটওয়্যার ব্যর্থতা প্রায়ই স্তরগুলোর সীমানায় দেখা দেয়। ইমপ্লিমেন্টেশন একটি পুরোনো স্পেসিফিকেশনের সঙ্গে মিলে যায়। সমাধানটি টিকিট পূরণ করে, কিন্তু একটি অপারেশনাল সীমাবদ্ধতা লঙ্ঘন করে। টেস্ট পাস করে, কারণ সেগুলো গতকালের অনুমানকে এনকোড করে। কোড ভেতরে ভেতরে সামঞ্জস্যপূর্ণ, অথচ প্রোডাকশন ডেটা এমন একটি প্যাটার্ন অনুসরণ করে, যা কেউ নথিভুক্ত করেনি।
লোকালি সঠিক একটি প্যাচও তবু ভুল পরিবর্তন হতে পারে।
রিপোজিটরি নিজে থেকে যেসব প্রশ্নের উত্তর দিতে পারে না
ধরুন, একজন ব্যবহারকারী একটি ডকুমেন্ট সম্পাদনা করলেন, তারপর আপডেট করা বাক্যটি খুঁজলেন—কিন্তু ফলাফলে দেখলেন পুরোনো সংস্করণ। “সার্চ যেন সঙ্গে সঙ্গে আপডেট হয়” শুনতে খুবই স্পষ্ট একটি অনুরোধ। রিপোজিটরি কোথা থেকে শুরু করা যেতে পারে তার কয়েকটি সম্ভাব্য জায়গা দেখাতে পারে, কিন্তু সঠিক সমাধানটি কী হবে তা নিজে থেকে নির্ধারণ করতে পারে না।
| প্রশ্ন | সম্ভাব্য উৎস |
|---|---|
| ডকুমেন্টের কোন সংস্করণটি কর্তৃত্বপূর্ণ? | সোর্স ডকুমেন্ট এবং রিভিশন হিস্ট্রি |
| পুরোনো টেক্সটটি কোথায় রয়ে গেছে? | সিঙ্ক লগ, এক্সট্র্যাকশন আউটপুট, সার্চ ইনডেক্স, বা ক্যাশ |
| এই প্রোডাক্টে “সঙ্গে সঙ্গে” বলতে কী বোঝায়? | প্রোডাক্টের প্রতিশ্রুতি বা সার্ভিস অবজেক্টিভ |
| ডকুমেন্টের কনটেন্ট বদলের সঙ্গে কি তার পারমিশনও বদলেছে? | সোর্স পারমিশন এবং অডিট হিস্ট্রি |
| পুরোনো ফলাফলটি কি শুধু একজন ব্যবহারকারী, একটি সোর্স, বা একটি অঞ্চলে সীমাবদ্ধ? | রিকোয়েস্ট ট্রেস এবং প্রোডাকশন মেট্রিক্স |
সার্চ কোড হয়তো ব্যাখ্যা করতে পারে কীভাবে ফলাফল ফেরত আসে। কিন্তু আসল ত্রুটিটি সিঙ্ক্রোনাইজেশন বিলম্ব, পুরোনো এক্সট্র্যাকশন, ক্যাশ ইনভ্যালিডেশন, পারমিশন প্রোপাগেশন, নাকি এমন একটি প্রত্যাশা যা প্রোডাক্ট কখনোই সংজ্ঞায়িত করেনি—তা এটি বলতে পারে না।
পরিণত সিস্টেমে এই পার্থক্য আরও গুরুত্বপূর্ণ হয়ে ওঠে। যে ফিল্ডটি অপ্রচলিত মনে হয়, সেটি হয়তো এখনও একটি লিগ্যাসি ক্লায়েন্টকে সমর্থন করছে। দেখতে ডুপ্লিকেট মনে হওয়া কোনো সার্ভিস হয়তো ভিন্ন পারমিশন প্রয়োজনীয়তার ডেটা আলাদা করে রাখে। আপাতদৃষ্টিতে অতিরিক্ত মনে হওয়া কোনো চেক হয়তো এমন একটি প্রোডাকশন ইনসিডেন্টের একমাত্র কোড-স্তরের চিহ্ন, যা বর্তমান টিম কখনো দেখেনি।
জটিলতা মুছে ফেলা মূল্যবান। কিন্তু জটিলতার ছদ্মবেশে থাকা ইতিহাস মুছে ফেলা ব্যয়বহুল।
আরও বেশি কনটেক্সট থাকলেও উত্তর ভুল হতে পারে
সবচেয়ে স্বাভাবিক সমাধান হলো AI-কে আরও বেশি উপাদান দেওয়া: পুরো রিপোজিটরি, প্রতিটি টিকিট, প্রতিটি ডকুমেন্ট, প্রতিটি বার্তা, এবং প্রতিটি লগ।
এতে অ্যাক্সেস তৈরি হয়, বোঝাপড়া নয়।
উৎসগুলো পুরোনো, পরস্পরবিরোধী, অনুমানভিত্তিক, বা ভিন্ন পাঠকের জন্য লেখা হতে পারে। একটি ব্রেইনস্টর্ম অনুমোদিত স্পেসিফিকেশনের চেয়ে বেশি গুরুত্ব পাওয়া উচিত নয়। ছয় মাস আগের কোনো রিকোয়ারমেন্ট যেন নীরবে গতকালের প্রোডাক্ট সিদ্ধান্তকে অগ্রাহ্য না করে। একটি প্রোডাকশন লগকে সেই রিলিজ, এনভায়রনমেন্ট, এবং কোড পাথের সঙ্গে যুক্ত থাকতে হবে, যেখান থেকে এটি তৈরি হয়েছে। কোনো গ্রাহকের অনুরোধকে তার পরিসর যাচাই না করে সার্বজনীন রিকোয়ারমেন্ট হিসেবে ধরা উচিত নয়।
তাই একটি শক্তিশালী কনটেক্সট সিস্টেমের শুধু রিট্রিভালের চেয়ে বেশি কিছু দরকার। এটিকে নিম্নলিখিত বিষয়গুলো নিয়ে যুক্তি করতে পারতে হবে:
- কর্তৃত্ব: কোন উৎসটি রিকোয়ারমেন্ট নির্ধারণ করার অনুমতি রাখে?
- সাম্প্রতিকতা: কোন তথ্যটি বর্তমান, এবং কোনটি অতিক্রান্ত হয়ে গেছে?
- উৎস-পরিচয়: প্রতিটি দাবি, সীমাবদ্ধতা, বা উপসংহার কোথা থেকে এসেছে?
- সম্পর্ক: কোন ইস্যু, রিলিজ, গ্রাহক, ডেটাসেট, এবং কোড পাথ একে অপরের সঙ্গে সম্পর্কিত?
- পারমিশন: এই কাজের জন্য কোন উৎসগুলো ব্যবহার করা যাবে এবং এই ব্যক্তিকে কোনগুলো দেখানো যাবে?
কনটেক্সট টোকেনের স্তূপ নয়। এটি সময়, কর্তৃত্ব, এবং সীমানা-সহ একটি গ্রাফ।
আরও বেশি কনটেক্সট মানে আরও বেশি প্রমাণ হওয়া উচিত, প্রমাণ ছাড়া আরও বেশি আত্মবিশ্বাস নয়।
কাজের প্রকৃত একক হলো পরিবর্তন
এডিটর এবং কোডিং টুলগুলো ফাইলকে কেন্দ্র করে সাজানো, কারণ আমরা ফাইলই পরিবর্তন করি। ইঞ্জিনিয়ারিং টিমগুলো সংগঠিত হয় পরিবর্তনকে ঘিরে।
একটি পরিবর্তনের শুরু হয় একটি কারণ দিয়ে। সেটি রিকোয়ারমেন্টে রূপ নেয়, কোড ও ডেটাকে স্পর্শ করে, রিভিউয়ের মধ্য দিয়ে যায়, প্রোডাকশনে পৌঁছায়, এবং নতুন প্রমাণ তৈরি করে। যদি এই ধাপগুলো বিচ্ছিন্নই থেকে যায়, তবে ভবিষ্যতের প্রতিটি কাজ আবারও নতুন করে প্রত্নতাত্ত্বিক অনুসন্ধান দিয়ে শুরু হবে।
বাস্তব সফটওয়্যারে কাজ করা একটি AI সিস্টেমের সেই লাইফসাইকেলই অনুসরণ করা উচিত।
ইমপ্লিমেন্টেশনের আগে, এটিকে অনুরোধটি, প্রাসঙ্গিক সীমাবদ্ধতাগুলো, এবং পরস্পরবিরোধী কোনো উৎস আছে কি না—তা শনাক্ত করতে হবে। এটিকে বুঝতে হবে, এটি কি একটি ত্রুটি ঠিক করছে, প্রত্যাশিত আচরণ বদলাচ্ছে, নাকি একটি নতুন চুক্তি প্রবর্তন করছে।
ইমপ্লিমেন্টেশনের সময়, প্রতিটি অর্থবহ সিদ্ধান্তকে প্রমাণের সঙ্গে যুক্ত করতে হবে। কেন এই মডিউল? কেন এই মাইগ্রেশন কৌশল? কেন এই ব্রাঞ্চটি রাখা হবে? যে ব্যাখ্যা থেকে কোড তৈরি হয়েছে, তা যেন সেই চ্যাটের বাইরেও টিকে থাকে।
বাস্তবায়নের পর, এটি পরিবর্তনের সঙ্গে যাচাইকরণের ফলাফল, পর্যালোচনার সিদ্ধান্ত এবং নতুনভাবে আবিষ্কৃত সীমাবদ্ধতাগুলো যুক্ত করা উচিত। নইলে পরের ব্যক্তি—অথবা পরের AI সেশন—কে সেগুলো আবার নতুন করে খুঁজে বের করতে হবে।
এটাই সেই পার্থক্য, যেখানে একদিকে আছে এমন একটি টুল যা একটি repository সম্পাদনা করতে পারে, আর অন্যদিকে আছে এমন একটি সিস্টেম যা প্রকৌশলগত কাজে অংশ নিতে পারে।
AI-এর কাজ হওয়া উচিত পুনর্গঠনের প্রয়োজন কমানো, বিচারবোধ সরিয়ে দেওয়া নয়
আরও ভালো context-কে কখনও কখনও স্বয়ংক্রিয় সফটওয়্যার উন্নয়নের পথে হিসেবে উপস্থাপন করা হয়। এর তাৎক্ষণিক মূল্য ততটা নাটকীয় নয়, বরং আরও ব্যবহারিক: কোনো পরিবর্তন আনার আগে বাস্তবতা পুনর্গঠনের খরচ কমিয়ে দেওয়া।
AI মূল requirement-টিকে প্রাসঙ্গিক code-এর পাশে এনে দিতে পারে। এটি এমন কোনো incident সামনে আনতে পারে, যা ব্যাখ্যা করে কেন একটি অস্বাভাবিক safeguard রাখা হয়েছে। এটি কোনো ব্যর্থ metric-কে সেই release-এর সঙ্গে যুক্ত করতে পারে, যা সেটিকে বদলে দিয়েছিল। বাস্তবায়ন শুরু হওয়ার আগেই এটি দেখাতে পারে যে দুটি authoritative source একে অপরের সঙ্গে একমত নয়।
এই সক্ষমতাগুলো প্রকৌশলগত বিচারবোধকে সরিয়ে দেয় না। এগুলো বিচারবোধকে আরও তথ্যসমৃদ্ধ করে তোলে।
কোন tradeoff গ্রহণযোগ্য, কোনো requirement সম্পূর্ণ কি না, এবং একটি release কতটা ঝুঁকি বহন করতে পারে—এসব সিদ্ধান্ত এখনও একজন মানুষকেই নিতে হয়। সিস্টেমের কাজ হওয়া উচিত প্রমাণকে দৃশ্যমান করা এবং যুক্তিকে পরিদর্শনযোগ্য রাখা। একটি মসৃণ patch-এর আড়ালে অনিশ্চয়তাকে লুকিয়ে রাখা তার কাজ নয়।
মানদণ্ডটি “এটি কি code তৈরি করতে পারে?” নয়।
মানদণ্ডটি হলো “এটি কি ব্যাখ্যা করতে পারে কেন এই মুহূর্তে এটাই সঠিক পরিবর্তন?”
repository-aware থেকে work-aware
কোডিং সহকারীরা প্রথমে উপযোগী হয়ে ওঠে ডেভেলপারের সামনে থাকা file-টি বুঝতে পারার মাধ্যমে। Repository awareness ছিল পরবর্তী বড় পদক্ষেপ: সম্পর্কিত code খুঁজে বের করা, symbol অনুসরণ করা, এবং একটি project জুড়ে পরিবর্তন প্রয়োগ করা।
পরবর্তী ধাপ হলো repository-কে ঘিরে থাকা কাজ সম্পর্কে সচেতনতা।
এর মানে হলো code-কে সেই specification-এর সঙ্গে যুক্ত করা, যা এটি চেয়েছিল; সেই conversation-এর সঙ্গে, যা এটিকে স্পষ্ট করেছিল; সেই production evidence-এর সঙ্গে, যা এটিকে চ্যালেঞ্জ করেছিল; এবং সেই সিদ্ধান্তের সঙ্গে, যা পরে মনে রাখা উচিত। এর মানে এটাও যে, যে context অপ্রাসঙ্গিক, পুরোনো, বা ব্যবহারকারীর অনুমতির বাইরে, সেটিকে বাদ দিতে হবে।
Dvina তৈরি করতে গিয়ে, আমরা বারবার এই ধারণাটিতে ফিরে আসি। কাজ কোনো একক file, application, বা conversation-এর ভেতরে ঘটে না। অর্থ বাস করে তাদের পারস্পরিক সংযোগে, এবং সময়ের সঙ্গে সেই সংযোগগুলো কীভাবে বদলায় তাতে।
repository এখনও অপরিহার্য। এটি সিস্টেমের আচরণের জন্য কার্যকরযোগ্য source of truth। তবে product intent, operational reality, বা organizational memory-এর জন্য এটি সম্পূর্ণ source of truth নয়।
পুরো প্রেক্ষাপটই বদলে দেয় কী তৈরি হবে
শুধু code থাকলে, স্বাভাবিক প্রশ্নটি হয়:
এই সিস্টেমের সঙ্গে মানানসই কোন পরিবর্তন?
আরও বিস্তৃত context থাকলে, প্রশ্নটি হয়ে যায়:
কোন পরিবর্তন এই সিস্টেম, এই requirement, এই ইতিহাস, এবং এই মুহূর্তের সঙ্গে মানানসই?
দ্বিতীয় প্রশ্নটি সীমাবদ্ধতাগুলোকে রিগ্রেশনে পরিণত হওয়ার আগেই ধরে ফেলে। এটি রিভিউয়ারদের ইমপ্লিমেন্টেশনের পেছনের যুক্তি বুঝতে সাহায্য করে। এটি নতুন টিম সদস্যদের বুঝতে সাহায্য করে কেন সিস্টেমটি এমন দেখায়। এটি AI-কে একটি বাস্তবভিত্তিক ভূমিকা দেয়: এডিটরের ভেতরে কোনো ওরাকল নয়, বরং এমন এক অংশগ্রহণকারী, যে কাজজুড়ে থাকা প্রমাণ একত্র করতে পারে।
আপনার repo কখনোই পুরো গল্প ছিল না।
সুযোগ হলো এমন সিস্টেম তৈরি করা, যা এর বাকি অংশও পড়তে পারে—এবং কীভাবে সিদ্ধান্তে পৌঁছেছে তা দেখাতে পারে।

