Skip to main content

Deterministic code context from symbol graphs — not vector search

Project description

Stubborn

Deterministic code context from symbol graphs — not vector search.

Status: Beta (Java-first) — release 0.9.0b3 · BETA.md · CHANGELOG

Stubborn compiles a live codebase into type-safe, privacy-preserving stub text for LLMs and agents. It uses SCIP symbol indexes and dependency graphs instead of vector chunking, so context is stubborn: exact, reproducible, and stripped of method bodies.

Independent project under stubborn-ai. Works with any SCIP-indexed codebase — Spring, monorepos, agents, and CI.

Why Stubborn?

Problem Vector RAG Stubborn
Type hallucinations Common Stub signatures from symbol graph
Token cost Full files / arbitrary chunks Pruned declaration stubs (~80–90% savings target)
Privacy May leak business logic No method bodies by design
Reproducibility Embedding drift Same SCIP → same context

Stub = skeleton declarations (like header files).
Stubborn = refuses to guess — only ships what the symbol graph proves.

Use cases

  • Copilot / Cursor agentsgetContext(class) before code generation
  • Large-repo onboarding — dependency skeleton for one target symbol
  • PR semantic auditdiff two SCIP indexes after a refactor
  • Refactor / legacy modernization — scoped context for large Java estates (see examples/migration-bridge)

Requirements

  • Python 3.11+ (or use Docker)
  • A SCIP index for your project (e.g. scip-java)

Docker quick start

docker compose build
docker compose run --rm e2e    # demo-spring E2E
docker compose run --rm petclinic-e2e  # spring-petclinic scale-up
docker compose run --rm cli --help

See docker/README.md.

Installation

PyPI: stubborn-stub · CLI: stubborn (alias: stub)

pip install stubborn-stub[mcp]

From source (development):

git clone https://github.com/stubborn-ai/stubborn.git
cd stubborn
pip install -e ".[dev]"

Try in 30 seconds (no Java required)

Uses the bundled minimal SCIP fixture — no JDK, Maven, or scip-java needed:

pip install stubborn-stub
stubborn index --scip examples/fixtures/minimal.scip --out /tmp/symbols.db
stubborn info /tmp/symbols.db
stubborn context /tmp/symbols.db \
  --target "semanticdb maven com/example/OrderService#" \
  --out /tmp/order-service.stub.java

Quick start

Full E2E with a modern Spring Boot demo: see examples/demo-spring.

1. Index symbols

# Binary SCIP from scip-java (recommended)
stubborn index --scip index.scip --out ./metadata/symbols.db

# Or use the bundled fixture while bootstrapping
stubborn index \
  --scip examples/fixtures/minimal.scip \
  --out ./metadata/symbols.db

2. Inspect

stubborn info ./metadata/symbols.db

3. Get LLM context for a target symbol

stubborn context ./metadata/symbols.db \
  --target "semanticdb maven com/example/OrderService#process()." \
  --out ./context/order-service.stub.java

# Compact cross-language format (~fewer tokens):
stubborn context ./metadata/symbols.db \
  --target "semanticdb maven com/example/OrderService#process()." \
  --format stubborn-dsl \
  --out ./context/order-service.stubborn-dsl

See docs/STUBBORN-DSL.md for the compact cross-language format.

Tune output granularity: --member-signatures off|target|neighbors|all, --javadoc off|summary|full (guide).

Or use the short CLI alias: stub.

4. Reconcile before/after (CI-friendly)

stubborn diff ./metadata/before.db ./metadata/after.db
# exit 1 if symbols are missing

5. MCP server (Cursor / agents)

pip install stubborn-stub[mcp]
export STUBBORN_DB=./metadata/symbols.db
stubborn mcp

Tools: get_context, list_symbols, metrics. See docs/MCP.md for Cursor configuration.

CLI

Command Description
init-db Create empty SQLite symbol graph
index Ingest SCIP (.scip, .scip.ndjson, or .json fixture)
info Index run summary
context Prune graph → emit LLM context (--format java-stub | stubborn-dsl)
metrics Compression KPI: stub vs full Java sources
mcp Run MCP server (stdio) for agents
diff Symbol set reconcile (missing/extra)

Architecture

[Source code] → scip-java / scip-clang / … → index.scip
       ↓
  stubborn index → SQLite symbol graph
       ↓
  stubborn context → stub text (java-stub or stubborn-dsl)
       ↓
  LLM / Agent / CI

SQLite schema: src/stubborn/store/schema/v1.sql

Roadmap

Version Focus
0.1 SQLite schema, JSON fixture ingest, Java stub weaver, CLI shell
0.2 Binary .scip protobuf ingest, .scip.ndjson, scip-java compatible
0.3 Token budget enforcement, metrics KPI, weaver quality, Docker CI
0.4 MCP server (get_context, list_symbols, metrics)
0.5 Type-neighbor pruning, PR symbol-diff Action, context guard
0.6 spring-petclinic scale-up E2E (~90% savings)
0.7 Stubborn-DSL weaver (--format stubborn-dsl)
0.8 Java-first beta track — BETA.md, demo-spring cases
0.9 Method signatures, STUBBORN-DSL-GUIDE
0.9.0b3 (now) Standalone cleanup — rename debt removed, ruff CI, CLI smoke tests
0.9.0b2 Java-first Beta — classifier + weave granularity switches
1.0 Multi-language E2E, stable API

Documentation

Doc Description
docs/README.md Documentation index
docs/STUBBORN-DSL.md Stubborn-DSL grammar
docs/STUBBORN-DSL-GUIDE.md java-stub vs stubborn-dsl decision guide
docs/STUBBORN-DSL-LLM.txt LLM system-prompt snippet
docs/MCP.md Cursor / agent integration
docs/SCIP-INGEST.md SCIP ingest
examples/README.md E2E examples

Optional ecosystem integrations

Stubborn is standalone. Some teams also use it alongside the anchor-migration program:

Repo Role
stubborn (this repo) LLM context compiler
migration-hub Optional program docs — integration guide
java-ast-ssot Full Java AST SSOT (complementary)
db-metadata Database schema SSOT (complementary)

See docs/POSITIONING.md.

Development

pip install -e ".[dev]"
pytest -v
ruff check src tests
ruff format --check src tests

MCP server:

pip install -e ".[mcp]"
stubborn mcp

License

MIT — see LICENSE.

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

stubborn_stub-0.9.0b3.tar.gz (35.7 kB view details)

Uploaded Source

Built Distribution

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

stubborn_stub-0.9.0b3-py3-none-any.whl (42.6 kB view details)

Uploaded Python 3

File details

Details for the file stubborn_stub-0.9.0b3.tar.gz.

File metadata

  • Download URL: stubborn_stub-0.9.0b3.tar.gz
  • Upload date:
  • Size: 35.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for stubborn_stub-0.9.0b3.tar.gz
Algorithm Hash digest
SHA256 f52fce8515a319e5eed0454b1f3ba01736f212579fe2e459f0ee4ba37e716111
MD5 da7dd69637f4c9ac5962d8cab880b27d
BLAKE2b-256 9324d44d779637fded5e313ee2c8aae92841f83b2476dcab573a6a2a33600e6c

See more details on using hashes here.

File details

Details for the file stubborn_stub-0.9.0b3-py3-none-any.whl.

File metadata

File hashes

Hashes for stubborn_stub-0.9.0b3-py3-none-any.whl
Algorithm Hash digest
SHA256 d8aea66daaa5648700c1a54ba402efa61c9702a627b304bd14b6c488944244ad
MD5 9e41050bf532f379129b6c176d83671b
BLAKE2b-256 bcff0bde558fbf3c27d3fe7e753f1a1d88fc58f02959794a3069009c3a820db2

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