begin は何をしますか?
コードベースに一度で、証拠に基づいて、さまよわずに方向づける。
このスキルが存在する理由は、エージェントがリポジトリを開き、それらしい単語で grep し、たまたまマッチした3つのファイルを読み、システムの 4% しか記述していない自信満々のアーキテクチャサマリを報告する、という失敗を防ぐためです。begin は、重要なコードがどこにあるかを推測する代わりに、測定し、測定結果が指し示すものだけを読みます。
契約
- 何も思い出さず、すべてを導出する。 重要性は実際のインポートグラフ上の PageRank から、複雑度は計数された決定ポイントから、焦点は git と PR ログから得られます。ファイル:行やコミットを指し示せないなら、それを言ってはいけません。
- すべての主張はアンカーされる。 BEGIN.md の各文は
path:line、コミット、または PR 番号を引用します。アンカーされていない文は推測であり、このスキルが排除しようとするものです。 - 2つのレイヤー、そのうち1つは生きたもの。
.begin/はマシン出力であり、再生成され、自己無視します。BEGIN.mdはあなたが書き、コミットし、導出元のコミットでスタンプした散文です。Post-commit フックはマシンレイヤーを再導出し、どの散文セクションがコードに追い越されたかを報告します。このスキルは決して追跡ファイルを編集しません —.begin/は自身の.gitignoreを持つため、リポジトリのものは変更されません。 - プロキシはプロキシとして名前付けされる。
complexityProxyは決定ポイントのカウントであり、パース結果ではありません。ネストはインデントから測定されます。そのように述べ、プロキシを事実に偽装してはいけません。 - 劣化した測定は、静かに使われることなく、告知される。 スキャンは、シャロークローン、死んだ churn ウィンドウ、ドロップされたファイル、まったくパースできない言語、またはパースできるが解像度が失敗した場合に
[!WARNING]ブロックを出力します。そのブロックをテーブルより先に読み、その内容を BEGIN.md で繰り返してください。 壊れたグラフに基づくランキングは、正常なものとまったく同じに見えます — それが危険のすべてです。
実行方法
S=~/.claude/skills/begin/scripts
bash $S/recon.sh # 誰が/何を/いつ: PR、あなたのコミット、ライブ編集、ドキュメント
node $S/scan.mjs # 構造: インポートグラフ、ホットスポット、サーフェス→エンジン
どちらも .begin/ に書き込み、ダイジェストを出力します。リポジトリ内のどこからでも実行してください — スキャンはリポジトリルートにアンカーされます。recon.sh は gh なし、ネットワークなし、リモートなしでも正常に動作しますが、node が必要です(リダクションは必須)。計測されたウォームキャッシュ: 259 ファイル 0.24 秒 · 3,384 ファイル 1.9 秒 · 2,809 ファイル 1.9 秒 · 1,819 ファイル 2.5 秒 · 1,397 ファイル 3.5 秒。ファイル数は時間を予測しません;コンテンツが予測します。
知っておくと便利なフラグ:
--since "90 days ago"— churn ウィンドウ(両スクリプトのデフォルトは 90)。--top 40— 出力するホットスポットの数(デフォルトは 25)。--author "..."— 正規表現。めったに必要ありません:デフォルトはリポジトリのuser.nameで、recon.shはリポジトリの最もアクティブな作者にフォールバックし、あなたがそこにコミットを持っていない場合にそのことを伝えます。これはあなたがクローンしたばかりのリポジトリでは正常なケースです。--exclude 'examples/**,site/**'— ベンダーツリーとドキュメントサイトをサーフェスカウントから除外します。パターンは両端でアンカーされ、削除されたファイル数が出力されます。なぜなら、静かな除外は後で欠落したエッジとして現れるからです。--root DIR— 別のリポジトリをスキャンします。
操作手順 — 正確にこれに従うこと
これらを順序を間違えて行うと、エージェントが間違ったファイルを読み込むことになります。
1. 構造の前に偵察
recon.sh を最初に実行します。これは「この人は何をしているのか?」という問いに答えます — 未コミットの編集、ブランチ対メインのコミット、最後の ~20 のマージされた PR(その本文も含む)、そしてそれぞれが何を変更したか。それがフォーカスの事前情報です。.begin/recon.md を完全に読んでください;短いです。
未コミットの差分は通常、リポジトリ内で最も有益な情報です — それはユーザーが現在抱いている質問です。Recon はそれについて3つのことをフラグします:ツリーがクリーンな場合はそれを明示的に言う(セクションを省略してあなたを探し回らせる代わりに)、差分がロックファイルとビルド出力のみの場合は最初の読み取りをそこに費やさないように伝える、そしてチェックアウトが origin より遅れている場合は何コミット遅れているかを言い、最近の PR からのファイルであなたのツリーにないものを名前付けします。
最後のものは注意点ではなく、前提条件です。 recon があなたが遅れていると報告した場合、以下のステップ 3.2 は安全ではありません:PR ファイルリストはあなたが持っていないコードを記述しています。git pull を先に行うか、PR 読み取りステップをスキップして、BEGIN.md でそのように述べてください。
2. 構造を次に
scan.mjs を実行し、.begin/scan.md をまず [!WARNING] ブロックから読んでください。その後、推測ではなく測定されたものが得られます:
- サーフェス — 人間や呼び出し元が実際にシステムに触れるすべての場所で、種類ごとにグループ化されています(
web-page、ui-component、http-route、cli-command、mcp-tool、worker、public-api、migration、さらにexample、config、testはサーフェスですがプロダクトではありません)。これがマップの UI 側です。 - ホットスポット — ランク付けされ、各ファイルをそこに置いた用語を
why列で示します:depended-on、churn、complex、recent。churnでトップにあるファイルは、depended-onでトップにあるファイルとは異なる性質を持ちます;列はどの会話を行うべきかを示します。 - サーフェス → エンジンパス — エンドポイントやボタンからハードな部分までのリテラルなインポートチェーンで、BFS によって計算されます。遅延
await import()エッジを横断するパスは、ロード時ではなく呼び出し時に解決されるため、そのようにラベル付けされます。 - インポートサイクルグループ — 静的値エッジ上の強連結集合で、1つの実際の有向ループがウォークアウトされます。型のみと遅延 (
await import(...)) エッジは除外されます。なぜなら、どちらも実際の初期化サイクルを形成しないからです。 - 到達不能ファイル — デッドコード、またはヒューリスティックが見逃したサーフェス。どちらかを判断し、それを述べてください。
2.5. リポジトリがすでに書いてくれたマップを読む
ホットスポットを開く前に、AGENTS.md、CLAUDE.md、ARCHITECTURE.md、またはディレクトリごとの README を確認してください — recon.md がそれらをリストアップします。サブシステムマップを同梱するリポジトリは、スキャンが2秒で推測し散文で再構築に1時間かかるものを、30行で提供します。それらを最初に読み、次にスキャンを使ってそれらを検証してください:ドキュメントは古くなり、グラフは古くなりません。
3. 測定が指し示したものだけを読む
以下の順序で読み、そこで止めてください:
- 未コミットの差分と現在のブランチのコミット(彼らが今やっていること)。
- 最新の3〜5のマージされたPRによって変更されたファイル(彼らがちょうど決定したこと)。
scan.mdから上位8〜15のホットスポット。- 上位3のそれぞれについて、その
reachedViaサーフェスを内側にたどり、ユーザーアクションからエンジンまでの完全なパスを述べられるようにする。 README、2.5 のエージェント向けドキュメント、およびホットスポットと見出しが一致するドキュメント。
最初のパスでは、このセットの外のファイルを開かないでください。何か欠けているように見えても、それは報告すべき発見であり、ブラウズするための許可証ではありません。
4. 書く前に検証する
テーブルはリードのセットであり、結論ではありません。各主張を BEGIN.md に入れる前に:
- ファイルを開き、引用しようとしている行があなたの考え通りであることを確認する。
- サーフェス → エンジンパスの場合、インポートが実際にソースに存在することを確認する。
- 動作に関するものについては、それらしい関数よりも、それを実証するテストを優先する。
- ホットパスを grep して飲み込まれた失敗を探す —
catch {}、.catch(() => {})、as any、as never、破棄された戻り値。バグはエラーが捨てられる場所に存在し、これらは初日に提供できる最も価値の高いものです。 - 主たる主張を反証しようとする試みに少なくとも1パスを費やし、確認に費やさないでください。 良い BEGIN.md の中で最も価値のある文は、スキャンと矛盾するものです。
スキャンが何かについて間違っている場合、BEGIN.md でそのように述べ、修正してください。グラフがデッドと呼び、実際には HTTP やキューを介して到達されるファイルは、記録できる最も有用なものの一つです。なぜなら、他の誰もそれをもう見つけられないからです。そのようなエントリポイントを .begin/surfaces.txt に宣言してください(パスごとに1行、オプションで path<TAB>kind)。次の実行はそれらをサーフェスとして扱います。
5. BEGIN.md を書く
references/BEGIN-template.md を使用し、最初に references/EXAMPLE-BEGIN.md を読んで調整してください — それは実際のものであり、モックアップではありません。順序に従った構造:
- このシステムが何をするか、1段落で — コードの用語ではなく、ユーザーの用語で。
- 基本メカニズム — 第一原理。核となる変換は何か?残りを明白にする1つのアイデアは何か?それがなければ何が壊れるか?
- サーフェス → エンジン —
scan.mdのパスからのテーブル、各行は検証済み。プロセスやネットワーク境界を横断する行がない場合、そのことを明示的に述べてください:分割言語リポジトリでは、実際の継ぎ目は通常、どのインポートグラフも見ることができない HTTP またはキュー呼び出しです。 - 複雑な部分、ランク付け — 最初に発見、最後に測定。各エントリには、その測定行にまだない
file:lineを引用するトラップが必要です。それを与えられないエントリは実際に読んでいないものです:削除してください。 - 決定とその理由 — それぞれを PR またはコミットにリンクし、PR 本文からの推論とともに。これがドキュメントをコードツアーではなく知識グラフにするものです。
- どこで中断したか — または、所有していないリポジトリでは、誰がこれを所有し、どこで成長しているか:アクティブな作者、最新のオープンPRが何を追加しているか、どれを最初に読むべきか。
- マシンレイヤーがここで見えなかったもの — そして未解決の質問、最も負荷のかかる単一の仮定を含む。これを決して省略しないでください。
また、実行と検証方法(recon.md が package.json から抽出したスクリプト)と、このリポジトリが過負荷に使用する単語の用語集を記録してください。どちらも新参者が最初に必要とするものであり、すべてのコードツアーが忘れるものです。
[[wiki-style]] アンカーで相互リンクしてください。各セクションにスタンプを押してください:
<!-- begin:section id="ingestion" sha="0055f01" files="src/adapter.ts,src/identity.ts" -->
sha = セクションを導出した時点の git rev-parse --short HEAD(後に BEGIN.md を追加するコミットではありません)。files = セクションの主張が基づいているファイル;src/engine/** のようなグロブも機能します。files= がない、または存在しないパスを指定する files= を持つセクションは、決して古くなることはなく、検証不可能として報告されます — これこそがこのスキルが防ごうとする失敗なので、パスを正しく設定してください。
6. 生きたものにする
bash $S/install-hook.sh # post-commit; --pre-push で他のトリガーも
フックはスキャンを再実行し、何セクションが古くなったかを示す1行の通知を出力し、詳細を .begin/stale.md に出力します。core.hooksPath(husky)と git worktrees を尊重し、既存のフックに追加してもそれを壊さず、非シェルフックへの追加を拒否し、追跡ファイルを決して触りません。--uninstall で削除します。これは自身のブロックのみを取り除きます。
/begin update
ユーザーがすでに BEGIN.md があるリポジトリに戻ってきたとき:
node $S/refresh.mjs && cat .begin/stale.md
古くなったセクションのみを書き換え、recon.sh を再実行してセクション6をリフレッシュし、書き換えられた各セクションを新しい HEAD sha で再スタンプします。現在のセクションはバイト単位で同一のままにします — すべてを書き換える更新は、読者の何が変わったかの感覚と git 履歴の有用性の両方を破壊します。
BEGIN.md がまだない場合、/begin update は単なる /begin です:1つを書いてください。
報告
短い1段落:基本メカニズム、最も重要な1〜2つのファイルとその理由、ユーザーが中断した場所、そして検証できなかった単一のもの。詳細は BEGIN.md にあり、返信にはありません。
チェックしなかったことを述べて終了します。完全なカバレッジを主張する begin パスは嘘をついています。
既知の制限 — これらを述べ、ごまかさないこと
- インポートグラフは静的です。リテラルな
import('./x')は解決されます(そして遅延としてマークされます)。計算されたimport(expr)、DIコンテナ、または文字列でキー付けされたレジストリはエッジを生成しないため、そのようなファイルは負荷がかかっているのに到達不能に見える可能性があります。分割言語リポジトリでは、フロントエンド↔バックエンドの継ぎ目は HTTP または WebSocket 呼び出しであり、設計上不可視です。スキャンは到達不能ファイルを正確にフラグするため、人間が判断できます。 - 完全な JS/TS および Python 解決 — tsconfig
paths(ルートだけでなくツリー内のすべての config)、extends、プロジェクトreferences、NodeNext./x.js→x.ts、および推測されたルートに対する Python 絶対、相対、サブモジュールインポート(CPythonastグラウンドトゥルースに対して約98%の再現率と適合率で測定)。Go、Rust、Ruby、Java、Kotlin、Swift、PHP、C#、C/C++ はエッジをまったく提供しません。 そのようなリポジトリでは、すべてのファイルが最小限の重要性を示し、「到達不能」に見えます;スキャンは警告し、空のグラフを発見として報告するのではなく、その警告を繰り返さなければなりません。 complexityProxyは言語ごとに決定ポイントをカウントします。コードからコメントと単一行文字列を削除した状態で。マークアップとスキーマファイルは設計上0点です;ベンダー化、最小化、生成されたファイルは検出され、別々にランク付けされます。複数行テンプレートリテラルはまだカウントされるため、テンプレートが多いファイルは少しホットに見えます。- Churn は
--sinceによって制限され、シャローまたは新しいクローンにはありません — スキャンはそれを大声で言います。2年前に一度書き換えられたファイルはまだほぼ0点で、リポジトリ内で最も重要なファイルである可能性があります。
テスト
node $S/test-scan.mjs # グラフ、サイクル、サーフェス、到達可能性、Python
node $S/test-scan.mjs --mutate pyDotDot # ...そしてアサーションが赤くなることを証明
bash $S/test-living.sh # 陳腐化、フック、ツリーのクリーン状態
node $S/redact.mjs --self-test # シークレットがキャッチされ、クリーンテキストが無傷であること
すべてのアサーションは、そのバグが実在し、かつて出荷されたから存在します。ミューテーション:alias、jsToTs、valueCycle、typeCycle、pyAbsolute、pyDotDot — それぞれが自身のアサーションを赤く変えなければならず、CI はそうでなければ失敗します。