AI এজেন্টকে কাজ কীভাবে দেবেন: একবারে একটি ফিচার, ফিচারের তালিকা ও সম্পন্নতার মানদণ্ড
AI এজেন্টকে কাজ একটি একটি করে দিন: কাজের মধ্যে সব সময় ঠিক একটি ফিচার থাকে, তার দেখা যায় এমন আচরণ এবং চালানো যায় এমন যাচাই-কমান্ড থাকে, আর পথে যা চোখে পড়ে এজেন্ট তা ব্যাকলগে লেখে, ঠিক করতে বসে না। প্রতিটি ফিচারের অবস্থা feature_list.json-এর মতো যন্ত্র-পাঠযোগ্য তালিকায় থাকে, আর «সম্পন্ন» অবস্থায় বদলাতে পারে কেবল যাচাই-স্ক্রিপ্ট, এজেন্ট নিজে নয়।
এজেন্ট সব কিছু একসঙ্গে ধরে কেন
আপনি এজেন্টকে বললেন রেজিস্ট্রেশন বানাতে। কয়েক ঘণ্টা পরে ডিফে বারোটি বদলানো ফাইল আর আটশো নতুন লাইন: ইউজার মডেল, ইমেইল যাচাই, মেইল সার্ভিস সংযোগ, পাসওয়ার্ড হ্যাশিং, নতুন করে লেখা middleware এবং সরানো টেস্ট। সবকিছু একে অন্যের সঙ্গে জড়িত, অথচ একটি সম্পূর্ণ দৃশ্যও পাস করে না। পরের সেশন এই কোড খুলে বুঝতে পারে না কোথা থেকে শুরু করতে হবে।
কারণটি «খারাপ মডেল» নয়। মানুষের মধ্যে «আজকের জন্য যথেষ্ট» অনুভূতি আর সাধারণ ক্লান্তি আছে, যা কাজের পরিধি নিজেই সীমিত করে। এজেন্টের এর কোনোটিই নেই। «আর একটু ইরর হ্যান্ডলিং-ও ঠিক করি» লিখতে তার কয়েক দশটি টোকেন লাগে, কিন্তু প্রকল্পের খরচ আসল: মনোযোগ ছড়িয়ে যায়, নির্ভরতা বাড়ে, আর কিছুই শেষ হয় না।
হিসাবটিও সরল। ধরা যাক C হলো কার্যকর কনটেক্সট ক্ষমতা, আর k হলো এজেন্টের একসঙ্গে ধরে রাখা কাজের সংখ্যা। প্রতিটি কাজ পায় প্রায় C/k পরিমাণ যুক্তির সামর্থ্য। এই মান যখন একটি কাজ শেষ করার জন্য যা লাগে তার নিচে নেমে যায়, তখন একটি কাজও শেষ হয় না। তাই AI এজেন্টকে কাজ কীভাবে দেবেন, এই প্রশ্নের উত্তর প্রম্পটের শব্দচয়ন দিয়ে শুরু হয় না, শুরু হয় একটি সীমা দিয়ে: একবারে একটিমাত্র কাজ।
একটি ফিচারের নিয়ম (WIP=1)
WIP হলো work in progress, অর্থাৎ একসঙ্গে চলা কাজের সংখ্যা। এজেন্টের জন্য এটি এক ধরা হয়: যেকোনো মুহূর্তে ঠিক একটি ফিচার সক্রিয় থাকে, এবং পরেরটি শুরু হয় কেবল তখনই, যখন বর্তমানটি যাচাই পাস করে। নিয়মটি প্রকল্পের নির্দেশনা-ফাইলে (AGENTS.md বা CLAUDE.md) লেখা হয়, যাতে এজেন্ট প্রতিটি সেশনে তা দেখে:
## কাজের নিয়ম
- যেকোনো সময় `active` অবস্থায় ঠিক একটি ফিচার থাকে।
- পরের ফিচার শুরু করা যাবে শুধু তখন, যখন বর্তমানটি `passing`-এ পৌঁছায়।
- «সঙ্গে সঙ্গে» রিফ্যাক্টর করা, নাম বদলানো, ডিরেক্টরি সাজানো
এবং সম্পর্কহীন বাগ ঠিক করা নিষিদ্ধ। সমস্যা চোখে পড়লে `BACKLOG.md`-এ লিখুন
এবং এগিয়ে যান।
- সক্রিয় ফিচারের পরিধির বাইরের বদল লঙ্ঘন হিসেবে গণ্য হবে, এমনকি যদি তা কাজের হয়।
শেষ নিয়মটি মনে হওয়ার চেয়ে বেশি গুরুত্বপূর্ণ। এজেন্ট তার «সঙ্গে সঙ্গে»-র কাজগুলোকে সত্যিই উপযোগী মনে করে, এবং অনেক সময় তা উপযোগীও হয়। কিন্তু পরিধির বাইরের উপযোগী বদলও একই ডিফে দুটি কাজকে মিশিয়ে দেয়, ফলে আলাদাভাবে ফেরত নেওয়া বা যাচাই করা আর যায় না।
BACKLOG.md: «সঙ্গে সঙ্গে»-র জিনিসগুলো কোথায় যাবে
«সঙ্গে সঙ্গে ঠিক করে দিই»-র ঝোঁককে শুধু নিষেধ করা যথেষ্ট নয়, তার একটি বৈধ পথ দরকার। সেই পথ হলো BACKLOG.md: এজেন্ট চোখে পড়া সমস্যা এক-দুই লাইনে লিখে রাখে এবং বর্তমান ফিচারে ফিরে আসে। তথ্য হারায় না, পরিধিও বাড়ে না। ব্যাকলগ না থাকলে WIP=1 নিয়মটি এজেন্ট ধীরে ধীরে এড়িয়ে যেতে শুরু করে, কারণ «বাগটা চুপচাপ রেখে দেওয়া» তার কাছে নিয়ম ভাঙার চেয়েও খারাপ মনে হয়।
# BACKLOG.md
- [ ] middleware/errors.py: /auth ও /orders-এ ত্রুটির ভিন্ন ফরম্যাট
- [ ] tests/: ইউজারের ফিক্সচার তিনটি ফাইলে নকল হয়ে আছে
- [ ] রেজিস্ট্রেশনে ইমেইল যাচাই লাগবে কি না? — জিজ্ঞেস করতে হবে
সম্পন্নতার মানদণ্ড: «সম্পন্ন» মানে একটি কমান্ড
সমস্যার দ্বিতীয় অংশ হলো এজেন্ট নিজেই ঠিক করে কাজটি শেষ হয়েছে কি না। «কোড দেখতে ঠিক আছে», «ফাংশনটি আছে», «কম্পাইল-ত্রুটি নেই» এগুলো অনুভূতি, তথ্য নয়। এজেন্টের জন্য সম্পন্নতার মানদণ্ড এমন একটি চালানো যায় এমন কমান্ড হতে হবে, যার ফলাফল স্পষ্ট: পাস বা ফেল।
F01: ইউজার রেজিস্ট্রেশন
verification: pytest tests/e2e/test_auth.py::test_register_flow
state: active
দুর্বল ও কঠোর মানদণ্ডের পার্থক্য উদাহরণে সবচেয়ে স্পষ্ট:
| দুর্বল মানদণ্ড | কঠোর মানদণ্ড |
|---|---|
| কোড কম্পাইল হয় | pytest tests/e2e/test_cart.py -q পাস করে |
| কোনো সিনট্যাক্স ত্রুটি নেই | /cart-এ curl করলে কোড 200 আসে |
ফাংশন addToCart আছে | পণ্য যোগ করার পরে GET /cart সেটি এবং সঠিক মোট দেখায় |
| দেখতে ঠিক লাগে | npx playwright test cart.spec.ts পাস করে |
ভালো যাচাই-কমান্ড নির্ধারক (একই কোডে একই ফল), মানুষের হস্তক্ষেপ ছাড়া চলে, এবং আচরণ বাইরে থেকে পরীক্ষা করে, ঠিক যেভাবে ব্যবহারকারী বা API ক্লায়েন্ট তা দেখবে। এমন কমান্ড লেখা না গেলে সেটি সংকেত যে কাজটি অস্পষ্টভাবে বলা হয়েছে।
ভাঙা: ফিচারের আকার কেমন হওয়া উচিত
«একবারে একটি ফিচার»-এর পরে সবচেয়ে বেশি প্রশ্ন ওঠে: ফিচার বলতে কী বোঝায়। খুব বড় কাজ একটি সেশনে শেষ হয় না, আর খুব ছোট কাজ চালু করা, প্রসঙ্গ পড়া ও যাচাইয়ের খরচে হারিয়ে যায়।
- খুব বড়: «কার্ট বানাও»। এটি এক সপ্তাহের কাজ এবং এক ডজন দৃশ্য।
- ঠিক মাপের: «ইউজার একটি পণ্য কার্টে যোগ করে তালিকায় দেখতে পায়»। একটি দেখা যায় এমন আচরণ, একটি যাচাই-দৃশ্য।
- খুব ছোট: «CartItem মডেলে quantity ফিল্ড যোগ করো»। এটি বাস্তবায়নের একটি ধাপ, আচরণ নয়; আলাদাভাবে যাচাই করার কোনো মানে নেই।
আকার মাপার সহজ উপায়: একটি ফিচার = একটি এজেন্ট-সেশন = একটি অর্থপূর্ণ কমিট = একটি এন্ড-টু-এন্ড (E2E) দৃশ্য। সেশনে না ধরলে আরও ভাঙুন। আলাদা দৃশ্য না লেখা গেলে ফিচারটি বড্ড ছোট, পাশের ফিচারের সঙ্গে জুড়ে দিন।
উদাহরণ: «কার্ট» কাজের ভাঙা
বড় চাহিদাটি এমন অবিভাজ্য এককে ভাঙা হয়, যার প্রতিটির একটিই আচরণ এবং নিজস্ব যাচাই-কমান্ড আছে:
- পণ্য কার্টে যোগ করা এবং তালিকায় তা দেখা।
- পণ্যের সংখ্যা বদলানো, সমষ্টি পুনর্গণনা হয়।
- কার্ট থেকে পণ্য মুছে ফেলা।
- অতিথির কার্ট অ্যাকাউন্টে লগইনের পরে টিকে থাকা।
- স্টকে নেই এমন পণ্য যোগ করা যাবে না, পরিষ্কার একটি ত্রুটি দেখাতে হবে।
চূড়ান্ত পরীক্ষা: কোনো এককেই «সঙ্গে সঙ্গে» অন্যটিকে ছুঁতে হয় না। যদি ৪ নম্বরের জন্য ১ নম্বর আবার লিখতে হয়, তবে ক্রম বা সীমানা ভুলভাবে বেছে নেওয়া হয়েছে।
ফিচারের তালিকা: feature_list.json
WIP=1 নিয়ম সেশনের ভেতরের শৃঙ্খলা রাখে। কিন্তু সেশনের মাঝে কে মনে রাখবে কী সম্পন্ন হয়েছে? চ্যাটে লেখা «auth আর ক্যাটালগ হয়ে গেছে, কার্ট প্রায় শেষ, তবে কিছু বাগ আছে» নতুন সেশনকে কিছুই জানায় না: «প্রায়» মানে কী, কোন টেস্ট পাস করেছে, পেমেন্ট কী আটকে রেখেছে, তা জানা যায় না। প্রতিটি নতুন সেশন একই গাড়ির নতুন চালকের মতো: নোট যদি আগের জনের মাথায় থেকে থাকে, নতুন জন কিছুই জানে না।
তাই অবস্থাটি বাইরে, একটি যন্ত্র-পাঠযোগ্য ফাইলে রাখা হয়। কোর্সে এটি .agent/feature_list.json:
[
{
"id": "F01",
"behavior": "ইউজার ইমেইল ও পাসওয়ার্ড দিয়ে নিবন্ধন করে এবং সঙ্গে সঙ্গে ঢোকে",
"verification": "pytest tests/e2e/test_auth.py::test_register_flow",
"state": "passing",
"evidence": "a3f9c12: 1 passed in 2.31s"
},
{
"id": "F02",
"behavior": "ইউজার পণ্য কার্টে যোগ করে এবং তালিকায় তা দেখে",
"verification": "pytest tests/e2e/test_cart.py::test_add_item -q",
"state": "active"
},
{
"id": "F03",
"behavior": "কার্ড দিয়ে অর্ডারের পেমেন্ট",
"verification": "pytest tests/e2e/test_payment.py -q",
"state": "blocked",
"blocker": "পেমেন্ট গেটওয়ের টেস্ট-কী নেই"
}
]
প্রতিটি এন্ট্রির তিনটি বাধ্যতামূলক ফিল্ড আছে: বাইরে থেকে দেখা যায় এমন আচরণের বিবরণ, মানুষ ছাড়া চালানো যায় এমন যাচাই-কমান্ড, এবং অবস্থা। ঐচ্ছিক চতুর্থ ফিল্ড evidence: কমিটের হ্যাশ ও যাচাইয়ের আউটপুট, যা প্রমাণ করে passing-এ যাওয়াটা সত্যিই হয়েছিল।
Markdown তালিকার বদলে JSON কেন? কারণ এটি শুধু এজেন্ট নয়, স্ক্রিপ্টও পড়ে: পরিকল্পনাকারী not_started থেকে পরের ফিচার বেছে নেয়, যাচাইকারী যাচাই-কমান্ড নেয়, সেশনের রিপোর্ট নিজে থেকে তৈরি হয়, আর অবস্থার বণ্টন প্রকল্পের স্বাস্থ্যের মেট্রিক দেয়। ফিচারের তালিকা হলো harness-এর মেরুদণ্ড, স্মারকলিপি নয়।
চারটি অবস্থা ও অনুমোদিত পরিবর্তন
| পরিবর্তন | কখন |
|---|---|
not_started → active | ফিচারটি কাজে নেওয়া হয়; অন্য কোনো সক্রিয় নেই |
active → passing | যাচাই-স্ক্রিপ্ট কোড 0 দিয়ে শেষ হয় |
active → blocked | বাইরের বাধা; কারণ blocker-এ লেখা থাকে |
blocked → active | বাধা সরেছে |
এর বাইরে আর কোনো পরিবর্তন নেই। বিশেষভাবে, যাচাই এড়িয়ে passing-এ যাওয়ার কোনো পথ নেই, এবং «প্রায় হয়ে গেছে» বলে কোনো অবস্থা নেই।
passing-এর গেট: এজেন্ট অনুরোধ করতে পারে, ঘোষণা নয়
পুরো ব্যবস্থার কেন্দ্রীয় নিয়ম: এজেন্ট state ফিল্ড হাতে বদলায় না। সে যাচাই চালাতে পারে, কিন্তু ফল নিজে ঘোষণা করতে পারে না, সেটি করে স্ক্রিপ্ট। «এজেন্ট রিপোর্ট করেছে» আর «স্ক্রিপ্ট নিশ্চিত করেছে»-র পার্থক্যই হলো কথা আর ঘটনার পার্থক্য। নিয়মটিও নির্দেশনা-ফাইলে লেখা হয়:
## ফিচার-তালিকার নিয়ম
- ফাইল: `.agent/feature_list.json`। এটাই পরিধির একমাত্র সত্যের উৎস।
- ঠিক একটি ফিচার `active` অবস্থায় থাকে।
- তুমি `state` ফিল্ড হাতে বদলাবে না। এটি বদলায় `scripts/verify.sh`।
- কোনো ফিচার `passing` করতে চালাও `./scripts/verify.sh F02` এবং কোড 0 আনো।
- ফিচার বাধাগ্রস্ত হলে `blocked`-এ নাও এবং অবশ্যই `blocker` লেখো।
- নতুন ফিচার শুধু `not_started`-এ এবং শুধু যাচাই-কমান্ড সহ যোগ হবে।
স্ক্রিপ্টটি দুই স্তরে যাচাই করে: প্রথমে প্রকল্পের সাধারণ পরীক্ষা (ফিচারটি যেন বাকিটা না ভাঙে), তারপর নির্দিষ্ট ফিচারের কমান্ড। স্থানীয় সাফল্য যদি সাধারণ রিগ্রেশনের সঙ্গে আসে, তাকে সাফল্য ধরা হয় না।
#!/usr/bin/env bash
# একমাত্র উপাদান, যার `passing` বসানোর অধিকার আছে।
set -uo pipefail
FID="$1"
FILE=".agent/feature_list.json"
CMD=$(jq -r --arg id "$FID" '.[] | select(.id==$id) | .verification' "$FILE")
if [ -z "$CMD" ] || [ "$CMD" = "null" ]; then
echo "FAIL: $FID-এর জন্য যাচাই-কমান্ড নেই"; exit 2
fi
echo "== সাধারণ যাচাই =="
make check || { echo "FAIL: সাধারণ যাচাই লাল, $FID passing হতে পারে না"; exit 1; }
echo "== ফিচার যাচাই: $CMD =="
if OUT=$(eval "$CMD" 2>&1); then
SHA=$(git rev-parse --short HEAD)
LAST=$(printf '%s\n' "$OUT" | tail -n 1)
TMP=$(mktemp)
jq --arg id "$FID" --arg ev "$SHA: $LAST" \
'map(if .id==$id then .state="passing" | .evidence=$ev else . end)' \
"$FILE" > "$TMP" && mv "$TMP" "$FILE"
echo "PASS: $FID"
else
printf '%s\n' "$OUT"
echo "FAIL: $FID"; exit 1
fi
নির্দেশনায় লেখা «state হাতে বদলাবে না» এখনো একটি অনুরোধ। এটিকে বাধ্যবাধকতায় বদলাতে লেখার অধিকার যান্ত্রিকভাবে বন্ধ করতে হয়: CI-তে যাচাই, যা evidence-কে কমিটের ইতিহাসের সঙ্গে মেলায়, অথবা আপনার টুলে এজেন্টের অধিকারের সীমা। নীতিটি হারনেসের সর্বত্র একই: গুরুত্বপূর্ণ নিয়মকে যান্ত্রিকতা দিয়ে সমর্থন করতে হয়।
কীভাবে মাপবেন যে এজেন্ট কাজ শেষ করছে
লোভনীয় মেট্রিক হলো সেশনে কত কোড লেখা হলো। বাস্তবে এটি উল্টো কাজ করে: বড় ডিফ প্রায়ই মানে এজেন্ট কয়েক দিকে ছড়িয়ে পড়েছে। গুনুন ফিচার, যেগুলো passing-এ আছে, লাইন নয়।
কোর্স থেকে একটি সুবিধাজনক মেট্রিক হলো VCR (Verified Completion Rate): যাচাই-করা কাজের সংখ্যা, ভাগ করা সক্রিয় করা কাজের সংখ্যা দিয়ে। নিয়ম সহজ: VCR এক-এর নিচে থাকা পর্যন্ত নতুন কাজ সক্রিয় করা যাবে না। এটি হারনেসের এজেন্টের ওপর প্রয়োগ করা উল্টো চাপ, এবং অসমাপ্ত কাজকে অনুভূতির বদলে একটি সংখ্যা হিসেবে দৃশ্যমান করার উপায়।
এজেন্টকে কাজ দেওয়ার সাধারণ ভুল
- যাচাই-কমান্ড ছাড়া কাজ। «রেজিস্ট্রেশন বানাও» কোনো দৃশ্য ছাড়া: এজেন্ট নিজে ঠিক করবে কোথায় থামবে, এবং ভুল জায়গায় থামবে।
- এক অনুরোধে কয়েকটি ফিচার। «কার্ট আর পেমেন্ট বানাও» মানে দুটি সক্রিয় কাজ, এবং কোনোটিই শেষ হবে না।
- অবস্থা শুধু চ্যাটে। কথোপকথনে লেখা অগ্রগতি সেশন শেষ হলেই হারায়। সেটি ফাইলে থাকতে হবে।
- যাচাইয়ের বদলে আত্মপ্রতিবেদন। «এজেন্ট বলেছে টেস্ট পাস করেছে» আর স্ক্রিপ্টের রিটার্ন কোড এক জিনিস নয়।
- ব্যাকলগ নেই। «সঙ্গে সঙ্গে» নিষিদ্ধ, কিন্তু চোখে পড়া জিনিস লেখার জায়গা নেই: এজেন্ট নিয়মটি এড়িয়ে যাবে।
একটি ফিচার একবারে যথেষ্ট না হলে
«একটি ফিচার — একটি সেশন — একটি যাচাই» একটি এজেন্ট ও একটি চক্রের জন্য ভালো কাজ করে। কাজ বাড়লে এবং স্বাধীন শাখা দেখা দিলে এটি কয়েকটি চক্রের ব্যবস্থায় বাড়ানো হয়: আলাদা পরিকল্পনা-নোড, বাস্তবায়ন-নোড, যাচাই-নোড এবং তাদের মধ্যে সমান্তরাল, শর্তযুক্ত সংযোগ, যেখানে যাচাই ব্যর্থ হলে বাস্তবায়নে ফিরে যাওয়া হয়। তবু সেখানে প্রতিটি বাস্তবায়ন-নোড একই নিয়মে চলে: একটি কাজ, একটি চালানো যায় এমন সম্পন্নতার মানদণ্ড, এবং অবস্থা এজেন্টের মাথার বাইরে। গ্রাফ একবারে-একটি নিয়ম বাতিল করে না, বরং তার ওপরে দাঁড়ায়।
একই বিশ্লেষণের একটি সতর্কবার্তা: চক্র নিজে যে মেট্রিক তাকে দেওয়া হয়েছে তা-ই ভালোভাবে অপ্টিমাইজ করে। সম্পন্নতার মানদণ্ড ভুলভাবে বাছলে, যেমন «টিকেট বন্ধ» বনাম «সমস্যা সমাধান হয়েছে», এজেন্ট মানদণ্ডটি পূরণ করতে শেখে, কাজটি নয়। তাই আচরণের বর্ণনা ও যাচাই-কমান্ড লেখায় মনে হওয়ার চেয়ে বেশি সময় দেওয়া উচিত।
সংক্ষেপে
AI এজেন্টকে কাজ দিতে হয় একটি একটি করে, দেখা যায় এমন আচরণ ও চালানো যায় এমন যাচাই-কমান্ড সহ, পথে চোখে পড়া জিনিসের জন্য ব্যাকলগ রেখে, এবং ফিচারের তালিকা একটি ফাইলে রেখে, যেখানে «সম্পন্ন» বসায় স্ক্রিপ্ট, এজেন্ট নয়। গতি সীমিত করার কাজটি এজেন্ট নিজে চালু করে না, সেটি করে harness। WIP=1 নিয়ম, feature_list.json এবং verify.sh কোর্সে একটি বাস্তব প্রকল্পের উদাহরণে বিস্তারিত দেখানো হয়েছে।
সাধারণ প্রশ্ন
কয়েকটি ছোট কাজ একসঙ্গে দেওয়া যাবে কি?
তালিকায় রাখা যায়, কিন্তু একবারে কাজে থাকবে একটিই। এজেন্ট পরেরটি তখনই নেয়, যখন বর্তমানটি যাচাই পাস করে; এভাবে প্রতিটি কাজ শেষ হয়।
কাজের জন্য স্বয়ংক্রিয় যাচাই লেখা না গেলে কী করব?
সাধারণত এর মানে কাজটি আচরণ নয়, একটি কর্ম হিসেবে লেখা হয়েছে। ব্যবহারকারী বা API ক্লায়েন্ট যা দেখবে সেই ভাষায় লিখুন; দৃশ্যমান অংশের জন্য ব্রাউজারে E2E টেস্ট ভালো কাজ করে।
feature_list.json কে লেখে, মানুষ না এজেন্ট?
প্রাথমিক তালিকা একসঙ্গে বানানো সুবিধাজনক: এজেন্ট ভাঙার প্রস্তাব দেয়, মানুষ সংশোধন করে। পরে এজেন্ট নতুন ফিচার যোগ করতে পারে, তবে শুধু not_started অবস্থায় এবং যাচাই-কমান্ড সহ।
ট্র্যাকারের কাজের সঙ্গে feature_list.json-এর পার্থক্য কী?
ট্র্যাকার মানুষের জন্য, আর ফিচার-তালিকা যন্ত্রের পড়ার জন্য: প্রতিটি এন্ট্রিতে একটি চালানো যায় এমন কমান্ড এবং কঠোর অবস্থা থাকে, যা স্ক্রিপ্ট বদলায়। দুটিকে সমন্বয় করা যায়, কিন্তু এজেন্টের প্রয়োজন রিপোজিটরির ফাইল।
একবারে একটি ফিচারের নিয়ম কি কাজ ধীর করে না?
সেশন ছোট হয়, কিন্তু শেষ হওয়া কাজের অনুপাত বাড়ে। অর্ধেক-হওয়া তিনটি মেশানো ফিচারের কোড গুছিয়ে নিতে যে সময় যেত, তা বাঁচে।
“Harness Engineering: инженерия надёжности AI-агентов” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।
- feature_list.json для AI-агента: WIP=1, статусы фич и верификация через verify.sh
- Graph Engineering для AI-агентов: когда одного цикла мало и нужен граф задач