omitnix · static codebase indexing

A map that tells the truth

Know what your codebase did not hide.

omitnix scans tracked source files and writes a repository-scoped JSON index of behaviour, authorization, and database access. Its defining feature is not a long list of findings: every discovered file must end in a named outcome, including the files that could not be read.

嘘をつかない目録

読めなかったファイルまで、数える。

omitnix は git が追跡しているソースを走査し、機能・認可・データベースアクセスをリポジトリ単位の JSON 索引に書き出します。特徴は所見の多さではありません。発見したファイルは 1 つ残らず、名前の付いた結末で終わることです。読めなかったファイルも含めて。

11language adapters言語アダプタ
3capability tiers能力の段
0.1.3current package version現在の版
367tests · 3 OS on CIテスト · CI は 3 OS

1. Completeness is an invariant, not a hope

1. 数が合うことは、願望ではなく不変条件

Many indexers show only what they successfully recognized. omitnix keeps the accounting visible: the discovery count must equal the sum of analyzed files, unresolved findings, files claimed but unreadable, and files no adapter claimed.

多くの索引生成器は、うまく認識できたものだけを見せます。omitnix は帳尻を画面に出し続けます。発見した数は、解析できた数・追えなかった数・担当すると言ったのに読めなかった数・どのアダプタも担当しなかった数の合計と、必ず一致しなければなりません。

The omitnix completeness invariant Discovered files flow through classification and become four counted outcomes. Discovered 80 files the input set Classify claim + read or explain why not Counted outcomes analyzed + unresolved + unknown + unclaimed nothing disappears between steps discovered = analyzed + unresolved + unknown + unclaimed
The invariant. If the equation does not hold, the run fails instead of presenting a deceptively tidy index.不変条件。 この式が成り立たなければ、実行は失敗します。見た目だけ整った索引を出すよりも、落ちるほうを選びます。
Why this matters: “Not shown” is not a finding. The result names the gap so a maintainer can decide whether to add a parser, configure a subject, or accept the boundary.
なぜ大事か: 「出ていない」は所見ではありません。結果のほうが空白に名前を付けるので、パーサを足すのか、対象を設定するのか、その境界を受け入れるのかを、読む側が決められます。

A repository-sized runリポジトリ 1 つぶん

58 analyzed / 80 discovered
2 unresolved · 0 unknown · 20 unclaimed

Measured on this repository on 2026-09-11.2026-09-11 に omitnix 自身のリポジトリで実測。

A workspace-sized runワークスペース 1 つぶん

34,274 analyzed / 37,281 files
1,824 unresolved · 97 unknown · 1,086 unclaimed

Measured across 55 repositories in 2 minutes 40 seconds.55 リポジトリを 2 分 40 秒で走査した実測値。

2. Unknown and unclaimed are different gaps

2. unknown と unclaimed は、別の種類の空白

Both categories remain in the count, but they tell the reader different things. unknown means an adapter claimed the file and then could not read it. unclaimed means no adapter claimed its extension, so omitnix never tried to interpret it.

どちらも数からは消えませんが、読む側に伝えていることが違います。unknown は、アダプタが担当すると言ったうえで読めなかったもの。unclaimed は、その拡張子を担当するアダプタがいないので、そもそも解釈を試みていないものです。

Unknown versus unclaimed One discovered file can be routed to a claimed but unreadable outcome or to an unclaimed extension outcome. Discovered one file extension in the input set unknown adapter claimed but could not read named one file at a time unclaimed no adapter claimed the extension fail_on_unknown may fail the run extension summary does not fail the run
Different owners, different next steps. Unknown files need a readable parser or a deliberate diagnosis. Unclaimed extensions need an adapter decision, not a claim that the file was inspected.持ち主が違えば、次の一手も違う。 unknown は、読めるパーサを入れるか、読めない理由をきちんと診断するかです。unclaimed で必要なのはアダプタを作るかどうかの判断であって、「調べました」と言い張ることではありません。

Why split them?なぜ分けるのか

An unclaimed extension gives the reader no file-level analysis to repair. Grouping it by extension keeps the report useful without pretending that a parser ran. An unknown file has a specific failed attempt and is therefore eligible for fail_on_unknown.

unclaimed には、直すべきファイル単位の解析結果がそもそもありません。拡張子ごとにまとめておけば、パーサが走ったふりをせずに報告としての役には立ちます。一方 unknown には「失敗した試み」が 1 件ずつ紐づいているので、fail_on_unknown で実行を落とす対象にできます。

3. A field has five honest states

3. 項目には、正直な 5 つの状態がある

File coverage and field coverage are not the same question. A file may be readable while a particular capability is outside the adapter's promise, deliberately finds nothing, or was never configured as a subject to search.

ファイルを読めたかと、項目を埋められたかは別の問いです。ファイルは読めていても、その項目がアダプタの約束の外だったり、探したうえで見つからなかったり、そもそも探す対象が設定されていなかったりします。

Five field states and two file outcomes Five field-level states sit above the file-level unknown and unclaimed outcomes. Field-level meaning value a finding exists none_ observed searched, found none out_of_ scope not this adapter's job not_ configured no subject was supplied empty shape carries meaning file-level coverage unknown claimed, but unreadable unclaimed no adapter claimed it
Shape is evidence. out_of_scope and not_configured have no value key; an empty list is different because it records a search that observed no matches.形そのものが証拠。 out_of_scopenot_configured には value キーがありません。空のリストはこれらとは別物で、「探したが一致が無かった」という記録です。

“None observed” is not “unused”

「見つからなかった」は「使われていない」ではない

If the adapter searched for configured authorization functions and found none, the report says exactly that. It does not infer that a capability is never used elsewhere.

設定された認可関数を探して見つからなかったなら、報告はそのとおりに書きます。「どこでも使われていない」とまでは推測しません。

“Out of scope” is not missing

「能力の外」は「欠落」ではない

A minimal adapter may not promise every field. That limitation is visible as a capability boundary instead of being rendered as an accidental blank.

最小構成のアダプタは、すべての項目を約束しているわけではありません。その制限は能力の境界として見える形で残り、うっかりの空欄として描かれることはありません。

4. Configuration changes the meaning of an empty result

4. 設定の有無で、空の結果の意味が変わる

Authorization and authentication are searches for named subjects. When a repository does not configure those names, omitnix must not claim that it searched and found nothing.

認可と認証は、名前を指定して探す処理です。その名前がリポジトリ側で設定されていないとき、omitnix は「探したが無かった」と言ってはいけません。

Configured versus not configured searches A configured repository can produce none observed, while an empty configuration produces not configured. Subjects configured authorization_functions search the files none_observed a real search found no call No subjects configured [ ] nothing to search for not_configured the report says it did not search
The empty-list trap. A search over an empty subject list is not evidence of absence. The explicit state prevents a blank configuration from masquerading as a clean security result.空リストの罠。 空の対象リストを探しても、無いことの証拠にはなりません。状態を明示することで、設定漏れが「セキュリティ上きれいな結果」に化けるのを防ぎます。

The measured failure this preventsこれで防いでいる、実際に出た誤り

On a repository with no configuration, 618 files once received authorization: none_observed. That wording implied 618 searches. The corrected result is not_configured, which tells the reader to configure subjects before interpreting authorization coverage.

設定が無いリポジトリで、618 ファイルに authorization: none_observed と付いたことがあります。この書き方は「618 回探した」と読めてしまいます。正しい結果は not_configured で、認可のカバレッジを読む前に対象を設定してください、と伝えます。

5. Adapters are small, discoverable, and explicit about ability

5. アダプタは小さく、置けば見つかり、能力を自分で宣言する

Language support lives in omitnix/adapters/. Adding an adapter is a three-part change: the adapter, its tree-sitter query, and a fixture. There is no central registration table in core to keep in sync.

言語対応は omitnix/adapters/ にあります。追加は 3 点セットです。アダプタ本体、その tree-sitter クエリ、そして fixture。本体側に同期を取り続ける登録表はありません。

Eleven adapters and three capability tiers Four adapter groups feed a core indexer, with three capability tiers above them. Capability tiers Full analysis Reverse lookup Minimal scan 11 adapter plug-ins PHP · Python · Go three languages TypeScript · JS · SQL three languages HTML · CSS · Rust three languages Shell · PowerShell plus Vue Core stays language-agnostic discover → analyze → render
Capability is part of the contract. A language adapter declares what it can analyze, so the gate does not reject a file for a field that the adapter never promised.能力も契約のうち。 言語アダプタは自分が解析できるものを宣言します。だから門は、そのアダプタが約束していない項目を理由にファイルを弾きません。

The repository contract3 点セットの役割分担

LayerWhat it contributesWhy it stays separate
AdapterFile claim, syntax walk, findingsLanguage rules remain local
QueryTree-sitter capture definitionsCore does not become a parser
FixtureSynthetic source and expected evidenceBehaviour stays reproducible
担うもの分けておく理由
アダプタ担当の宣言、構文の走査、所見言語ごとの事情をそこに閉じ込める
クエリtree-sitter の捕捉定義本体をパーサにしないため
fixture合成したソースと期待する証拠ふるまいを再現可能に保つため

6. Missing parser dependencies stay visible

6. パーサが入っていないことを、隠さない

When a file is claimed but its parser is not installed, omitnix does not swallow the import error or quietly omit the file. It records an unknown result with a reason and points to the one extra install that resolves that language's parser.

担当すると言ったファイルのパーサが入っていないとき、omitnix は import エラーを飲み込みませんし、そのファイルを黙って落としもしません。理由を添えて unknown として記録し、その言語のパーサを解決する 1 つのインストールを名指しします。

The missing dependency path A claimed file with a missing parser becomes an explained unknown and receives an installation hint. Python file adapter claims it Parser missing read attempt fails reason is retained unknown not hidden one named file Install hint pip install omitnix[python] one clear next step A failed import becomes actionable evidence.
Failure is part of the result. The dependency message names pip install "omitnix[python]" instead of leaving the maintainer to guess.失敗も結果の一部。 依存が足りないときのメッセージは pip install "omitnix[python]" と名指しします。読んだ人に推測させません。

What omitnix does not doやらないこと

It does not connect to a database, invent a SQL parser, or pretend to follow multiple indirect calls. It reads a schema snapshot when needed, delegates SQL syntax to sqlglot, and leaves unresolved edges named in the output.

データベースへは接続しません。SQL パーサを自作もしません。2 段以上の間接呼び出しを追えたふりもしません。必要ならスキーマの snapshot を読み、SQL の構文は sqlglot に任せ、追えなかった箇所は名前を付けて出力に残します。

7. Start with a JSON index

7. まず JSON の索引を 1 つ作る

Install the CLI, run it at a repository root, and inspect the generated evidence. The readable page is not a second source of facts: .omitnix/index.json is the index that downstream tools consume.

CLI を入れて、リポジトリの直下で実行し、出てきた証拠を見てください。読みやすい表示のほうは、事実の 2 つ目の出どころではありません。下流の道具が読むのは .omitnix/index.json です。

Install入れる

pip install omitnix

Run動かす

omitnix
omitnix --check
omitnix --gate

The first command writes the index. The latter two check freshness and newly added files.1 つ目が索引を書きます。あとの 2 つは、索引が古くなっていないかと、新しく追加されたファイルを確認します。

Repository-scoped evidence A repository produces its own index, keeping relative paths unambiguous across a workspace. Repository source files relative paths are local omitnix analyze + account commit and coverage metadata index.json evidence for tools one index per repository 1,832 workspace paths would collide without repository boundaries.
Keep scope explicit. Across 55 repositories, 1,832 files shared a bare relative path with another repository; the distinct relative-path count was 36,299.範囲を曖昧にしない。 55 リポジトリを横断すると、1,832 ファイルが他のリポジトリと同じ相対パスを持っていました。相対パスの異なり数は 36,299 です。

Learn moreもっと詳しく

Read the README for configuration, workspace scans, adapter contracts, and the JSON shape. Use this page for the mental model: account for every file, distinguish every boundary, and preserve the reason when analysis stops.

設定・ワークスペース走査・アダプタの契約・JSON の形は 日本語の README にあります(英語版)。このページは考え方のほうです。全部のファイルの帳尻を合わせる、境界を区別する、解析が止まったら理由を残す。