backstitch
Backstitch style spec-code traceability checks and semantic review tooling.
backstitch is a standalone developer tool. It owns the backstitch style v1
traceability grammar, deterministic trace graph construction, and semantic
analysis result schemas. This repository's own specs are a primary acceptance
corpus. Weft is an external target corpus and eventual consumer, not a package
dependency.
Current implementation status: the deterministic checker (backstitch check),
review-packet generation (backstitch packets), llm semantic analysis
(backstitch analyze, backstitch summarize-analysis), and TOML
configuration (backstitch config show|path) are implemented per
docs/specs/02-backstitch-core.md, 03-backstitch-configuration.md, and
04-backstitch-traceability-exclusions.md. The invariant traceability spec
(05-backstitch-invariants.md) is Proposed and not implemented. This
repository dogfoods itself: uv run backstitch check must pass with zero
errors and zero warnings.
Runtime
Backstitch requires Python 3.11 or newer. Runtime dependencies are pinned in
pyproject.toml, including llm, markdown-it-py, tree-sitter, and
tree-sitter-python. Python target-code structure is parsed with
tree-sitter-python, so Backstitch running on Python 3.11 can analyze newer
target syntax such as PEP 695 generics and PEP 701 f-strings without relying on
the running interpreter's ast grammar.
Testing
The default suite is hermetic — no network, no provider credentials:
uv run pytest tests -q
Optional live LLM tests
tests/live/test_live_llm.py drives the real CLI (packets -> analyze ->
check -> summarize-analysis) over this repository's own specs through the
production adapter. It is skipped unless you opt in with
BACKSTITCH_LIVE_LLM=1, so it never runs in the default suite. It asserts
structured contracts (one result row per packet, schema-valid JSONL, clean
analysis loading), not model wording or classification, which are not API.
Cloud-provider runs additionally assert model success: no result row may carry
an error field. Model choice is intentionally explicit: the test does not fall
back to your global llm default, so CI and local runs are reproducible. Use a
current GPT-5-series mini model; verify availability with
uv run llm models list.
# Using a key stored by `llm` (run once):
uv run llm keys set openai
BACKSTITCH_LIVE_LLM=1 LLM_MODEL=<configured-model> \
uv run pytest tests/live/test_live_llm.py -q
# Using a provider environment variable instead of a stored key:
OPENAI_API_KEY=... BACKSTITCH_LIVE_LLM=1 LLM_MODEL=gpt-5.4-mini \
uv run pytest -m live_llm -q
The same test also has a credential-free local lane for a loopback
OpenAI-compatible endpoint, normally Ollama. Verify any local (or cloud)
setup with backstitch doctor (--probe adds endpoint reachability), and
see docs/implementation/06-choosing-a-local-model.md for measured model
guidance. It proves local transport and
result handling, not judgment quality. Small CPU models often emit malformed
JSON, so non-strict local runs tolerate individual per-packet error rows as
long as analyze does not report total failure and at least one selected packet
produces a non-error row.
docker run -d --name backstitch-llm \
-p 127.0.0.1:11434:11434 \
-v "$PWD/.ollama-cache:/root/.ollama" \
ollama/ollama
docker exec backstitch-llm ollama pull llama3.2:3b
BACKSTITCH_LIVE_LLM=1 BACKSTITCH_LIVE_LLM_KIND=local \
uv run pytest -m live_llm -q
The floating ollama/ollama tag above is for developer convenience. The
separate manual local-llm workflow pins the image by digest, bounds
context/output through an Ollama Modelfile, serves the bounded alias as
backstitch-local-model:latest, binds only 127.0.0.1, and caches model
weights in an absolute runner path. On unconstrained local hardware (a 16 vCPU
Docker VM) the gate passes with llama3.2:3b in under a minute; with the
workflow's Modelfile bounds (num_ctx 4096, num_predict 1024,
temperature 0) and the adapter's provider-enforced JSON output it passed
8 of 8 local runs with no contained error rows
(docs/plans/2026-07-06-analyze-json-mode-plan.md). Occasional content-level
error rows remain possible — a failed run is a rerun, not an alarm — and the
lane stays a manual workflow until a passing run on the actual GitHub runner
is recorded.
Cloud-provider tests cost money and can be flaky for reasons unrelated
to Backstitch: provider outages, rate limits, model retirement, and
nondeterministic output. The local lane is also flaky in a different way: cold
model pulls, CPU inference, and small-model output quality can dominate runtime.
Keep the packet set small; live tests are smoke and contract checks, not
exhaustive semantic review. In CI the cloud live job is part of the normal CI
workflow: it runs when the repository OPENAI_API_KEY secret is available and
skips without failure when secrets are unavailable, such as on forked pull
requests. The local Ollama lane is a separate manual workflow and must not be a
required status check until it has stable passing run history. See
docs/implementation/04-backstitch-style-traceability.md for the boundary
rationale.
Release
Backstitch releases use bin/release.py locally and a tag-triggered GitHub
release gate. The helper runs local checks including the cloud and local live
LLM tests, creates a release commit when version files changed, and pushes the
vX.Y.Z tag. The GitHub workflow publishes to PyPI through Trusted Publishing
and creates the GitHub Release.
bin/release.py --version X.Y.Z --dry-run
bin/release.py --version X.Y.Z
# After version files and CHANGELOG.md are already prepared:
bin/release.py all --dry-run
bin/release.py all
See docs/implementation/05-release-publishing.md for setup, rollback, and
verification details.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file backstitch-0.2.0.tar.gz.
File metadata
- Download URL: backstitch-0.2.0.tar.gz
- Upload date:
- Size: 445.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36a43682667420ac7d4d588419891889c0edc9dac23cea1be5b37b7a369fe83c
|
|
| MD5 |
023f5c181c23a158fe264d6e9e7805ba
|
|
| BLAKE2b-256 |
1e36d918c8bf0723a0ee77b6a86d440ea4a8fe19bb62bcea7d505e7ce7527198
|
Provenance
The following attestation bundles were made for backstitch-0.2.0.tar.gz:
Publisher:
release-gate.yml on VanL/backstitch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
backstitch-0.2.0.tar.gz -
Subject digest:
36a43682667420ac7d4d588419891889c0edc9dac23cea1be5b37b7a369fe83c - Sigstore transparency entry: 2110544021
- Sigstore integration time:
-
Permalink:
VanL/backstitch@027ce7a4aea232331e506d625050ca3e7ed663df -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/VanL
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-gate.yml@027ce7a4aea232331e506d625050ca3e7ed663df -
Trigger Event:
push
-
Statement type:
File details
Details for the file backstitch-0.2.0-py3-none-any.whl.
File metadata
- Download URL: backstitch-0.2.0-py3-none-any.whl
- Upload date:
- Size: 70.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a598e0c6d8820a0a0a194d61b0ba43898c45b132872a66213afe66c70eeed465
|
|
| MD5 |
1d95634be3d56474b8add7b60e488c0a
|
|
| BLAKE2b-256 |
bedd2982c24c6e88342b7b36bd6f00c58ff324b51ebbf5fb30859dc39a9f48f7
|
Provenance
The following attestation bundles were made for backstitch-0.2.0-py3-none-any.whl:
Publisher:
release-gate.yml on VanL/backstitch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
backstitch-0.2.0-py3-none-any.whl -
Subject digest:
a598e0c6d8820a0a0a194d61b0ba43898c45b132872a66213afe66c70eeed465 - Sigstore transparency entry: 2110544458
- Sigstore integration time:
-
Permalink:
VanL/backstitch@027ce7a4aea232331e506d625050ca3e7ed663df -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/VanL
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-gate.yml@027ce7a4aea232331e506d625050ca3e7ed663df -
Trigger Event:
push
-
Statement type: