Skip to content

अच्छे स्पेक्स लिखना ​

आप शायद ही कभी एक खाली पृष्ठ से स्पेक लिखते हैं। आप एक बदलाव का सादे भाषा में वर्णन करते हैं, /opsx:propose आवश्यकताओं और परिदृश्यों का प्रारूप तैयार करता है, और फिर आप उन्हें अच्छा बनाते हैं। यह पृष्ठ उस अंतिम भाग के बारे में है — "अच्छा" कैसा दिखता है, और AI को उसकी ओर कैसे ले जाएँ।

यह बदलाव की समीक्षा का साथी है: समीक्षा करना एक ड्राफ्ट में कमजोर स्थानों को पकड़ना है, लिखना यह जानना है कि एक मजबूत स्पेक किस चीज़ से बना है।

स्पेक व्यवहार है, कोड नहीं ​

एक स्पेक बताता है कि आपका सिस्टम क्या करता है, ऐसे शब्दों में जिसे कोई भी जांच सकता है — नहीं कि यह कैसे बनाया गया है। यह आवश्यकताओं (व्यवहार के कथन) और परिदृश्यों (उन्हें सिद्ध करने वाले ठोस उदाहरण) से बना होता है।

markdown
### Requirement: Session Timeout
The system SHALL expire a session after 30 minutes of inactivity.

#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass with no activity
- THEN the session is invalidated and the user must re-authenticate

वह कैसे — कतार, लाइब्रेरी, तालिका स्कीमा — design.md या कोड में रखें। जब व्यवहार और कार्यान्वयन एक आवश्यकता में मिश्रित हो जाते हैं, तो आवश्यकता परीक्षण योग्य नहीं रहती और जैसे ही कोड बदलता है, यह पुरानी होने लगती है।

एक अच्छी आवश्यकता क्या बनाती है ​

एक अच्छी आवश्यकता एक व्यवहार होती है, इतनी स्पष्ट रूप से बताई गई कि आप इसे किसी और को परीक्षण के लिए दे सकें।

  • एक कथन, एक SHALL/MUST। यदि किसी आवश्यकता में तीन "और भी" खंड हैं, तो वह वास्तव में तीन आवश्यकताएँ हैं। उन्हें विभाजित करें।
  • अवलोकनीय। कोड के बाहर का कोई व्यक्ति यह बता पाने में सक्षम होना चाहिए कि यह कायम है या नहीं। "जब अपलोड 10 MB से अधिक हो जाता है तो सिस्टम एक त्रुटि बैनर दिखाएगा" अवलोकनीय है। "सिस्टम बड़े अपलोड को शालीनता से संभालेगा" ऐसा नहीं है।
  • सही शक्ति। OpenSpec RFC 2119 कीवर्ड का उपयोग करता है, और उनके अलग-अलग अर्थ होते हैं:
Keywordअर्थ
MUST / SHALLएक कठिन आवश्यकता। गैर-परक्राम्य।
SHOULDएक मजबूत सिफारिश, जिसमें न्यायसंगत अपवाद की गुंजाइश हो।
MAYवास्तव में वैकल्पिक।

डिफ़ॉल्ट रूप से MUST/SHALL का उपयोग करें। SHOULD का उपयोग केवल तभी करें जब आप वास्तव में "जब तक कोई अच्छा कारण न हो" का अर्थ रखते हों।

एक आवश्यकता की परीक्षा: क्या एक परीक्षक जिसने कोड कभी नहीं देखा, यह बता सकता है कि यह पास हुई या नहीं? यदि नहीं, तो इसे तेज करने की आवश्यकता है।

एक अच्छा परिदृश्य क्या बनाता है ​

परिदृश्य वे हैं जहाँ एक आवश्यकता अपनी उपयोगिता सिद्ध करती है। प्रत्येक परिदृश्य एक ठोस GIVEN / WHEN / THEN है जो एक स्वचालित परीक्षण बन सकता है।

  • यह अपनी आवश्यकता का अभ्यास करता है। एक परिदृश्य जो आवश्यकता को केवल अन्य शब्दों में दोहराता है, कुछ भी परीक्षण नहीं करता। इसे एक विशिष्ट स्थिति और विशिष्ट परिणाम के साथ बनाएँ।
  • उन मामलों को कवर करें जो मायने रखते हैं, केवल खुशहाल मार्ग ही नहीं। मान्य लॉगिन आसान है। खाली इनपुट, समाप्त टोकन, दूसरा क्लिक, जो गलत होता है — वे वही हैं जहाँ बग रहते हैं, और जहाँ एक परिदृश्य सबसे अधिक मूल्यवान होता है।
  • शीर्षक में मामले का नाम दें। "Scenario: Rejects an expired token" एक समीक्षक को बताता है कि एक नज़र में क्या कवर किया गया है; "Scenario: Test 2" नहीं बताता।

एक उपयोगी आदत: अनुमोदन से पहले पूछें वह एक मामला क्या है जिसे टूटा देखकर मैं परेशान होऊँगा? — और सुनिश्चित करें कि एक परिदृश्य उसका नाम लेता है।

डेल्टा का सही प्रकार चुनें ​

एक बदलाव तीन अनुभाग प्रकारों के साथ स्पेक्स में अपने संपादनों का वर्णन करता है। सही प्रकार का उपयोग आपके संग्रहीत स्पेक्स को सत्य बनाए रखता है:

  • ## ADDED Requirements — बिल्कुल नया व्यवहार जो पहले अस्तित्व में नहीं था।
  • ## MODIFIED Requirements — व्यवहार जो पहले से मौजूद था और बदल रहा है। पूर्ण नया संस्करण शामिल करें; क्या बदला इस पर एक संक्षिप्त नोट समीक्षक की मदद करता है।
  • ## REMOVED Requirements — व्यवहार जो हट रहा है, इस कारण की एक पंक्ति के साथ।

संग्रह करते समय, ADDED को मुख्य स्पेक में जोड़ा जाता है, MODIFIED पुराने संस्करण को बदल देता है, और REMOVED को उसमें से हटा दिया जाता है। किसी क्षमता की अंतिम आवश्यकता हटाने का अर्थ है उसे सेवानिवृत्त करना: एक स्पेक को खाली छोड़ने के बजाय, संग्रह openspec/specs/<capability>/spec.md को हटा देता है। क्योंकि यह एकमात्र संग्रह चरण है जो एक फ़ाइल हटाता है, इसे पूछा जाना चाहिए — बदलाव के .openspec.yaml में retire_capabilities: true जोड़ें, उस schema: के साथ जो उस फ़ाइल को पहले से चाहिए। इसके बिना संग्रह रद्द हो जाता है और आपको यह बताता है। सेवानिवृत्ति पूरी फ़ाइल को हटा देती है, इसलिए इसे तब भी अस्वीकार किया जाता है जब स्पेक में उसके शीर्षक, ## Purpose, और उसके आवश्यकता ब्लॉकों के अलावा कुछ भी हो — एक ## Notes अनुभाग, एक आवश्यकता के अंतर्गत एक टिप्पणी। रद्दीकरण उन पंक्तियों का नाम देता है; उन्हें ## Purpose या एक आवश्यकता में ले जाएँ, या स्पेक को हाथ से हटा दें। कॉल करने वाले के चेकआउट में स्पेक के लिए, संग्रह आउटपुट उस git checkout का भी नाम देता है जो एक प्रतिबद्ध फ़ाइल को पुनर्स्थापित करता है; चयनित स्टोर चेकआउट-स्कोप्ड पुनर्प्राप्ति मार्गदर्शन प्राप्त करते हैं। यदि आप एक वास्तविक बदलाव को ADDED के रूप में चिह्नित करते हैं, तो आप दो प्रतिस्पर्धी आवश्यकताओं के साथ समाप्त होते हैं; यदि आप नए व्यवहार को MODIFIED के रूप में वर्णित करते हैं, तो बदलने के लिए कुछ भी नहीं है। संदेह होने पर, वर्तमान स्पेक खोलें और देखें कि क्या आवश्यकता पहले से मौजूद है।

एक और अनुभाग जानने लायक है। जब आपका डेल्टा एक ऐसी क्षमता बनाता है जो अभी तक मौजूद नहीं है, तो इसे ## Purpose के साथ खोलें — क्षमता किस लिए है इस पर एक या दो वाक्य। संग्रह इसे बनाए गए मुख्य स्पेक के उद्देश्य के रूप में उपयोग करता है; इसे छोड़ दें और आपको हाथ से भरने के लिए एक TBD प्लेसहोल्डर मिलता है। एक मौजूदा स्पेक में पहले से एक उद्देश्य होता है, इसलिए डेल्टा का वहाँ अनदेखा किया जाता है — एक को बदलने के लिए सीधे openspec/specs/<capability-path>/spec.md संपादित करें। यहाँ, <capability-path> specs/ के सापेक्ष निर्देशिका है, जैसे समतल परियोजना में user-auth या डोमेन द्वारा व्यवस्थित परियोजना में identity/user-auth।

बदलाव का सही आकार ​

सबसे आम लेखन गलती कोई खराब शब्दों वाली आवश्यकता नहीं है — यह एक बदलाव है जो तीन बदलाव बनने की कोशिश कर रहा है।

एक अच्छे बदलाव का एक ही उद्देश्य होता है जिसे आप एक वाक्य में कह सकते हैं। "एक डार्क-मोड टॉगल जोड़ें।" "लॉगिन एंडपॉइंट को रेट-लिमिट करें।" "सत्रों को कुकीज़ से स्थानांतरित करें।" यदि बदलाव का वर्णन करने में बहुत सारा "और भी" चाहिए, तो यह उसे विभाजित करने का संकेत है।

संकेत कि बदलाव बहुत बड़ा है:

  • प्रस्ताव का दायरा असंबंधित सुविधाओं की सूची जैसा लगता है।
  • इसकी समीक्षा करने में एक दोपहर लग जाएगी, इसलिए कोई नहीं करेगा।
  • दो लोग बिना टकराव के इस पर काम नहीं कर सकते।
  • आधे कार्य अपने आप भेजे जा सकते हैं।

छोटे बदलावों की समीक्षा करना आसान होता है, एक केंद्रित सत्र में बनाना आसान होता है, और छह महीने बाद जब केवल संग्रह बचा हो तो उसके बारे में तर्क करना आसान होता है। आप हमेशा कई बदलावों को समानांतर में चला सकते हैं — संपादन और पुनरावृत्ति और वर्कफ़्लो देखें।

इसका विपरीत भी होता है: एक-पंक्ति टाइपो सुधार के लिए तीन आवश्यकताओं और एक डिज़ाइन दस्तावेज़ की आवश्यकता नहीं होती। समारोह को दांव से मिलाएँ।

AI को एक अच्छे ड्राफ्ट की ओर कैसे ले जाएँ ​

क्योंकि /opsx:propose पहला ड्राफ्ट करता है, आपको जो वापस मिलता है उसकी गुणवत्ता उसकी गुणवत्ता का अनुसरण करती है जो आप उसे देते हैं। आपको हाथ से आवश्यकताएँ लिखने की आवश्यकता नहीं है — आपको AI को अच्छी तरह से निशाना लगाना होगा:

  • उद्देश्य और सीमा बताएँ। "एक डार्क-मोड टॉगल जोड़ें जो पहले लोड पर OS सेटिंग का अनुसरण करता है — मौजूदा थीम API को न छुएं।" दायरे से बाहर का आधा हिस्सा उतना ही मायने रखता है जितना दायरे के अंदर का आधा।
  • उन मामलों का नाम बताएँ जिनकी आप परवाह करते हैं। "सुनिश्चित करें कि ऐसे उपयोगकर्ता के लिए एक परिदृश्य है जिसने पहले से मैन्युअल रूप से थीम चुनी है।" AI उसे कवर करता है जिस ओर आप इशारा करते हैं।
  • फिर संपादित करें। यह सादा Markdown है। एक अस्पष्ट SHALL को कसें, ऐसे परिदृश्य को हटाएँ जो कुछ परीक्षण नहीं करता, वह मामला जोड़ें जो छूट गया — या AI से कहें: "टाइमआउट आवश्यकता अस्पष्ट है, इसे 30 मिनट पर पिन करें।"

ड्राफ्ट, तेज करें, दोहराएँ। उसके कुछ दौर एक ऐसा स्पेक उत्पन्न करते हैं जिस पर आप भरोसा करेंगे, जो पूरा उद्देश्य है।

एक त्वरित चेकलिस्ट ​

आगे कहाँ जाएँ ​