# wisegit
[](https://www.npmjs.com/package/@sandip124/wisegit)
[](https://registry.modelcontextprotocol.io/v0.1/servers?search=wisegit)
[](https://opensource.org/licenses/MIT)
> *"Don't take a fence down until you know the reason it was put up."*
> — G.K. Chesterton
**wisegit** is a local MCP server that extracts decision intent from git history and protects intentional code from AI modification.
When Claude Code (or any MCP-compatible agent) is about to edit a file, wisegit injects a **decision manifest** showing which functions are frozen, stable, or open — so the AI respects what was intentional, not just what compiles.
**Zero config. Zero external services. Everything local.**
### Install
```bash
# Set up any repo (one command)
npx @sandip124/wisegit setup
# Or add as MCP server globally
claude mcp add wisegit -- npx @sandip124/wisegit serve
```
### Published on
- **npm:** [@sandip124/wisegit](https://www.npmjs.com/package/@sandip124/wisegit)
- **MCP Registry:** [io.github.Sandip124/wisegit](https://registry.modelcontextprotocol.io/v0.1/servers?search=wisegit)
- **GitHub:** [Sandip124/wisegit](https://github.com/Sandip124/wisegit)
## The Problem
LLMs have no concept of **intentional code**. A manually-tested fix and a broken stub look identical — both are just text. Real scenario:
1. You fix a Stripe race condition with `sleep(350)` — manually tested, committed.
2. Next session: "find bugs." Claude removes `sleep(350)` — looks like dead code.
3. Production incident.
**Root cause:** git history contains proof of intention. Nobody extracts it.
## How It Works
```
Git History → Tree-sitter AST → Intent Extraction → SQLite Event Store → MCP Tools
```
1. **Indexes your git history** — walks every commit, parses diffs at the AST level (function boundaries, not line counts)
2. **Classifies commits** — STRUCTURED (`fix:`, `feat:`), DESCRIPTIVE (plain sentences), or NOISE (`wip`, `x`)
3. **Extracts intent** — rule-based for structured/descriptive commits, LLM for noise (Phase 2)
4. **Computes freeze scores** — 0–1 per function, derived from protection signals (git, issue, code structure, test, structural, Naur, Aranda) minus adaptive obsolescence penalty (8 signals, entropy-calibrated). Age uses Weibull survival [18]; expertise uses DOE model [19]
5. **Serves decision manifests via MCP** — Claude Code calls `get_file_decisions` before editing any file
## What the AI Sees
```
[DECISION MANIFEST: payment.service.cs]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FROZEN: ProcessPayment() [score: 0.89] [Recovery: L1]
- sleep(350) → Stripe race condition. Won't Fix.
HIGH — commit a3f19b2
STABLE: ValidateOrder() [score: 0.55] [Recovery: L2]
- Fixed null reference on Safari iOS WebKit.
MEDIUM — commit 7c14694
OPEN: FormatReceipt() [score: 0.12] [Recovery: L3]
← safe to modify
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
- **FROZEN** (score >= 0.80): Do not modify without explicit user approval
- **STABLE** (score 0.50-0.79): Proceed with caution, review intent first
- **OPEN** (score < 0.50): Safe to modify freely
## Quick Start
### Prerequisites
- Node.js >= 20
That's it. No Docker, no PostgreSQL, no external services.
### 1. Set Up a Repository (one command)
```bash
cd /path/to/your/repo
npx @sandip124/wisegit setup
```
This single command:
- Creates a local SQLite database at `~/.wisegit/wisegit.db`
- Indexes your entire git history (462 commits in ~13 seconds)
- Creates `.mcp.json` for Claude Code auto-discovery
- Creates `CLAUDE.md` rules that instruct AI to check before editing
- Adds `.mcp.json` to `.gitignore`
### 2. Enrich with Issue Context (optional)
```bash
# Fetch issue/PR details from GitHub/GitLab
GITHUB_TOKEN=ghp_... npx @sandip124/wisegit enrich
```
This fetches referenced issues (e.g., `#134` in commit messages), detects Won't Fix / By Design decisions, and boosts freeze scores for functions linked to those issues.
### 3. Done
Open the repo in Claude Code. It will automatically:
1. Start the wisegit MCP server (via `.mcp.json`)
2. Read the protection rules (via `CLAUDE.md`)
3. Call `get_file_decisions` before editing any file
## MCP Tools
| Tool | Description |
|------|-------------|
| `get_file_decisions` | Decision manifest for a file — freeze scores, intent history, recovery levels, override status |
| `get_freeze_score` | Score + signal breakdown for a specific function |
| `get_function_history` | Full chronological decision timeline for a function |
| `get_theory_gaps` | Functions with unrecoverable rationale (inactive authors, timeline gaps) |
| `get_branch_context` | Branch merge history — what was migrated and why |
| `search_decisions` | Search past decisions by keyword across the entire repo |
| `create_override` | Override a frozen function (user approves in Claude Code UI) |
| `extract_intent` | Extract intent for NOISE commits using the host LLM — no Ollama needed |
| `find_similar_functions` | Search for existing functions that solve a similar problem before writing new code |
| `predict_impact` | Predict what functions will break if a given function is modified |
| `get_codebase_conventions` | Extract coding conventions for a file's neighborhood |
**MCP Resource:** `wisegit://manifest/{filePath}` — decision manifest as auto-discoverable resource
**MCP Prompt:** `check_before_edit` — mandatory workflow prompt that returns the decision manifest before editing any file
### LLM Intent Extraction Strategy
wisegit uses a smart fallback chain for extracting intent from NOISE commits:
| Context | LLM Used | How |
|---------|----------|-----|
| **Inside Claude Code** | Host LLM (Claude) | MCP sampling — asks Claude to analyze the diff. Zero setup. |
| **CLI with Ollama** | Ollama (llama3) | `wisegit init --ollama` — uses local Ollama instance |
| **CLI without Ollama** | None | Rule-based extraction only, NOISE commits get no intent |
Inside Claude Code, call `extract_intent` to retroactively recover intent for NOISE commits — uses Claude itself, no Ollama installation needed.
## CLI Commands
```bash
wisegit setup [--path
] [--global] # One-command repo setup
wisegit init [--full-history] [--path ] # Index git history
wisegit enrich [--path ] # Fetch issue/PR context from GitHub/GitLab
wisegit audit # Show decision manifest
wisegit history [--file ] # Show decision timeline
wisegit recompute [--path ] # Recompute scores with PageRank + theory gaps
wisegit override --file --reason "..." # Override a frozen function
wisegit overrides # List active overrides
wisegit sync # Rebuild local cache from git + .wisegit/
wisegit config list # View team configuration
wisegit config set # Modify team policy
wisegit team-status # Team overview: enrichments, overrides, contributors
wisegit team-health # Theory health: healthy/fragile/critical functions
wisegit branch-capture # Capture branch context from last merge
wisegit branch-list # List all captured branch snapshots
wisegit branch-recover # Recover context from old merge commit
wisegit calibrate # Show adaptive obsolescence weights vs defaults
wisegit report [--output ] # Generate HTML report with scores + insights
wisegit serve # Start MCP server (stdio)
wisegit hook install|uninstall # Manage git hooks (post-commit + post-merge)
```
## Configure for Claude Code
### Option A: Per-repo (recommended)
Run `npx @sandip124/wisegit setup` in any repo. It creates `.mcp.json` automatically.
### Option B: Global registration
```bash
claude mcp add wisegit -- npx @sandip124/wisegit serve
```
### Option C: Manual `.mcp.json`
Create `.mcp.json` in your repo root:
```json
{
"wisegit": {
"command": "npx",
"args": ["@sandip124/wisegit", "serve"]
}
}
```
## Supported Languages
| Language | Extensions |
|----------|-----------|
| C# | `.cs` |
| TypeScript | `.ts`, `.tsx` |
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` |
| Python | `.py` |
| Go | `.go` |
| Rust | `.rs` |
More languages can be added via Tree-sitter grammar configs in `src/ast/languages/`.
## Issue Enrichment
A commit saying `fix: handle null token #134` points to an issue containing reproduction steps, root cause, and explicit decision rationale — everything the commit message never says.
```bash
# Fetch issue context from GitHub/GitLab
wisegit enrich --path /path/to/repo
# With auth (5000 req/hr instead of 60)
GITHUB_TOKEN=ghp_... wisegit enrich
```
**Supported platforms:** GitHub, GitLab (Azure DevOps, Jira, Bitbucket planned)
**Auth tokens:** `GITHUB_TOKEN` / `GH_TOKEN` for GitHub, `GITLAB_TOKEN` for GitLab. Never stored by wisegit.
### Issue-derived freeze signals
| Signal | Freeze Boost | When |
|--------|-------------|------|
| Won't Fix / By Design | **+0.35** | Issue closed as `not_planned`, or has `wontfix`/`by-design` label, or comment says "intentional" |
| Reproduction steps | +0.15 | Issue body contains "steps to reproduce" |
| Platform-specific label | +0.10 | Issue labeled `ios`, `safari`, `windows`, etc. |
| Issue unreachable | +0.10 | Issue ref exists but API returned 404 — absent context = protect more |
| PR review comments | +0.15 | Linked PR had reviewer discussion |
## Freeze Score Signals
The freeze score is **never stored directly** — it's derived by replaying the event stream for each function. Signal categories:
| Category | Weight | Source |
|----------|--------|--------|
| Git History | 0.20 | Reverts, verified keywords, incident refs, contributor count, Weibull age [18] |
| Issue Enrichment | 0.20 | Won't Fix/By Design, reproduction steps, platform labels |
| Code Structure | 0.15 | Inline comments, magic numbers, defensive patterns |
| Test Signals | 0.15 | Dedicated tests, edge case labels, co-committed tests |
| Structural Importance | 0.15 | Call count (PageRank), public API, DOE expertise model [19] |
| Naur Theory | 0.10 | Global patterns, intentional contradictions, removal cost |
| Aranda Signals | 0.05 | Forgotten patterns, timeline gaps, broken issue links |
| Obsolescence (8 signals) | adaptive | Dead code, stale subgraph, migration leftover, obsolete deps, superseded, SAAD, change burst absence, co-change divergence |
**Freeze score formula:**
```
freeze_score = base_score x (1 - obsolescence_penalty)
```
Protection signals produce the base score (weighted average of present signal categories, not additive sum); obsolescence signals produce the penalty.
Obsolescence weights are **adaptive** — calibrated per-repository using Shannon entropy
and Bayesian feedback. Falls back to hardcoded defaults when < 20 functions have signals.
Age signal uses **Weibull survival model** [18] (k=0.7, lambda=2.4y); contributor expertise uses **DOE model** [19] (4 variables: contribution share, recency, duration, frequency).
Academic grounding: 24 published papers. See [REFERENCE.md](REFERENCE.md) for full citations.
## Cross-Repo Validation
Tested on 3 real-world open-source codebases:
| Repo | Commits | Functions | FROZEN | STABLE | Max Score |
|------|---------|-----------|--------|--------|-----------|
| pallets/flask | 5,565 | 4,355 | 72 | 2,272 | 0.927 |
| expressjs/express | 6,382 | 409 | 1 | 247 | 0.811 |
| zeeguu/api | 4,515 | 3,216 | 1 | 12 | 0.583 |
Flask's core APIs (`__init__`, `run`, `wsgi_app`, `url_for`) correctly scored FROZEN (0.87+). Express routing primitives (`paramCallback`, `Route`, `Router`) correctly scored FROZEN/STABLE. Scores adapt to each codebase's history rather than producing uniform distributions.
See [REFERENCE.md](REFERENCE.md) for detailed validation findings and implementation changes.
## Legacy Codebase Evolution
wisegit is designed for codebases that have accumulated years of intentional decisions. The freeze score doesn't mean "never change this" — it means "understand these decisions before you change it."
**Progressive migration, not shiny rewrites.** Per Távora [12]: the business rules in messy code are *correct and valuable*. The technical debt is in the structure, not the decisions. wisegit protects the decisions while you fix the structure.
| Stage | How wisegit helps |
|-------|-------------------|
| **Understand AS-IS** | `wisegit audit` shows what's intentional. `wisegit team-health` shows where institutional knowledge is lost. |
| **Protect during refactoring** | Manifests tell developers + AI which behaviors were deliberately chosen |
| **Record rationale** | Override reasons persist in `.wisegit/overrides.jsonl` — not buried in Slack |
| **Preserve migration context** | Branch snapshots record what was replaced and what should never return |
| **Track cross-boundary deps** | Co-change signals detect coupling between legacy and replacement code |
See [REFERENCE.md](REFERENCE.md) for the full legacy evolution section with academic grounding (24 published papers).
## Team Support
wisegit uses a three-layer architecture — no separate "team mode" needed:
| Layer | What | Shared? |
|-------|------|---------|
| **Deterministic base** | Commit classification, rule-based intent, git signals | Via git (automatic) |
| **Team knowledge** | Enrichments, overrides, intents, branch contexts | Via `.wisegit/` (git-tracked) |
| **Local cache** | SQLite at `~/.wisegit/wisegit.db` | Never (derived) |
```
.wisegit/ # Tracked by git — shared with team
├── config.json # Team policy (thresholds, AI authors)
├── enrichments.jsonl # Issue enrichment cache
├── overrides.jsonl # Override audit trail
└── branch-contexts.jsonl # Branch merge snapshots
```
**JSONL format** — one JSON object per line. Concurrent appends produce no git merge conflicts.
After a teammate pushes `.wisegit/` changes, run `wisegit sync` to import them into your local cache.
See [TEAM-ROADMAP.md](TEAM-ROADMAP.md) for the full team architecture design.
## Architecture
```
┌─────────────────────────────────────────────────┐
│ Claude Code / MCP Client │
│ ┌───────────────────────────────────────────┐ │
│ │ 1. Reads CLAUDE.md protection rules │ │
│ │ 2. Calls get_file_decisions before edits │ │
│ │ 3. Respects FROZEN / STABLE / OPEN │ │
│ └───────────────────────────────────────────┘ │
└─────────────────┬───────────────────────────────┘
│ MCP (stdio)
┌─────────────────▼───────────────────────────────┐
│ wisegit MCP Server │
│ ┌──────────┐ ┌──────────┐ ┌─────────────────┐ │
│ │get_file_ │ │get_freeze│ │search_decisions │ │
│ │decisions │ │_score │ │ │ │
│ └────┬─────┘ └────┬─────┘ └───────┬─────────┘ │
└───────┼─────────────┼───────────────┼───────────┘
│ │ │
┌───────▼─────────────▼───────────────▼───────────┐
│ SQLite (~/.wisegit/wisegit.db) │
│ ┌──────────────┐ ┌────────────┐ ┌───────────┐ │
│ │decision_events│ │freeze_scores│ │issue_ │ │
│ │(append-only) │ │(derived) │ │enrichments│ │
│ └──────────────┘ └────────────┘ └─────┬─────┘ │
└────────────────────────────────────────┼────────┘
│
┌────────────────────────────────────────▼────────┐
│ Issue Enrichment (wisegit enrich) │
│ ┌─────────┐ ┌─────────┐ ┌──────────────────┐ │
│ │ GitHub │ │ GitLab │ │ Jira (planned) │ │
│ │ REST API│ │ REST API│ │ │ │
│ └─────────┘ └─────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────┘
```
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `WISEGIT_DB_PATH` | `~/.wisegit/wisegit.db` | SQLite database path |
| `GITHUB_TOKEN` / `GH_TOKEN` | — | GitHub API token (5000 req/hr vs 60 unauthenticated) |
| `GITLAB_TOKEN` | — | GitLab API token for issue enrichment |
| `OLLAMA_URL` | `http://localhost:11434` | Ollama server URL (Phase 2) |
| `OLLAMA_CHAT_MODEL` | `llama3` | Model for intent extraction (Phase 2) |
| `OLLAMA_EMBED_MODEL` | `nomic-embed-text` | Model for embeddings (Phase 2) |
## Security
- **Everything runs locally** — only issue enrichment makes outbound API calls (opt-in via `wisegit enrich`)
- **Append-only event store** — decisions are never deleted, only added
- **SQLite database** stored at `~/.wisegit/wisegit.db` — no network exposure
- MCP tool inputs validated with strict Zod schemas (path traversal protection, length limits)
- Error messages sanitized before returning to MCP clients
- File writes check for symlinks before writing
- Config files parsed with allowlisted keys only (no prototype pollution)
## Roadmap
- [x] **Phase 1** — Event store, AST chunking, commit classification, intent extraction, MCP server, CLI
- [x] **Phase 1.5** — Issue enrichment (GitHub, GitLab) with Won't Fix/By Design detection, freeze boost signals
- [x] **Phase 2** — Full freeze score: call graph + PageRank, theory gap detection (Naur death, forgotten patterns), co-change signals, Aranda signals, Ollama client, Go + Rust support
- [x] **Phase 4** — Override system (mandatory reason, time-boxed expiry, audit trail), branch context preservation (post-merge hook, snapshot storage, recovery)
- [x] **Phase A** — Shared team knowledge layer: `.wisegit/` directory with JSONL files for enrichments, overrides, branch contexts, and team config
- [x] **Phase B** — Team-aware manifests: theory holder tracking, risk levels (healthy/fragile/critical), team status + health commands
- [x] **Phase C** — AI-era adaptations: commit origin detection (HUMAN/AI_REVIEWED/AI_UNREVIEWED), origin-weighted freeze scores
- [x] **Phase D** — Override approval workflow, team health metrics
- [x] **Phase E** — Adaptive obsolescence calibration: 8 obsolescence signals, entropy-calibrated weights, Bayesian feedback, `wisegit calibrate` CLI
## License
MIT