---
read_when:
    - exec या Plugin की अनुमोदन जीवनचक्र, भंडारण, प्रोटोकॉल या प्राधिकरण में बदलाव
    - किसी चैनल में अनुमोदन लिंक या मूल अनुमोदन नियंत्रण जोड़ना
    - चाइल्ड-सेशन अनुमोदनों को पैरेंट या ऑर्केस्ट्रेटर दृश्यों में प्रक्षेपित करना
summary: Control UI, नेटिव ऐप्स, चैनलों और पैरेंट सेशनों में टिकाऊ, डीप-लिंक योग्य अनुमोदनों की डिज़ाइन
title: बहु-सतही ऑपरेटर अनुमोदन
x-i18n:
    generated_at: "2026-07-27T18:56:43Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 9defdaada1911df1184f64429e1787c4881e735c433d6dbc30a5946e11cc7cce
    source_path: refactor/operator-approvals.md
    workflow: 16
---

# बहु-सतही ऑपरेटर अनुमोदन

यह डिज़ाइन [#103505](https://github.com/openclaw/openclaw/issues/103505) को ट्रैक करता है। यह प्रक्रिया-स्थानीय अनुमोदन प्राधिकार को Gateway-स्वामित्व वाले, SQLite-समर्थित एकल जीवनचक्र से बदलता है। Gateway के स्वामित्व वाले प्रत्येक exec या plugin/tool अनुमोदन को एक स्थिर ID, एक प्रमाणीकृत Control UI रूट, परमाण्विक पहले-उत्तर-की-जीत समाधान, और उसके स्रोत तथा पूर्वज सत्र स्ट्रीमों के लिए केवल-ऑपरेटर प्रक्षेपण मिलते हैं।

इनलाइन क्रियाएँ और डीप लिंक साथ-साथ मौजूद रहते हैं। अनुमोदन-मोड का कोई टॉगल नहीं है।

## लक्ष्य

- exec और plugin/tool गेट के लिए एक टिकाऊ अनुमोदन ऑब्जेक्ट।
- स्थिर `${controlUiBasePath}/approve/{approvalId}` रूट।
- किसी भी अधिकृत Control UI, नेटिव ऐप, या चैनल सतह से समाधान।
- समवर्ती सतहों पर परमाण्विक पहले-उत्तर-की-जीत व्यवहार।
- समान पुनः प्रयास आइडेम्पोटेंट हैं; परस्पर-विरोधी विलंबित उत्तर विजेता को अधिलेखित नहीं कर सकते।
- टाइमआउट, विकृत विश्वसनीय निर्णय, अनुपलब्ध रूट, रद्दीकरण, और पुनरारंभ विफलता-बंद रखते हैं।
- अनुरोधित और अंतिम घटनाएँ स्रोत सत्र तथा सभी प्रासंगिक पैरेंट/ऑर्केस्ट्रेटर स्वामियों तक पहुँचती हैं।
- चैनलों को टाइप की गई अनुमोदन और नेविगेशन क्रियाएँ मिलती हैं; ट्रांसपोर्ट कॉलबैक डेटा चैनल-निजी रहता है।
- मौजूदा exec/plugin Gateway विधियाँ संगत रहती हैं, जबकि उनका कार्यान्वयन एक सेवा पर अभिसरित होता है।

## गैर-लक्ष्य

- Gateway पुनरारंभ के बाद अवरुद्ध टूल निष्पादन को स्वयं स्थायी बनाना या पुनः आरंभ करना।
- अनुमोदन ID या URL को बेयरर क्रेडेंशियल बनाना।
- मॉडल-दृश्य ट्रांसक्रिप्ट में अनुमोदन प्रॉम्प्ट जोड़ना या पैरेंट एजेंटों को जगाना।
- अनुमोदन नीति, उत्पाद कमांड, या समीक्षक प्राधिकरण को चैनल plugins में स्थानांतरित करना।
- प्रति चैनल, डिवाइस, या पूर्वज अनुमोदन स्थिति का क्लोन बनाना।
- exec अनुमत-सूचियों, plugin नीति संयोजन, या `allow-always` स्थायित्व को फिर से डिज़ाइन करना, सिवाय वहाँ जहाँ अंतिम परिणामों को अस्पष्टतारहित बनाने के लिए आवश्यक हो।
- पहले चरण में Gateway-रहित एम्बेडेड TUI को दूरस्थ रूप से पहुँच योग्य बनाना। यह केवल स्थानीय रहता है और कोई समीक्षक न होने पर इसे विफलता-बंद रहना आवश्यक है।

## रोलआउट-पूर्व आधाररेखा और साक्ष्य मानचित्र

यह तालिका #103505 खोले जाने के समय की कार्यान्वयन स्थिति दर्ज करती है। नीचे दिए गए रोलआउट अनुभाग उस आधाररेखा के ऊपर निर्मित टिकाऊ रजिस्ट्री, टाइप की गई क्रियाओं, डीप-लिंक पृष्ठ, और नेटिव-क्लाइंट चरणों को ट्रैक करते हैं।

| सतह           | आधाररेखा प्रवेश बिंदु और स्वामी                                                                                                                                  | आधाररेखा व्यवहार और कमी                                                                                                                                                                    |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| एजेंट exec        | `src/agents/bash-tools.exec-approval-request.ts`, `src/agents/bash-tools.exec-host-shared.ts`                                                                   | दो-चरणीय `exec.approval.*` पंजीकरण प्रारंभिक `/approve` रेस को रोकता है, लेकिन टाइमआउट अब भी `askFallback` के माध्यम से अनुमति में बदल सकता है।                                                        |
| Plugin टूल गेट  | `src/agents/agent-tools.before-tool-call.ts`                                                                                                                    | `plugin.approval.*` का अनुरोध करता है; `timeoutBehavior: "allow"` टाइमआउट हो चुके गेट को अनुमोदित कर सकता है। एम्बेडेड मोड में `src/infra/embedded-plugin-approval-broker.ts` में अलग प्रक्रिया-स्थानीय प्राधिकार है। |
| Plugin Node गेट  | `src/gateway/node-invoke-plugin-policy.ts`                                                                                                                      | Plugin प्रबंधक के माध्यम से सीधे बनाता और प्रसारित करता है, जिससे सर्वर-विधि जीवनचक्र का एक भाग दोहराया जाता है।                                                                                 |
| Gateway प्राधिकार | `src/gateway/server-aux-handlers.ts`, `src/gateway/exec-approval-manager.ts`, `src/gateway/server-methods/approval-shared.ts`                                   | अलग exec और plugin प्रबंधक प्रक्रिया-स्थानीय मैप का उपयोग करते हैं। अंतिम प्रविष्टियाँ 15 सेकंड तक बनी रहती हैं। पहले-उत्तर-की-जीत केवल एक प्रक्रिया के भीतर लागू होती है।                                          |
| Gateway प्रोटोकॉल  | `packages/gateway-protocol/src/schema/exec-approvals.ts`, `packages/gateway-protocol/src/schema/plugin-approvals.ts`, `src/gateway/methods/core-descriptors.ts` | exec में केवल-लंबित `get` है; plugin में कोई `get` नहीं है; डीप लिंक के लिए किसी भी प्रकार से स्वतंत्र अंतिम लुकअप मौजूद नहीं है।                                                                                   |
| वितरण          | `src/infra/exec-approval-channel-runtime.ts`, `src/infra/approval-native-runtime.ts`, `src/infra/approval-handler-runtime.ts`                                   | उद्गम रूटिंग, अनुमोदक DM, लंबित रीप्ले, नेटिव हैंडलर, और इन-प्रोसेस अंतिम सफ़ाई का समर्थन करता है। एक अलग अनुवर्ती परिवर्तन टिकाऊ अंतिम सामंजस्य जोड़ता है।                          |
| पोर्टेबल क्रियाएँ  | `src/interactive/payload.ts`, `src/plugin-sdk/interactive-runtime.ts`, `src/plugin-sdk/approval-reply-runtime.ts`                                               | अनुमोदन बटन ऐसी कमांड क्रियाएँ हैं जिनमें `/approve ...` होता है; URL और वेब ऐप लक्ष्य बिना टाइप वाले बटन फ़ील्ड हैं।                                                                           |
| Telegram          | `extensions/telegram/src/approval-handler.runtime.ts`, `extensions/telegram/src/button-types.ts`                                                                | रेंडरर निजी कॉलबैक डेटा बनाने से पहले अनुमोदन अर्थविज्ञान पहचानने के लिए कमांड टेक्स्ट को पार्स करता है।                                                                                     |
| Control UI        | `ui/src/app/exec-approval.ts`, `ui/src/app/overlays.ts`, `ui/src/components/exec-approval.ts`                                                                   | अनुमोदन UI एक वैश्विक मोडल है। `ui/src/app-route-paths.ts` और `ui/src/app-routes.ts` सटीक रूट का उपयोग करते हैं और अज्ञात पथों को चैट में पुनर्लिखते हैं।                                                    |
| सत्र स्वामित्व | `src/agents/subagent-registry.types.ts`, `src/agents/subagent-registry-read.ts`, `src/config/sessions/types.ts`                                                 | नियंत्रक, अनुरोधकर्ता, स्पष्ट पैरेंट, और लेगेसी स्पॉन स्वामित्व मौजूद हैं, लेकिन अनुमोदन घटनाएँ उन सत्र स्ट्रीमों में प्रक्षेपित नहीं की जातीं।                                                    |
| साझा स्थिति      | `src/state/openclaw-state-schema.sql`, `src/state/openclaw-state-db.ts`                                                                                         | मौजूदा तत्काल ट्रांज़ैक्शन और Kysely सशर्त अपडेट `state/openclaw.sqlite` में टिकाऊ तुलना-और-सेट का समर्थन करते हैं।                                                                   |

प्रतिनिधि वर्तमान परीक्षणों में `src/gateway/exec-approval-manager.test.ts`, `src/gateway/server-methods/approval-shared.test.ts`, `src/agents/bash-tools.exec-gateway-approval.e2e.test.ts`, `extensions/telegram/src/approval-handler.runtime.test.ts`, और `ui/src/e2e/approval-flow.e2e.test.ts` शामिल हैं।

Plugin SDK ही एकमात्र चैनल/plugin सीमा बनी रहती है। अनुमोदन रनटाइम और प्रस्तुति परिवर्तनों को मौजूदा `src/plugin-sdk/approval-*.ts` और `src/plugin-sdk/interactive-runtime.ts` उपपथों के माध्यम से निर्यात करना आवश्यक है; plugin उत्पादन कोड को Gateway आंतरिक भाग आयात नहीं करने चाहिए।

## पूर्ववर्ती कार्य

Omnigent उपयोगी UX और विफलता अर्थविज्ञान प्रदान करता है:

- [`approval.py`](https://github.com/omnigent-ai/omnigent/blob/46e3cd9754c3b8567f7b09f4d19b6249dabe0e80/omnigent/runtime/policies/approval.py) ASK को रोककर रखता है, प्रति-नीति टाइमआउट लागू करता है, और केवल हूबहू स्वीकृति को अनुमोदन मानता है।
- [`sessions.py`](https://github.com/omnigent-ai/omnigent/blob/46e3cd9754c3b8567f7b09f4d19b6249dabe0e80/omnigent/server/routes/sessions.py) में सर्वर-पक्षीय नेटिव हार्नेस गेट और पूर्वज अनुरोध/समाधान प्रक्षेपण शामिल हैं।
- [`ApprovePage.tsx`](https://github.com/omnigent-ai/omnigent/blob/46e3cd9754c3b8567f7b09f4d19b6249dabe0e80/web/src/pages/ApprovePage.tsx) स्वतंत्र मोबाइल अनुमोदन पृष्ठ प्रदान करता है।

इसके भंडारण दावे की बिना आलोचनात्मक जाँच के नकल न करें। वर्तमान सक्रिय लंबित स्थिति [`_elicitation_registry.py`](https://github.com/omnigent-ai/omnigent/blob/46e3cd9754c3b8567f7b09f4d19b6249dabe0e80/omnigent/server/_elicitation_registry.py) में प्रक्रिया-स्थानीय है, और अप्रयुक्त लंबित तालिका को [`e3b1f2a4c9d7_drop_pending_tool_calls_table.py`](https://github.com/omnigent-ai/omnigent/blob/46e3cd9754c3b8567f7b09f4d19b6249dabe0e80/omnigent/db/migrations/versions/e3b1f2a4c9d7_drop_pending_tool_calls_table.py) द्वारा हटा दिया गया है। OpenClaw जानबूझकर इससे आगे जाता है: SQLite प्रामाणिक स्रोत है और प्रत्येक अंतिम संक्रमण डेटाबेस तुलना-और-सेट है।

## आर्किटेक्चर और स्वामित्व

Gateway जीवनचक्र का स्वामी है:

1. कोई एजेंट, plugin हुक, या Node नीति प्रकार-विशिष्ट अनुरोध और प्रक्रिया-स्थानीय निष्पादन बाइंडिंग प्रदान करती है।
2. Gateway इसे सत्यापित करता है और एक स्वच्छीकृत समीक्षक प्रक्षेपण बनाता है।
3. अनुमोदन सेवा स्रोत/स्वामी दर्शक-वर्ग की गणना करती है, प्रामाणिक पंक्ति प्रविष्ट करती है, फिर इन-प्रोसेस प्रतीक्षक को पंजीकृत करती है।
4. टिकाऊ प्रविष्टि के बाद, Gateway मौजूदा अनुमोदन घटनाएँ, सत्र प्रक्षेपण, चैनल सूचनाएँ, और नेटिव पुश प्रकाशित करता है।
5. प्रत्येक सतह उसी सेवा के माध्यम से समाधान करती है।
6. सेवा एक अंतिम संक्रमण कमिट करती है, रनटाइम प्रतीक्षक को जगाती है, और अंतिम प्रक्षेपण प्रकाशित करती है।
7. विफल घटना वितरण कभी भी कमिट किए गए निर्णय को वापस नहीं लेता; क्लाइंट `approval.get` या सूची रीप्ले के माध्यम से पुनर्प्राप्ति करते हैं।

स्वामित्व सीमाएँ:

- `src/gateway/`: अनुमोदन सेवा, प्राधिकरण, RPC अडैप्टर, URL निर्माण, प्रतीक्षक जीवनचक्र, और घटना प्रकाशन।
- `src/state/`: साझा स्कीमा और जनरेट किए गए Kysely प्रकार।
- `src/infra/`: स्वच्छीकृत अनुमोदन व्यू मॉडल और पोर्टेबल प्रस्तुति निर्माण।
- `src/agents/`: लौटाए गए निर्णय का अनुरोध करना, प्रतीक्षा करना, और उसे लागू करना; कोई स्थायित्व नहीं।
- `src/channels/` और `extensions/*`: टाइप की गई क्रियाएँ रेंडर करना, चैनल उपयोगकर्ताओं को अधिकृत करना, निजी कॉलबैक एन्कोड करना, और वितरित नियंत्रण अपडेट करना।
- `src/plugin-sdk/`: केवल सार्वजनिक अनुमोदन और प्रस्तुति अनुबंध।
- `ui/`: स्वतंत्र पृष्ठ और मौजूदा कतार/मोडल क्लाइंट।

इन-प्रोसेस प्रतीक्षक एक सूचना तंत्र है, प्राधिकार नहीं। पंजीकरण पंक्ति प्रविष्ट करता है और अनुरोध प्रकाशित करने से पहले प्रतीक्षक को समकालिक रूप से स्थापित करता है, इसलिए कोई समाधानकर्ता उन चरणों के बीच अंतःक्षेप नहीं कर सकता। बाद का प्रत्येक समाधानकर्ता उस प्रतीक्षक को पूरा करने से पहले SQLite के माध्यम से कमिट करता है।

## स्थायी रिकॉर्ड

साझा स्थिति डेटाबेस में एक `operator_approvals` तालिका जोड़ें।

| कॉलम                                             | उद्देश्य                                                                                                                                       |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `approval_id`                                      | वैश्विक रूप से अद्वितीय कैनोनिकल ID। प्रोटोकॉल संगतता के लिए मौजूदा exec ID और `plugin:` ID बनाए रखें, लेकिन प्रीफ़िक्स से कभी भी प्रकार का अनुमान न लगाएँ।      |
| `resolution_ref`                                   | उन ट्रांसपोर्ट कॉलबैक के लिए अद्वितीय पूर्ण SHA-256 base64url लोकेटर, जो कैनोनिकल ID नहीं ले जा सकते। यह प्राधिकरण या सार्वजनिक URL ID नहीं है। |
| `kind`                                             | बंद `exec \| plugin` विभेदक।                                                                                                        |
| `status`                                           | बंद `pending \| allowed \| denied \| expired \| cancelled` स्थिति।                                                                          |
| `presentation_json`                                | सत्यापित, प्रकार-टैग किया हुआ समीक्षक प्रक्षेपण। कच्चे रनटाइम अनुरोध, कमांड बाइंडिंग और कॉलबैक पेलोड प्रक्रिया-स्थानीय रहते हैं।               |
| `source_agent_id`, `source_session_key`            | स्रोत पहचान और सत्र प्रक्षेपण एंकर। सत्र कुंजी टिकाऊ है; बदलता हुआ सत्र UUID टिकाऊ नहीं है।                                          |
| `audience_session_keys_json`                       | सीमित चौड़ाई-प्रथम स्वामित्व traversal द्वारा निर्मित क्रमबद्ध, डुप्लिकेट-रहित JSON ऐरे। अनुरोधित और टर्मिनल इवेंट इसी स्नैपशॉट का उपयोग करते हैं। |
| `requested_by_device_id`, `requested_by_client_id` | टिकाऊ अनुरोधकर्ता/ऑडिट मेटाडेटा। कनेक्शन ID मेमोरी में रहता है और क्रॉस-सर्फ़ेस प्रिंसिपल नहीं है।                                         |
| `reviewer_device_ids_json`                         | वैकल्पिक, स्पष्ट रूप से लक्षित समीक्षक डिवाइस, जो केवल विश्वसनीय अनुमोदन रनटाइम द्वारा दिए जाते हैं।                                                  |
| `runtime_epoch`                                    | पार्क किए गए निष्पादन का स्वामी प्रक्रिया epoch; पुनः आरंभ के बाद अनाथ पंक्तियाँ रद्द करने के लिए उपयोग किया जाता है।                                                     |
| `created_at_ms`, `expires_at_ms`, `updated_at_ms`  | प्रामाणिक समय-निर्धारण।                                                                                                                         |
| `decision`                                         | उपलब्ध होने पर स्पष्ट उपयोगकर्ता निर्णय।                                                                                                       |
| `terminal_reason`                                  | बंद कारण, जैसे `user`, `timeout`, `malformed-verdict`, `no-route`, `run-aborted`, या `gateway-restart`।                                |
| `resolved_at_ms`, `resolver_kind`, `resolver_id`   | विजेता और ऑडिट पहचान सर्वर-साइड बनाए रखी जाती है। समीक्षक प्रक्षेपण कच्चे रिज़ॉल्वर पहचानकर्ता छोड़ देते हैं।                                           |
| `consumed_at_ms`, `consumed_by`                    | `allow-once` के लिए अलग रीप्ले गार्ड; उपभोग करने पर दर्ज निर्णय मिटना नहीं चाहिए।                                                       |

आवश्यक इंडेक्स:

| इंडेक्स                                      | उद्देश्य                                                                     |
| ------------------------------------------ | --------------------------------------------------------------------------- |
| अद्वितीय `(resolution_ref)`                  | सम्मिलन के दौरान क्रॉस-कॉलम `approval_id`/`resolution_ref` अस्पष्टता अस्वीकार करें। |
| `(status, expires_at_ms)`                  | लंबित अनुमोदन खोजें और प्रामाणिक समय-सीमाओं का मिलान करें।               |
| `(source_session_key, created_at_ms DESC)` | एक स्रोत सत्र के लिए हाल के अनुमोदन रीप्ले करें।                             |
| `(resolved_at_ms)`                         | निर्धारित प्रतिधारण नीति के अनुसार बनाए रखे गए टर्मिनल अनुमोदनों की छँटाई करें।  |

ऑडियंस ऐरे छोटे और सीमित हैं। सत्र-फ़िल्टर किया हुआ रीप्ले पहले Kysely के माध्यम से दृश्यमान लंबित पंक्तियाँ चुनता है, फिर एप्लिकेशन कोड में सीमित ऑडियंस ऐरे को डिकोड और फ़िल्टर करता है; यह स्ट्रिंग मिलान या कच्ची SQL JSON क्वेरी का उपयोग नहीं करता।

टर्मिनल पंक्तियों को 30 दिनों तक बनाए रखें, जो `src/audit/audit-event-store.ts` में मेटाडेटा ऑडिट प्रतिधारण के अनुरूप है। छँटाई एक निर्धारित रखरखाव नीति है, कोई नया कॉन्फ़िगरेशन सर्फ़ेस नहीं। डेटाबेस निजी स्थानीय कंट्रोल-प्लेन स्थिति है, लेकिन समीक्षक API को पूरा संग्रहीत अनुरोध या रनटाइम बाइंडिंग कभी उजागर नहीं करनी चाहिए।

## स्थिति मशीन और तुलना-एवं-सेट

केवल ये ट्रांज़िशन मान्य हैं:

- `pending -> allowed`: स्पष्ट `allow-once` या `allow-always`।
- `pending -> denied`: स्पष्ट अस्वीकृति, विश्वसनीय विकृत टर्मिनल निर्णय, या कोई डिलीवरी मार्ग नहीं।
- `pending -> expired`: प्रामाणिक समय-सीमा पूरी हुई।
- `pending -> cancelled`: रन निरस्तीकरण, व्यवस्थित शटडाउन, या पुनः आरंभ के बाद अनाथ स्थिति की पुनर्प्राप्ति।

हर गैर-अनुमत टर्मिनल स्थिति का प्रभावी निर्णय अस्वीकृति है।

समाधान एक तत्काल SQLite ट्रांज़ैक्शन और इसके समतुल्य Kysely सशर्त अपडेट का उपयोग करता है:

```sql
UPDATE operator_approvals
SET status = ?, decision = ?, terminal_reason = ?, resolved_at_ms = ?
WHERE approval_id = ?
  AND status = 'pending'
  AND expires_at_ms > ?;
```

यदि अपडेट किसी पंक्ति को प्रभावित नहीं करता, तो वही ट्रांज़ैक्शन रिकॉर्ड पढ़ता है:

- अनुपलब्ध या अनधिकृत: नहीं मिला लौटाएँ; अस्तित्व उजागर न करें।
- अभी भी लंबित, लेकिन समय-सीमा पूरी: तुलना-एवं-सेट करके इसे `expired` बनाएँ, फिर वह टर्मिनल पंक्ति लौटाएँ।
- वही दर्ज निर्णय: दर्ज विजेता के साथ इडेम्पोटेंट सफलता लौटाएँ।
- अलग निर्णय: एकीकृत API दर्ज विजेता के साथ `applied: false` लौटाता है; लेगेसी एडाप्टर जहाँ अपने जारी किए गए अनुबंध के अनुसार आवश्यक हो, वहाँ `APPROVAL_ALREADY_RESOLVED` बनाए रखते हैं।
- कोई भी टर्मिनल स्थिति: इसे कभी परिवर्तित न करें।

`now == expires_at_ms` की समय-सीमा समाप्त हो चुकी है। Gateway का समय प्रामाणिक है।

`allow-once` निष्पादन, मौजूदा सटीक कमांड/सिस्टम-रन संदर्भ से बँधे `consumed_at_ms IS NULL` पर दूसरे CAS का उपयोग करता है। उपभोग के बाद भी अनुमोदन पंक्ति ऑडिट रिकॉर्ड बनी रहती है।

ऐसा विकृत HTTP/RPC इनपुट, जिसे प्रमाणित नहीं किया जा सकता या जो किसी अनुमोदन की पहचान नहीं कर सकता, बिना परिवर्तन के अस्वीकार किया जाता है और कभी अनुमोदन नहीं दे सकता। किसी ज्ञात अनुमोदन के लिए विश्वसनीय हार्नेस/वेटर से प्राप्त विकृत टर्मिनल निर्णय `denied` में ट्रांज़िशन करता है।

## Gateway API

प्रकार-निरपेक्ष समीक्षक विधियाँ जोड़ें:

| विधि                                    | अनुबंध                                                                                                                                                                                                            |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `approval.get { id }`                     | दृश्यमान लंबित या बनाए रखा गया टर्मिनल प्रक्षेपण लौटाता है।                                                                                                                                                          |
| `approval.resolve { id, kind, decision }` | कैनोनिकल ID या निश्चित आकार का ट्रांसपोर्ट संदर्भ स्वीकार करता है, फिर प्राधिकरण, प्रकार और अनुमत-निर्णय सत्यापन, समय-सीमा मिलान तथा टर्मिनल CAS चलाता है। प्रतिक्रिया में हमेशा कैनोनिकल ID होता है। |

सफल CAS के बाद कमिट किया हुआ प्रक्षेपण तुरंत लौटाएँ। लेगेसी इवेंट, चैनल फ़ॉरवर्डर और पुश टर्मिनलाइज़र सर्वोत्तम-प्रयास वाले अनुवर्ती कार्य हैं; धीमा या विफल सर्फ़ेस विजेता प्रतिक्रिया में विलंब या उसे रोलबैक नहीं कर सकता।

प्रकार-विशिष्ट अनुरोध सत्यापन `exec.approval.request` और `plugin.approval.request` में रहता है। मौजूदा `exec.approval.get/list/waitDecision/resolve` और `plugin.approval.list/waitDecision/resolve` कैनोनिकल सेवा के प्रोटोकॉल-सीमा एडाप्टर बन जाते हैं, क्योंकि वे जारी किए गए Gateway API हैं। आंतरिक कॉलर उसी बदलाव में सेवा पर माइग्रेट होते हैं।

समीक्षक प्रक्षेपण एक टैग किया हुआ यूनियन है:

```ts
type OperatorApproval = {
  id: string;
  status: OperatorApprovalStatus;
  presentation:
    | { kind: "exec"; commandText: string /* सुरक्षित exec पूर्वावलोकन */ }
    | { kind: "plugin"; title: string; description: string /* सुरक्षित plugin पूर्वावलोकन */ };
  // सामान्य जीवनचक्र फ़ील्ड
};
```

स्थिर पथ व्युत्पन्न होता है, स्थायी रूप से संग्रहीत नहीं। `approval.get`, `urlPath` लौटाता है; जो सर्फ़ेस किसी अनुमोदित सार्वजनिक मूल को जानते हैं, वे पूर्ण `url` भी प्राप्त कर सकते हैं। समीक्षक स्नैपशॉट स्रोत और ऑडियंस सत्र कुंजियाँ छोड़ देते हैं। Gateway उन रूटिंग कुंजियों को अलग `session.approval` प्रक्षेपण के लिए सर्वर-साइड रखता है।

## इवेंट और पोर्टेबल कार्रवाइयाँ

PR 1 जारी किए गए इवेंट नाम, पेलोड और मौजूदा रिकॉर्ड-स्तरीय प्राप्तकर्ता फ़िल्टर बनाए रखता है:

- `exec.approval.requested`
- `exec.approval.resolved`
- `plugin.approval.requested`
- `plugin.approval.resolved`

इन लेगेसी इवेंट में पूरा रनटाइम अनुरोध हो सकता है, इसलिए इन्हें हर अनुमोदन-स्कोप्ड क्लाइंट तक प्रसारित नहीं किया जाना चाहिए। PR 5 लेगेसी इवेंट डिलीवरी को व्यापक बनाने के बजाय स्वच्छ किए गए जीवनचक्र प्रक्षेपण के माध्यम से टैग किए हुए जीवनचक्र फ़ील्ड (`status`, `sourceSessionKey`, `urlPath`, टर्मिनल मेटाडेटा और प्रस्तुति-स्तरीय `kind`) जोड़ता है।

अनुमोदन-स्कोप्ड `session.approval` प्रक्षेपण इवेंट जोड़ें। स्थायी ऑडियंस कुंजियों के साथ कैनोनिकल इवेंट एक बार प्रकाशित करें; सटीक-सत्र सब्सक्राइबर हर मेल खाने वाली कुंजी के लिए वही इवेंट प्राप्त करते हैं:

- `sessionKey`: प्रक्षेपण प्राप्त करने वाली स्ट्रीम।
- `sourceSessionKey`: गेट उत्पन्न करने वाला चाइल्ड/स्रोत।
- `phase`: `pending \| terminal`, अनुमोदन स्थिति के आधार पर विभेदित।
- एक सुरक्षित `OperatorApproval` प्रक्षेपण।

क्लाइंट `sessions.messages.subscribe { key, agentId?, includeApprovals: true }` के साथ ऑप्ट-इन करते हैं। सफल प्रतिक्रिया एक `approvalReplay` जोड़ती है, जिसमें उस सटीक स्ट्रीम कुंजी के अधिकतम 1,000 वर्तमान लंबित अनुमोदन होते हैं, जिनकी समीक्षा के लिए सब्सक्राइब करने वाला क्लाइंट रिकॉर्ड स्तर पर भी अधिकृत है। `truncated: false` फ़िल्टर किए गए रीप्ले को प्रामाणिक बनाता है और पुनः कनेक्ट करने वाले क्लाइंट अपने स्थानीय लंबित सेट को उससे बदलते हैं; `truncated: true` एक ओवरलोड संकेत है और क्लाइंट को अनदेखी स्थानीय प्रविष्टियाँ तब तक बनाए रखनी चाहिए, जब तक कैनोनिकल लुकअप या बाद के जीवनचक्र इवेंट उनका समाधान नहीं कर देते। रीप्ले के दौरान बाद में खोजी गई टिकाऊ समय-समाप्ति, नया स्नैपशॉट लौटाए जाने से पहले केवल सब्सक्राइब किए गए, रिकॉर्ड-अधिकृत ऑडियंस को टर्मिनल टूम्बस्टोन उत्सर्जित करती है। `operator.admin` सीधे ऑप्ट-इन कर सकता है; अधिक सीमित क्लाइंट के लिए युग्मित डिवाइस पहचान और `operator.approvals` दोनों आवश्यक हैं। केवल सत्र सदस्यता कभी अनुमोदन दृश्यता प्रदान नहीं करती।

`src/gateway/server-broadcast.ts` में इवेंट को `operator.approvals` के अंतर्गत पंजीकृत करें। प्रक्षेपण अवलोकनात्मक है: यह कभी ट्रांसक्रिप्ट पंक्तियाँ नहीं जोड़ता, `sessions.changed` उत्सर्जित नहीं करता, या किसी एजेंट को नहीं जगाता।

`src/interactive/payload.ts` में `MessagePresentationAction` का विस्तार करें:

```ts
type MessagePresentationAction =
  | { type: "command"; command: string }
  | { type: "callback"; value: string }
  | {
      type: "approval";
      approvalId: string;
      approvalKind: "exec" | "plugin";
      decision: ExecApprovalDecision;
    }
  | { type: "url"; url: string }
  | { type: "web-app"; url: string };
```

कोर टाइप किए गए निर्णय एक्शन और, अनुमोदित पूर्ण Control UI ओरिजिन उपलब्ध होने पर, एक अलग समीक्षा लिंक बनाता है। चैनल अनुमोदन एक्शन को अपने कॉलबैक प्रारूप में एन्कोड करते हैं और समाधान को कैनोनिकल सेवा को भेजते हैं। कॉलबैक सटीक कैनोनिकल ID का उपयोग करता है, यदि वह समा सके; अन्यथा वह पंक्ति के अद्वितीय पूर्ण-डाइजेस्ट `resolution_ref` का उपयोग करता है। संदर्भ केवल एक संक्षिप्त लुकअप कुंजी है: सामान्य Gateway प्रमाणीकरण, रिकॉर्ड प्राधिकरण, स्पष्ट प्रकार, अनुमत-निर्णय सत्यापन, समय-सीमा समाधान और प्रथम-उत्तर CAS अब भी लागू होते हैं। चैनलों को IDs को छोटा नहीं करना चाहिए, हैश प्रीफ़िक्स का समाधान नहीं करना चाहिए, `/approve` टेक्स्ट को पार्स नहीं करना चाहिए या ID प्रीफ़िक्स से प्रकार का अनुमान नहीं लगाना चाहिए।

`button.url`, `button.webApp` और कमांड-समर्थित अनुमोदन नियंत्रणों को अप्रचलित plugin SDK संगतता इनपुट के रूप में बनाए रखें। उन्हें SDK सीमा पर सामान्यीकृत करें; उसी PR में प्रत्येक बंडल किए गए आंतरिक कॉलर को माइग्रेट करें। `/approve {id} {decision}` एक टेक्स्ट फ़ॉलबैक और CLI/चैट कमांड बना रहता है, बटन का अर्थगत अनुबंध नहीं।

## Control UI

रूट `${basePath}/approve/{approvalId}` है। ID एकमात्र पथ पैरामीटर है; स्रोत सत्र पहचान रिकॉर्ड से आती है।

चूँकि वर्तमान राउटर में सटीक स्थिर रूट हैं और वह अज्ञात पथों को Chat में पुनर्लिखता है, सामान्य रूट सामान्यीकरण से पहले `ui/src/app/bootstrap.ts` में इस डीप लिंक का पता लगाएँ। सामान्य Gateway/प्रमाणीकरण सेटअप का पुनः उपयोग करें, लेकिन साइडबार शेल और वैश्विक मोडल के बाहर एक स्वतंत्र अनुमोदन पृष्ठ रेंडर करें।

दस्तावेज़ का स्वामी वह Gateway है जिसने उसका URL प्रस्तुत किया। उसका प्रारंभिक कनेक्शन पूर्ण ऐप के स्थायी रिमोट-Gateway चयन को अनदेखा करता है, उस चयन की सेटिंग बदले या कॉपी किए बिना; केवल प्रमाणीकरण सेवा देने वाले Gateway के लिए सत्र-स्कोप में रहता है। विश्वसनीय नेटिव प्रमाणीकरण या अलग से पुष्टि किया गया `gatewayUrl` ओवरराइड उसे पुनः लक्षित कर सकता है। कोर plugin HTTP रूट और स्थिर-एक्सटेंशन पहचान से पहले एक-सेगमेंट वाले `/approve` नेमस्पेस को आरक्षित करता है, जिसमें `.json` या `.js` पर समाप्त होने वाली IDs भी शामिल हैं; Control UI प्रस्तुति अक्षम होने पर आरक्षित रूट `404` के साथ सुरक्षित रूप से विफल होता है। पृष्ठ को मुख्य Control UI बंडल में रखें ताकि विफल लेज़ी चंक किसी सुरक्षा निर्णय को स्पिनर पर अटका न दे।

पृष्ठ की अवस्थाएँ:

- लोड हो रहा है
- प्रमाणीकरण आवश्यक है
- लंबित
- समाधान हो रहा है
- यहाँ अनुमोदित या अस्वीकृत
- अन्यत्र समाधान हुआ
- समाप्त
- रद्द
- निषिद्ध/नहीं मिला
- पुनः प्रयास सहित कनेक्शन त्रुटि

पृष्ठ किसी दूसरी अप्रमाणीकृत REST API को नहीं, बल्कि Gateway RPC को कॉल करता है। ब्राउज़र रीफ़्रेश स्थायी अवस्था को फिर से पढ़ता है। यह Gateway क्रेडेंशियल्स को कभी URL, क्वेरी या फ़्रैगमेंट में नहीं रखता।

## प्राधिकरण और गोपनीयता

URL स्थान-निर्धारक है, प्राधिकार नहीं। समाधान के लिए आवश्यक हैं:

1. प्रमाणीकृत Gateway कनेक्शन;
2. `operator.approvals` या `operator.admin`;
3. रिकॉर्ड-स्तरीय समीक्षक प्राधिकरण।

रिकॉर्ड-स्तरीय नियम:

- `operator.admin` समीक्षा कर सकता है।
- `reviewer_device_ids` मौजूद होने पर प्रामाणिक है। केवल सूचीबद्ध युग्मित
  `operator.approvals` डिवाइस समीक्षा कर सकता है; अनुरोध करने वाले डिवाइस को कोई अंतर्निहित
  पहुँच नहीं है, जब तक कि वह भी सूचीबद्ध न हो।
- स्पष्ट समीक्षक सूची के बिना, अनुरोध करने वाला युग्मित
  `operator.approvals` डिवाइस अपने रिकॉर्ड की समीक्षा कर सकता है।
- वास्तविक रूप से पुराने रिकॉर्ड, जिनमें कोई अनुरोधकर्ता या समीक्षक बाइंडिंग नहीं है, व्यापक
  युग्मित-डिवाइस दृश्यता बनाए रखते हैं ताकि अपग्रेड पहले से लंबित कार्य को न अटकाएँ।
- डिवाइस-विहीन आंतरिक रनटाइम स्कोप किए गए
  अनुमोदन-रनटाइम कनेक्शन के माध्यम से समाधान कर सकते हैं, लेकिन पढ़ नहीं सकते। वह प्राधिकार केवल
  सर्वर-प्रमाणीकृत रनटाइम टोकन से आता है; सार्वजनिक `approval.resolve` फ़ील्ड उसे
  बना नहीं सकते।
- लाइव अनुरोधकर्ता कनेक्शन स्वामित्व पुराने अडैप्टरों के लिए मान्य रहता है; इसका
  अनुमान कभी मेल खाते क्लाइंट नाम से नहीं लगाया जाता।
- ऑडियंस सदस्यता केवल प्रस्तुति बदलती है। यह प्राधिकरण को कभी विस्तृत नहीं करती।

`approval.get` केवल स्वच्छ किया गया समीक्षक प्रोजेक्शन उजागर करता है और आंतरिक स्रोत/ऑडियंस रूटिंग कुंजियाँ छोड़ देता है। PR 5 का `session.approval` इवेंट अपना एक गंतव्य `sessionKey` और `sourceSessionKey` साथ रखता है, जब Gateway स्थायी ऑडियंस स्नैपशॉट को सर्वर-साइड लागू कर चुका होता है। मौजूदा exec/plugin इवेंट अपने ऐतिहासिक पेलोड और प्रतिबंधित प्राप्तकर्ताओं को तब तक बनाए रखते हैं, जब तक उपभोक्ता माइग्रेट नहीं हो जाते। निष्पादन योग्य अनुरोध, कमांड बाइंडिंग और निरंतरता केवल प्रक्रिया-स्थानीय वेटर में रहते हैं। स्थायी पंक्ति में सुरक्षित प्रस्तुति के साथ जीवनचक्र, रूटिंग और ऑडिट मेटाडेटा होता है; यह कभी कच्चे पर्यावरण मान, क्रेडेंशियल्स, प्रमाणीकरण हेडर या चैनल कॉलबैक डेटा संग्रहीत नहीं करती।

## ऑडियंस प्रोजेक्शन

सम्मिलित करने से पहले ऑडियंस की एक बार गणना करें और क्रमबद्ध स्नैपशॉट को स्थायी बनाएँ। स्वामित्व एक ग्राफ़ है, हमेशा एकल पैरेंट शृंखला नहीं: किसी चाइल्ड का वर्तमान नियंत्रक और मूल अनुरोधकर्ता दोनों हो सकते हैं, और वे स्वामी अलग-अलग रूट तक ले जा सकते हैं।

निर्धारक ब्रेड्थ-फ़र्स्ट वॉक का उपयोग करें:

1. स्रोत सत्र कुंजी से क्यू को आरंभ करें।
2. हर डीक्यू की गई कुंजी के लिए नवीनतम सबएजेंट रजिस्ट्री पंक्ति पढ़ें और दोनों अलग स्वामित्व किनारों को निश्चित क्रम में एनक्यू करें: `controllerSessionKey`, फिर `requesterSessionKey`।
3. उपयोग योग्य रजिस्ट्री पंक्ति मौजूद होने पर, सत्र-प्रविष्टि वंश का भी अनुसरण न करें, जो स्टीयरिंग के बाद पुराना हो सकता है। अन्यथा एकल वर्तमान फ़ॉलबैक किनारा `parentSessionKey ?? spawnedBy` एनक्यू करें।
4. एनक्यू करते समय सामान्यीकृत करें और डुप्लिकेट हटाएँ, ताकि पहला, सबसे छोटा पथ जीते।
5. 64 अद्वितीय कुंजियों पर रुकें; यह ऑडियंस-आकार सीमा ट्रैवर्सल गहराई को भी सीमित करती है।

रजिस्ट्री स्रोत `src/agents/subagent-registry-read.ts` है; स्वामित्व फ़ील्ड `src/agents/subagent-registry.types.ts` में परिभाषित हैं। सत्र फ़ॉलबैक फ़ील्ड `src/config/sessions/types.ts` में परिभाषित हैं।

अनुरोधित और टर्मिनल प्रोजेक्शन उसी स्थायी ऑडियंस का उपयोग करते हैं, भले अनुमोदन लंबित रहने के दौरान फ़ोकस/नियंत्रक स्वामित्व बदल जाए। यह अनुरोध प्रोजेक्शन पाने वाली प्रत्येक ऑडियंस सत्र स्ट्रीम के लिए टर्मिनल सफ़ाई की गारंटी देता है। समाधान हमेशा स्रोत अनुमोदन ID को लक्षित करता है; ऑडियंस सत्र कभी क्लोन की गई अनुमोदन अवस्था प्राप्त नहीं करते। अग्रेषित चैनल-संदेश की सफ़ाई नीचे दिया गया अलग डिलीवरी-लोकेटर अनुवर्ती कार्य बनी रहती है।

केवल अनुमोदन के लिए ट्रांसक्रिप्ट संदेश न लिखें, सिस्टम प्रॉम्प्ट इंजेक्ट न करें, स्वामी टर्न शुरू न करें या `sessions.changed` उत्सर्जित न करें।

## वितरित सतह अभिसरण

नेटिव अनुमोदन हैंडलर पहले से अपने वितरित संदेश प्रविष्टियों को इतनी देर तक बनाए रखते हैं कि सक्रिय नियंत्रणों को बदला या निष्क्रिय किया जा सके। सामान्य अग्रेषित अनुमोदन संदेश वर्तमान में `MessageReceipt` को हटा देते हैं, इसलिए दूसरी सतह पर लिया गया निर्णय उनके पुराने नियंत्रणों को लंबित दिखता छोड़ सकता है। एक अलग अनुवर्ती कार्य साझा अवस्था डेटाबेस में `operator_approval_deliveries` चाइल्ड तालिका के साथ इस अंतर को बंद करता है।

प्रत्येक पंक्ति अनुमोदन ID, एक अद्वितीय डिलीवरी ID, चैनल/खाता/सटीक रूट, सीमित JSON-सत्यापित चैनल-निजी संदेश लोकेटर, डिलीवरी टाइमस्टैम्प और टर्मिनलाइज़ेशन अवस्था संग्रहीत करती है। यह कभी कॉलबैक डेटा, निर्णय टोकन या कच्चे अनुमोदन अनुरोध संग्रहीत नहीं करती। चैनल लोकेटर एन्कोडिंग और संदेश परिवर्तन का स्वामी है; कोर कैनोनिकल स्थिति, लक्ष्य चयन, पुनः प्रयास नीति और फ़ॉलबैक टर्मिनल टेक्स्ट का स्वामी है।

डिलीवरी पंजीकरण और टर्मिनल समाधान सुरक्षित रूप से प्रतिस्पर्धा करते हैं:

1. लंबित प्रेषण की रसीद लौटने के बाद, डिलीवरी लोकेटर सम्मिलित करें और एक ही ट्रांज़ैक्शन में पैरेंट अनुमोदन स्थिति पढ़ें।
2. यदि पैरेंट पहले ही टर्मिनल है, तो विलंबित डिलीवरी को लंबित छोड़ने के बजाय तत्काल टर्मिनलाइज़ेशन शेड्यूल करें।
3. प्रत्येक कमिट किया गया टर्मिनल ट्रांज़िशन सभी अंतिम रूप न दी गई डिलीवरी पंक्तियों को अलग से शेड्यूल करता है; छोड़े जा सकने वाले ब्रॉडकास्ट ट्रिगर नहीं हैं।
4. चैनल टर्मिनलाइज़र `replaced`, `retired`, या `unsupported` रिपोर्ट करता है। प्रतिस्थापित डुप्लिकेट टर्मिनल संदेश को रोकता है; निष्क्रिय किया गया मौजूदा टर्मिनल अनुवर्ती संदेश भेजता है; असमर्थित या विफलता अनुमोदन CAS को रोल बैक किए बिना फ़ॉलबैक करती है।
5. स्टार्टअप अधूरी डिलीवरी वाले टर्मिनल अनुमोदनों का पुनः प्रयास करता है, जिससे सफ़ाई Gateway पुनरारंभ के प्रति सहनशील बनती है।

यह ट्रांसपोर्ट जीवनचक्र एक वैकल्पिक डिलीवरी अडैप्टर हुक है, रेंडरर या मॉडल-सामना करने वाला संदेश एक्शन नहीं। QQ C2C/समूह संदेशों में वर्तमान में कोई संपादन, हटाने या कीबोर्ड-साफ़ करने की API नहीं है; वह अडैप्टर असमर्थित रहता है और ट्रांसपोर्ट को परिवर्तन API मिलने तक बाद के क्लिक के बाद ही कैनोनिकल सत्य दिखा सकता है।

## पुनरारंभ, टाइमआउट और रूट अर्थविज्ञान

SQLite स्थायित्व निष्पादन पुनरारंभ को निहित नहीं करता। कमांड/टूल बाइंडिंग स्मृति में रहती हैं क्योंकि उनमें सुरक्षा-संवेदनशील रनटाइम तथ्य हो सकते हैं और वे पुनरारंभ योग्य जॉब अनुबंध नहीं हैं।

Gateway स्टार्टअप पर:

- एक नया रनटाइम युग जनरेट करें;
- पुराने युगों की लंबित पंक्तियों को कारण `gateway-restart` सहित परमाण्विक रूप से `cancelled` में ट्रांज़िशन करें;
- पंक्तियाँ बनाए रखें ताकि उनके URLs समझा सकें कि क्या हुआ;
- गायब रनटाइम बाइंडिंग के विरुद्ध बाद का अनुमोदन कभी निष्पादित न करें।

टाइमर वेक-अप अनुकूलन हैं। समय-सीमा प्राधिकार `expires_at_ms` में संग्रहीत है; पढ़ना, प्रतीक्षा और समाधान सभी समाप्ति समाधान चलाते हैं।

अंतिम कठोर व्यवहार:

- टाइमआउट -> `expired`, अस्वीकार;
- कोई रूट नहीं -> `denied`, अस्वीकार;
- रन निरस्त -> `cancelled`, अस्वीकार;
- विकृत विश्वसनीय निर्णय -> `denied`, अस्वीकार;
- केवल अनुमत स्पष्ट अनुमति निर्णय -> `allowed`।

वर्तमान जारी किया गया exec व्यवहार अब भी इस अनुबंध से टकराता है:

- `src/agents/bash-tools.exec-host-shared.ts` `askFallback` लागू कर सकता है।
- `docs/tools/exec-approvals.md` और `docs/cli/approvals.md` उस सतह का दस्तावेज़ीकरण करते हैं।

Plugin अनुमोदन अब टाइमआउट और विकृत निर्णयों पर सुरक्षित रूप से विफल होते हैं; पुराना
`timeoutBehavior` फ़ील्ड अब भी स्वीकार किया जाता है, लेकिन अनदेखा रहता है। exec कठोर-अर्थविज्ञान
अनुवर्ती कार्य को स्पष्ट स्वामी/सुरक्षा समीक्षा सहित कोड, प्रकार, दस्तावेज़, परीक्षण और चेंजलॉग
एक साथ अपडेट करने होंगे। `askFallback` माइग्रेशन के दौरान
गेट-पूर्व नीति चयन का वर्णन करना जारी रख सकता है, लेकिन उसे बनाए गए
लंबित रिकॉर्ड के टाइमआउट को अनुमोदन में नहीं बदलना चाहिए।

## संगतता योजना

- योगात्मक Gateway प्रोटोकॉल; प्रोटोकॉल संस्करण में कोई वृद्धि नहीं।
- बाहरी सीमा पर मौजूदा exec/plugin विधियाँ और इवेंट बनाए रखें।
- `plugin:` प्रीफ़िक्स सहित मौजूदा IDs बनाए रखें, लेकिन प्रीफ़िक्स को प्रकार-सूचना के रूप में उपयोग करना बंद करें।
- `/approve` टेक्स्ट कमांड व्यवहार बनाए रखें।
- पुराने बटन URL/Web App फ़ील्ड और कमांड एक्शन को plugin SDK संगतता इनपुट के रूप में बनाए रखें; नया कोर आउटपुट टाइप किया गया है।
- उसी टाइप किए गए-एक्शन बदलाव में सभी बंडल किए गए चैनल और आंतरिक कॉलर माइग्रेट करें।
- नए URL/पृष्ठ और बाद के टाइमआउट व्यवहार बदलाव के लिए चेंजलॉग प्रविष्टि जोड़ें।
- एलिसिटेशन-मोड सेटिंग न जोड़ें।

## रोलआउट

### PR 1: स्थायी जीवनचक्र

- यह डिज़ाइन नोट।
- साझा SQLite स्कीमा, Kysely जनरेशन, स्टोर और 30-दिवसीय प्रूनिंग।
- Gateway अनुमोदन सेवा, रनटाइम वेटर ब्रिज और पुनरारंभ अनाथ प्रबंधन।
- एकीकृत `approval.get/resolve`।
- Exec/plugin विधि अडैप्टर।
- प्रथम-उत्तर-विजयी, आइडेम्पोटेंसी, समाप्ति, प्राधिकरण और उपभोग परीक्षण।
- अभी कोई UI या चैनल व्यवहार परिवर्तन नहीं।

### PR 2: टाइप किए गए एक्शन और चैनल कॉलबैक

- टाइप किए गए अनुमोदन, URL और Web App ऐक्शन।
- कोर प्रेज़ेंटेशन बिल्डर और Plugin SDK एक्सपोर्ट।
- स्पष्ट स्वामी प्रकार के साथ ट्रांसपोर्ट-निजी कॉलबैक एन्कोडिंग।
- ट्रांसपोर्ट सीमाओं से बड़े कैनोनिकल ID के लिए टिकाऊ निश्चित-आकार के कॉलबैक संदर्भ।
- कमांड-टेक्स्ट और अनुमोदन-ID अनुमान से दूर बंडल किए गए चैनलों का माइग्रेशन।
- क्लिक किए गए सरफ़ेस पर कैनोनिकल प्रथम-उत्तर सत्य और सर्वोत्तम-प्रयास सक्रिय-नेटिव टर्मिनल अपडेट; टिकाऊ चैनल-संदेश टर्मिनलाइज़ेशन अनुवर्ती कार्य बना रहेगा।
- SDK और बंडल किए गए चैनल के परीक्षण।

### PR 3: Control UI डीप लिंक

- स्वतंत्र प्रमाणीकृत अनुमोदन पृष्ठ और बेस-पाथ-सजग स्टार्टअप रूटिंग।
- ऑपरेटर के सहेजे गए रिमोट चयन को बदले बिना सर्विंग-Gateway बाइंडिंग।
- कोर-स्वामित्व वाला अनुमोदन HTTP नेमस्पेस, जिसमें एसेट-जैसे ID शामिल हैं।
- Gateway द्वारा निर्मित URL पेलोड और लाइफ़साइकल इवेंट उपलब्ध होने तक लंबित-स्थिति पोलिंग।
- मोबाइल-चौड़ाई, पुनः कनेक्शन, प्रतिस्पर्धी उत्तर, रीलोड और माउंटेड-पाथ प्रमाण।

### PR 4: नेटिव क्लाइंट

- iOS और Android समीक्षा सरफ़ेस प्रकार-सजग `approval.get/resolve` का उपयोग करते हैं; watchOS युग्मित iPhone के माध्यम से समीक्षक-सुरक्षित प्रॉम्प्ट और निर्णय रिले करता है।
- Watch अपने कॉम्पैक्ट रिले अनुबंध द्वारा समर्थित exec निर्णय प्रदान करता है: एक बार अनुमति देना और अस्वीकार करना।
- कैनोनिकल प्रथम-उत्तर टर्मिनल सत्य स्थानीय प्रयास किए गए निर्णय की स्थिति को प्रतिस्थापित करता है।
- खोई हुई या अस्पष्ट समाधान अभिस्वीकृतियाँ कैनोनिकल रीडबैक तक नियंत्रणों को फ़्रीज़ रखती हैं।
- पहले जारी किए गए Gateway v4 इंस्टेंस एक सीमित लेगेसी-विधि फ़ॉलबैक के माध्यम से exec समीक्षा बनाए रखते हैं; सरफ़ेसों के बीच बनाए रखी गई टर्मिनल स्थिति के लिए एकीकृत विधियाँ आवश्यक हैं।
- समीक्षक चेतावनियाँ और स्वामी संदर्भ iPhone, Watch और Android पर दृश्यमान रहते हैं।
- नेटिव यूनिट, बिल्ड और प्लेटफ़ॉर्म प्रमाण।

### PR 5: पूर्वज लाइफ़साइकल प्रसार

- `session.approval` PR 1 में स्थायी किए गए ऑडियंस स्नैपशॉट से लंबित/टर्मिनल डिलीवरी।
- ट्रांसक्रिप्ट परिवर्तन या एजेंट वेक के बिना सटीक-सेशन सदस्यता, पुनः कनेक्शन रीप्ले और टर्मिनल टूम्बस्टोन।
- लाइफ़साइकल कॉलबैक टिकाऊ इंसर्ट/CAS के बाद चलते हैं और कभी भी अनुमोदन प्राधिकार नहीं बनते।
- नेस्टेड-सबएजेंट और पुनः कनेक्शन प्रमाण।

### PR 6: फ़ेल-क्लोज़्ड व्यवहार

- `node-invoke-plugin-policy.ts` और एम्बेडेड Plugin ब्रोकर को डुप्लिकेट प्राधिकार से दूर माइग्रेट करना।
- सख़्त टाइमआउट, विकृत इनपुट, नो-रूट, बाइंडिंग और एक-बार-अनुमति उपभोग सिमेंटिक्स।
- अनुरोध लंबित होने के बाद जारी की गई अनुमतिशील टाइमआउट सेटिंग का पालन किए बिना उन्हें अप्रचलित घोषित करना।
- बहु-सरफ़ेस प्रतिस्पर्धा और विफलता-इंजेक्शन प्रमाण।

### अनुवर्ती कार्य: टिकाऊ रिमोट-संदेश क्लीनअप

- फ़ॉरवर्ड की गई डिलीवरी के लोकेटर स्थायी करें और पुनः आरंभ के बाद डिलीवर किए गए प्रत्येक चैनल संदेश को टर्मिनलाइज़ करें।
- इस ट्रांसपोर्ट लाइफ़साइकल को कैनोनिकल अनुमोदन प्राधिकार और टाइप किए गए प्रेज़ेंटेशन ऐक्शन से अलग रखें।

## परीक्षण

आवश्यक केंद्रित कवरेज:

- SQLite को दोबारा खोलने पर लंबित और टर्मिनल प्रोजेक्शन सुरक्षित रहते हैं।
- दो समवर्ती समाधानकर्ता ठीक एक CAS विजेता उत्पन्न करते हैं।
- समान-निर्णय पुनः प्रयास आइडेम्पोटेंट रूप से सफल होता है; परस्पर-विरोधी पुनः प्रयास दर्ज किए गए विजेता को लौटाता है।
- समय-सीमा पर या उसके बाद समाधान अनुमोदित नहीं कर सकता।
- `allow-once` टर्मिनल ऑडिट स्थिति मिटाए बिना ठीक एक बार उपभोग योग्य है।
- स्टार्टअप पुराने रनटाइम एपोक रद्द करता है।
- अनधिकृत लुकअप और समाधान रिकॉर्ड का अस्तित्व प्रकट नहीं करते।
- स्पष्ट समीक्षक अनुमति-सूची और सामान्य युग्मित `operator.approvals` व्यवहार।
- Exec और Plugin की लेगेसी विधियाँ समान स्टोर साझा करती हैं।
- Gateway अनुरोध/सूची/प्राप्ति/समाधान स्कीमा और योगात्मक इवेंट पेलोड।
- टाइप किए गए ऐक्शन का सामान्यीकरण, फ़ॉलबैक रेंडरिंग, SDK एक्सपोर्ट और बंडल किए गए चैनल स्विच।
- Telegram कॉलबैक एन्कोडिंग में ट्रांसपोर्ट-निजी डेटा होता है और कमांड-स्ट्रिंग अनुमान नहीं होता।
- प्रत्यक्ष चाइल्ड, शाखित नियंत्रक/अनुरोधकर्ता स्वामी, नेस्टेड स्वामी, पुनः असाइनमेंट, सेशन-फ़ील्ड फ़ॉलबैक, चक्र और ऑडियंस-आकार सीमा।
- अनुरोधित और टर्मिनल ऑडियंस सरणियाँ एकसमान हैं।
- स्वामी प्रोजेक्शन से कोई ट्रांसक्रिप्ट परिवर्तन या एजेंट वेक नहीं होता।
- Control UI रूट `/` और कॉन्फ़िगर किए गए बेस पाथ पर काम करता है; रीफ़्रेश लंबित या टर्मिनल सत्य दिखाता है।
- एक साथ दिए गए Control UI और Telegram उत्तर एक विजेता तथा हारने वाले पर "अन्यत्र समाधान हो चुका है" दिखाते हैं।
- नेटिव अनुमोदन पहचानकर्ता और Gateway स्वामी पहचानकर्ता रूटिंग और समाधान-मिलान में सटीक UTF-8 बाइट सुरक्षित रखते हैं।
- नेटिव RPC-फ़ैमिली नेगोशिएशन प्रत्येक स्वीकृत Gateway रूट के लिए एक कैनोनिकल या लेगेसी फ़ैमिली निर्धारित करता है और उपयोग के बाद कभी चुपचाप डाउनग्रेड नहीं करता।
- खोई हुई नेटिव समाधान अभिस्वीकृतियाँ कैनोनिकल रीडबैक तक ऐक्शन फ़्रीज़ रखती हैं; विफल रीडबैक न तो विजेता गढ़ सकता है, न Watch रीफ़्रेश को अभिस्वीकृत कर सकता है।
- Watch स्नैपशॉट अनुरोध सहसंबंध केवल सटीक युग्मित Gateway स्वामी और पूर्ण हुए कैनोनिकल iPhone रीडबैक के लिए स्वीकार किया जाता है।
- Testbox/Crabbox के माध्यम से उपयोगकर्ता-पथ प्रमाण, जिसमें मोबाइल-चौड़ाई वाला अनुमोदन पृष्ठ, Telegram ऐक्शन क्लीनअप और Android, iPhone तथा Watch पर एक लंबित/समाधान/देर से आने वाले हारने वाले का राउंड ट्रिप शामिल है।

## प्रेक्षणीयता

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

ट्रैक करें:

- प्रकार के अनुसार अनुरोधित संख्या;
- प्रकार/स्थिति/कारण के अनुसार टर्मिनल संख्या;
- लंबित गेज;
- अनुरोध-से-टर्मिनल विलंबता;
- समाधान रेस परिणाम: विजेता, आइडेम्पोटेंट पुनः प्रयास, टकराव, अवधि समाप्त;
- डिलीवरी रूट संख्या और नो-रूट अस्वीकृतियाँ;
- स्टार्टअप-अनाथ रद्दीकरण;
- ऑडियंस आकार।

कमिट किया गया ट्रांज़िशन सफल माना जाता है, भले ही बाद की इवेंट डिलीवरी विफल हो जाए। लाइफ़साइकल सदस्य PR 5 रीप्ले और कैनोनिकल लुकअप के माध्यम से रिकवर करते हैं। टिकाऊ चैनल-संदेश टर्मिनलाइज़ेशन ऊपर दिया गया अलग अनुवर्ती कार्य बना रहता है।

## खुले निर्णय

1. **बाहरी रूप से पहुँच योग्य Control UI मूल।** प्रत्येक स्नैपशॉट स्थिर सापेक्ष `urlPath` वहन करता है। Gateway एक्सपोज़र सफल होने के बाद केवल कैश किए गए Tailscale Serve/Funnel स्थान से ही एक निरपेक्ष URL विज्ञापित किया जा सकता है; `allowedOrigins`, अनुरोध Host हेडर, `gateway.remote.url` और केवल-प्रदर्शन लूपबैक/LAN उम्मीदवार कैनोनिकल मूल नहीं हैं। Telegram बूटस्ट्रैप के माध्यम से अनुमोदन पाथ बनाए रखने के लिए अपने प्रमाणीकृत Mini App रैपर का उपयोग कर सकता है। अलग से समीक्षा किए गए स्पष्ट सार्वजनिक-URL अनुबंध के अस्तित्व तक मनमाने रिवर्स प्रॉक्सी केवल सापेक्ष बने रहेंगे। किसी चैनल को मूल का अनुमान कभी न लगाने दें।
2. **Exec सख़्त टाइमआउट संगतता कटओवर।** Plugin अनुमोदन टाइमआउट अब फ़ेल-क्लोज़्ड होते हैं और `timeoutBehavior` अप्रचलित है। शेष जारी किए गए `askFallback` अनुबंध के लिए स्पष्ट स्वामी/सुरक्षा समीक्षा, चेंजलॉग, दस्तावेज़ और माइग्रेशन/अप्रचलन निर्णय आवश्यक हैं, उसके बाद ही लंबित अनुरोध के टाइमआउट होने पर वह निष्पादन अधिकृत करना बंद कर सकता है।
3. **Gateway-रहित एम्बेडेड मोड।** अनुशंसित: प्रारंभ में इसे केवल स्थानीय रखें, फिर Gateway उपलब्ध होने पर इसे कैनोनिकल सेवा का क्लाइंट बनाएँ। ऐसे डीप लिंक का विज्ञापन न करें जिसे कोई सर्वर समाधान नहीं कर सकता।
