# पुराना API documentation: agent actions को सुरक्षित रूप से test करें

पुराना API documentation केवल editorial समस्या नहीं है, यह agent safety की समस्या है। कोई व्यक्ति outdated example पढ़कर रुक सकता है और colleague से पूछ सकता है। Autonomous coding agent अक्सर उसी example को request में बदल देता है और response को इस बात का evidence मान लेता है कि उसने सही काम किया।

इसलिए मानक अलग होना चाहिए। अगर documentation agent को API call करने, token rotate करने, record delete करने या production host तक पहुँचने का तरीका सिखाता है, तो text को executable input मानें। इसे tool के साथ test करें। Publication के समय सही रहा page अगर live service से अब मेल नहीं खाता, तो agent को unsafe action की ओर ले जा सकता है, भले ही API अपने वर्तमान maintainers की मंशा के अनुसार काम कर रही हो।

सबसे खतरनाक drift अक्सर loud failure नहीं होती। 404 तुरंत ध्यान खींचता है। लेकिन ऐसी request जो अब भी 200 लौटाती है और अधिक resources चुनती है, बदला हुआ default इस्तेमाल करती है या अपेक्षित confirmation को bypass करती है, आसानी से छूट जाती है। यही mismatch साफ activity log और खराब परिणाम पैदा करता है।

## Documentation agent के control plane का हिस्सा बन जाती है

Agent documentation का उपयोग operations चुनने, parameters भरने, responses समझने और retry का निर्णय लेने के लिए करता है। इसलिए examples, reference tables, authentication guides और migration notes उसके control plane का हिस्सा हैं। Service code सही हो सकता है, जबकि यही control plane agent को उसे गलत तरीके से इस्तेमाल करने को कहे।

Tool definition और guide के बीच कृत्रिम अंतर न बनाएँ। Tool definition कहती है `deleteProject(project_id)`. Guide बताती है कि project identifier कहाँ से लेना है, dry run है या नहीं, deletion cascade करती है या नहीं और authorization failure के बाद क्या करना है। Agent को दोनों चाहिए। किसी एक में गलती हो तो action गलत हो सकता है।

इसीलिए stale example केवल misspelled paragraph नहीं है। मान लें पुराना निर्देश कहता है कि missing `scope` parameter का अर्थ «current project» है। बाद में backend बदलकर उसी omission का अर्थ कर देता है «इस credential को उपलब्ध सभी projects». Endpoint अब भी काम करता है और example parse भी होता है। Agent पुराने guide का पालन करके पूरे account पर local समझा गया बदलाव लागू कर सकता है।

Documentation agent का confidence भी तय करती है। Concrete snippets पास के vague warning से अधिक प्रभावशाली होते हैं। एक page «least privilege इस्तेमाल करें» कहे और दूसरा account wide access वाला bearer token example दे, तो व्यवहार में snippet जीतेगा। Agent उस रास्ते को चुनता है जिससे result मिलता है।

इन चीज़ों को action-bearing documentation मानें:

- Request और command examples
- Defaults और allowed values बताने वाली parameter tables
- Authentication, credentials और environment setup instructions
- Retry, pagination, idempotency और error handling guidance
- Migration और deprecation instructions

**Syntax drift** और **meaning drift** अलग हैं। Syntax drift में field या path बदलने से example fail होता है। Meaning drift में example valid रहता है, लेकिन उसका असर बदल जाता है। Syntax drift लेखक को शर्मिंदा करती है। Meaning drift data को नुकसान पहुँचा सकती है, पैसे खर्च करा सकती है, records उजागर कर सकती है या access बढ़ा सकती है। Test suite को दोनों पकड़ने चाहिए।

## सफल request भी example को गलत साबित कर सकती है

केवल status code जाँचने वाला documentation test आसान failures पकड़ता है, unsafe failures नहीं। HTTP success बताती है कि server ने request स्वीकार की। इससे यह सिद्ध नहीं होता कि request सही object पर गई, वर्णित side effect हुआ या stated boundary बनी रही।

मान लें reference page यह request प्रकाशित करती है:

```bash
curl -sS -X POST "$API_URL/v1/exports" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"project":"demo","include_archived":false}'
```

Basic test `202 Accepted` देखकर सफल घोषित कर देता है। इससे कई महत्वपूर्ण बदलाव छूट सकते हैं:

- Service चुपचाप `project` का नाम बदलकर `project_id` कर देती है और पुराने field को absent मानती है।
- `include_archived` opt out से बदलकर ignored compatibility field बन जाता है।
- Credential को account wide visibility मिल जाती है और `demo` किसी दूसरे tenant के project से resolve होता है।
- Endpoint काम queue करता रहता है, लेकिन अब attachments भी export करता है, जबकि guide कहती है कि वे शामिल नहीं होंगे।

Test को केवल status नहीं, result और service state भी देखनी चाहिए। Disposable account में एक active और एक archived record बनाएँ। Documented request भेजें, resulting job को poll करें और assert करें कि artifact में active record है, archived record नहीं है और सही project identifier दर्ज है। अगर service इतना evidence नहीं देती कि यह assertion लग सके, तो documentation भी इस behavior का सुरक्षित वादा नहीं कर सकती।

HTTP status code request handling का परिणाम बताता है, caller की business intent की सफलता नहीं। इसलिए protocol assertions के लिए HTTP semantics रखें, फिर वास्तविक outcome पर assertions जोड़ें। `export_excludes_archived_records` जैसे test name से claim साफ होता है। `docs_example_returns_success` केवल बताता है कि किसी ने request चलाई।

## Examples को screenshot review नहीं, contract tests चाहिए

Release review में docs page से example terminal में copy करना उपयोगी है, लेकिन यह scale नहीं करता, dependable evidence नहीं छोड़ता और happy path पर निर्भर रहता है। लोग command को locally सुधारकर page ठीक करना भूल भी सकते हैं।

Executable examples को structured source file में रखें, उसी source से rendered snippet बनाएँ और CI में वही source चलाएँ। OpenAPI examples, Markdown code extraction या अलग fixture directory इस्तेमाल कर सकते हैं। तरीका कम महत्वपूर्ण है। जरूरी बात यह है कि reader को दिखने वाली command वही हो जो test चलाता है।

ऐसा अलग «test version» चुपचाप न रखें जिसमें safer URLs, narrower scopes या published example से अधिक headers हों। इससे green build का भ्रम पैदा होगा, जबकि public instructions stale होती रहेंगी। केवल environment के अनुसार बदलने वाले values parameterize करें, जैसे base URL, test credentials और fixture identifiers। Method, path, body shape और security-related flags समान रखें।

एक छोटा shell test pattern दिखा सकता है:

```bash
set -euo pipefail

project_id="docs-check-$RANDOM"
response=$(curl -sS -X POST "$API_URL/v1/projects" \
  -H "Authorization: Bearer $DOCS_TEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"id\":\"$project_id\",\"name\":\"Documentation check\"}")

printf '%s' "$response" | jq -e \
  --arg id "$project_id" \
  '.id == $id and .name == "Documentation check" and .archived == false'
```

`jq -e` का expected output JSON value `true` है और mismatch पर process nonzero exit करता है। महत्वपूर्ण बात shell syntax नहीं है। Assertion prose के claim को encode करती है: API दिए गए identifier वाला project बनाती है, supplied name सुरक्षित रखती है और उसे default रूप से archive नहीं करती।

Rendered documentation के लिए अलग check बनाएँ। अगर Markdown extractor page से `bash` block उठाता है, तो approved environment variables भरकर test को वही block चलाना चाहिए। OpenAPI description से docs generate करते हैं तो hand-copied version नहीं, generated example test करें। Screenshot review readability के लिए उपयोगी है, behavior सिद्ध करने के लिए नहीं।

## Live service checks में defaults और failure paths भी शामिल करें

सबसे खतरनाक API changes defaults, authorization boundaries और failure handling में आते हैं। Happy path tests इन तीनों से बचते हैं क्योंकि उन्हें लिखना और green रखना आसान होता है।

उन omission cases को test करें जो agent बना सकता है। Agents payloads conditionally बनाते हैं, इसलिए पहले lookup में value न मिलने पर optional field गायब हो सकती है। हर documented optional parameter के लिए तय करें कि omission safe है, reject होना चाहिए या उसका अर्थ अलग है। फिर documented behavior को सीधे test करें।

`dry_run` field वाली operation के लिए isolated environment में कम से कम ये cases चलाएँ:

1. `dry_run: true` plan लौटाए और fixture को न बदले।
2. `dry_run: false` केवल named fixture पर stated change करे।
3. `dry_run` हटाने पर request reject हो या documented default लागू हो।
4. अपर्याप्त scope वाला token किसी change से पहले fail हो।
5. Documented request दोहराने पर idempotency guidance के अनुसार behavior हो।

तीसरा case accidental damage का सामान्य स्रोत पकड़ता है। Service team interactive users के लिए default बदल देती है, जबकि docs पुराना default मानती रहती हैं। Human interface confirmation screen दिखा सकता है, API client नहीं।

Failure examples को भी test करें। Documentation अक्सर «429 पर retry करें» कहती है, लेकिन यह नहीं बताती कि `Retry-After` मिलेगा या नहीं, repeat करना safe है या नहीं और idempotency token चाहिए या नहीं। ऐसी सलाह rate limit को duplicate invoices, deployments या revocations में बदल सकती है।

Exact failure guidance test करें। Test service या controlled environment में throttled condition बनाएँ। Confirm करें कि documented client stated header पढ़ता है, निर्देश के अनुसार wait करता है और API support करने पर वही idempotency identifier फिर भेजता है। अगर service error को predictably पैदा नहीं कर सकती, तो confident recipe की जगह uncertainty document करें।

OpenAPI का `default` keyword भी trap बन सकता है। JSON Schema और OpenAPI में declared default अक्सर बताता है कि tools क्या assume या display कर सकते हैं। इससे हर server implementation अपने आप वह value लागू नहीं करती। Field हटाकर deployed service जाँचें। Schema default और server default अलग claims हैं, जब तक test उन्हें जोड़ न दे।

## Destructive workflows के लिए disposable proof चाहिए

Destructive examples को shared staging account पर test करके safe न मानें। Shared environments में पुराने fixtures, manual experiments और अस्पष्ट reach वाले credentials जमा होते हैं। अंततः documentation test गलत object से match करेगा या cleanup command अपनी सीमा से आगे जाएगी।

Dedicated test tenant या account इस्तेमाल करें, जिसके credentials केवल test resources तक पहुँचें। हर fixture को unique run marker के साथ बनाएँ। Mutation से पहले marker से उसे retrieve करें। Test के बाद resulting state verify करें, केवल response के claim पर भरोसा न करें।

Delete example को पूरा lifecycle दिखाना चाहिए:

```text
create fixture: docs-delete-<run-id>
read fixture: confirm owner=test-suite and run_id=<run-id>
delete fixture: send the rendered documentation request
read fixture: expect the documented absence or tombstone state
list nearby fixtures: confirm unrelated fixtures remain
```

आखिरी check जरूरी है। केवल चुने object के गायब होने की पुष्टि करने वाला deletion test overly broad selector नहीं पकड़ सकता। एक समान पड़ोसी fixture रखें जिसे बचना चाहिए। इससे पता चलेगा कि endpoint समान prefix वाले सभी resources तो नहीं हटा रही।

जब immutable identifier उपलब्ध हो, तो docs agents को `latest`, `all`, blank filter या human-readable name जैसे convenience selectors इस्तेमाल करने को न कहें। Tutorial में ये friendly लगते हैं, busy account में unsafe हो जाते हैं। Broad selector सचमुच जरूरी हो तो scope request body या command arguments में साफ दिखाएँ, server default में छिपाएँ नहीं। Irreversible operations के लिए preflight read प्रकाशित करें। पहले object fetch करके immutable ID और relevant state verify करें, फिर mutation करें।

## Tool tests को केवल schema नहीं, meaning की तुलना करनी चाहिए

Schema validation आवश्यक है, लेकिन schemas consequences की तुलना में shape को अधिक faithfully बताते हैं। Request body सभी type constraints पूरी कर सकती है और फिर भी गलत environment या privilege के साथ action कर सकती है।

Assertions चार सवालों पर बनाएँ: action से कौन प्रभावित हुआ? कौन-सी state बदली? कौन-सी state नहीं बदली? किस identity ने authorize किया? ये सवाल HTTP APIs, SSH commands और internal tools सभी पर लागू होते हैं।

HTTP में service द्वारा दिया गया request identifier capture करें, फिर test environment में resulting resource या audit record query करें। Request identifier, actor, target और mutation का मिलान करें। SSH में disposable host पर commands चलाएँ, exit status और output capture करें, फिर अलग verification command से host state देखें। Action command को अपना homework grade न करने दें।

Useful fixture में contrast होना चाहिए। अगर command को एक service restart करनी है, तो दूसरी service बनाएँ जो running रहनी चाहिए। अगर query एक repository तक सीमित है, तो दूसरा ऐसा repository भी रखें जिसे credential देख सकता है लेकिन request को छूना नहीं चाहिए। Contrast के बिना broad action सही दिख सकती है।

Consumer-driven contract tools request shape और expected fields की पुष्टि कर सकते हैं। वे यह तय नहीं कर सकते कि request सही production account चुनती है, `force` का अर्थ बदल गया है या deletion documented object से आगे cascade करती है। Contract test रखें, लेकिन overreach दिखाने वाले fixtures के साथ outcome test भी जोड़ें।

Tool description भी test करें। अगर tool `environment` expose करती है, तो `production` को acceptable value तभी बताएँ जब test verify करे कि वह documented host पर route करती है और stated authorization path इस्तेमाल करती है। Agents arguments भरने के लिए descriptions का उपयोग करते हैं। Stale description, stale API example का prose version है।

## Agent को freshness evidence और safe refusal path चाहिए

Agent को यह अनुमान नहीं लगाना चाहिए कि repository या internal portal में दिखाई देने से documentation current है। जिस operation को वह call करने वाला है, उससे जुड़ा machine-readable verification evidence दें।

एक सरल manifest पर्याप्त हो सकता है:

```json
{
  "operation": "POST /v1/exports",
  "documentation_source": "docs/api/exports.md#creating-an-export",
  "verified_in": "isolated-test-tenant",
  "verification_commit": "<commit-id>",
  "assertions": [
    "returns an export job",
    "omits archived fixtures when include_archived is false",
    "rejects a token without export scope"
  ],
  "review_required_when": ["production", "include_archived=true"]
}
```

Commit identifier अपने आप trust badge नहीं है। वह reviewer को documentation और test source तक trace करने देता है। Age limit चाहिए तो build records में verification time रखें, लेकिन timestamp को safety का प्रमाण न मानें। Service deployment कल के test को invalid कर सकती है।

Decision rule स्पष्ट होनी चाहिए। अगर requested operation के लिए deployed interface का passing verification record नहीं है, तो agent approved test context में nonmutating preflight चलाए या व्यक्ति से exact action approve करने को कहे। उसे neighboring endpoint के आधार पर improvise नहीं करना चाहिए।

«unknown» और «safe» को अलग रखें। Evidence न होने पर abstention को successful outcome बनाना होगा। Reason दें, जैसे: `documentation example has no verified outcome test for this operation`. इससे developer को vague refusal के बजाय repair target मिलता है। हर risky phrase की लंबी policy file बनाने से समस्या हल नहीं होगी। Concrete operation को concrete test से जोड़ें और result agent को दें।

## Release gates तभी काम करते हैं जब misleading page block हो

Documentation verification program तब विफल होता है जब report बनती है, लेकिन किसी को action लेना आवश्यक नहीं होता। Contract बदलने पर check publication रोकनी चाहिए या कम से कम affected example तक agent access रोकना चाहिए।

API specification, route handlers, authentication middleware, SDK request builders और documentation sources में changes से checks जोड़ें। इनमें बदलाव relevant example tests चलाएँ। Failure पर तीन ईमानदार विकल्प हैं: पुराना behavior लौटाएँ, नए behavior के लिए docs और tests update करें, या verification सफल होने तक operation को agents के लिए unavailable करें।

Manual review judgment के लिए उपयोगी है, लेकिन अकेली recommendation नहीं होनी चाहिए। Reviewer से text के आधार पर service, credentials, defaults और state transitions mentally simulate करवाना routine releases में reliable नहीं है।

Failures को स्पष्ट बनाएँ। Report में page, code block, operation, fixture, observed response और violated assertion का नाम दें। «Documentation integration failed» scavenger hunt पैदा करता है। «exports.md line 42 कहती है कि archived records exclude होंगे, लेकिन export artifact में fixture archived-run-817 शामिल है» सीधे repair बताता है।

Service change के कारण test असुविधाजनक हो तो उसे तुरंत ढीला न करें। पहले तय करें कि पुराना promise उपयोगी था या नहीं। उपयोगी था तो उसे restore करें या नई limitation प्रमुखता से लिखें। Unsafe था तो softer sentence के साथ example बचाने के बजाय उसे हटा दें। Agent अक्सर बची हुई command का पालन करेगा।

Versioned documentation में भी यही discipline चाहिए। पुराने API version का page सही हो सकता है, लेकिन current base URL वाले agent को mislead कर सकता है। Version को endpoint path, server URL या tool metadata में रखें, ताकि agent उसे request से bind कर सके। केवल ऊपर की heading में «v1» लिखना कमजोर evidence है।

## Authorization blast radius घटाता है, खराब instructions ठीक नहीं करता

Approval और credential isolation जरूरी हैं क्योंकि documentation checks defects miss कर सकते हैं। वे गलत operation चुनने पर नुकसान घटाते हैं, stale instruction को सही नहीं बनाते।

दोनों काम अलग रखें। Documentation verification पूछता है, «क्या example live service और उसके consequences का सही वर्णन करता है?» Action authorization पूछता है, «क्या इस agent को अभी यह call करने की अनुमति होनी चाहिए?» इन्हें मिलाने से confusion होता है। User project export approve कर सकता है, जबकि stale example credential को दिखने वाले हर project को export कर रहा हो।

Agent-driven HTTP और SSH actions के लिए Sallyport credentials को agent से बाहर रख सकता है और session या individual credential use पर व्यक्ति से authorization माँग सकता है। जब documentation evidence भरोसेमंद न हो या action human review योग्य हो, यह उपयोगी आखिरी boundary है।

Approval screen में operation, target और scope ऐसे शब्दों में दिखने चाहिए जिन्हें व्यक्ति समझ सके। `POST /v1/exports` पर्याप्त नहीं है, अगर body में `include_archived=true` या account-wide selector है। Authorization layer meaningful scope न दिखा सके तो tool interface को तब तक narrow करें जब तक वह दिखा सके।

Audit records tests सुधारने की सामग्री देते हैं। जब कोई व्यक्ति run revoke करे या action पर सवाल उठाए, exact request, agent द्वारा cited documentation source और उपलब्ध verification evidence देखें। इसे blame assignment न बनाएँ। Missing fixture, assertion या refusal condition जोड़ने के लिए इसका उपयोग करें।

## सबसे पहले उस example को test करें जिसका पछतावा सबसे अधिक होगा

Reference का सबसे साफ GET request लेकर शुरुआत न करें। उस example से शुरू करें जो delete, publish, rotate, grant, charge कर सकता है या production host तक पहुँच सकता है। Isolated fixture दें, exact rendered command चलाएँ और intended change के साथ उस nearby change पर भी assertion लगाएँ जो नहीं होना चाहिए।

फिर test को documentation source से जोड़ें और publication या agent use से पहले failure को visible बनाएँ। यह नया tool description लिखने जितना आकर्षक नहीं है, लेकिन एक खतरनाक assumption हटाता है: page सुरक्षित है क्योंकि वह कभी review पास कर चुका था।

Live service बदलती है। Docs अपने आप उतनी तेजी से नहीं बदलेंगी, जब तक test उन्हें service से मिलने के लिए मजबूर न करे। इस meeting को release का हिस्सा बनाएँ, इससे पहले कि agent पुराने वाक्य को action में बदल दे।
