অধ্যায় 5 · পরিমাপ ও ঘটনা
ঘটনা ও ধারাবাহিক উন্নতি: ট্রায়াজ, পোস্ট-মর্টেম ও রিভিউ চক্র
- পৃষ্ঠা 20 / 22
- 19 মিনিট পড়া
নিয়ন্ত্রণ ব্যর্থ হয়। মডেল বদলায়, ডেটা সরে যায়, কোনো ব্যবহার মূল্যায়নের সীমা ছাড়িয়ে বেড়ে যায়। দায়িত্বশীল দল সেই দিনের জন্য আগে থেকে তৈরি থাকে: সে দ্রুত একটা ঘটনার মাত্রা ঠিক করতে পারে, দরকারের বেশি ব্যক্তিগত ডেটা না নিয়েই প্রমাণ রাখে, আগে ক্ষতি থামায় আর পরে কারণ বোঝে, কাউকে দোষ না দিয়ে শেখে, সংশোধনমূলক কাজ শেষ করে, এবং প্রমাণ করে যে সেগুলো কাজ করেছে। এই পাতায় সেই চক্রটা আছে, ট্র্যাকিং ও যাচাইয়ের ধাপের জন্য ছোট স্ক্রিপ্টসহ।
আপনার দরকার Python 3.12 এবং শুধু তার স্ট্যান্ডার্ড লাইব্রেরি। ব্লকগুলো ক্রমে একটা সেশনে লিখুন; এগুলো ভেরিয়েবল ভাগ করে নেয়, আর প্রতিটা ব্লকের নিচের লেখাটা তার আসল আউটপুট।
সততার নিয়ম। কোম্পানি, মানুষ, টিকেট ও প্রতিটা সংখ্যা কাল্পনিক (টয় ডেটা)। তথ্য না থাকলে স্ক্রিপ্ট MISSING, UNKNOWN বা NOT TESTED জানায়, কিছু বানায় না। তীব্রতার মাত্রা, সময়সীমা ও থ্রেশহোল্ড উদাহরণের জন্য বেছে নেওয়া। এখানে কিছুই আইনি পরামর্শ নয়।
যা শিখবেন
- ঘটনার তীব্রতা ও এসকেলেশনের ধরন কীভাবে ঠিক করবেন, অপ্রয়োজনীয় ব্যক্তিগত ডেটা ছাড়া প্রমাণ কীভাবে রাখবেন, আর কখন একটা ফিচার বন্ধ রাখবেন।
- ঘটনার সময় কে কাকে কী জানান, আর তাৎক্ষণিক নিয়ন্ত্রণ (containment) ও মূল-কারণ বিশ্লেষণ কীভাবে আলাদা।
- টেমপ্লেট ও একটা কাজের উদাহরণসহ দোষারোপহীন ঘটনা-পরবর্তী রিভিউ কীভাবে চালাবেন।
- মালিক ও সময়সীমাসহ সংশোধনমূলক কাজ কীভাবে ট্র্যাক করবেন, আর আগে-পরের পরীক্ষায় তা কাজ করেছে কি না কীভাবে যাচাই করবেন।
- পুনর্মূল্যায়নের ট্রিগার কীভাবে ঠিক করবেন, আর একটা দায়িত্বশীল-AI রিভিউ প্যাক জড়ো করা কীভাবে শুরু করবেন।
যে ঘটনাটা আমরা অনুসরণ করব
কাল্পনিক পরিস্থিতি:
Company: Juniper Support (invented), a software firm with a support team in Lima, Cairo and Pune.
Tool: TicketSort reads each new support ticket and labels it P1 (urgent), P2 or P3 (low).
An agent sees the label first. P3 tickets are answered last.
Change: on 2026-09-14 the vendor released model ts-2.2. Juniper's configuration said "latest",
so it switched from ts-2.1 on its own. Nobody was told and nobody tested it.
Finding: on 2026-09-23 agent Rosa noticed refund requests waiting for days. Many were written
partly in a second language. The label had drifted, but no alert had fired.
Question: what should the team do in the first hours, what should it write afterwards, and how
will it know that the fixes worked?কার্ডের সারকথা: জুনিপার সাপোর্ট (কাল্পনিক) একটা সফটওয়্যার কোম্পানি, যার সাপোর্ট দল লিমা, কায়রো ও পুনেতে। TicketSort প্রতিটা নতুন সাপোর্ট টিকেটকে P1 (জরুরি), P2 বা P3 (কম গুরুত্বের) লেবেল দেয়; এজেন্ট আগে লেবেলটা দেখেন, আর P3 টিকেটের উত্তর সবার শেষে যায়। ২০২৬-০৯-১৪ তারিখে ভেন্ডর মডেল ts-2.2 ছাড়ে; জুনিপারের কনফিগারেশনে "latest" লেখা থাকায় সে নিজে থেকেই ts-2.1 থেকে বদলে যায়, কাউকে জানানো হয়নি, কেউ পরীক্ষাও করেনি। ২০২৬-০৯-২৩ তারিখে এজেন্ট রোজা লক্ষ করেন রিফান্ডের অনুরোধ কয়েক দিন ধরে অপেক্ষায় আছে, যার অনেকগুলো আংশিক দ্বিতীয় ভাষায় লেখা। লেবেল সরে গিয়েছিল, কিন্তু কোনো অ্যালার্ট বাজেনি। প্রশ্ন: প্রথম কয়েক ঘণ্টায় দলের কী করা উচিত, পরে কী লিখবে, আর সংশোধনগুলো যে কাজ করেছে তা কীভাবে জানবে?
এটা এই টিউটোরিয়ালের অন্যত্রের আবেদনকারী ও যোগ্যতা-বাছাইয়ের টয় উদাহরণ থেকে আলাদা একটা ঘটনা। এটা শুরু হয় ঠিক সেখানে, যেখান থেকে রিভিউ, অডিট ও বাস্তব গভর্ন্যান্স: পরিবর্তনের অনুমোদন, ঝুঁকি গ্রহণ ও কর্মীদের উদ্বেগ পাতার পরিবর্তন-অনুমোদনের অংশ সতর্ক করেছিল: ভেন্ডরের এমন পরিবর্তন, যা কেউ অনুমোদন করেননি।
তীব্রতা ও এসকেলেশন
ঘটনার তীব্রতা ও এসকেলেশনের ধরন ঠিক করুন। তীব্রতার মাত্রা ঠিক করে কাকে জানানো হবে, কত দ্রুত, আর ফিচার চলবে কি না। এটা এমন সহজ রাখুন যা চাপের মধ্যেও ব্যবহার করা যায়, ভিত্তি রাখুন মানুষের ক্ষতি, বিব্রতকর অবস্থা নয়, আর বলে দিন তথ্য অজানা থাকলে কী হবে: অজানা তথ্য জানা না যাওয়া পর্যন্ত আপাতত মাত্রা বাড়িয়ে ধরে।
| মাত্রা | অর্থ (আমাদের উদাহরণ) | কাকে, কখন জানানো হয় |
|---|---|---|
| S1 | নিরাপত্তা বা অধিকারের ঝুঁকি, বা ব্যক্তিগত ডেটার গুরুতর প্রকাশ | পরিচালককে তখনই; ফিচার বন্ধ |
| S2 | অর্থ বা প্রবেশাধিকারের ক্ষতি, বা অনেক মানুষ প্রভাবিত, বা কারণ অজানা | সাপোর্ট প্রধানকে সেদিনই; বন্ধ বা সীমিত করুন |
| S3 | বাস্তব কিন্তু ছোট, ফেরানো-যায় এমন ক্ষতি | ২ কর্মদিবসের মধ্যে মালিককে |
| S4 | অসুবিধা, অল্প মানুষ | সাপ্তাহিক রিভিউ |
def severity(f):
harm, people, rev = f.get("harm"), f.get("people"), f.get("reversible")
unknown = [k for k, v in (("harm", harm), ("people", people), ("reversible", rev)) if v is None]
if harm == "safety_or_rights":
level = "S1"
elif harm == "money_or_access":
level = "S2" if people is None or people >= 50 or rev is not True else "S3"
elif harm in ("inconvenience", "none"):
level = "S3" if people is not None and people >= 500 else "S4"
else:
level = "S2" # harm itself unknown: treat as serious until known
return level + (f" (provisional: unknown {', '.join(unknown)})" if unknown else "")
print("day 0 :", severity(dict(harm="money_or_access", people=None, reversible=None)))
print("day 2 :", severity(dict(harm="money_or_access", people=25, reversible=True)))
print("other :", severity(dict(harm="inconvenience", people=40, reversible=True)))
print("other :", severity(dict(harm="safety_or_rights", people=3, reversible=False)))day 0 : S2 (provisional: unknown people, reversible)
day 2 : S3
other : S4
other : S1প্রথম দিনে তিনটা তথ্য নেই বলে শুরু হয় S2 দিয়ে। দ্বিতীয় দিনে ২৫ জন প্রভাবিত আর রিফান্ড তখনো দেওয়া সম্ভব, তাই নিয়ম S3 দেয়, তবু কারণ এখনও অজানা বলে দল সেটাকে S2-ই রাখতে পারে। নিয়ম সিদ্ধান্তকে সাহায্য করে; যে মানুষ সিদ্ধান্তের মালিক, তাঁকে সরায় না। যুক্তিসঙ্গত দলগুলো এই রেখা আলাদাভাবে টানে, আর প্রতিটা বাস্তব ঘটনার পর মাত্রাগুলো রিভিউ করা উচিত।
প্রমাণ রাখুন, ব্যক্তিগত ডেটা নয়
অপ্রয়োজনীয় ব্যক্তিগত ডেটা ছাড়া প্রাসঙ্গিক প্রমাণ সংরক্ষণ করুন। প্রমাণ অন্য কাউকে ঘটনাটা পুনরুৎপাদন করে যাচাই করতে দেয়। এর জন্য প্রতিটা গ্রাহকের বার্তা লাগে না। রাখুন: ভার্সনের পরিচয় (মডেল, কনফিগারেশন, প্রম্পট), সময়চিহ্ন, সংখ্যা ও টেবিল, নেওয়া পদক্ষেপের লগ, এবং কয়েকটা সম্পাদিত (redacted) উদাহরণ। এড়িয়ে চলুন: পুরো টিকেট চ্যাট বা ইমেলে পেস্ট করা, নামসহ স্ক্রিনশট, আর সবকিছু চিরকাল রেখে দেওয়া। সংরক্ষণের তারিখ ঠিক করুন, কে প্রমাণ খুলতে পারবেন তা সীমিত করুন, আর কে দেখলেন তা লিখে রাখুন। বিরোধ হতে পারে মনে হলে কিছু মুছে ফেলার আগে আপনার আইনি উপদেষ্টাকে জিজ্ঞেস করুন।
import hashlib
SALT = "demo-salt" # Toy data. In real use keep the salt secret and apart from the evidence.
KEEP = ("model", "priority", "language_mix", "created")
def evidence(ticket):
pid = "t_" + hashlib.sha256((SALT + ticket["id"]).encode()).hexdigest()[:8]
return {"ref": pid, **{k: ticket[k] for k in KEEP if k in ticket}}
ticket = dict(id="TK-10231", customer="Selam T.", email="a.t@example.invalid", text="Refund, please...",
model="ts-2.2", priority="P3", language_mix=True, created="2026-09-16")
print("keep:")
for k, v in evidence(ticket).items():
print(f" {k}: {v}")
print("left out:", sorted(set(ticket) - set(KEEP) - {"id"}))keep:
ref: t_ee021877
model: ts-2.2
priority: P3
language_mix: True
created: 2026-09-16
left out: ['customer', 'email', 'text']t_... রেফারেন্সটা একটা ছদ্মনাম (pseudonym): যাঁর কাছে মূল তালিকা আছে তিনি এটা টিকেটের সঙ্গে আবার জুড়তে পারেন, তাই অন্যভাবে যাচাই না করা পর্যন্ত একে ব্যক্তিগত ডেটা ধরুন, আর সল্ট ও টিকেটের তালিকা প্রমাণের ফাইলের চেয়ে কড়া নিয়ন্ত্রণে রাখুন।
কখন একটা ফিচার বন্ধ করবেন
কখন একটা ফিচার বন্ধ রাখা উচিত তা চিহ্নিত করুন। বন্ধ করা সবচেয়ে জোরালো নিয়ন্ত্রণ-পদক্ষেপ, তাই শর্তগুলো আগে থেকে ঠিক করুন। আমাদের উদাহরণের ট্রিগার: মানুষের ক্ষতি সম্ভাব্য ও চলমান; নীতির কোনো ব্যবহার-বন্ধের শর্ত পূরণ হয়েছে (দেখুন উচ্চ-ঝুঁকির ব্যবহার ও ব্যবহার-বন্ধের নিয়ম: আপিল, এসকেলেশন ও বিকল্প); কারণ অজানা এবং মাত্রা S1 বা S2; ফিচারটা যে নিয়ন্ত্রণের ওপর নির্ভর করে তা ব্যর্থ হচ্ছে বলে জানা; অথবা ইচ্ছাকৃত অপব্যবহারের প্রমাণ আছে। বন্ধ করার আগে জিজ্ঞেস করুন, ছোট কোনো পদক্ষেপে ক্ষতি আটকানো যায় কি না।
| বিকল্প | এই ঘটনায় উদাহরণ | এর দাম |
|---|---|---|
| পরিধি সীমিত করা | P3 টিকেট স্বয়ংক্রিয়ভাবে বন্ধ করা বন্ধ রাখুন | সামান্য; ক্ষতি চলতে পারে |
| মানুষের যাচাই যোগ করা | একজন এজেন্ট ওই সময়ের প্রতিটা P3 টিকেট পড়েন | কর্মীর সময় |
| আগের অবস্থায় ফেরা | আগের মডেল ভার্সন পিন করুন | একটা জানা-ভালো ভার্সন লাগে |
| বন্ধ করা | কারণ জানা পর্যন্ত হাতে বাছাই | সবার জন্য ধীর সেবা |
কে বন্ধ করতে পারেন তা ঠিক করুন (এখানে S1 ও S2-তে যেকোনো ইনসিডেন্ট লিড, অনুমতি না চেয়েই), আর কে আবার চালু করতে পারেন (মালিক ও একজন রিভিউয়ার, প্রমাণসহ)। কত সহজে বন্ধ করা উচিত তা নিয়ে মতভেদ আছে। সাপোর্ট লিড বলেন, প্রতিদিন কয়েকশ টিকেট হাতে বাছাই করলে প্রতিটা গ্রাহকের দেরি হয়। একজন গ্রাহক-প্রতিনিধি উত্তর দেন, কয়েক দিনের ধীর সেবা নীরব ভুল-অগ্রাধিকারের চেয়ে সস্তা। একজন ইঞ্জিনিয়ার মনে করিয়ে দেন, রোলব্যাক নিজেই এক ধরনের বন্ধ করা, আর প্রায়ই তা-ই যথেষ্ট। এই পাতা বেছে নেয় না; এটা চায় আপনি নিয়ম, খরচ ও দায়িত্বপ্রাপ্ত ব্যক্তিকে সেই দিনের আগে লিখে রাখুন যেদিন তা দরকার হবে।
কে কাকে কী জানান
বিজ্ঞপ্তি ও যোগাযোগের দায়িত্ব ঠিক করুন। ঘটনার সময় কে কথা বলবেন তা জানতে চেয়েই মানুষ সময় হারায়। আগে থেকে ঠিক করে রাখুন।
| ভূমিকা | দায়িত্ব |
|---|---|
| ইনসিডেন্ট লিড | প্রতিক্রিয়া চালান, লগ রাখেন, কাকে কী ও কখন জানানো হবে তা ঠিক করেন |
| সিস্টেমের মালিক | সিস্টেম সম্পর্কে তথ্য দেন; বন্ধ করা ও আবার চালু করা অনুমোদন করেন |
| গোপনীয়তা বা আইনি উপদেষ্টা | নিয়ন্ত্রক ও প্রভাবিত মানুষকে জানানোর দায়িত্ব বিচার করেন (নিচের নোট দেখুন) |
| যোগাযোগ বা সাপোর্ট লিড | গ্রাহক ও কর্মীদের বার্তা লেখেন ও পাঠান |
| ভেন্ডর যোগাযোগকারী | চুক্তির ঘটনা-সংক্রান্ত ধারা ব্যবহার করে ভেন্ডরের কাছে জানতে চান কী বদলেছে ও কবে |
| পরিচালক | S1 ও S2-তে অবগত থাকেন; প্রকাশ্য বিবৃতির সিদ্ধান্ত নেন |
প্রভাবিত মানুষের কাছে একটা ভালো বার্তা বলে কী ঘটেছে (শুধু যা জানা), কারা প্রভাবিত, আপনারা কী করছেন, তাঁরা কী করতে পারেন, কীভাবে প্রশ্ন বা আপত্তি জানাবেন, এবং পরবর্তী আপডেট কখন। তাতে কারণ অনুমান থাকে না, তথ্য আসার আগে ভেন্ডর বা কোনো ব্যক্তিকে দোষ দেওয়া থাকে না, আর যা দিতে পারবেন না তার প্রতিশ্রুতি থাকে না।
আইনি নোট (২০২৬-১০-১২ অনুযায়ী; আইনি পরামর্শ নয়): কোনো ঘটনা সম্পর্কে নিয়ন্ত্রক, গ্রাহক বা অন্য প্রভাবিত মানুষকে আপনাকে জানাতে হবে কি না এবং কখন, তা নির্ভর করে আপনার দেশ, খাত, জড়িত ডেটার ধরন ও চুক্তির ওপর। এই পাতা কোনো সময়সীমা বা সীমা বলে না। আপনারটা খুঁজতে আপনার গোপনীয়তা বা আইনি উপদেষ্টাকে জিজ্ঞেস করুন, ভেন্ডর-চুক্তির ঘটনা-সংক্রান্ত ধারা পড়ুন এবং আপনার নিয়ন্ত্রকের অফিসিয়াল পাতা খুঁজুন। আপনার দেশ ও খাতের বর্তমান অফিসিয়াল টেক্সট দেখে নিন।
আগে নিয়ন্ত্রণ, পরে বিশ্লেষণ
তাৎক্ষণিক নিয়ন্ত্রণকে মূল-কারণ বিশ্লেষণ থেকে আলাদা রাখুন। নিয়ন্ত্রণ (containment) এখনই ক্ষতি থামায় বা কমায়; বিশ্লেষণ বোঝে কেন, যাতে তা আবার না ঘটে। দুটো মেশালে দুটোই দেরি হয়।
| নিয়ন্ত্রণ | মূল-কারণ বিশ্লেষণ | |
|---|---|---|
| লক্ষ্য | ক্ষতি থামানো ও কমানো | অবদানকারী কারণ ও কী ব্যর্থতাটা সম্ভব করেছে তা খোঁজা |
| সময় | ঘণ্টা | পরিস্থিতি স্থির হওয়ার পর দিন থেকে সপ্তাহ |
| পদক্ষেপ | মডেল পিন করা, অটো-ক্লোজ বন্ধ, প্রভাবিত টিকেট আবার বাছাই, গ্রাহকদের জানানো | টাইমলাইন বানানো, একই কেসে পুরোনো ও নতুন মডেল পরীক্ষা, চুক্তি পড়া |
| ফাঁদ | এত দ্রুত বদলানো যে প্রমাণ হারায়: আগে স্ন্যাপশট নিন | প্রথম কারণে থেমে যাওয়া ("ভেন্ডর বদলেছে"), যখন কয়েকটা কারণ একসঙ্গে মিলেছিল |
দোষারোপহীন ঘটনা-পরবর্তী রিভিউ
একটা দোষারোপহীন ঘটনা-পরবর্তী রিভিউ লিখুন। Google-এর Site Reliability Engineering বই, সফটওয়্যার অপারেশনসের একটা প্রকাশিত চর্চা, পোস্ট-মর্টেমকে শাস্তির নয়, শেখার উপায় হিসেবে বর্ণনা করে: সেটা সুপারিশ করে ব্যক্তিকে দোষ না দিয়ে অবদানকারী কারণে মনোযোগ দিতে, মানুষ সদিচ্ছায় কাজ করেছেন ধরে নিতে, সিস্টেম ঠিক করতে, কোন ঘটনায় রিভিউ লেখা হবে তা আগে ঠিক করতে, এবং রিভিউ ভাগ করে নিতে। এই কোর্স চর্চাটা ধার নেয় এবং নিজের ব্যাখ্যা যোগ করে। দোষারোপহীন মানে জবাবদিহিহীন নয়: জবাবদিহি সংশোধনমূলক কাজ শেষ করার জন্য, ব্যর্থতার সবচেয়ে কাছে থাকার জন্য নয়। কোনো ঘটনায় অসদাচরণের প্রশ্ন উঠলে তা সামলায় আলাদা প্রক্রিয়া, শেখার রিভিউ নয়।
টেমপ্লেট:
Review of: (title) Severity: (S1-S4) Status: (draft / reviewed)
Facts only. Use roles, not names, for people who made decisions.
SUMMARY two sentences: what happened and to whom
IMPACT who, how many, how long; what is not known
DETECTION how and when it was noticed; what should have noticed it earlier
TIMELINE timestamps of changes, discovery, decisions and actions
CONTRIBUTING FACTORS conditions in the system that made it possible (never "person X erred")
WENT WELL / WAS LUCKY what worked; what could have gone worse
ACTIONS each with one owner, a due date and a way to check it worked
OPEN QUESTIONS what we still do not knowকাজের উদাহরণ (কাল্পনিক): TicketSort ঘটনার রিভিউ।
Review of: TicketSort labels drifted for mixed-language tickets Severity: S2 Status: draft
Written 2026-10-02 by the incident lead (a support lead). Roles, not names.
SUMMARY From 2026-09-14 to 2026-09-23, urgent tickets written partly in a second language were
missed by the tool (13 of 25, Toy data), against 6 of 60 for English-only tickets.
IMPACT 13 urgent tickets delayed, up to 9 days; 4 had a payment deadline. Unknown: customers
who left without writing again.
DETECTION An agent noticed refund requests waiting on 2026-09-23. No alert existed.
TIMELINE 09-14 vendor model ts-2.2 replaced ts-2.1 (configuration said "latest")
09-23 agent raises concern; incident lead named; severity S2 (provisional)
09-23 model pinned to ts-2.1; auto-close off; hand re-sort of the 9 days begins
09-26 all affected tickets re-prioritised; affected customers contacted
CONTRIBUTING FACTORS
- the configuration followed "latest", so a vendor change reached production unreviewed
- the release test set had no mixed-language urgent tickets
- the weekly dashboard showed one overall average, which hid the group gap
- the contract did not require notice of model changes
WENT WELL a support agent spoke up; rollback took about two hours; messages were plain
WAS LUCKY refunds had a 14-day window, and the gap was found on day 9
ACTIONS tracker items A1 to A5
OPEN was ts-2.1 better for these tickets, or just never measured by language?লক্ষ করুন কী নেই: কাউকে কারণ হিসেবে নাম দেওয়া হয়নি। প্রশ্ন হলো কী একটা পরিবর্তনকে পরীক্ষা ছাড়া গ্রাহকের কাছে পৌঁছাতে দিল, আর উত্তর থেকে এমন কাজ আসে যা কোনো একজন মানুষের চেয়ে বেশি টিকে থাকে।
মালিক ও সময়সীমাসহ সংশোধনমূলক কাজ
সংশোধনমূলক কাজ, মালিক ও সময়সীমা ঠিক করুন। একজন মালিক ও একটা তারিখ ছাড়া কাজ একটা ইচ্ছা মাত্র। এর শক্তি মাপুন: কারণ সরিয়ে দেওয়া তা ধরার চেয়ে ভালো, আর তা মানুষের মনে রাখার ওপর নির্ভর করার চেয়ে ভালো। বাস্তব পরিকল্পনায় নানা ধরন মিশে থাকে। স্ক্রিপ্টটা একটা ট্র্যাকার পড়ে, একটা স্থির তারিখ ধরে কী মেয়াদোত্তীর্ণ বা অসম্পূর্ণ তা জানায়, ফাঁক কখনও ভরে না।
from datetime import date
AS_OF = date(2026, 10, 12)
ACTIONS = [ # Toy data: invented tracker
dict(id="A1", what="Pin the model version; remove the 'latest' alias", kind="removes cause",
owner="Bao (platform)", due="2026-09-24", status="done", evidence="config commit 4f2a"),
dict(id="A2", what="Add 12 mixed-language urgent tickets to the release test set", kind="detects",
owner="Rosa (support)", due="2026-10-05", status="open", evidence=""),
dict(id="A3", what="Report priority by language group every week", kind="detects",
owner="", due="2026-10-15", status="open", evidence=""),
dict(id="A4", what="Ask the vendor for a model-change notice clause", kind="reduces impact",
owner="Wanjiru (vendor manager)", due="", status="open", evidence=""),
dict(id="A5", what="Remind staff to check priorities", kind="relies on memory",
owner="Soren (support lead)", due="2026-09-30", status="done", evidence=""),
]
def due_date(a):
try:
return date.fromisoformat(a["due"])
except ValueError:
return None
for a in ACTIONS:
notes = []
if not a["owner"]:
notes.append("MISSING owner")
if due_date(a) is None:
notes.append("MISSING due date")
elif a["status"] != "done" and due_date(a) < AS_OF:
notes.append(f"OVERDUE by {(AS_OF - due_date(a)).days} days")
if a["status"] == "done" and not a["evidence"]:
notes.append("done but no evidence recorded")
print(f"{a['id']} {a['kind']:<17}{'; '.join(notes) or 'ok'}")A1 removes cause ok
A2 detects OVERDUE by 7 days
A3 detects MISSING owner
A4 reduces impact MISSING due date
A5 relies on memory done but no evidence recordedA2 মেয়াদোত্তীর্ণ, A3 ও A4 অসম্পূর্ণ, আর A5 "সম্পন্ন" চিহ্নিত অথচ দেখানোর কিছু নেই: স্মরণ করানোও সবচেয়ে দুর্বল ধরনের কাজ। A3-এর সময়সীমা তিন দিন পরে, তাই দেরি হয়নি, কিন্তু মালিক নেই। ট্র্যাকার নিয়মিত বৈঠকে রিভিউ হয়, আর সময়সীমা বদলালে রেকর্ডে কারণ লিখতে হয়।
কাজগুলো কাজ করেছে কি না
সংশোধনমূলক কাজ আসলে কাজ করেছে কি না যাচাই করুন। "সম্পন্ন" বলে কাজটা হয়েছে; সমস্যা চলে গেছে তা বলে না। যে পরিমাপ সমস্যাটা ধরেছিল তা নতুন ডেটায়, যথেষ্ট কেস নিয়ে আবার চালান, আর মূলটার সঙ্গে তুলনা করুন। এখানে পরিমাপ হলো সত্যিই জরুরি টিকেটের মধ্যে ভাষার গ্রুপ অনুযায়ী P1 বা P2 লেবেল পাওয়ার অনুপাত। কোনো গ্রুপে কেস খুব কম থাকলে যাচাই NOT TESTED জানায়, আর একটা ভালো সপ্তাহ এখনও প্রমাণ নয়।
CHECKS = { # Toy data: {group: (urgent tickets, labelled P1 or P2)}
"during incident": {"english_only": (60, 54), "mixed_language": (25, 12)},
"week 1 after fix": {"english_only": (58, 52), "mixed_language": (22, 19)},
"week 2 after fix": {"english_only": (61, 55), "mixed_language": (11, 10)},
}
def verify(period, max_gap=0.10, min_urgent=20):
c = CHECKS[period]
small = min(total for total, _ in c.values())
if small < min_urgent:
return "NOT TESTED", f"smallest group has {small} urgent tickets (minimum {min_urgent})"
rate = {g: hit / total for g, (total, hit) in c.items()}
gap = rate["english_only"] - rate["mixed_language"]
return ("PASS" if gap <= max_gap else "FAIL"), f"flagged {rate['english_only']:.2f} vs {rate['mixed_language']:.2f}, gap {gap:.2f}"
for period in CHECKS:
result, why = verify(period)
print(f"{period:<18}{result:<11}{why}")during incident FAIL flagged 0.90 vs 0.48, gap 0.42
week 1 after fix PASS flagged 0.90 vs 0.86, gap 0.03
week 2 after fix NOT TESTED smallest group has 11 urgent tickets (minimum 20)ঘটনার সময়টা ফেল করে (ব্যবধান ০.৪২), প্রথম সপ্তাহ পাস করে, আর দ্বিতীয় সপ্তাহের বিচার করা যায় না, কারণ মিশ্র-ভাষার জরুরি টিকেট এসেছে মাত্র ১১টা। NOT TESTED সঠিক উত্তর, স্ক্রিপ্টের ফাঁক নয়। পার্শ্বপ্রতিক্রিয়াও দেখুন: ঠিক করার পর শুধু-ইংরেজি টিকেট খারাপ হয়েছে, নাকি দল দেখাই ছেড়ে দিয়েছে?
পুনর্মূল্যায়নের ট্রিগার
বদলে যাওয়া ডেটা বা ব্যবহারের জন্য পুনর্মূল্যায়নের ট্রিগার ঠিক করুন। একটা অ্যাসেসমেন্ট কেবল সেই ডেটা ও ব্যবহারের জন্য বৈধ, যা সে বর্ণনা করেছিল। কী পরিবর্তন গণ্য হবে তা ঠিক করুন, বর্তমান অবস্থাকে মূল্যায়িত অবস্থার সঙ্গে মেলান, আর পার্থক্য হলে আবার মূল্যায়ন করুন।
| যা বদলেছে | উদাহরণ | কেন গুরুত্বপূর্ণ |
|---|---|---|
| ডেটা | নতুন ভাষা, নতুন চ্যানেল, নতুন অঞ্চল, টিকেটের আলাদা মিশ্রণ | টেস্ট সেট আর বাস্তব ইনপুটের প্রতিনিধি থাকে না |
| মডেল বা ভেন্ডর | নতুন ভার্সন, নতুন প্রদানকারী, নতুন সেটিংস | না জানিয়েই আচরণ বদলাতে পারে |
| ব্যবহার | যে লেবেল ইঙ্গিত ছিল সেটা এখন স্বয়ংক্রিয়ভাবে টিকেট বন্ধ করে | একই ভুল বড় ক্ষতি করে |
| মাত্রা | অনেক বেশি টিকেট বা ব্যবহারকারী | বিরল ব্যর্থতা ঘন ঘন হয়ে যায় |
| সময় ও প্রেক্ষাপট | রিভিউয়ের পর দীর্ঘ বিরতি; নতুন আইন বা নির্দেশনা (বর্তমান অফিসিয়াল টেক্সট দেখুন) | অনুমানগুলো পুরোনো হয়ে যায় |
ASSESSED = dict(model="ts-2.1", languages=["English", "Spanish"], channels=["email"],
weekly_volume=1200, decision_use="priority hint; an agent decides",
regions=["Americas", "Africa"], reviewed="2026-03-01")
CURRENT = dict(model="ts-2.1", languages=["English", "Spanish", "Portuguese"],
channels=["email", "chat"], weekly_volume=2100,
decision_use="closes P3 tickets after 14 days", reviewed="2026-03-01")
def triggers(a, c, max_growth=0.5, max_days=183): # growth and age limits are chosen for this example
out = []
for k in a:
if k not in c:
out.append(f"UNKNOWN {k}: not recorded now, cannot check")
for k in ("languages", "channels"):
new = sorted(set(c.get(k, [])) - set(a[k]))
if new:
out.append(f"new {k}: {', '.join(new)}")
for k in ("model", "decision_use"):
if k in c and c[k] != a[k]:
out.append(f"{k} changed: '{a[k]}' to '{c[k]}'")
growth = c.get("weekly_volume", a["weekly_volume"]) / a["weekly_volume"] - 1
if growth > max_growth:
out.append(f"weekly volume up {growth:.0%}")
age = (AS_OF - date.fromisoformat(a["reviewed"])).days
if age > max_days:
out.append(f"last review {age} days ago")
return out
for line in triggers(ASSESSED, CURRENT) or ["no trigger fired"]:
print("-", line)- UNKNOWN regions: not recorded now, cannot check
- new languages: Portuguese
- new channels: chat
- decision_use changed: 'priority hint; an agent decides' to 'closes P3 tickets after 14 days'
- weekly volume up 75%
- last review 225 days agoপাঁচটা ট্রিগার জ্বলে (নতুন ভাষা, নতুন চ্যানেল, ব্যবহারের পরিবর্তন, ভলিউম বৃদ্ধি আর রিভিউয়ের পর কেটে যাওয়া সময়), আর একটা ফিল্ড যাচাই করা যায় না কারণ কেউ তা লিখে রাখেননি। ব্যবহারের পরিবর্তনটাই সবচেয়ে গুরুতর: যে ইঙ্গিত এজেন্ট বদলাতে পারতেন, সেটা এখন স্বয়ংক্রিয় পদক্ষেপ, যা একটা নতুন সিদ্ধান্ত-বিন্দু, তাই এর জন্য রিভিউ, অডিট ও বাস্তব গভর্ন্যান্স: পরিবর্তনের অনুমোদন, ঝুঁকি গ্রহণ ও কর্মীদের উদ্বেগ পাতায় শেখানো পরিবর্তন-অনুমোদন আর নতুন করে অ্যাসেসমেন্ট লাগে।
আপনার রিভিউ প্যাক শুরু করা
ক্যাপস্টোনের প্রস্তুতি: একটা দায়িত্বশীল-AI রিভিউ প্যাক জড়ো করুন। শেষ পাতাগুলো চায় আপনি যা বানিয়েছেন তা একটা প্যাকে জড়ো করুন। এখনই একটা ফিচারের জন্য জড়ো করা শুরু করুন: ইমপ্যাক্ট অ্যাসেসমেন্ট ও ঝুঁকির রেজিস্টার; প্রয়োজন ম্যাপ; ছোট-স্যাম্পলের সতর্কতাসহ ন্যায্যতার পরিমাপ; ডেটা-গভর্ন্যান্সের নোট; সিস্টেম কার্ড; তদারকি ও ব্যবহার-বন্ধের ডিজাইন; অপব্যবহারের রিভিউ; ট্রেড-অফ নোট; গভর্ন্যান্স রেজিস্টারের এন্ট্রি; আগের পাতা থেকে উদ্দেশ্য ও নিয়ন্ত্রণ-পরীক্ষার ফল; আর এই পাতা থেকে তীব্রতার টেবিল, ঘটনার টেমপ্লেট ও পুনর্মূল্যায়নের ট্রিগার। প্রতিটা আইটেমে একটা অবস্থা (সম্পন্ন, খসড়া বা MISSING) ও একজন মালিক লিখুন। তারপর প্র্যাকটিস ল্যাব: টয় ডেটা ও Python দিয়ে একটা সীমিত AI ফিচারের মূল্যায়ন পাতা ব্যবহার করুন; ক্যাপস্টোন পাতা, ক্যাপস্টোন, চিট শিট ও এরপর কী: গো/নো-গো মূল্যায়ন প্যাক, প্যাকটাকে একটা সিদ্ধান্তে পরিণত করে।
কাজের জায়গায় এটা কোথায় দেখা যায়
সাপোর্ট, অপারেশনস ও প্রোডাক্ট দলগুলো আলাদা সুরক্ষা দল পাওয়ার অনেক আগেই একটা ছোট ঘটনা-পদ্ধতি, তীব্রতার টেবিল ও একটা ট্র্যাকার রাখে। গ্রাহক ও অডিটররা প্রায়ই সেগুলো দেখতে চান। উপরের মতো একটা ছোট, সাধারণ ঘটনার রিভিউতেই বেশির ভাগ উন্নতি আসে।
সাধারণ ভুল
- নিয়ন্ত্রণের আগে বিশ্লেষণ। কারণ খুঁজতে কাটানো প্রতিটা ঘণ্টায় ক্ষতি চলতে থাকে। আগে নিয়ন্ত্রণ করুন, প্রমাণের স্ন্যাপশট নিন, তারপর বিশ্লেষণ করুন।
- ঘটনার চ্যাটে ব্যক্তিগত ডেটা কপি করা। এতে সমস্যা ছড়ায়। সংখ্যা, ভার্সন ও সম্পাদিত নমুনা ভাগ করুন।
- কোনো ব্যক্তিকে কারণ হিসেবে নাম দেওয়া। এতে অনুসন্ধান শেষ হয়ে যায় আর সিস্টেমের পরিস্থিতি লুকায়। পরিস্থিতির বর্ণনা দিন।
- "সম্পন্ন"-কে "ঠিক হয়েছে" ধরা। পরিমাপটা নতুন ডেটায় আবার চালান, আর ডেটা পাতলা হলে NOT TESTED বলুন।
- মালিক বা তারিখহীন কাজ। সেগুলো সময়সূচিতে নেই। একজন মালিক, একটা তারিখ ও সম্পন্ন হওয়ার প্রমাণ ঠিক করুন।
নিজে চেষ্টা করুন
এই পাতার নেমস্পেস ব্যবহার করুন। কাজগুলো ঝুঁকির স্কোরিং, নিয়ন্ত্রণ ও সিদ্ধান্ত: একটা টয় রিস্ক রেজিস্টার বানানো পাতার অবশিষ্ট ঝুঁকির ধারণা আবার ছোঁয়।
- সহজ। সহায়তা-নিবন্ধের একটা বানান ভুল ১২ জন গ্রাহক ধরেছেন, যাঁদের অর্থ বা প্রবেশাধিকারের ক্ষতি হয়নি; কয়েক মিনিটে ঠিক হয়েছে।
severityদিয়ে মাত্রা ঠিক করুন, আর বলুন কাকে জানানো হবে। - মাঝারি। এই দোষারোপের লাইনটাকে অবদানকারী কারণ হিসেবে নতুন করে লিখুন: "বাও মডেল পিন করতে ভুলে গিয়েছিলেন, তাই তিনিই ঘটনাটা ঘটালেন।"
- কঠিন। একটা ফাংশন
fixed(periods)লিখুন, যা টানা দুটো PASS সময়কালের পরেই VERIFIED বলে, আর সংশোধনের পরের দুই সপ্তাহে চালান।
উত্তর
সহজ।
print(severity(dict(harm="inconvenience", people=12, reversible=True)))S4পাস চেকলিস্ট: S4, কোনো অজানা তথ্য ছাড়া; সাপ্তাহিক রিভিউই যথেষ্ট, জরুরি এসকেলেশন নয়; পাতার নিয়মটা একটা বেছে নেওয়া সিদ্ধান্ত। একটা শক্ত উত্তর যোগ করে যে নিরাপত্তার নির্দেশনায় বানান ভুল একটা ভিন্ন ক্ষতি আর তার জন্য ভিন্ন মাত্রা লাগত।
মাঝারি। একটা শক্ত উত্তর: "কনফিগারেশন 'latest' অনুসরণ করত, তাই ভেন্ডরের পরিবর্তন রিভিউ ছাড়াই প্রোডাকশনে পৌঁছেছে; ধরার মতো কোনো টেস্ট বা অ্যালার্ট ছিল না; মডেল পরিবর্তন অনুমোদনের দায়িত্ব প্রক্রিয়ায় কাউকে দেওয়া ছিল না।" পাস চেকলিস্ট: কোনো ব্যক্তি কারণ হিসেবে নামধারী নন; প্রতিটা কারণ এমন পরিস্থিতি যা বদলানো যায়; প্রতিটা একটা সম্ভাব্য কাজের দিকে ইঙ্গিত করে। দুর্বল উত্তর "মানুষের ভুল" বলে থেমে যায়।
কঠিন।
def fixed(periods):
results, streak = [], 0
for p in periods:
r = verify(p)[0]
results.append(r)
streak = streak + 1 if r == "PASS" else 0 # a FAIL or NOT TESTED breaks the streak
return results, "VERIFIED" if streak >= 2 else "NOT YET VERIFIED"
print(fixed(["week 1 after fix", "week 2 after fix"]))(['PASS', 'NOT TESTED'], 'NOT YET VERIFIED')পাস চেকলিস্ট: PASS ছাড়া অন্য যেকোনো ফলে ধারা ভাঙে; দ্বিতীয় সপ্তাহ NOT TESTED, তাই ফল NOT YET VERIFIED, VERIFIED নয়; উত্তরে বলা আছে আরও ডেটা দরকার। দুর্বল উত্তর NOT TESTED-কে পাস ধরে নেয়।
সারসংক্ষেপ
- তীব্রতা ঠিক করুন মানুষের ক্ষতির ভিত্তিতে, অজানা তথ্যে মাত্রা বাড়িয়ে ধরুন, আর আগে থেকে ঠিক করুন কে ফিচার বন্ধ করতে পারেন এবং কোন ছোট পদক্ষেপগুলো আছে।
- অন্যরা যা ঘটেছে তা পুনরুৎপাদন করতে পারেন এমন প্রমাণ রাখুন, দরকারের বেশি ব্যক্তিগত ডেটা নয়; জানুন কে কাকে কী জানান, আর নিজের বিজ্ঞপ্তির দায়িত্ব যাচাই করুন।
- আগে নিয়ন্ত্রণ, পরে বিশ্লেষণ; সিস্টেমের অবদানকারী কারণে মনোযোগ দিয়ে দোষারোপহীন রিভিউ লিখুন।
- প্রতিটা সংশোধনমূলক কাজে একজন মালিক, একটা তারিখ ও প্রমাণ রাখুন; আগে-পরের পরীক্ষায় যাচাই করুন, আর সৎভাবে NOT TESTED জানান।
- ডেটা, মডেল, ব্যবহার, মাত্রা বা সময় মূল্যায়িত অবস্থা থেকে বদলে গেলে আবার মূল্যায়ন করুন।
এরপর: প্র্যাকটিস ল্যাব: টয় ডেটা ও Python দিয়ে একটা সীমিত AI ফিচারের মূল্যায়ন পাতায় একটা ফিচারের ওপর পুরো কোর্স একসঙ্গে আনা হবে, গ্রেডেড কাজসহ।