Skip to main content

Gapmap scans a repository to find the "Gaps", the dangerous, load-bearing parts of a codebase that are highly complex but have zero human documentation. It then compiles those risks into machine-readable guardrails so that AI coding assistants (like Cursor) are physically blocked from breaking your architecture.

Project description

GapMap

Find the riskiest undocumented code in a Python repository, generate machine-readable Context Manifests for AI agents, and answer questions about the codebase with grounded, cited retrieval.

Component Path What it does
GapMap CLI gapmap/ Entity call graph, documentation-debt scoring, manifest generation
GapMap Shield gapmap/mcp_server.py MCP server exposing manifests to IDE agents
RAG pipeline gapmap/src/, main.py Semantic search and grounded Q&A over repo text
Dashboard dashboard/ Next.js UI over .gapmap/audit.json

Enterprise use case

When a senior engineer leaves, undocumented load-bearing code does not have to become an outage. GapMap turns departure into a risk-reduction pipeline: audit the blast radius, encode tacit knowledge into manifests, and gate AI-assisted edits through MCP.

flowchart LR
    subgraph S1["① Senior engineer departure"]
        direction TB
        D1["Primary author offboards"]
        D2["High-centrality legacy entity<br/>e.g. payment_router.py::route_payment"]
        D3["Undocumented · bus-factor = 1"]
        D1 --> D2 --> D3
    end

    subgraph S2["② GapMap ownership audit"]
        direction TB
        A1["gapmap audit · gapmap ownership"]
        A2["tree-sitter AST → entity call graph"]
        A3["git blame → churn · temporal risk"]
        A4["Risk score = callers × LOC × git factor"]
        A5["Isolates CRITICAL asset → .gapmap/audit.json"]
        A1 --> A2 & A3 --> A4 --> A5
    end

    subgraph S3["③ Automated handover"]
        direction TB
        H1["gapmap generate &lt;entity&gt;"]
        H2["Context manifest JSON"]
        H3["upstream_callers · source_hash<br/>ai_execution_invariants"]
        H1 --> H2 --> H3
    end

    subgraph S4["④ GapMap Shield (FastMCP)"]
        direction TB
        M1["Junior engineer + IDE agent<br/>attempts refactor"]
        M2["get_execution_invariants<br/>scan_workspace_risks"]
        M3["Invariants injected pre-edit<br/>implicit contracts enforced"]
        M4["Constrained change · no regression"]
        M1 --> M2 --> M3 --> M4
    end

    S1 ==> S2 ==> S3 ==> S4
ASCII version (plain-text viewers)
Senior engineer          GapMap CLI audit              Automated handover           MCP Shield (FastMCP)
departure                + ownership                                             
    │                         │                            │                         │
    ▼                         ▼                            ▼                         ▼
┌──────────────┐      ┌──────────────────┐        ┌─────────────────┐      ┌──────────────────────┐
│ Offboard     │      │ AST call graph   │        │ gapmap generate │      │ Agent edit request   │
│ High inbound │ ───► │ git blame/churn  │ ─────► │ .gapmap/        │ ───► │ get_execution_       │
│ callers      │      │ bus-factor flag  │        │ manifests/*.json│      │ invariants()         │
│ Undocumented │      │ CRITICAL entity  │        │ execution       │      │ → safety params      │
└──────────────┘      └──────────────────┘        │ invariants      │      │ → regression avoided │
                                                  └─────────────────┘      └──────────────────────┘

Outcome: knowledge loss contained · tacit contracts machine-readable · AI edits grounded in graph + git signals

Configure departed authors via GAPMAP_DEPARTED_CONTRIBUTORS or .gapmap.toml[ownership] (see Configuration) before running the audit.

Table of contents

Prerequisites

Requirement Needed for
Python 3.10+ All commands
Git (recommended) git blame risk signals, ownership, trend history
Node.js 18+ & npm gapmap dashboard only (not required for audit/CLI)
OPENAI_API_KEY (optional) LLM-polished invariants and Q&A (pip install "gapmap-ai[llm]")

GapMap analyzes Python repos only today. Point --repo at the root of the project you want to scan (where your .py files live).

Installation

Option A — PyPI or uvx (recommended for users)

No clone required. Installs the CLI only (dashboard and MCP server need Option B for development, or run MCP via python -m gapmap.mcp_server after install).

# Zero-install — runs in a temporary env (requires uv: https://docs.astral.sh/uv/)
uvx gapmap-ai audit --repo /path/to/your/project

# Or install permanently
pip install gapmap-ai
gapmap audit --repo /path/to/your/project

# Full features (vector search + LLM + MCP + tests)
pip install "gapmap-ai[all]"

Extras: pip install "gapmap-ai[vector]", "gapmap-ai[llm]", or "gapmap-ai[mcp]".

Option B — Clone and install (contributors / dashboard / MCP)

git clone https://github.com/Utkrisht12/GapMaP.git
cd GapMaP

python3 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

pip install -e ".[all]"

[all] installs the CLI, vector search (FAISS), LLM support, FastMCP, and pytest. For a minimal audit-only install:

pip install -e .

Option C — Install from Git without cloning (CLI only)

pip install "gapmap-ai[all] @ git+https://github.com/Utkrisht12/GapMaP.git"

The dashboard still requires a full clone (Option B) because gapmap dashboard runs the Next.js app from the dashboard/ directory in this repo.

Verify

gapmap --help
# or
gapmap-ai --help

Run on any Python repo

Replace /path/to/your/project with the repository you want to audit.

# 1. Scan structure and call-graph quality
gapmap parse --repo /path/to/your/project

# 2. Top undocumented risks (writes .gapmap/audit.json)
gapmap audit --repo /path/to/your/project

# 3. Explain why a specific entity is risky
gapmap ask route_payment "why is this risky?" --repo /path/to/your/project

# 4. Generate a context manifest for the top gap (or a named entity)
gapmap generate --repo /path/to/your/project

# 5. Optional — open the risk dashboard (requires Node.js + repo clone)
gapmap dashboard --repo /path/to/your/project
# → http://localhost:3000

Audit this repo after install:

gapmap audit --repo .
gapmap dashboard --repo .

GapMap works fully offline for audit, parse, generate, stale, ownership, and trend. Vector search and LLM polish need the optional extras ([vector], [llm]).

GapMap CLI

GapMap parses every Python file with tree-sitter, builds an entity-level call graph (NetworkX), scores each entity with weighted incoming callers × LOC × a temporal git factor, checks which risky entities are missing from docs and docstrings, and turns the result into audits, explanations, context manifests, and an HTML report.

All commands

Command Purpose
gapmap parse Files, LOC, imports, graph resolution breakdown
gapmap audit Top undocumented high-risk entities
gapmap ask Graph-grounded explanation for one entity
gapmap generate Generate context manifest(s) under .gapmap/manifests/
gapmap report Self-contained HTML report
gapmap dashboard Interactive risk UI (clone + Node.js)
gapmap stale Find manifests whose source has drifted
gapmap ownership Knowledge-debt ownership and bus-factor
gapmap trend Documentation coverage over time
gapmap autodoc Batch-generate manifests for critical hubs (CI / auto-PR)

Common flags: --repo PATH (default: .), --refresh (ignore .gapmap_cache).

Example session

export REPO=/path/to/your/project

gapmap parse --repo "$REPO"
gapmap audit --repo "$REPO" --top 15
gapmap ask payment_router.py "why is this risky?" --repo "$REPO"
gapmap generate route_payment --repo "$REPO"
gapmap report --repo "$REPO" -o gapmap-report.html

What makes the graph accurate

  • Import-aware call resolution. from auth import Handler resolves to the imported entity, not every same-named class. Edges carry confidence and resolution (symbol, qualified, same-file, import, ambiguous).
  • Smarter documentation detection. MCPClient matches "MCP client"; single-word names stay strict to avoid false positives.
  • Temporal risk from git history. Author churn and bus-factor signals from git blame amplify volatile or single-owner hotspots.

Context manifests

gapmap generate writes hybrid JSON Context Manifests to .gapmap/manifests/<entity_name>.json in the target repository (not inside the GapMap package). Files are overwritten in place so agents always read current ground truth.

Example: gapmap generate route_payment --repo /path/to/project creates .gapmap/manifests/route_payment.json.

Schema

{
  "metadata": {
    "entity": "payment_router.py::route_payment",
    "generated_date": "2026-06-18",
    "source_hash": "a1b2c3d4e5f6",
    "source_loc": 142
  },
  "risk_profile": {
    "score": 500,
    "rank_overall": 1,
    "rank_undocumented": 1,
    "risk_level": "CRITICAL",
    "git_metrics": {
      "primary_author": "alice",
      "days_since_last_edit": 12,
      "recent_commit_messages": ["fix routing edge case"]
    }
  },
  "systemic_role": {
    "upstream_callers": ["a.py::invoke"],
    "downstream_callees": ["auth.py::check"]
  },
  "ai_execution_invariants": "## Structural Constraints\n* ..."
}
  • Structured fields (metadata, risk_profile, systemic_role) are deterministic and machine-parseable.
  • ai_execution_invariants is a markdown string: execution constraints, implicit contracts, and safety rules for an AI coding assistant.
  • With [llm] and OPENAI_API_KEY, invariants are synthesized by GPT from source, callers, and git history. Offline, a deterministic template is used.

Manifests embed source_hash and source_loc so gapmap stale detects when code has drifted away from the registered invariants.

GapMap Shield (MCP)

GapMap Shield exposes context manifests to IDE agents over the Model Context Protocol (stdio). Install the MCP extra, then run:

pip install "gapmap-ai[mcp]"
python -m gapmap.mcp_server

Tools

Tool When to use
get_execution_invariants(repo_root, entity_name) Before modifying or refactoring an entity — returns risk level and ai_execution_invariants
scan_workspace_risks(repo_root) When orienting in a new repo — lists all HIGH and CRITICAL entities

Cursor / IDE config

{
  "mcpServers": {
    "gapmap-shield": {
      "command": "python",
      "args": ["-m", "gapmap.mcp_server"]
    }
  }
}

⚠️ Cursor integration note (spawn python ENOENT): Cursor runs local MCP servers in a detached shell context that often cannot resolve a bare "python" command. If you see a red dot or a connection failure, use the absolute path to your active Python interpreter (e.g. /Users/yourname/miniforge3/bin/python) in your Cursor MCP configuration command field instead of "python".

GapMap Shield also suppresses the FastMCP startup banner on stderr (show_banner=False) so Cursor does not treat banner output as a connection error.

Point agents at the target repo's repo_root when calling tools. Manifests must exist under {repo_root}/.gapmap/manifests/ (create them with gapmap generate first).

Documentation automation

export REPO=/path/to/your/project

# Batch-generate manifests for documentation gaps
gapmap generate --all-critical --repo "$REPO"
gapmap generate --top 10 --repo "$REPO"
gapmap generate --min-score 300 --repo "$REPO"

# Drift detection (exits non-zero in CI when stale manifests exist)
gapmap stale --repo "$REPO"
gapmap stale --fix --repo "$REPO"

gapmap ownership --repo "$REPO"
gapmap trend --repo "$REPO"
gapmap autodoc --regenerate-stale --repo "$REPO"

Risk dashboard

Requires Node.js, a clone of this repo, and an audit JSON file.

# From the GapMap repo root, after pip install -e ".[all]"
gapmap audit --repo /path/to/your/project
gapmap dashboard --repo /path/to/your/project --port 3000

Opens http://localhost:3000 with risk scores, call graph, coverage trends, stale manifests, ownership, and graph-quality metrics from .gapmap/audit.json.

UI-only (mock data, no audit):

cd dashboard
npm install    # first time only
NEXT_PUBLIC_GAPMAP_USE_MOCK=true npm run dev

See dashboard/README.md for component details.

Semantic search and Q&A

Separate from gapmap ask: main.py runs repo-wide semantic retrieval (not entity-specific). Requires [vector] extra and a source checkout (main.py is not shipped as a PyPI console command).

pip install -e ".[vector]"   # or .[all]

python main.py --repo /path/to/your/project -v
python main.py --repo /path/to/your/project --query "How does caching work?"
python main.py --repo /path/to/your/project --ask "How does caching work?"
python main.py --repo /path/to/your/project --interactive
python main.py --repo /path/to/your/project --save .cache/gapmap-index
gapmap ask main.py --query main.py --ask
Scope One entity Whole repo Whole repo
Output Risk explanation Raw chunks + scores Synthesized answer + citations
Context Call graph + risk + optional vectors Vectors only Vectors + synthesis

Without openai or an API key, synthesis falls back to a deterministic extractive engine (works offline).

pip install -e ".[llm]"
export OPENAI_API_KEY=sk-...
python main.py --repo . --ask "How does staleness detection work?"

Configuration

Copy .gapmap.toml.example to .gapmap.toml in the target repo you are auditing:

[policy]
critical_threshold = 500
auto_document = true
regenerate_when_stale = true

[docs]
output_dir = ".gapmap/manifests"
min_score = 100

[ownership]
departed_contributors = ["alice", "bob@corp.com"]

Optional dependencies

pip install "gapmap-ai[vector]"   # RAG
pip install "gapmap-ai[llm]"      # LLM invariants and Q&A
pip install "gapmap-ai[mcp]"      # GapMap Shield MCP server
pip install "gapmap-ai[all]"      # full install
pip install -e ".[all]"           # from source (contributors)
Extra Enables
vector RAG indexing and search (sentence-transformers, faiss-cpu)
llm LLM-backed execution invariants and Q&A (openai)
mcp GapMap Shield MCP server (fastmcp)
dev Test suite (pytest)
all Everything above

CI workflows

Workflow Purpose Trigger
gapmap-sentinel.yml Fail on new critical undocumented hubs Manual only
gapmap-autodoc.yml Open a PR with generated manifests Manual only

Both use workflow_dispatch while the project is under construction. Uncomment push / pull_request in each file when ready.

gapmap audit --repo . --json-export report.json

Writes CI export JSON; .gapmap/audit.json is always updated for the dashboard.

Development

git clone https://github.com/Utkrisht12/GapMaP.git && cd GapMaP
pip install -e ".[all]"
pytest

Tests use a deterministic fake encoder — no network or model downloads.

Project layout

.
├── gapmap/                 CLI, analysis engine, MCP server
│   └── mcp_server.py       GapMap Shield (FastMCP)
├── dashboard/              Next.js risk dashboard
├── docs/                   ARCHITECTURE.md
├── tests/                  pytest suite
├── main.py                 RAG pipeline entry point (source checkout only)
└── .gapmap.toml.example    policy template

Target repos receive generated artifacts under .gapmap/:

/path/to/your/project/
└── .gapmap/
    ├── audit.json          machine-readable audit (from `gapmap audit`)
    ├── history.jsonl       coverage trend (from `gapmap trend`)
    └── manifests/          context manifests (from `gapmap generate`)
        └── route_payment.json

Publishing to PyPI

Package name on PyPI: gapmap-ai (console commands: gapmap and gapmap-ai). Published at https://pypi.org/project/gapmap-ai/

pip install -U packaging build twine
python -m build

# Production (username is always __token__)
export TWINE_USERNAME=__token__
export TWINE_PASSWORD='pypi-...'   # your API token — never commit this
twine upload dist/*

Bump version in pyproject.toml before each upload — PyPI does not allow overwriting an existing release.

After publish, users can run:

uvx gapmap-ai audit --repo /path/to/your/project
pip install gapmap-ai && gapmap audit --repo /path/to/your/project

Push to GitHub does not update PyPI automatically; publish is manual (or add a GitHub Actions release workflow later).

Architecture

Module-level diagrams, data flow, and CI details: docs/ARCHITECTURE.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gapmap_ai-0.2.1.tar.gz (109.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gapmap_ai-0.2.1-py3-none-any.whl (95.5 kB view details)

Uploaded Python 3

File details

Details for the file gapmap_ai-0.2.1.tar.gz.

File metadata

  • Download URL: gapmap_ai-0.2.1.tar.gz
  • Upload date:
  • Size: 109.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.14

File hashes

Hashes for gapmap_ai-0.2.1.tar.gz
Algorithm Hash digest
SHA256 20fc2f83376d698dbb505860835f868f9a76ce00c8db87a751e2ea19e4a4be29
MD5 61a874225157b9cf76a2fc4d92f426bd
BLAKE2b-256 a9ff5fb3d0c8704c15075bf274d127a4646b0ae5075fd4164d0f3582ede6380a

See more details on using hashes here.

File details

Details for the file gapmap_ai-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: gapmap_ai-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 95.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.14

File hashes

Hashes for gapmap_ai-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bf30ce735186d4dd7fa24bc3e5af961a77895edc03ad60d259a3ab3dadac90fe
MD5 ad15fea5635802e0eccbfa82ab8e5562
BLAKE2b-256 12dcf352ed5be599d65fc85c4cf52f45925160912003a80c7d83f953d14ba340

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page