解析忠実度
2 つの解析ティアは、見た目のまったく同じ出力を生みます。それは罠なので、すべてのアダプタは自分の提供できるものを宣言し、ハンドブックはそれを開示します。
問題
Handbooks は 18 の言語を、2 つのエンジンで解析します:
- full ティア — 言語ごとの手書きアダプタ。型駆動の呼び出し解決、継承メンバー、属性ごとの 状態追跡、ステートメントスパンを備えます。
- generic ティア — 言語ごとの宣言的スペックを持つ、1 つの設定駆動エンジン。ファイルと 関数のインベントリは正確ですが、呼び出し関係はベストエフォートです。
どちらも同じ中間表現を生成します。ノードとエッジを眺めるだけでは、下流の何者にも両者を 区別できません。
それこそが罠です。読者は — そしてとりわけエージェントは — generic ティアの呼び出しエッジを Python 級の事実として受け取り、その前提で推論してしまうでしょう。
解決策: 宣言し、記録し、開示する
1. すべてのアダプタは、提供できるものを宣言する
interface AdapterCapabilities {
tier: 'full' | 'generic';
callTypes: readonly CallType[]; // which edge kinds it can actually produce
selfAttrs: boolean; // can it track self/this attribute reads and writes?
statementSpans: boolean; // can it report statement spans (resync precision)?
}このフィールドは省略可能ではなく、必須です。アダプタは誰でも登録できますが、何も宣言 しない手作りのアダプタは、忠実度の主張を捏造してもらえる代わりに、単にグラフのメタデータ から外されます。
2. Phase 1 は、それを言語ごとに記録する
{
"metadata": {
"language": "multi",
"languages": {
"typescript": { "tier": "full", "selfAttrs": true, "statementSpans": true, "callTypes": ["..."] },
"kotlin": { "tier": "generic", "selfAttrs": false, "statementSpans": false, "callTypes": ["..."] }
}
}
}グラフごとではなく、言語ごとです — 複数言語のランではティアが混在し、単一の
language: "multi" ラベルではそれが完全に隠れてしまいます。
3. ハンドブックは、信頼が形成される場所でそれを述べる
generic ティアの言語が 1 つでも存在すると、概要のシステム文章の直下に 1 行が加わります:
解析忠実度 — Kotlin、Scala の呼び出し関係は generic(設定駆動)アナライザに由来します: ベストエフォートであり、不完全な場合があります。これらの言語のファイルインベントリと 構造は正確です。
そして、すべての言語が full ティアのときはどこにも現れないため、よくあるケースは
ノイズのないままです。同じ開示は HTML サイト、エージェントロケータ索引、llms-full.txt
にも現れます。
私の言語はどちらのティア?
full ティア: Python、TypeScript(および JavaScript)、Go、Rust、Java、C#、C/C++、 Ruby、PHP、Swift、Dart、Solidity、Shell。
generic ティア: Kotlin、Scala、Zig、Objective-C、OCaml。
拡張子と注意点は 言語サポート を参照してください。
「ベストエフォート」が実際に何を犠牲にするか
| full ティア | generic ティア | |
|---|---|---|
| ファイルのインベントリ | 正確 | 正確 |
| 関数とメソッドのインベントリ | 正確 | 正確 |
| 行範囲とシグネチャ | 正確 | 正確 |
| 名前による直接呼び出し | 正確 | おおむね |
self.method() / this.method() | 解決される | 多くの場合 |
既知の型経由の self.attr.method() | 解決される | 不可 |
型注釈経由の param.method() | 解決される | 不可 |
| 継承メンバー | 解決される | 不可 |
| 属性ごとの状態追跡 | あり | なし |
| ステートメントスパン(resync の精度) | あり | なし |
ルーティングの根拠にするもの — ファイルがどこにあるか、どの関数を含むか、それが何行目を 占めるか — は、どちらのティアでも正確です。 劣化するのは「関係」のグラフであり、影響を 受けるのはアドレスではなく、グルーピングの品質と共変更のヒントです。
2 つの正直な注意点
Swift。 同梱の文法は V8 ≥ 13 でプロセスを異常終了させます — Node 24 では 5 回中 5 回の
致命的クラッシュを計測、Node 21 では問題なし、そして 19 の文法の中でこれ 1 つだけです。
アダプタはそのようなランタイム上ではdiscovery の時点で拒否し、ラン全体を道連れにする
代わりに、対処法(node --liftoff-only)を名指しします。
Shell。 case 文を含むスクリプトはスキップされます。その文法が throw するからです —
外部スキャナが、固定された WASM リンカの提供しないシンボルを import しています。case は
どこにでもあるため、これは自明でないスクリプトの大半に当てはまります(nvm で計測:
全 6 ファイル、全 122 関数)。したがって、シェルのカバレッジは部分的なものとして扱って
ください。スキャンログが原因を名指しし、スキップされたスクリプトは reason: "unparsable" として
1 つずつ phase1/scan-coverage.json に記録されます。欠落は推測するものではなく、
列挙できるものです。
どちらもスキャン中にロガーを通じて報告されます。-v を付けて実行すると確認できます。
言語をティア上げする
generic ティアの言語はパーサーではなく、宣言的スペックです —
言語の追加 を参照してください。full ティアへの昇格
とは、LanguageAdapter を直接実装し、正直なケイパビリティを宣言することを意味します。
アダプタの契約が小さいのは意図的です。