DEV Community

Cover image for osFoundry में Claude Code को GitNest check दोबारा चलवाने के लिए commit क्यों बताना पड़ता है?
BBT for BBT हिन्दी

Posted on

osFoundry में Claude Code को GitNest check दोबारा चलवाने के लिए commit क्यों बताना पड़ता है?

यह वह tool है जिसे Claude Code तब call करता है जब उसे किसी fail हुए GitNest check को फिर से चलवाना हो। नीचे इसे ठीक वैसे ही दिखाया गया है जैसे osFoundry का live MCP endpoint इसे tools/list में दिखाता है (catalogue के लिए token की ज़रूरत नहीं):

{
  "name": "propose_gitnest_check_rerun",
  "description": "Ask the repository owner to retry one finished check on a specific composed change-set version. Approval rechecks repository access, version, commit and check state.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "repository_id": {"type": "string"},
      "change_set_id": {"type": "string"},
      "check_name": {"type": "string", "maxLength": 200},
      "expected_change_set_version": {"type": "integer", "minimum": 1},
      "expected_composition_oid": {"type": "string"},
      "idempotency_key": {"type": "string", "minLength": 8, "maxLength": 128}
    },
    "required": ["repository_id", "change_set_id", "check_name",
                 "expected_change_set_version", "expected_composition_oid", "idempotency_key"],
    "additionalProperties": false
  },
  "annotations": {"readOnlyHint": false, "openWorldHint": false, "destructiveHint": true},
  "securitySchemes": [{"type": "oauth2", "scopes": ["osfoundry:write"]}]
}
Enter fullscreen mode Exit fullscreen mode

इसका read वाला साथी दो arguments लेता है: list_gitnest_checks {repository_id, change_set_id}, "bounded check status for the current composed commit of a change set"। फ़ैसले के लिए दो और reads काम आते हैं: list_gitnest_saved_results (limit 1–50) और read_gitnest_work (kind में tasks, changes या runs)। तीनों osfoundry:read हैं और readOnlyHint: true रखते हैं।

सिर्फ़ एक check दोबारा चलाने के लिए छह required fields काफ़ी ज़्यादा हैं। CI बटन को बस एक job ID चाहिए। जो दो fields ज़्यादा हैं, यानी version और commit, यह पोस्ट उन्हीं के बारे में है। इस Mac पर कोई claude binary installed नहीं है, इसलिए client का काम checks_sim.py करता है। code और उसका पूरा output code/ में है।

जब agent checks पढ़ता है, तो "green" का मतलब क्या है?

कुछ भी propose करने से पहले agent को check list सही पढ़नी होती है। osFoundry की GitNest UI किसी commit के check runs का सार एक छोटे pure function (check-runs.ts में summarise) से निकालती है। उसके tests का क्रम ही नियम है:

  1. एक भी run नहीं है तो none, कभी passed नहीं।
  2. कोई भी failure, timed_out या cancelled हो तो failed।
  3. जो कुछ भी अभी success नहीं है, वह state को running पर रखता है, उस status समेत जिसे client पहचानता नहीं।
  4. इसके बाद ही passed।

script इस नियम को port करती है और उसकी तुलना उन दो shortcuts से करती है जो model अपने आप लिख देता है:

== verdict ==
case             summarise          no-failure  ratio 
no checks        none               green       green 
all passed       passed 2           green       green 
one queued       running 1/2        green       red   
one failed       failed: e2e        red         red   
one timed out    failed: e2e        green       red   
one cancelled    failed: e2e        green       red   
unknown status   running 1/2        green       red   
shortcut wrong: no-failure 5/7, ratio 1/7
Enter fullscreen mode Exit fullscreen mode

"कुछ fail नहीं हुआ, तो green है" वाला तरीका 7 में से 5 cases में गलत है। यह बिना जाँचे commit को green कहता है, queue में पड़े check को green कहता है और timeout को भी green कहता है। ratio वाला check (passed == total) बेहतर है, लेकिन शून्य checks पर 0 == 0 होता है और यह भी green कह देता है। GitNest के code comments इसी case को सबसे भ्रामक बताते हैं, क्योंकि जिस commit पर कोई check नहीं चला, वह verify हुआ ही नहीं। UI इसे "No checks have run against this commit" के रूप में दिखाती है, बिना tick के।

अगर आप Claude Code से "क्या green है?" का जवाब चाहते हैं, तो ये चार नियम उसे CLAUDE.md में दें। tool status लौटाता है, फ़ैसला नहीं।

rerun के साथ version और commit क्यों जाते हैं?

क्योंकि approve करने वाला व्यक्ति एक खास commit देख रहा होता है, और उसके click करने से पहले change set बदल सकता है।

GitNest में change set को saved results से जोड़कर एक commit बनाया जाता है। अगर उसे दोबारा compose किया जाए, किसी नए saved result या खिसके हुए base की वजह से, तो उसे नया version और नया composed commit मिलता है, और उसके checks फिर से शुरू होते हैं। rerun का proposal किसी इंसान का इंतज़ार करता है। अगर उसमें सिर्फ़ "rerun e2e on cs_4e81a0" लिखा हो, तो approval उस वक़्त change set जो भी है उस पर e2e चला देगा, जो शायद ऐसा commit हो जिसे owner ने कभी देखा ही नहीं।

checks_sim.py इसी इंतज़ार को model करती है। हर trial एक proposal है। agent version 3, commit A पढ़ता है, जिसमें e2e fail है। owner का review time log-normal है, जिसका median 8 मिनट है। यह एक assumption है, measurement नहीं। इंतज़ार के दौरान change set Poisson process की तरह recompose होता है, औसतन हर 45 मिनट में, और recompose के बाद checks चलने में 4 मिनट लगते हैं। 10% trials में दूसरे Claude Code session ने वही failure पढ़कर अपनी key के साथ अपना proposal भेजा, और owner दोनों को approve करता है। approval के समय तीन guards, हर एक के 10,000 trials:

== approval-time guards (n=10000, review median 8 min, recompose mean every 45 min, 10% second session) ==
guard          ran on reviewed commit ran on unreviewed commit            duplicate run          refused (stale)   refused (not finished)
none                             7789                     1411                     1764                        0                        0
version+oid                      7789                        0                      740                     2435                        0
full                             7789                        0                        0                     2435                      740
Enter fullscreen mode Exit fullscreen mode

बिना guard के 1,411 approvals ने ऐसे commit पर check दोबारा चलाया जिसे owner ने review नहीं किया था, और 1,764 ने ऐसा check queue किया जो पहले से queue में था या चल रहा था। approval के समय version और commit की तुलना करने से unreviewed runs 0 हो जाते हैं, और बदले में 2,435 पुराने cards reject होते हैं। बचे हुए 740 duplicates दूसरे sessions के हैं: वही version, वही commit, लेकिन पहला approval check को पहले ही दोबारा queue कर चुका था। तीसरा guard, "क्या यह check अब भी finished है?", इन्हें पकड़ता है। tool description में यही पूरा set लिखा है: "Approval rechecks repository access, version, commit and check state."

recompose rate वह input है जिस पर सबसे कम भरोसा है, इसलिए तीन rates पर बिना guard वाली row यह रही:

== sensitivity: unreviewed-commit runs with guard 'none' ==
recompose every  15 min  unreviewed  2449  duplicates 3128
recompose every  45 min  unreviewed  1411  duplicates 1764
recompose every 180 min  unreviewed   452  duplicates 1208
Enter fullscreen mode Exit fullscreen mode

हर तीन घंटे में बदलने वाला change set भी हर 10,000 में 452 गलत-commit runs देता है। happy path पर guard की कोई कीमत नहीं: reviewed commit वाली गिनती तीनों rows में 7,789 है।

version और commit दोनों क्यों?

इस model में दोनों हमेशा साथ बदलते हैं, इसलिए अकेले किसी एक का score भी वही आता। लेकिन दोनों अलग सवालों का जवाब देते हैं। version change set का अपना counter है, जो उसका content बदलने पर बदलता है। commit वह है जिस पर checks असल में चले, और card पर यही "Reviewed commit: …" के रूप में छपता है। client से दोनों भेजवाने का मतलब है कि server किसी भी एक के आधार पर मना कर सकता है, और owner card पर internal counter नहीं, commit hash पढ़ता है। schema version को integer ≥ 1 के रूप में enforce करता है। commit एक free string है, इसलिए उसकी जाँच server पर होती है।

call से पहले schema क्या पकड़ लेता है?

script jsonschema से arguments को live inputSchema के ख़िलाफ़ validate करती है:

== propose_gitnest_check_rerun arguments ==
ok                 PASS
no oid             REJECT  'expected_composition_oid' is a required property
version 0          REJECT  0 is less than the minimum of 1
version as string  REJECT  '3' is not of type 'integer'
two checks         REJECT  ['e2e', 'lint'] is not of type 'string'
check 201 chars    REJECT  'ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
key 7 chars        REJECT  'abcdefg' is too short
extra 'force'      REJECT  Additional properties are not allowed ('force' was unexpected)
required: repository_id, change_set_id, check_name, expected_change_set_version, expected_composition_oid, idempotency_key
Enter fullscreen mode Exit fullscreen mode

इनमें से दो rejections design का हिस्सा हैं, सिर्फ़ साफ़-सफ़ाई नहीं। check_name string है, list नहीं, इसलिए "सब कुछ दोबारा चलाओ" का मतलब है हर check के लिए एक card, और owner हर एक पर अलग फ़ैसला करता है। और additionalProperties: false की वजह से जो model अपनी तरफ़ से "force": true जोड़ दे, उसे चुपचाप ignore होने वाले flag की जगह error मिलता है।

idempotency key इस बात से बननी चाहिए कि proposal किस बारे में है, attempt से नहीं। script "rerun-" + sha256(change_set_id, version, oid, check_name)[:32] इस्तेमाल करती है:

key retry same: True   key after recompose same: False   len 38
Enter fullscreen mode Exit fullscreen mode

response खो जाने के बाद retry वही key भेजता है और दूसरा card नहीं बनता। recompose से key बदल जाती है, इसलिए नए commit का proposal नया card होता है, और यही सही है।

ये tools कितने भारी हैं, और server कितनी दूर है?

== tools/list ==
59 tools, 48140 B via json.dumps, 12722 tok (cl100k)
list_gitnest_checks              612 B  158 tok  readOnly=True  destructive=False scope=osfoundry:read
list_gitnest_saved_results       707 B  182 tok  readOnly=True  destructive=False scope=osfoundry:read
read_gitnest_work                685 B  189 tok  readOnly=True  destructive=False scope=osfoundry:read
propose_gitnest_check_rerun     1011 B  268 tok  readOnly=False destructive=True  scope=osfoundry:write
all 13 gitnest tools 11227 B 3009 tok
Enter fullscreen mode Exit fullscreen mode

13 GitNest tools catalogue के लगभग एक-चौथाई tokens लेते हैं (tiktoken cl100k_base से गिने गए, इसलिए इन्हें अनुमान मानें)। जापान में इस Mac से live endpoint पर हर तरह की दस unauthenticated calls:

$ python3 probe.py
initialize                       HTTP 200     308 B  median    566 ms  min   326  max   807
  capabilities: {"tools": {"listChanged": false}}
tools/list                       HTTP 200   45368 B  median    722 ms  min   420  max  1406
tools/call list_gitnest_checks   HTTP 401     337 B  median    552 ms  min   409  max   903
Enter fullscreen mode Exit fullscreen mode

401 में error_description="Connect osFoundry to continue" और एक resource_metadata URL होता है, और यही Claude Code को उसके OAuth flow में भेजता है। initialize कोई push advertise नहीं करता, इसलिए client को कुछ नहीं बताता कि retry approve हो गया या check पूरा हो गया। check का इंतज़ार यानी आपकी मशीन पर runner का काम और एक इंसान का click, मिनटों का मामला, milliseconds का नहीं। सस्ता pattern यह है कि propose करने के बाद turn खत्म करें, और जब user कहे कि उसने approve कर दिया, तब एक बार list_gitnest_checks call करें।

check असल में चलाता कौन है?

osFoundry नहीं। GitNest का runner panel कहता है कि checks "run on your machine, not ours"। एक registered runner अपने token से poll करता है (OSF_RUNNER_TOKEN=… osfoundry-runner --api https://api.osfoundry.io), और runner के बिना checks "stay queued"। retry approve करने से check सिर्फ़ दोबारा queue होता है। Claude Code के पास runner token कभी नहीं होता, और read tools local bindings और credentials शामिल नहीं करते। agent देख सकता है कि e2e fail हुआ। आपके और आपके runner के बिना वह कुछ भी execute नहीं करवा सकता।

अगर आप इसे खुद जोड़ रहे हैं

  • verdict वाला नियम client के instructions में डालें, सिर्फ़ अपनी UI में नहीं। "कोई check नहीं" और "अनजान status" ही वे जगहें हैं जहाँ agents green बता देते हैं।
  • rerun में वह commit लिखवाएँ जिस पर review हुआ था, और तुलना approval के समय करें, proposal के समय नहीं।
  • approval के समय check की अपनी state भी दोबारा जाँचें। version और commit एक ही failure के दो proposals नहीं पकड़ते।
  • एक proposal में एक ही check लें। list देने से flaky test का retry एक ऐसा blanket rerun बन जाता है जिसे किसी ने चुना ही नहीं।
  • idempotency key को (change set, version, commit, check) से बनाएँ, ताकि retries एक हो जाएँ और recomposes नहीं।
  • execution को platform और agent दोनों से दूर रखें: token runner के पास, बटन इंसान के पास।

checks panel वाला change-set review page GitNest page पर है। protocol के बारे में जानने के लिए MCP glossary entry देखें।

Top comments (0)