cgis_find_orphans
Identify orphan classes that survive only via re-exports, using construction, inheritance, and references to flag dead-code candidates for deletion.
Instructions
Classes nothing in production builds, extends or names — dead-code candidates.
Finds classes that no test, type checker or linter flags, because each is
still imported somewhere: a package re-export keeps a class importable long
after its last real caller is gone. On one mid-sized backend this reported
43 of 1 789 classes, and the hand-written equivalent's findings were all
real and all deleted.
Two filters decide the answer. **Tests are not users** — a class built only
by its own test is exactly the shape being hunted. **A re-export is not a
use** — ``IMPORTS_SYMBOL`` does not count, or nothing is ever reported. What
counts is construction (``CALLS``), inheritance (``EXTENDS``) and being named
(``REFERENCES`` — an annotation, or a class handed to a framework); the last
keeps abstract ports and Protocols off the list.
``prefix`` narrows to one package on a dot boundary. ``include_tests`` counts
test code as a user, turning the report into "unreachable from anywhere".
Machine-generated classes are **hidden by default**, and ``include_generated``
puts them back. The query is right about them — nothing constructs a
betterproto stub — but nobody hand-deletes one either, so they are noise
rather than a finding. Measured on owner-api at b7d02fe6, five of six
reported orphans were generated entities and the sixth a nested pydantic
``Config``: the unfiltered report had no actionable row in it (#432).
Returns JSON ``{orphans, considered, test_sources, generated_excluded}``;
each orphan carries ``fqn``/``file``/``line``. **A listing is a candidate for
deletion, not a proof** — a class named only inside a decorator (#429) or
arriving through a star import is invisible here, so the sweep errs towards
reporting a live class rather than hiding a dead one. ``test_sources: 0`` in a
repository that has tests means the graph predates the ``is_test`` column:
re-ingest. ``generated_excluded`` counts every generated class left out of
the population under the same ``prefix``, referenced or not — so ``0`` on a
repository with generated code means the same for ``is_generated``, which has
no backfill: the marker is in the file header, not in the database.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prefix | No | Only consider classes under this FQN prefix, cut on a dot boundary. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. | graph.db |
| include_tests | No | Count test code as a user, so the report means "unreachable from anywhere". | |
| include_generated | No | Include machine-generated classes, which are hidden by default. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |