কোডিং এজেন্ট আপনার নির্দেশনা উপেক্ষা করে কেন
নির্দেশনা মেনেও এজেন্ট কাজ বন্ধ করে না? context window, অস্পষ্ট নিয়ম, বিরোধী code এবং compaction কীভাবে কারণ হয়, তা যাচাইয়ের ব্যবহারিক diagnosis জানুন।
কোডিং এজেন্ট আপনার নির্দেশনা উপেক্ষা করে কেন
কোডিং এজেন্ট আপনার নির্দেশনা উপেক্ষা করে চারটি কারণে। এর কোনোটিই অতিরিক্ত ভদ্র হওয়া নয়। নিয়মটি কখনো context window-তে ছিল না। নিয়মটি এত অস্পষ্ট ছিল যে কোনো কাজের সঙ্গে মিলিয়ে যাচাই করা যায়নি। context-এর অন্য কোনো বিষয় নিয়মটির বিরোধিতা করেছে; সাধারণত এজেন্ট এইমাত্র যে code পড়েছে, সেটিই এর কারণ। অথবা নিয়মটি এখনো loaded আছে, কিন্তু বর্তমান turn থেকে অনেক দূরে অবস্থান করছে এবং এজেন্ট কাছের বিষয়গুলো অনুসরণ করছে।
প্রতিটি কারণের আলাদা সমাধান আছে। তাই প্রথম কাজ হলো কারণগুলো আলাদা করা। বড় হাতের অক্ষর বা IMPORTANT শব্দ ব্যবহার করা কোনো diagnosis নয়। নিচের ব্যাখ্যায় Claude Code-কে উদাহরণ হিসেবে ব্যবহার করা হয়েছে, কারণ August 2026 পর্যন্ত এর loading এবং compaction আচরণ বিস্তারিতভাবে documented আছে। অন্যান্য tool-এর খুঁটিনাটি ভিন্ন হলেও সামগ্রিক আচরণ একই।
প্রথমে দুটি term। context window হলো কোনো নির্দিষ্ট turn-এ model যে text দেখে: system prompt, আপনার instruction file, conversation এবং agent যে প্রতিটি file পড়েছে। harness হলো model-এর চারপাশের program; এটি disk থেকে file পড়ে এবং সেই text block তৈরি করে। এই post-এর প্রায় প্রতিটি অভিযোগ আসলে model সম্পর্কে নয়, harness সম্পর্কে।
আপনার instruction file কোনো setting নয়, এটি একটি message
Instruction file configuration নয়। Runtime-এর কোনো অংশ CLAUDE.md পড়ে সেটি প্রয়োগ করে না। Harness disk থেকে file-টি পড়ে তার text conversation-এ বসায়। Claude Code-এ এই content system prompt-এর পরে একটি user message হিসেবে পাঠানো হয়। তাই model আপনার rules-কে আপনার লেখা অন্য যেকোনো text-এর মতোই দেখে।
এর একটি অস্বস্তিকর পরিণতি আছে। Window-তে থাকা অন্য সব text-এর সঙ্গে আপনার rules সমান ভিত্তিতে প্রতিযোগিতা করে। একটি rule হলো একটি claim। Agent সদ্য যে file খুলেছে, সেটি হলো evidence। দুটির মধ্যে অমিল হলে evidence প্রায়ই জয়ী হয়। কোনো error-ও দেখানো হয় না, কারণ model-এর দৃষ্টিতে কিছুই ভুল ঘটেনি।
Official documentation-এ বিষয়টি স্পষ্টভাবে বলা আছে: instruction file-কে enforced configuration নয়, context হিসেবে বিবেচনা করা হয়। Model যা সিদ্ধান্তই নিক না কেন, কোনো action আটকাতে হলে sentence নয়, hook প্রয়োজন। এই কথাটি মনে রাখুন। এই post-এর শেষে দেওয়া অধিকাংশ fix হলো নির্দিষ্ট একটি ক্ষেত্রে এই নীতির প্রয়োগ।
কোন নির্দেশনা ফাইল লোড হয় এবং কখন
Claude Code আপনি যে directory থেকে এটি শুরু করেছেন, সেখান থেকে directory tree বরাবর উপরের দিকে যায়। filesystem root থেকে আপনার working directory পর্যন্ত প্রতিটি CLAUDE.md এবং CLAUDE.local.md launch-এর সময় সম্পূর্ণভাবে লোড হয়। এগুলো সেই ক্রমে একত্র করা হয়। তাই আপনি যেখান থেকে Claude Code শুরু করেছেন, তার সবচেয়ে কাছের ফাইলটি সর্বশেষ পড়া হয়। একই directory-এর মধ্যে .local ফাইলটি মূল ফাইলের পরে যুক্ত হয়।
আপনার working directory-এর নিচে থাকা subdirectory-গুলোর ফাইল ভিন্নভাবে কাজ করে। এগুলো launch-এর সময় লোড হয় না। agent ওই directory-এর কোনো ফাইল পড়লে তখন এগুলো লোড হয়। .claude/rules/-এর path scoped rule-গুলোর ক্ষেত্রেও একই নিয়ম প্রযোজ্য, যদি সেগুলোতে paths: frontmatter field থাকে। matching file পড়ার সময় এগুলো context-এ যুক্ত হয়, প্রতিটি turn-এ নয়।
Reported failure-এর বড় একটি অংশ এই পার্থক্য দিয়ে ব্যাখ্যা করা যায়। আপনি packages/api/CLAUDE.md-এ একটি rule রাখলেন, API সম্পর্কে একটি প্রশ্ন করলেন, এবং agent packages/api/-এর কোনো ফাইল না খুলেই উত্তর দিল। rule-টি উপেক্ষা করা হয়নি। এটি কখনো context-এ উপস্থিতই ছিল না। আপনার repository যদি monorepo-তে প্রতিটি package-এর জন্য আলাদা instruction file-এ নির্দেশনা ভাগ করে, তাহলে প্রতিবার প্রথমে এই বিষয়টি পরীক্ষা করুন।
আরও একটি loading trap আছে। "agent আমার নির্দেশনা উপেক্ষা করেছে" সমস্যার এটিই সবচেয়ে সাধারণ ধরন। Claude Code AGENTS.md নয়, CLAUDE.md পড়ে। কোনো repository যদি AGENTS.md-কে standard হিসেবে ব্যবহার করে এবং সেখানে CLAUDE.md না থাকে, তাহলে Claude Code লোড করার মতো কিছুই পায় না। সমর্থিত bridge হলো একটি CLAUDE.md, যার প্রথম line-এ @AGENTS.md থাকে। এটি launch-এর সময় ওই ফাইল import করে। এর নিচে Claude নির্দিষ্ট নোট যোগ করা যায়। অতিরিক্ত কিছু যোগ করার না থাকলে symlink-ও কাজ করে। প্রথমে ওই ফাইলে কী রাখা উচিত, সেটি আলাদা প্রশ্ন। এ বিষয়ে agent instruction-কে human documentation থেকে আলাদা করা অংশে আলোচনা করা হয়েছে।
পুনর্লিখনের আগে ফাইলটি লোড হয়েছে কি না নিশ্চিত করুন
এজেন্ট ফাইলটি দেখতে পারছে—এমন প্রমাণ না পাওয়া পর্যন্ত কোনো শব্দ পরিবর্তন করবেন না। দুটি পরীক্ষা আছে। প্রথমে সহজ পরীক্ষাটি চালান।
সেশনের ভেতরে /context চালান। এটি বর্তমান window-কে category অনুযায়ী ভাগ করে দেখায়, এবং Memory files তালিকায় বাস্তবে লোড হওয়া প্রতিটি instruction file-এর নাম থাকে। কোনো ফাইল এই তালিকায় না থাকলে সেটি conversation-এর অংশ নয়। তাই ওই ফাইলের ভেতরে লেখা কোনো নির্দেশ কার্যকর হবে না। /memory ফাইলের অবস্থানগুলোর তালিকা দেখায় এবং সেগুলো editing-এর জন্য খোলে; এখনো না থাকা ফাইলও এর অন্তর্ভুক্ত।
আরও নির্ভরযোগ্য তথ্যের জন্য load event log করুন। কোনো CLAUDE.md বা rules file context-এ প্রবেশ করলেই InstructionsLoaded hook event চালু হয়। এর matcher জানায় load কেন হয়েছে: session_start, nested_traversal, path_glob_match, include অথবা compact। .claude/settings.json-এ এটি রাখুন:
{
"hooks": {
"InstructionsLoaded": [
{
"matcher": "nested_traversal",
"hooks": [
{
"type": "command",
"command": "cat >> /tmp/instructions-loaded.log"
}
]
}
]
}
}hook তার payload standard input-এ JSON হিসেবে পায়। তাই cat পুরো record-টি যোগ করে। কাজ করার সময় tail -f /tmp/instructions-loaded.log দিয়ে এটি দেখুন। এই event-এর exit status উপেক্ষা করা হয়। ফলে hook শুধু পর্যবেক্ষণ করতে পারে, load বন্ধ করতে পারে না। যে session-এ nested file লোড হওয়ার কথা, সেই session চলাকালে log-এ ফাইলটি না দেখা গেলে rewording বন্ধ করুন। সমস্যা file placement-এ।
দীর্ঘ সেশন আপনার নিয়মগুলোর ওপর কী প্রভাব ফেলে
এখানে দুটি পৃথক প্রভাব কাজ করে এবং এগুলোর জন্য ভিন্ন প্রতিক্রিয়া প্রয়োজন।
দূরত্ব। turn 1-এ উল্লেখ করা কোনো নিয়ম turn 90-এও context window-তে থাকে। তবে তখন সেটি আপনার বর্তমান কাজের সঙ্গে আরও সাম্প্রতিক এবং আরও নির্দিষ্ট 90টি turn-এর পাঠ্যের সঙ্গে প্রতিযোগিতা করে। এটি configuration দিয়ে পুরোপুরি দূর করা যায় না, তবে মাপা যায়। একই কাজ একটি নতুন সেশনে চালান। সেখানে নিয়মটি কার্যকর থাকে কিন্তু দীর্ঘ সেশনের অনেক পরে ব্যর্থ হলে, কারণটি দূরত্ব।
সংক্ষিপ্তকরণ। window পূর্ণ হলে harness এ পর্যন্ত কথোপকথনের সারাংশ তৈরি করে এবং সেই সারাংশ থেকে কাজ চালিয়ে যায়। কোন তথ্য টিকে থাকবে, তা summariser গুরুত্বপূর্ণ মনে করেছে কি না তার ওপর নির্ভর করে। আপনি কোন তথ্যকে গুরুত্বপূর্ণ মনে করেন, তার সঙ্গে এটি এক নয়। Claude Code প্রতিটি mechanism-এর ফলাফল আলাদাভাবে নথিভুক্ত করে এবং পার্থক্যগুলো বড়। Project root CLAUDE.md এবং unscoped rules compaction-এর পরে disk থেকে আবার inject করা হয়। Auto memory disk থেকে আবার inject করা হয়। paths: frontmatter-যুক্ত নিয়মগুলো হারিয়ে যায়, যতক্ষণ না matching file আবার পড়া হয়। Subdirectory-র nested CLAUDE.md files হারিয়ে যায়, যতক্ষণ না ওই subdirectory-র কোনো file আবার পড়া হয়।
ওই table অনুযায়ী আপনার instructions-এর অগ্রাধিকার নির্ধারণ করলে fragility-এর ক্রমটি স্পষ্ট হয়। আপনি শুধু chat-এ টাইপ করেছেন এমন নিয়ম সেশনের সবচেয়ে ভঙ্গুর অংশ। Summary-তে সেটি থাকলেই কেবল তা টিকে থাকে। packages/api/CLAUDE.md-এর কোনো নিয়মের ভঙ্গুরতা পরের স্তরে, কারণ সেটি একবার load হওয়ার পরে summary-তে বাদ পড়ে এবং ওই directory-তে পরের read না হওয়া পর্যন্ত ফিরে আসে না। Project root file-এর নিয়ম সবচেয়ে টেকসই, কারণ প্রতিবার এটি disk থেকে আবার পড়া হয়।
তাই কোনো instruction যদি পুরো session জুড়ে কার্যকর থাকতে হয়, সেটি project root file-এ রাখুন এবং কোনো paths: frontmatter ব্যবহার করবেন না। অন্য সব ক্ষেত্রে সচেতনভাবে tradeoff নির্ধারণ করুন। context window-তে কী থাকে তা পরিচালনা করা-এ /compact-এর একটি focus argument এবং অসংলগ্ন কাজের মধ্যে /clear নিয়ে আলোচনা করা হয়েছে। দুটিই summariser আপনার নিয়মগুলোর অর্থ নির্ধারণের সুযোগ কত ঘন ঘন পায়, তা পরিবর্তন করে।
কেন আশপাশের code rule-কে ছাপিয়ে যায়
এটি এমন একটি ব্যর্থতা, যা মানুষ সবচেয়ে বেশি বর্ণনা করে এবং সবচেয়ে কম শনাক্ত করে। আপনার file-এ বলা আছে, database access repository layer-এর মাধ্যমে করতে হবে। Agent এমন একটি handler লেখে, যা ORM (object relational mapper)-কে সরাসরি কল করে। Style-এর কারণে agent আপনাকে উপেক্ষা করেনি। বরং evidence-এর ওজন বেশি ছিল।
একটি rule একটি পছন্দের কথা জানায়। Code সেই পছন্দের বাস্তব উদাহরণ দেখায়। Agent যে module সম্পাদনা করতে যাচ্ছে, সেখানে তিনটি file খুলে যদি দেখে তিনটিই ORM-কে সরাসরি কল করছে, তাহলে context-এর এক পাশে থাকে একটি abstract sentence, আর অন্য পাশে থাকে সাম্প্রতিক কাজের সঙ্গে মিলে যাওয়া তিনটি concrete example। স্থানীয় pattern অনুকরণ করা সাধারণত সঠিক আচরণ। এখানে এটি শুধু এই কারণে ভুল, কারণ আপনি এমন কিছু জানেন যা context জানে না: file-গুলো legacy।
তাই rule-এর মধ্যেই সেটি লিখুন। যে rule নিজস্ব counter-evidence উল্লেখ করে, তা বাস্তব repository-তে টিকে থাকে। যে rule শুধু একটি সাধারণ preference জানায়, তা টেকে না।
New database accessapp/repositories/-এর মাধ্যমে করতে হবে।app/legacy/-এর অধীনের file-গুলো এখনও ORM-কে সরাসরি কল করে। সেগুলো পুরোনো code, pattern নয়। সেগুলো অনুকরণ করবেন না।
দ্বিতীয় sentence-টিই মূল কাজ করে। Agent code খুঁজে পাওয়ার আগেই এটি জানিয়ে দেয় যে কী দেখতে যাচ্ছে এবং সেটি কীভাবে ব্যাখ্যা করতে হবে। একই সংশোধন repository যে কোনো দৃশ্যমানভাবে বিরোধী rule-এর ক্ষেত্রেও প্রযোজ্য: এমন একটি commit style, যা আপনার history অনুসরণ করে না; এমন একটি test layout, যা আপনার suite-এর অর্ধেকও ব্যবহার করে না; অথবা এমন একটি import convention, যা শুধু নতুন code-এ প্রযোজ্য। Code এবং file-এর মধ্যে যেখানে অমিল আছে, file-এ সেই অমিলটি স্পষ্টভাবে উল্লেখ করুন।
অস্পষ্ট নিয়ম যাচাই করা যায় না, তাই তা অনুসরণ করাও যায় না
"পরিষ্কার code লিখুন।" "অতিরিক্ত engineering করবেন না।" "সরল রাখুন।" "Migration-এর ক্ষেত্রে সতর্ক থাকুন।" নির্দিষ্ট কোনো কাজের ভিত্তিতে এগুলোর কোনোটিই পরীক্ষা করা যায় না—agent বা আপনি, কেউই তা করতে পারবেন না। এমন কোনো নিয়ম দেওয়া হলে, যার ভিত্তিতে agent নিজের output যাচাই করতে পারে না, agent অনুমান করে কাজ করে; আর আপনি সেই অনুমানকে অনুভূতির ভিত্তিতে মূল্যায়ন করেন।
আপনার file-এর প্রতিটি লাইনে এই পরীক্ষা প্রয়োগ করুন। নিয়মটি ভাঙলে non-zero exit করবে—এমন shell command লিখুন। সেই command লিখতে না পারলে নিয়মটি যাচাইযোগ্য নয়। এই জোড়াগুলো তুলনা করুন:
- যাচাইযোগ্য নয়: "Function ছোট রাখুন।" যাচাইযোগ্য: "60 line-এর বেশি দীর্ঘ function-এর ঠিক উপরে কেন এমন দৈর্ঘ্য প্রয়োজন, তা ব্যাখ্যা করে একটি comment থাকতে হবে।"
- যাচাইযোগ্য নয়: "আপনার পরিবর্তন পরীক্ষা করুন।" যাচাইযোগ্য: "কোনো task সম্পন্ন বলার আগে
npm testচালিয়ে failure count paste করুন।" - যাচাইযোগ্য নয়: "File-গুলো সুশৃঙ্খল রাখুন।" যাচাইযোগ্য: "HTTP handler-গুলো
src/api/handlers/-এ থাকবে। ওই directory-তে অন্য কিছু রাখা যাবে না।" - যাচাইযোগ্য নয়: "Code সঠিকভাবে format করুন।" যাচাইযোগ্য: "
.tsfile-এ 2 space indentation ব্যবহার করুন।"
"অতিরিক্ত engineering করবেন না"—এই নিয়মটি মানুষ প্রথমেই বাদ দেয়। কারণ এর সমাধান ছোট বাক্য নয়, বরং দীর্ঘ বাক্য: কাজ করে এমন সবচেয়ে ছোট পরিবর্তনের প্রকৃত অর্থ স্পষ্ট করে বলা agent-কে এমন criteria দেয়, যার সঙ্গে সে নিজের diff মিলিয়ে দেখতে পারে।
Size-এর ক্ষেত্রেও একই সমস্যা, শুধু ভিন্ন রূপে। Claude Code-এর নির্দেশনায় প্রতিটি instruction file 200 line-এর কম রাখার লক্ষ্য দেওয়া হয়েছে এবং সরাসরি বলা হয়েছে যে দীর্ঘ file adherence কমায়। 700 line-এর file বেশি দৃঢ় instruction নয়। এটি পরস্পরের সঙ্গে বিরোধের আরও বেশি সম্ভাবনাসহ 700 line-এর দাবি। উপরন্তু, প্রতিটি turn-এ এই file আপনার window-এর সীমার মধ্যে গণনা হয়, যা আপনার token usage-এ সরাসরি দেখা যায়। এমনভাবে file-এর কাঠামো তৈরি করা, যাতে পাঠক scan করে প্রতিটি নিয়মের heading খুঁজে পান, তা agent কার্যকরভাবে অনুসরণ করতে পারে এমন instruction file লেখা-তে ব্যাখ্যা করা হয়েছে।
দশ মিনিটে কীভাবে সমস্যাটি নির্ণয় করবেন
নিচের কমান্ডগুলো ক্রমানুসারে চালান। শেষ ধাপে সরাসরি চলে গেলে শেষে এমন একটি দীর্ঘ ফাইল তৈরি হয়, যেখানে জোর দিয়ে লেখা নিয়ম থাকলেও সেগুলো কাজ করে না।
- এটি লোড হয়েছে কি না নিশ্চিত করুন।
/contextচালিয়ে Memory files তালিকা দেখুন। ফাইলটি সেখানে না থাকলে অবস্থান ঠিক করুন এবং থামুন। এই তালিকার অন্য কোনো ধাপ এখনো প্রযোজ্য নয়। - একটি নতুন session-এ পুনরুৎপাদন করুন। একটি নতুন session শুরু করুন এবং নিয়মটি সক্রিয় করার মতো সবচেয়ে ছোট task দিন। নতুন session-এ কাজ হলেও দীর্ঘ session-এ ব্যর্থ হলে context distance বা compaction-এর সমস্যা হতে পারে। নতুন session-এও ব্যর্থ হলে সমস্যাটি নিয়মটির মধ্যেই।
- প্রতিদ্বন্দ্বী নির্দেশনা সরান। এমন একটি directory-তে একই পরিবর্তনের অনুরোধ করুন, যার বিদ্যমান code ইতিমধ্যে নিয়মটি অনুসরণ করে। নিয়ম মেনে চলা ফিরে এলে বুঝবেন, আশপাশের code আপনার বাক্যকে ছাপিয়ে যাচ্ছিল।
- সংঘাত খুঁজুন। একই আচরণ সম্পর্কে দুটি ফাইলে ভিন্ন নির্দেশনা থাকা একটি নথিভুক্ত ব্যর্থতার কারণ। model ইচ্ছামতো যেকোনো একটি বেছে নিতে পারে এবং তা আপনাকে জানাবে না।
- নিয়মটি যাচাইযোগ্য করে আবার পরীক্ষা করুন। একটি নির্দিষ্ট path এবং একটি condition দিয়ে নিয়মটি নতুন করে লিখুন। নিয়ম মেনে চলার হার উল্লেখযোগ্যভাবে বাড়লে বুঝবেন, সমস্যার কারণ ছিল phrasing।
ধাপ 4-এর জন্য একটি command-ই যথেষ্ট। শুধু যে ফাইলটি সম্পাদনা করছিলেন সেটি নয়, বিষয়টি নিয়ে সব instruction source-এ search করুন:
grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/nullদুটি ফাইলে ভিন্ন নির্দেশনা পাওয়া গেলে সেটিই আপনার bug। একটি মুছে ফেলুন। আরও জোরালো ভাষা ব্যবহার করে কোনোটিকে অগ্রাধিকার দেওয়ার চেষ্টা করবেন না, কারণ অগ্রাধিকার নির্ধারণের জন্য কোনো ranking engine নেই।
প্রভাবের ক্রম অনুযায়ী সমাধান
নিচের প্রতিটি ধাপ আগের ধাপের তুলনায় বেশি কার্যকর, তবে সেটআপ করতেও বেশি সময় লাগে। কোনো নিয়ম সহজে নতুনভাবে লিখে ঠিক করা গেলে ওপরের ধাপ থেকে শুরু করুন। কোনো নিয়ম এত গুরুত্বপূর্ণ হয়ে উঠলে যে মাঝে মাঝে বাদ পড়া গ্রহণযোগ্য নয়, তখনই নিচের ধাপে যান।
- নিয়মটি নির্দিষ্ট করুন। একটি path, command বা condition উল্লেখ করুন। আগে দেখানো পদ্ধতিতে agent repository-তে যে বিপরীত প্রমাণ খুঁজে পাবে, সেটিও যোগ করুন। এতে কোনো অতিরিক্ত খরচ নেই এবং আশ্চর্যজনকভাবে অনেক ক্ষেত্রে সমস্যার সমাধান হয়।
- নিয়মটি যার ওপর প্রযোজ্য, তার কাছাকাছি রাখুন। একটি nested
CLAUDE.md,.claude/rules/-এ path-scoped rule, অথবা ফাইলের একেবারে শুরুতে একটি comment ব্যবহার করতে পারেন। এতে নিয়মটি যে code-এর ওপর প্রযোজ্য, সেটির সঙ্গে একই read-এ agent-এর কাছে পৌঁছায়। এর বিনিময়টি মেনে নিন: এভাবে load হওয়া যেকোনো বিষয় পরবর্তী compaction-এ context থেকে বাদ পড়ে এবং পরের matching read-এ আবার ফিরে আসে। - Enforcement একটি hook-এ সরিয়ে নিন। Prose অনুরোধ করে। Hook সিদ্ধান্ত নেয়। Hook নির্দিষ্ট lifecycle event-এ code হিসেবে চলে এবং model যা সিদ্ধান্ত নেয় তা নির্বিশেষে নিয়ম প্রয়োগ করে।
- নিয়মটি একটি deterministic tool-এর কাছে দিন এবং prose মুছে ফেলুন। Formatting, import order, line length, নিষিদ্ধ import এবং commit message-এর format-এর মতো বিষয় এতে পড়ে।
ruff format,prettier --write,eslintঅথবা একটিpre-commithook ব্যবহার করুন। Formatter প্রতিবার সঠিক ফল দেয় এবং কোনো token খরচ করে না। বাক্যটি বেশিরভাগ সময় সঠিকভাবে কাজ করে, কিন্তু প্রতিটি turn-এ token খরচ করে।
ধাপ 3 বিস্তারিতভাবে দেখা যাক। ধরুন, agent কখনো migration file সম্পাদনা করতে পারবে না। .claude/settings.json-এ এটি রাখুন:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
}
]
}
]
}
}এবং .claude/hooks/guard-migrations.sh-এ এটি রাখুন:
#!/usr/bin/env bash
set -euo pipefail
path=$(jq -r '.tool_input.file_path // empty')
case "$path" in
*/migrations/*)
echo "Files under migrations/ are written by hand. Stop and ask first." >&2
exit 2
;;
esac
exit 0chmod +x .claude/hooks/guard-migrations.sh চালান। এরপর একটি নতুন session শুরু করে agent-কে migrations/-এর অধীনে থাকা কোনো file সম্পাদনা করতে বলুন। সম্পাদনাটি প্রত্যাখ্যান হবে এবং কারণ হিসেবে আপনার message ফেরত আসবে। PreToolUse-এ exit status 2 সেট থাকলে tool call চালানোর আগেই তা আটকে যায়, আর আপনার stderr text model-এর কাছে blocking message হিসেবে পাঠানো হয়। ${CLAUDE_PROJECT_DIR} project root-এ resolve হয়, তাই agent যে directory-তেই থাকুক না কেন hook কাজ করে। Agent-কে নিয়মটির সঙ্গে একমত হতে, নিয়মটি মনে রাখতে বা নিয়মটি তখনও context-এ রাখতে হয় না। সম্পাদনাটি হয় না।
কোনো logic ছাড়া সরল prohibition-এর জন্য আপনার settings-এ permissions.deny ব্যবহার করলেও একই কাজ হয়, তবে maintain করার মতো কোনো script লাগে না। কোনটি আপনার কাছে অনুমতি না চেয়েই চলবে, তা permission mode নির্ধারণ করে। কোনো instruction সত্যিই user message-এর বদলে system prompt level-এ থাকতে হলে --append-system-prompt সেটি সেখানে রাখে। তবে এটি প্রতিটি invocation-এ pass করতে হয়, তাই interactive কাজের চেয়ে script-এর জন্য এটি বেশি উপযোগী।
যে বিষয় নির্দেশ দিয়ে এড়ানো যায় না
এর কোন অর্ধেক আপনার দায়িত্ব, তা স্পষ্টভাবে নির্ধারণ করুন। কোথায় রাখা হবে, কীভাবে লেখা হবে, বিভিন্ন file-এর মধ্যে বিরোধ এবং file-এর আকার—এগুলো author-এর সমস্যা এবং author-ই সমাধান করবেন। বাকি বিষয়গুলো model-এর আচরণের অংশ; ভালো wording ব্যবহার করলেও সেগুলো পুরোপুরি দূর হবে না।
সম্মতি compliance নয়। কোনো agent একটি rule স্বীকার করতে পারে, সেটি সঠিকভাবে পুনরাবৃত্তি করতে পারে, এবং দুইটি tool call পরেই rule ভঙ্গ করতে পারে। এই স্বীকৃতির কোনো খরচ নেই এবং এটি ভবিষ্যৎ আচরণের নির্ভরযোগ্য পূর্বাভাসও দেয় না। এটিকে সমাধান হিসেবে বিবেচনা করবেন না এবং test হিসেবেও গণনা করবেন না।
কিছু অভ্যাস স্থায়ী হয়। comment যোগ করা, defensive error handling যোগ করা, শেষে summary লেখা, অথবা স্বাভাবিক পরবর্তী command চালানো—এ ধরনের আচরণ নিষেধ করা হলেও আবার দেখা যায়। তবে হার কমে, শূন্য হয় না। নিজের হার মাপতে পারেন: fresh session-এ একই task দশবার চালান এবং violation-এর সংখ্যা গণনা করুন। যেখানে এই সংখ্যা শূন্য হওয়া দরকার, সেখানে rule-টি prompt-এ থাকা উচিত নয়।
আপনার session নিজেই একটি example হয়ে যায়। agent 12তম turn-এ rule ভঙ্গ করলে এবং আপনি তা মেনে নিলে, সেই violation context-এ demonstration হিসেবে থেকে যায়। এটি rule-এর চেয়ে অনেক বেশি সাম্প্রতিক। violation দেখামাত্র সংশোধন করুন। সংশোধন না করা violation session-এর বাকি অংশকে সেই আচরণ শেখায়।
একটি instruction file security boundary নয়। এটি আচরণকে প্রভাবিত করে, কিন্তু তা enforce করে না। যেসব ক্ষেত্রে ভুলের ক্ষতি বেশি—যেমন credentials বা destructive command—সেগুলো permissions বা hook-এর মাধ্যমে নিয়ন্ত্রণ করুন। agent-এর নাগালের বাইরে secret রাখা data-এর ক্ষেত্রেও একই নীতি প্রয়োগ করে: agent-কে কোনো file না পড়তে বলবেন না; বরং file-টি যাতে পড়া না যায়, সেই ব্যবস্থা করুন।
সংক্ষেপে: file-টি load হয়েছে কি না প্রমাণ করুন, rule-টিকে যাচাইযোগ্য করুন, rule-টি যে বিষয় নিয়ন্ত্রণ করে তার পাশে রাখুন, এবং miss rate গুরুত্বপূর্ণ থাকলে prose থেকে rule-টি সরিয়ে নিন। agent যে rule উপেক্ষা করতে পারে না, সেটি agent-কে দেওয়া কোনো rule নয়।
FAQ
Claude Code আমার CLAUDE.md উপেক্ষা করছে কেন?
উপেক্ষা করা হয়েছে ধরে নেওয়ার আগে ফাইলটি লোড হয়েছে কি না পরীক্ষা করুন। /context চালিয়ে Memory files তালিকাটি দেখুন; সেখানে নাম না থাকা কোনো ফাইল conversation-এর অংশ নয়। Instruction file-গুলো system prompt-এর পরে user message হিসেবে পাঠানো হয় এবং enforced configuration-এর বদলে context হিসেবে বিবেচিত হয়। তাই কঠোরভাবে মেনে চলার কোনো নিশ্চয়তা নেই। বাস্তবে সাধারণত চারটির একটি কারণ থাকে: ফাইলটি এমন একটি subdirectory-তে আছে যেখান থেকে agent কখনো পড়েনি, দুটি ফাইলে পরস্পরবিরোধী নির্দেশ আছে এবং model ইচ্ছামতো একটি বেছে নিয়েছে, নিয়মটি এত অস্পষ্ট যে কোনো action-এর সঙ্গে মিলিয়ে যাচাই করা যায় না, অথবা আশপাশের code নিয়মটির বিপরীত আচরণ দেখায়।
Session চলাকালে instruction file সম্পাদনা করলে কি কোনো পরিবর্তন হয়?
Conversation-এ ইতিমধ্যে থাকা copy-এর ক্ষেত্রে হয় না। আপনার working directory-এর ওপরের file-গুলো launch-এর সময় সম্পূর্ণভাবে লোড হয়। তাই model-এর কাছে থাকা text হলো launch-এর সময়কার text। সম্পাদিত version নিতে নতুন session শুরু করুন। অথবা agent-কে তার স্বাভাবিক file tools ব্যবহার করে file পড়তে বলুন। এতে বর্তমান version একটি নতুন message হিসেবে conversation-এ যুক্ত হবে। Compaction-এর পরে project root file disk থেকে আবার পড়া হয়। তাই সেই সময় নতুন version-ও যুক্ত হয়।
Root CLAUDE.md এবং nested file-এর মধ্যে মতবিরোধ হলে কোনটি কার্যকর হয়?
কোনোটিই নির্ভরযোগ্যভাবে নয়। আবিষ্কৃত file-গুলো একে অপরকে override না করে context-এর সঙ্গে concatenate করা হয়। এগুলো filesystem root থেকে working directory পর্যন্ত ক্রমানুসারে সাজানো থাকে। ফলে সবচেয়ে কাছের file-টি শুধু সবার শেষে পড়া হয়। Contradiction সমাধানের জন্য কোনো precedence engine নেই। Claude Code-এর documentation-এও বলা আছে যে পরস্পরবিরোধী নিয়ম arbitrarily resolve হতে পারে। Nested file-গুলো এমন addition হিসেবে লিখুন যেখানে সেগুলো কোন path নিয়ন্ত্রণ করে তা উল্লেখ থাকবে। অন্য নিয়মকে অতিক্রম করার চেষ্টা না করে contradiction মুছে ফেলুন।
আমার instructions কি /compact-এর পরেও থাকে?
কীভাবে লোড হয়েছে তার ওপর নির্ভর করে। Project root CLAUDE.md, unscoped rules এবং auto memory compaction-এর পরে disk থেকে আবার inject করা হয়। paths: frontmatter-যুক্ত rules এবং subdirectory-র nested CLAUDE.md file আবার matching file পড়া না হওয়া পর্যন্ত হারিয়ে যায়। Chat-এ শুধু টাইপ করা কোনো instruction summariser সেটি রেখে দিলে তবেই টিকে থাকে। কোনো নিয়ম পুরো session জুড়ে কার্যকর রাখতে হলে project root file-এ সেটি রাখুন এবং সেখানে কোনো paths: frontmatter ব্যবহার করবেন না।
কখন কোনো নিয়ম prose-এর বদলে hook হওয়া উচিত?
যখন check-টি deterministic এবং তা না মানার ক্ষতি একটি ছোট script লেখার খরচের চেয়ে বেশি হয়। File path restriction, commit-এর আগে প্রয়োজনীয় command এবং নিষিদ্ধ tool call—সবই এর অন্তর্ভুক্ত। একটি PreToolUse hook status 2 দিয়ে exit করলে tool call সরাসরি block হয় এবং stderr text-কে কারণ হিসেবে model-এর কাছে পাঠায়। ফলে নিয়মটি context-এ থাকুক বা না থাকুক, এটি কার্যকর থাকে। Formatter বা linter যে বিষয় নির্ধারণ করতে পারে, তার দায়িত্ব সেই tool-এর ওপর দিন এবং instruction file থেকে সেটি সম্পূর্ণভাবে মুছে ফেলুন।