नियम और हुक्स (Rules & Hooks): Codex में स्वचालित नियंत्रण और कपाट जोड़ना
📚 सीरीज नेविगेशन: पिछला लेख [23 प्लगइन्स (Plugins)] आपको थर्ड-पार्टी क्षमताओं को एक साथ पैक करके इंस्टॉल करना सिखाता है। यह लेख अधिक बुनियादी और आपके नियंत्रण की दो चीज़ों के बारे में बात करता है—नियम (Rules) यह नियंत्रित करते हैं कि 'कौन सी कमांड सैंडबॉक्स से बाहर चल सकती हैं', और हुक्स (Hooks) यह तय करते हैं कि 'कोडिंग प्रक्रिया के किसी विशिष्ट चरण पर स्वचालित रूप से कोई स्क्रिप्ट कैसे रन हो'। एक सुरक्षा सीमा है, और दूसरा ट्रिगर। इन्हें सेट करने के बाद, आपको बार-बार मैन्युअल रूप से निर्देश देने या कमांड्स चलाने की आवश्यकता नहीं होगी। अगला लेख [25 Worktrees समानांतर काम] यह समझाएगा कि कैसे आप एक साथ कई Codex सत्रों को बिना किसी टकराव के चला सकते हैं।
यहाँ पिछले महीने मेरे और मेरे सहयोगी के बीच हुई एक वास्तविक बातचीत का अंश है। हम एक ऐसे बग की जाँच कर रहे थे जिसके कारण CI बार-बार विफल हो रहा था:
मैं: "इस सप्ताह मैंने Codex द्वारा कोड बदलने के बाद मैन्युअल रूप से
ruff formatकम से कम दस बार चलाया होगा।" सहयोगी: "क्या तुमनेAGENTS.mdमें 'कोड बदलने के बाद फ़ॉर्मेट करें' नहीं लिखा है?" मैं: "लिखा है। लेकिन यह तीन में से एक बार भूल जाता है—वह अनुरोध था, कोई गारंटी नहीं। एक बार भी भूलने पर CI की फ़ॉर्मेट जाँच विफल हो जाती है।" सहयोगी: "तो तुम एक हुक (hook) क्यों नहीं जोड़ देते? जैसे ही कोई घटना ट्रिगर होगी, स्क्रिप्ट स्वतः चल जाएगी, इसके लिए Codex को याद रखने की आवश्यकता नहीं होगी।"
इस बातचीत ने मुझे सोचने पर मजबूर किया। मैंने PostToolUse हुक सेटअप किया, और उसके बाद से Codex जब भी कोई फ़ाइल बदलता है, फ़ॉर्मेटिंग स्वतः हो जाती है। मुझे दुबारा कभी मैन्युअल रूप से फ़ॉर्मेट नहीं करना पड़ा और न ही CI कभी विफल हुआ। इस लेख में हम नियमों और हुक्स को विस्तार से समझेंगे—कि ये क्या हैं, इन्हें कैसे लिखा और टेस्ट किया जाता है।
इस लेख को पढ़ने के बाद, आपको मिलेगा:
- नियम और हुक्स क्या नियंत्रित करते हैं, और वे
AGENTS.mdकी तुलना में "निश्चितता" कैसे प्रदान करते हैं। - नियम (
.rulesफ़ाइल +prefix_rule) कैसे लिखे जाते हैं ताकि किसी कमांड को "हमेशा स्वीकृत" या "ब्लॉक" किया जा सके, औरcodex execpolicy checkद्वारा जाँच। - हुक्स को किन फ़ाइलों में कॉन्फ़िगर किया जाता है, और उनके स्टार्टअप के लिए कौन से "घटनाक्रम (events)" (
PreToolUse/PostToolUse/Stop/SessionStartआदि) उपलब्ध हैं। - Codex हुक्स का सुरक्षा नियम—नया हुक डिफ़ॉल्ट रूप से क्यों ब्लॉक रहता है और इसके लिए
/hooksसे अनुमोदन आवश्यक है। - हुक और Codex के बीच डेटा का आदान-प्रदान (stdin JSON, exit codes, stdout JSON), और Claude Code से कुछ भिन्नताएँ।
- दो उपयोगी उदाहरण: कोड बदलने पर स्वचालित फ़ॉर्मेटिंग, और हानिकारक कमांड्स को ब्लॉक करना; तथा हुक काम न करने पर समाधान।
⚠️ नीचे दी गई सभी विशिष्ट कमांड्स, कॉन्फ़िगरेशन विकल्प और डिफ़ॉल्ट मान Codex आधिकारिक दस्तावेज़ों (Hooks / Rules) पर आधारित हैं। नियम (Rules) अभी एक प्रयोगात्मक फ़ीचर है जो भविष्य में बदल सकता है।
01 नियम "सुरक्षा सीमा" हैं, और हुक्स "ट्रिगर"
दोनों में अंतर स्पष्ट रूप से समझें:
- नियम (Rules) यह तय करते हैं कि "क्या कोई कमांड सैंडबॉक्स से बाहर चलने के योग्य है"—यह एक सुरक्षा सीमा है जो प्रत्येक कमांड की जाँच करके "स्वीकृत / अनुमोदन आवश्यक / ब्लॉक" का निर्णय लेती है।
- हुक्स (Hooks) यह तय करते हैं कि "कोडिंग प्रक्रिया के किसी विशिष्ट चरण पर स्वचालित रूप से कोई स्क्रिप्ट चलनी चाहिए"—यह एक ट्रिगर है जो विशिष्ट घटनाओं पर स्वतः सक्रिय होता है, Codex के निर्णय से स्वतंत्र।
तुलना: सोसायटी के सुरक्षा नियमों और लिफ्ट की ऑटो-लाइट से। सुरक्षा नियमों में लिखा होता है कि "किसे प्रवेश की अनुमति है, किसे रजिस्टर में लिखना होगा, और किसे ब्लॉक रखना है"—यह नियम है: जब भी कोई प्रवेश करेगा, गार्ड नियमों की जाँच करेगा। वहीं, लिफ्ट में लगी लाइट जो "किसी के प्रवेश करने पर स्वतः जल जाती है" वह हुक है: उसे इससे मतलब नहीं कि आप कौन हैं, "व्यक्ति के प्रवेश करने" की घटना पर लाइट स्वतः जल जाएगी। एक सुरक्षा जाँच है और दूसरा स्वचालित ट्रिगर।
इनका AGENTS.md (लेख 11) से अंतर क्या है?
AGENTS.mdमें लिखे निर्देश अनुरोध हैं; जबकि नियम या हुक्स के रूप में जोड़े गए निर्देश गारंटी हैं।
सरल शब्दों में:
AGENTS.mdमें लिखना कि "कोड बदलने पर फ़ॉर्मेट करें" या "उत्पादन डेटा को न छुएं"—यह Codex के लिए अनुरोध है, जिसका यह पालन करने का प्रयास करता है, लेकिन वह भूल सकता है।- हुक द्वारा फ़ॉर्मेट करना या नियम द्वारा कमांड ब्लॉक करना—यह तय स्थिति पर हमेशा लागू होगा, Codex के याद रखने पर निर्भर नहीं।
कुछ उपयोगी उदाहरण:
- "
gh pr viewकमांड का मैं अक्सर उपयोग करता हूँ, इसके लिए बार-बार पॉप-अप न दिखाया जाए"—नियम द्वारा इसके लिए "हमेशा स्वीकृत" का विकल्प सेट करें। - "
rm -rfयाgit push --forceजैसी कमांड्स को पूरी तरह ब्लॉक करना"—नियम द्वारा इन्हें स्थायी रूप से ब्लॉक करें। - "कोड बदलने पर स्वचालित रूप से फ़ॉर्मेटिंग/लिनटर चलाना"—हुक का उपयोग करें ताकि यह स्वतः हो सके।
💡 संक्षेप में: नियम कमांड्स को सैंडबॉक्स से बाहर चलाने की सुरक्षा सीमा है, और हुक विशिष्ट घटनाओं पर स्वचालित रूप से स्क्रिप्ट चलाने का ट्रिगर है; दोनों नियमों को निश्चितता प्रदान करते हैं।
02 नियम (Rules): विशिष्ट कमांड्स के लिए सुरक्षा सीमा सेट करना
⚠️ प्रयोगात्मक, बदलाव संभव।
सैंडबॉक्स सुरक्षा (लेख 15) एक सामान्य सीमा है—जहाँ सीमा से बाहर जाने पर अनुमोदन माँगा जाता है। लेकिन यदि आप विशिष्ट कमांड के स्तर पर बारीक नियंत्रण चाहते हैं: जैसे "कमांड gh pr view को बिना पूछे चलने की अनुमति हो" या "grep की जगह rg का उपयोग अनिवार्य हो"। इसके लिए नियमों का उपयोग किया जाता है।
तुलना: सुरक्षा गार्ड को दी गई विशिष्ट सूची से। सैंडबॉक्स सामान्य नियम है (जैसे "अपरिचितों से पूछताछ करें"), और नियम विशिष्ट सूची है: जिसमें लिखा होता है कि "इन विश्वसनीय व्यक्तियों को बिना पूछे प्रवेश दें" और "इन व्यक्तियों को सीधे ब्लॉक रखें"। यह सुरक्षा को अधिक सुदृढ़ बनाता है।
इसके उपयोग:
- अक्सर उपयोग होने वाली विश्वसनीय कमांड्स (जैसे
gh,make test) को व्हाइटलिस्ट करना ताकि बार-बार अनुमोदन न करना पड़े। - अप्रचलित या असुरक्षित कमांड्स (जैसे
grep) को ब्लॉक करके बेहतर टूल्स (जैसेrg) का उपयोग सुनिश्चित करना। - गंभीर रूप से हानिकारक कमांड्स (जैसे
rm -rf /) को ब्लॉक करना।
नियम फ़ाइल कहाँ होती है और कैसी दिखती है
नियम .rules फ़ाइलों में लिखे जाते हैं, जिन्हें संबंधित सेटिंग्स निर्देशिका के rules/ फ़ोल्डर में रखा जाता है। उदाहरण के लिए, उपयोगकर्ता स्तर पर ~/.codex/rules/default.rules। इसका सिंटैक्स Python जैसा होता है (वास्तव में Starlark भाषा है)।
एक सरल नियम का उदाहरण: "gh pr view कमांड चलाने से पहले हमेशा अनुमोदन माँगा जाए":
# gh pr view कमांड चलाने से पहले अनुमति माँगें
prefix_rule(
# कमांड का उपसर्ग (प्रत्येक भाग अलग से)
pattern = ["gh", "pr", "view"],
# निर्णय: allow (स्वीकृत) / prompt (अनुमोदन आवश्यक) / forbidden (ब्लॉक)
decision = "prompt",
# विवरण
justification = "PR देखने की अनुमति है, लेकिन अनुमोदन आवश्यक है",
# परीक्षण उदाहरण
match = [
"gh pr view 7888",
"gh pr view --repo openai/codex",
],
not_match = [
"gh pr --repo openai/codex view 7888",
],
)prefix_rule के विकल्प:
| विकल्प | विवरण | टिप्पणी |
|---|---|---|
pattern (आवश्यक) | कमांड का उपसर्ग (प्रत्येक भाग अलग से) | यह विशिष्ट शब्द या शब्दों का समूह हो सकता है |
decision (डिफ़ॉल्ट allow) | मैच होने पर निर्णय | allow / prompt / forbidden (सबसे सख्त की जीत) |
justification (वैकल्पिक) | नियम का कारण | यह अनुमोदन स्क्रीन पर दिखाई दे सकता है |
match / not_match (वैकलक) | नियम का परीक्षण करने के लिए | सिस्टम नियम लोड करते समय इसकी जाँच करता है |
decision की प्राथमिकता तय है—सबसे सख्त नियम की जीत होती है (forbidden > prompt > allow):
| decision | विवरण |
|---|---|
allow | सैंडबॉक्स से बाहर सीधे चलाने की अनुमति, बिना पूछे |
prompt | चलाने से पहले हमेशा अनुमति माँगी जाएगी |
forbidden | सीधे ब्लॉक करें, न पूछें और न चलाने दें |
बदलाव करने के बाद Codex को रीस्टार्ट करना आवश्यक है। जब आप CLI में किसी कमांड को "हमेशा स्वीकृत" करते हैं, तो Codex उसे स्वतः ~/.codex/rules/default.rules में लिख देता है, इसलिए यह फ़ाइल समय के साथ स्वतः भी अपडेट होती है।
सुरक्षा डिज़ाइन: एक साथ लिखी कई कमांड्स को अलग-अलग जाँचना
यह सुरक्षा के लिए बहुत महत्वपूर्ण है। यदि कोई git add . && rm -rf / जैसी एक ही लाइन में कई कमांड्स लिखता है, तो Codex सुरक्षा सुनिश्चित करने के लिए इन्हें अलग-अलग भागों में तोड़कर जाँचता है, और सबसे सख्त नियम को लागू करता है:
["bash", "-lc", "git add . && rm -rf /"]इसे दो स्वतंत्र कमांड्स में विभाजित किया जाएगा:
["git", "add", "."]
["rm", "-rf", "/"]यहाँ लाभ यह है: भले ही आपने git add को allow किया हो, rm -rf / को अलग से ब्लॉक कर दिया जाएगा। इससे खतरनाक कमांड्स को सुरक्षा नियमों को बायपास करके चलाने से रोका जा सकता है।
लेकिन ध्यान रखें: केवल सामान्य क्रमिक कमांड्स ही विभाजित की जा सकती हैं। यदि कमांड में रीडायरेक्शन (>), वेरिएबल रिप्लेसमेंट ($(...)), पर्यावरण वेरिएबल या वाइल्डकार्ड (*) का उपयोग किया गया है, तो Codex उसे विभाजित नहीं कर पाएगा और उसे एक ही कमांड bash -lc के रूप में जाँचेगा। इसलिए इसे बहुत जटिल न बनाएं।
नियमों की जाँच: execpolicy check का उपयोग
बदलावों को सीधे लागू करने से पहले उनका परीक्षण करें:
codex execpolicy check --pretty \
--rules ~/.codex/rules/default.rules \
-- gh pr view 7888 --json title,body,commentsयह JSON आउटपुट दिखाएगा कि इस कमांड पर क्या निर्णय लिया गया है और कौन सा नियम लागू हुआ है। नियमों को लागू करने से पहले इस प्रकार जाँच कर लेना सही रहता है ताकि कोई उपयोगी कमांड ब्लॉक न हो जाए।
💡 संक्षेप में: नियम
.rulesफ़ाइल में लिखे जाते हैं और कमांड उपसर्ग की जाँच करते हैं (सबसे सख्त निर्णय लागू होता है); जटिल कमांड्स को विभाजित करके जाँचा जाता है; बदलावों की जाँच के लिएcodex execpolicy checkका उपयोग करें।
03 हुक्स (Hooks): सक्रिय होने के समय (Events)
हुक्स किसी भी समय सक्रिय नहीं होते, बल्कि वे Codex कोडिंग प्रक्रिया की विशिष्ट घटनाओं (events) पर सक्रिय होते हैं। सही हुक चुनने के लिए इन घटनाओं को समझना आवश्यक है।
लेख 02 में हमने देखा था कि Codex का काम "विचार → क्रिया → परिणाम" चक्र में चलता है। हुक्स इसी चक्र के विभिन्न चरणों पर सक्रिय होते हैं:

यह आरेख दिखाता है: सत्र शुरू होने पर SessionStart, निर्देश सबमिट करने पर UserPromptSubmit, और टूल्स के उपयोग के समय PreToolUse (रन होने से पहले) और PostToolUse (रन होने के बाद) सक्रिय होते हैं। सत्र समाप्त होने पर Stop सक्रिय होता है।
चार सबसे महत्वपूर्ण घटनाक्रम जिनका अक्सर उपयोग किया जाता है:
| घटना | विवरण | उपयोग |
|---|---|---|
PreToolUse | टूल रन होने से पहले | खतरनाक कमांड्स को ब्लॉक करना या बदलना (कमांड रोक सकता है) |
PostToolUse | टूल रन होने के बाद | कोड बदलने पर फ़ॉर्मेटिंग या लिनटर चलाना |
Stop | Codex द्वारा उत्तर देने के बाद | काम की जाँच करना (जैसे टेस्ट पास न होने पर सुधार के लिए दुबारा कहना) |
SessionStart | सत्र शुरू या रीस्टार्ट होने पर | प्रोजेक्ट की वर्तमान स्थिति को संदर्भ में जोड़ना |
एक और महत्वपूर्ण घटना PermissionRequest है (अनुमोदन पॉप-अप से पहले सक्रिय होती है), जिसके द्वारा आप स्वचालित रूप से अनुमति दे या अस्वीकार कर सकते हैं।
नाम में Pre और Post से अंतर समझें: Pre क्रिया से "पहले" है, इसलिए केवल यही क्रिया को रोकने में सक्षम है; Post क्रिया के "बाद" है, इसलिए यह क्रिया को रोक नहीं सकता, केवल उसके बाद आवश्यक सुधार (जैसे फ़ॉर्मेटिंग) कर सकता है।
यह प्रक्रिया इस आरेख में दिखाई गई है:

यह आरेख दिखाता है कि सत्र शुरू होने से लेकर समाप्त होने तक विभिन्न चरणों पर हुक्स कैसे जुड़े होते हैं, और घटना होने पर वे स्वतः ट्रिगर होते हैं।
Claude Code से अंतर: Codex में Stop या PostToolUse घटनाओं पर decision: "block" का अर्थ कार्य को अस्वीकार करना नहीं है, बल्कि "कार्य को दुबारा जाँचना / आगे बढ़ाना" है। यह प्रतिक्रिया को दुबारा मॉडल के पास भेज देता है ताकि वह सुधार कर सके।
💡 संक्षेप में: हुक्स विशिष्ट जीवनचक्र घटनाओं पर सक्रिय होते हैं; मुख्य घटनाक्रम
PreToolUse(पहले),PostToolUse(बाद में),Stop(उत्तर के बाद) औरSessionStart(शुरुआत) हैं।
04 हुक्स कहाँ लिखे जाते हैं, और matcher का उपयोग
हुक्स को कॉन्फ़िगर करने के स्थान और तरीके:
हुक्स कहाँ कॉन्फ़िगर करें
हुक्स को दो स्थानों पर लिखा जा सकता है: एक स्वतंत्र hooks.json फ़ाइल में, या config.toml के भीतर [hooks] तालिका में। पथ विवरण:
| फ़ाइल का स्थान | प्रभाव | टीम के साथ साझा करना |
|---|---|---|
~/.codex/hooks.json | सभी प्रोजेक्ट्स पर | नहीं, केवल स्थानीय मशीन पर |
~/.codex/config.toml | सभी प्रोजेक्ट्स पर | नहीं |
<repo>/.codex/hooks.json | केवल वर्तमान प्रोजेक्ट पर | हाँ, Git में शामिल कर सकते हैं |
<repo>/.codex/config.toml | केवल वर्तमान प्रोजेक्ट पर | हाँ |
नियम पहले जैसा ही है: पूरी टीम के लिए उपयोगी हुक्स को प्रोजेक्ट के .codex/ फ़ोल्डर में लिखें; व्यक्तिगत हुक्स को होम निर्देशिका ~/.codex/ में लिखें।
- विभिन्न फ़ाइलों में लिखे गए हुक्स आपस में जुड़ जाते हैं और एक साथ चलते हैं।
- एक ही स्थान पर
hooks.jsonऔरconfig.tomlदोनों में हुक्स न लिखें, इससे एरर आ सकता है। - प्रोजेक्ट स्तर के हुक्स केवल तभी लोड होते हैं जब प्रोजेक्ट पर भरोसा (Trust) किया गया हो।
हुक कॉन्फ़िगरेशन का उदाहरण
प्रोजेक्ट के .codex/hooks.json में लिखने का उदाहरण: "जब भी Codex कोई Bash कमांड चलाए, उसके बाद एक स्क्रिप्ट चले":
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use.py\"",
"timeout": 30,
"statusMessage": "Bash आउटपुट की समीक्षा"
}
]
}
]
}
}ढांचा तीन स्तरों में विभाजित है:
"PostToolUse"—घटना (टूल रन होने के बाद)।"matcher": "Bash"—यह तय करना कि केवल Bash टूल के लिए ही यह सक्रिय हो।hooksसूची—चलने वाली स्क्रिप्ट:"type": "command"दर्शाता है कि यह एक कमांड है, और"command"उसका पथ है।
ध्यान रखने योग्य बातें:
timeoutका मान सेकंड में होता है; न लिखने पर डिफ़ॉल्ट मान 600 सेकंड होता है।- अभी केवल
"type": "command"प्रकार के हुक्स ही समर्थित हैं; अन्य को छोड़ दिया जाता है। - एक ही घटना पर कई हुक्स होने पर वे समानांतर में चलते हैं, एक हुक दूसरे को चलने से नहीं रोक सकता।
- स्क्रिप्ट का पथ सेट करते समय वर्तमान वर्किंग निर्देशिका का ध्यान रखें—सुरक्षा के लिए
$(git rev-parse --show-toplevel)द्वारा Git रूट से पूर्ण पथ लिखना सही रहता है (जैसा ऊपर उदाहरण में किया गया है)। - Windows के लिए आप
command_windowsविकल्प का उपयोग करके अलग कमांड लिख सकते हैं।
Claude Code से अंतर: Codex में timeout सेकंड में होता है (वहाँ मिलीसेकंड में होता है), और यहाँ disableAllHooks जैसा कोई सीधा विकल्प नहीं होता (हुक्स बंद करने के लिए [features] hooks = false लिखना होता है)।
config.toml में इसे लिखने का तरीका:
[[hooks.PostToolUse]]
matcher = "^Bash$"
[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use.py"'
timeout = 30
statusMessage = "Bash आउटपुट की समीक्षा"matcher: हुक को सीमित करना
matcher विकल्प यह नियंत्रित करता है कि हुक कब सक्रिय हो। यदि यह विकल्प नहीं लिखा जाता, तो हुक घटना होने पर हमेशा चलेगा; इसका उपयोग करके आप इसे विशिष्ट टूल्स तक सीमित रख सकते हैं।
तुलना: सुरक्षा कैमरे के मोशन डिटेक्टर से। यदि कैमरा पूरे हॉल की हलचल पर अलार्म बजाएगा, तो अनावश्यक अलार्म बजेंगे। आप मोशन डिटेक्शन को केवल "दरवाज़े के पास" सीमित करना चाहते हैं। matcher भी यही सीमा तय करता है।
Codex में matcher रेगुलर एक्सप्रेशन (regex) होता है। टूल घटनाओं (PreToolUse/PostToolUse) के लिए यह टूल के नाम की जाँच करता है। उदाहरण:
| matcher मान | विवरण | उदाहरण |
|---|---|---|
"Bash" | केवल Bash टूल के लिए | Bash कमांड चलने पर सक्रिय |
"^apply_patch$" | फ़ाइल में बदलाव करने वाले टूल के लिए | फ़ाइल संपादन पर सक्रिय |
"Edit|Write" | संपादन के अन्य नाम | फ़ाइल संपादन पर सक्रिय |
"mcp__filesystem__.*" | MCP फ़ाइल सिस्टम टूल्स के लिए | संबंधित MCP टूल रन होने पर |
* या खाली छोड़ना | सभी टूल्स के लिए | घटना होने पर हमेशा सक्रिय |
ध्यान दें:
- फ़ाइल संपादन टूल का मूल नाम
apply_patchहै। आप matcher मेंEditयाapply_patchका उपयोग कर सकते हैं, लेकिन स्क्रिप्ट में डेटा प्राप्त करते समय टूल का नाम हमेशाapply_patchही दिखाई देगा। - सभी घटनाओं के लिए
matcherकाम नहीं करता।UserPromptSubmitऔरStopके लिए इसका उपयोग नहीं किया जा सकता क्योंकि वे किसी टूल से संबंधित नहीं हैं, वे हमेशा सक्रिय होते हैं। PreToolUseसभी प्रकार की कमांड्स को ब्लॉक नहीं कर सकता, यह केवल साधारण shell,apply_patchऔर MCP टूल्स पर ही काम करता है। इसलिए इसे सुरक्षा की एकमात्र परत न मानें।
💡 संक्षेप में: हुक्स को
hooks.jsonया config.toml में लिखा जाता है; matcher Regular Expression का उपयोग करके इसे विशिष्ट टूल्स तक सीमित रखता है;timeoutसेकंड में होता है।
05 सुरक्षा नियम: नया हुक स्टार्टअप पर ब्लॉक क्यों रहता है
यह Codex हुक्स की एक महत्वपूर्ण विशेषता है जो Claude Code से अलग है: जब आप कोई नया हुक लिखते हैं या पुराना बदलते हैं, तो वह डिफ़ॉल्ट रूप से सक्रिय नहीं होता—सुरक्षा कारणों से Codex उसे ब्लॉक रखता है।
चूँकि हुक आपकी मशीन पर आपके विशेषाधिकारों के साथ कोई भी कमांड चला सकते हैं, यदि किसी अपरिचित रिपोजिटरी में कोई हानिकारक हुक छिपा हो, तो वह मशीन को नुकसान पहुँचा सकता है। इसलिए सुरक्षा सुनिश्चित करने के लिए यह व्यवस्था की गई है।
तुलना: नए ऐप को अनुमति देने से। जब आप फोन में कोई ऐप इंस्टॉल करते हैं, तो क्रेडेंशियल्स या कैमरे के उपयोग के लिए अनुमति पॉप-अप दिखाई देता है, जब तक आप अनुमति नहीं देते वह काम नहीं कर सकता।
सुरक्षा नियम:
- Codex हुक फ़ाइल के हैश (Hash) के आधार पर सुरक्षा स्थिति याद रखता है। नया हुक लिखने या उसमें एक भी अक्षर बदलने पर हैश बदल जाता है, और Codex उसे "समीक्षा आवश्यक" मानकर ब्लॉक कर देता है।
- जुड़े हुए हुक्स की समीक्षा करने और उन्हें सक्रिय (trust) करने के लिए
/hooksस्लैश कमांड का उपयोग करें। - यदि स्टार्टअप पर कोई हुक बिना अनुमति के ब्लॉक है, तो स्क्रीन पर चेतावनी दिखाई देगी।
कस्टम हुक लिखने के बाद Codex शुरू करें → /hooks चलाएं → हुक की जाँच करें और उसे अनुमति (trust) दें। इसके बाद ही वह सक्रिय होगा।
/hooksएक इंटरफ़ेस खुलेगा जहाँ आप सभी हुक्स देख सकते हैं, और उन्हें अनुमति दे सकते हैं। सिस्टम द्वारा प्रबंधित (managed) हुक्स को आप यहाँ से बंद नहीं कर सकते क्योंकि वे एडमिनिस्ट्रेटर नियमों द्वारा लागू होते हैं।
परीक्षण या स्वचालित वातावरण (CI) के लिए आप --dangerously-bypass-hook-trust फ़्लैग का उपयोग करके सुरक्षा जाँच को बायपास कर सकते हैं, लेकिन स्थानीय मशीन पर ऐसा करने से बचें।
💡 संक्षेप में: सुरक्षा के लिए नए या बदले गए हुक्स ब्लॉक रहते हैं; उन्हें सक्रिय करने के लिए
/hooksस्लैश कमांड चलाकर अनुमति देना आवश्यक है।
06 हुक और Codex के बीच डेटा का आदान-प्रदान: stdin, exit code, stdout
यह समझना आवश्यक है कि हुक स्क्रिप्ट Codex के साथ कैसे बातचीत करती है।
बातचीत तीन माध्यमों से होती है: Codex इनपुट डेटा stdin द्वारा भेजता है → स्क्रिप्ट काम करती है → स्क्रिप्ट exit code और stdout द्वारा परिणाम वापस देती है।
इनपुट: JSON डेटा प्राप्त करना
जब हुक सक्रिय होता है, तो Codex संबंधित विवरण को JSON फॉर्मेट में stdin द्वारा भेजता है। इसके मुख्य विकल्प:
| फ़ील्ड | विवरण |
|---|---|
session_id | सत्र आईडी |
cwd | कार्य निर्देशिका |
hook_event_name | घटना का नाम |
transcript_path | सत्र इतिहास का पथ |
model | सत्र में सक्रिय मॉडल |
permission_mode | सुरक्षा स्तर |
टूल आधारित घटनाओं में tool_name (जैसे "Bash") और tool_input (कमांड विवरण) भी शामिल होते हैं। उदाहरण:
{
"session_id": "abc123",
"cwd": "/Users/sarah/myproject",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /tmp/x"
}
}आपकी स्क्रिप्ट इस JSON से tool_input.command को पढ़कर जाँच कर सकती है कि कमांड सुरक्षित है या नहीं।
आउटपुट: exit code द्वारा नियंत्रण
काम होने के बाद, स्क्रिप्ट exit code द्वारा Codex को निर्देश देती है:
| exit code | विवरण |
|---|---|
0 | सामान्य—क्रिया जारी रखने की अनुमति |
2 | विशेष निर्देश (रोकना / प्रतिक्रिया देना) |
exit 2 का प्रभाव घटना के अनुसार बदलता है:
PreToolUse/UserPromptSubmitमें: यह क्रिया या निर्देश को ब्लॉक (रोक) कर देता है, और एरर विवरण को stderr से Codex में भेजता है।PostToolUse/Stopमें: यह क्रिया को रोक नहीं सकता (चूँकि वह पहले ही हो चुकी है), बल्कि यह विवरण को सुधार के लिए मॉडल के पास वापस भेज देता है (चक्र आगे बढ़ाता है)।
यानी रोकने का काम केवल Pre घटनाओं में ही हो सकता है।
stdout द्वारा JSON परिणाम देना
अधिक नियंत्रण के लिए आप exit 0 सेट करके stdout पर JSON आउटपुट दे सकते हैं। उदाहरण:
1. PreToolUse में कमांड ब्लॉक करना—permissionDecision: "deny" देना:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "सुरक्षा कारणों से इस कमांड को ब्लॉक किया गया है"
}
}2. SessionStart में संदर्भ जोड़ना—additionalContext देना:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "इस प्रोजेक्ट के नियमों का पालन करें।"
}
}ध्यान दें:
PreToolUseमेंstdoutपर सामान्य टेक्स्ट लिखने से कोई प्रभाव नहीं होगा; संदर्भ के लिए JSON फॉर्मेट मेंadditionalContextका उपयोग करें।SessionStartऔरUserPromptSubmitमें सामान्य टेक्स्ट का उपयोग किया जा सकता है; जबकिStopमें हमेशा JSON फॉर्मेट आवश्यक है।PreToolUseमेंcontinueफ़ील्ड काम नहीं करती, ब्लॉक करने के लिए हमेशाpermissionDecisionयाexit 2का उपयोग करें।
💡 संक्षेप में: हुक Codex से
stdinद्वारा JSON प्राप्त करता है, औरexit codeतथाstdoutद्वारा परिणाम वापस देता है;exit 2क्रिया को रोकने या प्रतिक्रिया देने के लिए है।
07 कोडिंग उदाहरण
दैनिक उपयोग के दो कोडिंग उदाहरण:
उदाहरण 1: कोड बदलने पर स्वचालित फ़ॉर्मेटिंग (PostToolUse)
यह सबसे उपयोगी हुक है जो कोडिंग शैली (Formatting) को स्वचालित रखता है।
चरण 1: .codex/hooks/format.py स्क्रिप्ट बनाएं (यह कोड बदलने पर फ़ॉर्मेटिंग कमांड चलाएगी):
#!/usr/bin/env python3
import json, subprocess, sys
data = json.load(sys.stdin)
# प्रोजेक्ट निर्देशिका में Ruff फ़ॉर्मेटर चलाना
subprocess.run(["ruff", "format", "."])चरण 2: प्रोजेक्ट के .codex/hooks.json में इसे पंजीकृत करें, और apply_patch (फ़ाइल बदलाव) के साथ जोड़ें:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/format.py\"",
"timeout": 30,
"statusMessage": "कोड फ़ॉर्मेट करना"
}
]
}
]
}
}चरण 3: Codex शुरू करें और /hooks चलाकर इसे अनुमति (trust) दें। अब जब भी Codex कोई फ़ाइल बदलेगा, फ़ॉर्मेटिंग स्वतः हो जाएगी। आप ruff की जगह prettier या gofmt का भी उपयोग कर सकते हैं।
उदाहरण 2: खतरनाक कमांड्स को ब्लॉक करना (PreToolUse)
यह सुरक्षा के लिए उपयोगी है।
चरण 1: .codex/hooks/block-dangerous.py स्क्रिप्ट बनाएं:
#!/usr/bin/env python3
import json, sys
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
if "rm -rf" in command:
print("Block: rm -rf कमांड प्रतिबंधित है", file=sys.stderr) # एरर संदेश
sys.exit(2) # ब्लॉक करने के लिए exit 2
sys.exit(0) # अन्य कमांड्स को सामान्य रूप से चलने देंचरण 2: .codex/hooks.json में Bash टूल के साथ जोड़ें:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/block-dangerous.py\"",
"statusMessage": "कमांड की सुरक्षा जाँच"
}
]
}
]
}
}चरण 3: /hooks से अनुमति दें। अब यदि Codex rm -rf कमांड चलाने का प्रयास करेगा, तो हुक उसे ब्लॉक कर देगा।
नियम: साधारण कमांड प्रतिबंधों के लिए नियमों (Rules) का उपयोग करें, और जटिल तार्किक जाँच के लिए हुक्स (Hooks) का उपयोग करें।
💡 संक्षेप में: उदाहरणों में फ़ॉर्मेटिंग के लिए
PostToolUseऔर ब्लॉक करने के लिएPreToolUse(exit 2 के साथ) का उपयोग किया जाता है; इन्हें कॉन्फ़िगर करने के बाद/hooksसे सक्रिय करना आवश्यक है।
08 अभ्यास: सरल हुक बनाना और चलाना
आइए एक सरल हुक बनाने और उसे चलाने का अभ्यास करें—जो Codex द्वारा Bash कमांड चलाने पर उसे एक लॉग फ़ाइल में नोट करेगा। यह पूरी तरह सुरक्षित अभ्यास है।
Windows उपयोगकर्ताओं के लिए: Python पथ का ध्यान रखें और Git Bash या WSL का उपयोग करें। अभ्यास से पहले प्रोजेक्ट में
git initचला लें ताकि Git रूट का पथ मिल सके।
चरण 1: स्क्रिप्ट और कॉन्फ़िगरेशन फ़ाइलें बनाएं
.codex/hooks/log-bash.py फ़ाइल बनाएं और यह लिखें:
#!/usr/bin/env python3
import json, sys, os
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
log = os.path.expanduser("~/codex-bash-log.txt")
with open(log, "a") as f:
f.write(command + "\n").codex/hooks.json फ़ाइल बनाएं और यह लिखें:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/log-bash.py\"",
"statusMessage": "Bash कमांड लॉग करना"
}
]
}
]
}
}चरण 2: Codex शुरू करें और हुक को अनुमति दें
codexचैट में चलाएं:
/hooksसूची में आपको नया हुक दिखाई देगा, उस पर जाकर उसे अनुमति (trust) दें।
चरण 3: एक कमांड चलाएं
इसे एक सरल कमांड चलाने के लिए कहें:
कृपया वर्तमान निर्देशिका की फ़ाइलें देखने के लिए ls चलाएं।कमांड चलने पर हुक सक्रिय होगा।
चरण 4: लॉग फ़ाइल की जाँच करें
सत्र से बाहर आकर टर्मिनल में देखें:
cat ~/codex-bash-log.txt(Windows पर type ~/codex-bash-log.txt चलाएं)
अपेक्षित परिणाम: फ़ाइल में आपको चलाई गई ls कमांड दिखाई देगी। यह दर्शाता है कि हुक ने अपना काम किया है।
चरण 5: हटाना (वैकल्पिक)
अभ्यास के बाद .codex/hooks.json से हुक सेटिंग्स हटा दें और लॉग फ़ाइल डिलीट कर दें।
💡 संक्षेप में: अभ्यास के चरण हैं—स्क्रीप्ट और कॉन्फ़िगरेशन फ़ाइलें बनाना →
/hooksसे अनुमति देना → टूल रन करना → लॉग फ़ाइल की जाँच करना।
09 समस्या निवारण (Troubleshooting)
यदि हुक काम नहीं कर रहा है, तो निम्नलिखित की जाँच करें:
| समस्या | समाधान |
|---|---|
| हुक सक्रिय नहीं हो रहा | ① क्या आपने /hooks में इसे अनुमति (trust) दी है? (यह सबसे आम कारण है); ② क्या स्क्रिप्ट बदलने के बाद दुबारा अनुमति दी है? ③ क्या घटना या matcher नाम सही है? |
| हुक सूची में दिखाई नहीं दे रहा | ① JSON प्रारूप की जाँच करें (यहाँ अंतिम कॉमा या टिप्पणियाँ मान्य नहीं हैं); ② फ़ाइल का पथ और नाम जाँचें; ③ क्या एक ही स्तर पर config.toml और hooks.json दोनों में हुक्स लिखे हैं? |
| कमांड नॉट फाउंड एरर | स्क्रिप्ट का पथ सही नहीं है। $(git rev-parse --show-toplevel) द्वारा हमेशा पूर्ण पथ का उपयोग करें,相对 (relative) पथ से बचें। |
| ब्लॉक करने की कोशिश विफल हुई | ① क्या आपने PreToolUse घटना का उपयोग किया है? Post ब्लॉक नहीं कर सकता; ② क्या स्क्रिप्ट में exit 2 या permissionDecision: "deny" दिया है? |
| हुक टाइमआउट एरर | timeout मान सेकंड में होता है। यदि काम बड़ा है तो टाइमआउट बढ़ाएं। |
परीक्षण के लिए आप सीधे कमांड लाइन पर डेटा पास करके स्क्रिप्ट की जाँच कर सकते हैं:
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp/x"}}' | python3 .codex/hooks/block-dangerous.py
echo $? # exit code की जाँच करें: ब्लॉक होने पर 2 आना चाहिएहुक्स को पूरी तरह अक्षम करने के लिए config.toml में यह लिखें:
[features]
hooks = false💡 संक्षेप में: हुक काम न करने पर सबसे पहले
/hooksअनुमति की जाँच करें, पथ की जाँच करें, और रेगुलर एक्सप्रेशन (regex) की पुष्टि करें।
10 सारांश
इस लेख में हमने नियमों (Rules) और हुक्स (Hooks) को समझा है—कि ये किस प्रकार कोडिंग गतिविधियों को नियंत्रित और स्वचालित करते हैं।
मुख्य बिंदुओं का सारांश:
| विषय | साधन | मुख्य बिंदु |
|---|---|---|
| कमांड नियंत्रण | नियम prefix_rule | allow/prompt/forbidden (सबसे सख्त की जीत); execpolicy check द्वारा जाँच |
| हुक सक्रिय होने का समय | घटनाक्रम (Events) | Pre (क्रिया से पहले, ब्लॉक करने में सक्षम), Post (क्रिया के बाद), Stop, SessionStart |
| हुक फ़ाइल | hooks.json / config.toml | तीन स्तर: घटना + matcher + क्रिया; timeout सेकंड में |
| सुरक्षा सक्रियण | /hooks | नया हुक डिफ़ॉल्ट रूप से ब्लॉक रहता है, अनुमति (trust) आवश्यक है |
| डेटा विनिमय | stdin / exit code / stdout | JSON डेटा; exit 2 द्वारा नियंत्रण |
अब आप यह कर सकते हैं: नियमों और हुक्स के उद्देश्यों को समझाना, नियम फ़ाइल लिखना, घटना चक्र को समझना, hooks.json में हुक कॉन्फ़िगर करना और /hooks से सक्रिय करना, और समस्याओं को हल करना। यह क्षमता आपके कोडिंग वातावरण को अधिक सुरक्षित और स्वचालित बनाती है।
अगला लेख [25 Worktrees समानांतर काम]—अब तक आप एक समय में एक ही Codex सत्र चला रहे थे। लेकिन बड़े प्रोजेक्ट्स में काम करते समय, आप चाहेंगे कि एक सत्र में बग ठीक हो और दूसरे में नया फ़ीचर बने, बिना किसी फ़ाइल टकराव के। अगले लेख में हम Git worktree का उपयोग करके कार्यों को पृथक रखना सीखेंगे।