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.0b2 · BETA.md

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. Not migration-only — any live project benefits. Optional integration with anchor-migration (see examples/migration-bridge).

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
  • Legacy migration — optional consumer of anchor-migration (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]"

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 -e ".[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.0b2 (now) 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

Related projects

Repo Role
db-metadata Database schema SSOT
java-ast-ssot Full Java AST SSOT (human + rewrite)
stubborn (this repo) LLM context compiler
migration-hub Program docs; ADR-010 integration contract

See docs/POSITIONING.md and docs/INTEGRATION.md.

Development

pip install -e ".[dev]"
pytest -v

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.0b2.tar.gz (36.1 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.0b2-py3-none-any.whl (42.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for stubborn_stub-0.9.0b2.tar.gz
Algorithm Hash digest
SHA256 d836f81ffa217a30db49f783e997965e1fdf2804af566ceda5fea7e5daef34e1
MD5 43b3fb8b559fd7ce34dbee00739fef41
BLAKE2b-256 118dc052899a25473223c5b66192c85fc0636754251e673a4484ef1cee8902ab

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stubborn_stub-0.9.0b2-py3-none-any.whl
Algorithm Hash digest
SHA256 c09662496e34fdee89d6443c552b9969cf1fd934e6c31d1db00937bc68c75690
MD5 fbda1b1bfb00598275f3ef02f9821810
BLAKE2b-256 3db0c300968ac8cc11d2febea64533ea6d675e6aef4890de360d971aff94cd22

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