Handbooks
अवधारणाएँ

पाँच phases

हर generation phase क्या बनाता है, उसकी क्या लागत है, fail होने पर वह किसमें degrade होता है, और उनमें से सिर्फ़ एक को दोबारा कैसे चलाएँ।

handbook generate पाँच phases चलाता है। सिर्फ़ पहला मुफ़्त है; बाक़ी आपके LLM endpoint से बात करते हैं।

Phaseक्या बनाता हैLLM?अकेले दोबारा चलने योग्य?
1call graph
2aहर scanned file का एक card
2bstage skeleton + file assignment
2cstage के भीतर grouping और क्रम
3narration + cross-stage state registers
--phase all        # everything (default)
--phase 1          # just the call graph
--phase 2          # 2a + 2b + 2c
--phase 2a         # one phase
--phase 2c,3       # a comma list

Phase 1 — call graph

कोई LLM नहीं। Deterministic। मुफ़्त।

Language adapters हर file को tree-sitter से parse करते हैं और एक language-agnostic intermediate representation बनाते हैं। फिर graph builder edges को kept और dropped में बाँटता है, in/out degree annotate करता है, और उन constructors के लिए nodes synthesize करता है जो referenced तो हैं पर कभी explicit रूप से defined नहीं।

यह हर scanned file का एक content hash भी दर्ज करता है। वही hash बाद में resync को वह in-place body edit पकड़ने देता है जो line numbers और signatures को छुए बिना होता है — ठीक वही case जो एक विशुद्ध structural diff से पूरी तरह छूट जाता है।

जो वह पढ़ नहीं सका

Discovery ने जिस file को सूची में रखा पर analyzer उसे facts में नहीं बदल सका, वह चुपचाप छोड़ी नहीं जाती — उसे दर्ज किया जाता है। हर ऐसी file अपने reason के साथ phase1/scan-coverage.json में पहुँचती है:

  • unreadable — पढ़ना ही विफल हो गया (कोई permission mode, कोई dangling symlink, या ऐसी file जिसे build ने run के बीचोंबीच मिटा दिया)। कोई facts नहीं।
  • unparsable — grammar ने throw कर दिया, या कोई tree लौटाया ही नहीं। कोई facts नहीं। आम मामला है case वाली कोई shell script।
  • partial — file parse तो हुई, पर syntax errors के साथ। उसके बाक़ी हिस्से में मिले functions और calls असली हैं; ग़ायब बस वही है जो error node के भीतर बैठा था।

पहली दो categories की files scannedFiles से भी हटा दी जाती हैं, क्योंकि जिस file से कुछ निकला ही नहीं उसे phase 2a के हाथ में ऐसे नहीं थमाया जाना चाहिए मानो वह ख़ाली हो। Phase 1 अपने अंत में log में उस चूक का नाम ले लेता है:

[scan] coverage: 409 files analyzed; 3 recorded in scan-coverage.json (partial=1 unparsable=1 unreadable=1)

उस artifact में ख़ाली files array इसी बात का सकारात्मक रूप है: सब कुछ parse हो गया।

Output: phase1/graph.json, functions.csv, graph.dot, dropped-calls.json, scan-coverage.json.

इसे हमेशा सबसे पहले चलाएँ

handbook analyze ठीक यही phase है। इसकी कोई लागत नहीं, और tokens ख़र्च करने से पहले यह पता लगाने का यही एकमात्र तरीक़ा है कि आप node_modules scan कर रहे हैं, या कोई पूरी language ही छूट रही है।


Phase 2a — file cards

LLM। आम तौर पर सबसे महँगा phase।

Phase 1 ने जो-जो file सचमुच पढ़ी, उसी को एक card मिलता है — यानी graph.json की scannedFiles, जिसमें scan-coverage.json में दर्ज unreadable और unparsable paths शामिल नहीं होते:

  • purpose — सादी भाषा में एक-दो वाक्य
  • role — एक closed vocabulary से (entrypoint, domain_logic, io_transport, …)
  • lifecyclestartup, main loop, cross-cutting, none, …
  • और --detail deep में: 120–300 शब्दों का walkthrough, साथ में per-function purpose, data flow और relations, जो graph facts पर merge होते हैं

Batching कैसे होती है

--read-batch-size files प्रति request, --read-workers batches एक साथ उड़ान में। Deep mode का default एक file प्रति batch है, क्योंकि एक deep card काफ़ी लंबा output है और कई cards को एक ही reply में ठूँसना ही वह तरीक़ा है जिससे replies truncate होती हैं।

तीन-tier degradation

अगर किसी batch की reply parse नहीं होती:

  1. batch को अलग-अलग files में तोड़कर retry करें;
  2. oversized अकेली file के लिए per-function chunk पर retry करें;
  3. फिर भी fail हो, तो एक ईमानदार ख़ाली card लिखें — सिर्फ़ structure, कोई prose नहीं।

कोई file सिर्फ़ इसलिए handbook से ग़ायब नहीं होती कि उसकी prose fail हो गई। हर चूक phase2/cards/_coverage.json में listed होती है, और जिन replies से कुछ भी काम का नहीं निकला वे (20 तक, hash-नाम से) phase2/cards/_rejected/ के नीचे रखी जाती हैं, ताकि आप अटकल लगाने की बजाय पढ़ सकें कि क्या ग़लत हुआ।

Resume करना

Cards पूरे होते ही लिखे जाते हैं। Ctrl-C सुरक्षित है, और --resume उन files को छोड़ देता है जिनके पास requested depth का पूरा card पहले से है।

handbook generate --source $REPO --work $WORK --phase 2a --detail deep --resume

Phase 2b — skeleton और assignment

LLM। वह phase जो तय करता है कि handbook है क्या

दो modes।

--synth-mode oneshot (default)

Nav-pack (directory rollups + entry points) से एक stage skeleton synthesize करो, फिर हर file को batches में ठीक एक stage assign करो।

सस्ता, और यह आँकने के लिए आम तौर पर काफ़ी कि आकार सही है या नहीं।

--synth-mode doctor

एक actor–critic repair loop। हर round में:

  1. actor असली graph से आए ground-truth statistics के विरुद्ध अधिकतम तीन structural बदलाव प्रस्तावित करता है — split, merge, move, retitle, reparent;

  2. तीन critics समानांतर में review करते हैं, हर एक अलग विफलता खोजता है:

    Criticक्या खोजता है
    engineerक्या यह उससे मेल खाता है जो code सचमुच करता है? क्या referenced items असली हैं?
    architectधुँधली boundaries, फूले हुए stages, भूखे stages, ग़लत जगह रखे cross-cutting concerns
    readerक्या नतीजा ज़्यादा पठनीय है? Cohesive pages, सहज titles, एक followable narrative
  3. बचे हुए बदलाव graph के विरुद्ध यांत्रिक रूप से re-validate होते हैं — ऐसा बदलाव जो किसी non-existent stage का नाम लेता है, या जो files को orphan कर देता, skeleton को छूने से पहले ही reject हो जाता है;

  4. प्रभावित files दोबारा assign होती हैं।

यह तब रुकता है जब कुछ भी unassigned न बचे और कोई बदलाव review से न बच पाए, या --max-doctor-rounds (default 6) पर, या बिना प्रगति के दो rounds के बाद।

जिस critic की reply parse नहीं होती वह REJECT गिना जाता है। टूटा हुआ reviewer किसी बदलाव को कभी पास न कर दे।

अपना skeleton ख़ुद लाना

handbook generate --source $REPO --work $WORK --skeleton my-skeleton.yaml

Files आपके stages में assign होती हैं। --strategy member के साथ इसकी जगह अलग-अलग functions classify होते हैं, और file-स्तर के artifacts उसी से derive किए जाते हैं।

Output: phase2/skeleton.yaml, phase2/assignment.json, phase2/strategy.json.


Phase 2c — organization

LLM, पर सस्ता। एक deterministic क्रम में degrade होता है।

हर stage के भीतर files call-graph topology के हिसाब से क्रमबद्ध होती हैं और 2–8 titled sub-groups में बाँटी जाती हैं, हर group के साथ एक-पंक्ति की summary।

हर विफलता एक deterministic flat क्रम में degrade होती है। Files कभी नहीं गिराई जातीं। पूरा phase इसी invariant के इर्द-गिर्द लिखा गया है: न पढ़ी जा सकने वाली grouping एक cosmetic समस्या है, ग़ायब file एक correctness समस्या।

--strategy member के साथ यह phase एक no-op है — organization 2b पर ही deterministic ढंग से derive हो चुका था, इसलिए अकेले --phase 2c run को किसी LLM की ज़रूरत ही नहीं।

Output: phase2/organization.yaml.


Phase 3 — narration और registers

LLM। भारी मात्रा में cached।

Narration, नीचे से ऊपर

पहले leaf stages, फिर parents — ताकि parent की summary यह जानते हुए लिखी जाए कि उसके children क्या कहते हैं — फिर system overview, सब कुछ जानते हुए।

हर prose call phase3/cache/ के नीचे cache होती है, जिसकी key है prompt version, language और पूरे prompt का hash। एक stage छूने के बाद phase 3 दोबारा चलाना एक stage की re-narration करता है।

State registers

"register" state का वह टुकड़ा है जो stages के आर-पार बहता है — एक connection pool, एक feature flag, एक retry budget, एक auth token। Extraction एक loop-until-dry gap pass चलाता है: यह तब तक पूछता रहता है जब तक कोई round कुछ नया न पाना बंद कर दे।

Fan-out बदलावों के लिए यही अकेला सबसे उपयोगी artifact है, क्योंकि "कौन-कौन से stages इस state को छूते हैं" ठीक वही सवाल है जो एक बिखरा हुआ बदलाव पूछता है।

Output: phase3/narration.json, phase3/registers.json.


दो strategies

--strategy file (default)--strategy member
SkeletonLLM synthesize करता हैskeleton.yaml आप ख़ुद लिखते हैं
Leaf unitएक source fileएक function या method
Phase 2bfiles को stages में assignहर member classify, फिर file artifacts derive
Phase 2cLLM groupingपहले ही हो चुका — deterministic
सबसे उपयुक्तऐसा repo जिसे आप अभी नहीं जानतेऐसा repo जिसका आकार आप पहले से जानते हैं
लागतकमज़्यादा — हर member classify होता है

चुनी हुई strategy phase2/strategy.json में दर्ज होती है। किसी दूसरी --strategy के साथ बिना --phase 2b का partial re-run refuse कर दिया जाता है, क्योंकि file-strategy default का किसी member-derived organization को चुपचाप overwrite कर देना ठीक उसी क़िस्म का corruption है जिसे बाद में पकड़ना मुश्किल होता है।

एक run अपने बारे में क्या दर्ज करता है

<work>/run-manifest.json
{
  "version": 1,
  "model": "gpt-4o-mini",
  "phases": ["1", "2a", "2b", "2c", "3"],
  "startedAt": "2026-08-08T13:02:11.004Z",
  "finishedAt": "2026-08-08T13:19:44.881Z",
  "usage": { "promptTokens": 1840221, "completionTokens": 214880, "totalTokens": 2055101 },
  "stats": { "phasesRun": ["1", "2a", "2b", "2c", "3"], "nCards": 412, "nStages": 9, "nRegisters": 6 }
}

यह आख़िरी सफल run का वर्णन करता है। Fail हुआ run पिछले manifest को अछूता छोड़ता है, और abort हुआ run कोई manifest लिखता ही नहीं।

आगे

इस पृष्ठ पर