Local-first CLI that reads your Spec-Driven Development artifacts and recommends the AI model that best fits the project.
Project description
๐งโโ๏ธ SpecJudge
Stop guessing which AI model to use. Ask your specs.
SpecJudge reads your Spec-Driven Development artifacts and tells you which AI model actually fits the job โ before you spend a single token implementing it.
$ specjudge .
Model comparison (SpecJudge) - judge: devstral-small-2
โโโโโโณโโโโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโณโโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโ
โ โ Model โ Rating โ Price โ Priced on โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ ๐ฅ โ Gemma 4 31B (local) โ good โ open-source/free โ 2026-07-20 โ
โ ๐ฅ โ Gemma 4 31B โ good โ 0.35 out / 0.12 in โ 2026-07-20 โ
โ ๐ฅ โ Qwen 3.6-35B-A3B (local) โ good โ open-source/free โ 2026-07-20 โ
โ โ GLM-5.1 โ good โ 3.04 out / 0.97 in โ 2026-07-20 โ
โ โ Claude Opus 4.8 โoverkillโ 25.00 out / 5.00 in โ 2026-07-20 โ
โโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโ
๐ฅ Gold: Gemma 4 31B (local)
Right-sized: capability matches demand exactly in every dimension.
Add --open for a visual matrix in your browser, filterable by model family and by open source.
The problem
You've finished defining a project with Spec-Driven Development. Now you have to pick a model to implement it. Two expensive mistakes are waiting:
| Mistake | Cost |
|---|---|
| Model too powerful for the job | You pay for capability the project never uses |
| Model too limited for the job | It doesn't produce the result โ you pay and get nothing |
SpecJudge puts that decision at the one moment it's cheapest to make it: the specs exist, but nothing has been spent yet. And it grounds the answer in your project, not a generic benchmark.
Quick start
Requirements: Python 3.11+, uv, and Ollama with at least one local model.
ollama pull llama3.1:8b # a judge to evaluate your project
uv tool install specjudge
specjudge /path/to/your/project
That's it. On first run SpecJudge lists your local models, asks which one to use as the judge, and remembers your choice.
Run without installing, with pipx, or from source
# Ephemeral run, no install
uvx specjudge /path/to/your/project
# pipx works too
pipx install specjudge
# From source
git clone https://github.com/JoaquinRuiz/SpecJudge.git && cd SpecJudge
uv sync --extra dev
uv run specjudge --help
Privacy
The judge runs on your machine through Ollama. Your specs โ your business logic, your design decisions โ never touch a third-party service, and deciding which model to buy costs you nothing in API calls. The browser report is a self-contained HTML file that loads nothing from the network.
This isn't a nice-to-have; it's Principle I of the project constitution.
How it works
your project local judge model catalog
โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ constitution โ โ Ollama, on โ โ models.yaml โ
โ spec โโโโโโโโโโโโบ โ your machine โโโโโโโโโโโโบ โ (community- โ
โ tasks โ how hard โ estimates โ compare โ maintained) โ
โโโโโโโโโโโโโโโโโ is this? โ the demand โ capabilityโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโ vs demand โ
โผ
๐ฅ ๐ฅ ๐ฅ podium
The judge estimates how demanding your project is across a few dimensions. Declarative rules in
rating-rules.yaml cross that demand against each model's declared capability. The best fit
wins โ no black box, and every verdict comes with a reason you can read.
Reading the output
Every model gets a rating on a fixed scale:
| Rating | Meaning |
|---|---|
good |
Capable enough โ the sweet spot |
overkill |
Capable, but you're paying for headroom you won't use |
fair |
Falls somewhat short |
poor |
Not capable enough |
The podium ranks models by how well they fit your project's complexity โ neither under-capable nor more powerful than needed.
Price does not decide the ranking. It's shown for every model so you can see what each option costs, and it only breaks ties between models that fit equally well. A cheaper model never wins over one that fits better โ recommending something that can't do the job is the most expensive mistake of all. Right-sizing is what keeps you from overpaying.
If no model in the catalog is capable enough, SpecJudge says so instead of recommending one anyway. Same when your project is too thinly specified to judge โ see Data states below.
Options, data states and exit codes
specjudge [PROJECT_PATH] [OPTIONS]
| Option | Description |
|---|---|
--open, -o |
Also open a visual matrix in your browser |
--judge <model> |
Force the judge model for this run (not persisted) |
--set-judge |
Re-run judge selection and save it |
--catalog <path> |
Use an alternative model catalog |
--json |
Emit the result as JSON (for scripting) |
--no-color |
Disable color/highlighting |
Data states โ SpecJudge is explicit about how much it can be trusted:
- Sufficient โ constitution, spec and tasks present: reliable recommendation.
- Scarce โ artifacts missing or thin on detail: recommendation issued, with a warning.
- Insufficient โ no tasks to evaluate: no recommendation at all.
Exit codes โ degradation is distinguishable programmatically:
| Code | Meaning |
|---|---|
0 |
Success (includes scarce and "no model is sufficient") |
2 |
Insufficient project information โ no recommendation |
3 |
Judge unavailable (Ollama not running, no local models, unusable answer) |
4 |
Model catalog missing or empty |
Contributing
Models and prices change every few weeks. That's the whole reason this project needs you.
The most valuable contribution requires zero Python โ SpecJudge keeps everything volatile in human-readable data files, deliberately separate from the code. Adding a model is one YAML block:
- id: my-new-model
name: My New Model
family: MyFamily # groups it in the report's filters (Claude, GPT, Qwen...)
open_source: false # open weights you can download and self-host?
provider: SomeAI
capabilities:
reasoning: high # low | medium | high | top
size: high
domain_specialization: medium
price:
input_per_million: 1.50
output_per_million: 6.00
currency: USD
pricing_date: 2026-07-20 # required โ makes freshness verifiable
Open data/models.yaml, add it, send the PR. Contract tests validate the schema automatically,
so a mistake can't slip through unnoticed.
Good first contributions
| Difficulty | What | Where |
|---|---|---|
| ๐ข No code | Update a price that has changed | data/models.yaml |
| ๐ข No code | Add a model that's missing | data/models.yaml |
| ๐ข No code | Fix a capability rating you disagree with | data/models.yaml |
| ๐ก No code | Tune the rating rules or thresholds | data/rating-rules.yaml |
| ๐ก Light | Improve the judge prompt for small models | src/specjudge/judge/evaluator.py |
| ๐ด Code | Support another local runtime besides Ollama | src/specjudge/judge/ |
Disagree with a rating? That's a contribution, not a complaint โ the catalog is opinion made inspectable. Open a PR with your reasoning.
Before you send a PR
uv run pytest # full suite โ Ollama is mocked, no local models needed
uv run ruff check .
See CONTRIBUTING.md for the full schemas and project governance.
What won't be merged
Contributions that add mandatory paid dependencies to the core. A tool whose purpose is to save you money must not require money to run. That's Principle III, and it isn't negotiable.
About the author
Joaquรญn Ruiz โ jokiruiz.com ยท youtube.com/@jokioki
๐ El motor de la Inteligencia Artificial ๐ Programar con Inteligencia Artificial ๐ Del vibe coding al Spec-Driven Development โ coming soon
License
MIT ยฉ Joaquรญn Ruiz
Project details
Release history Release notifications | RSS feed
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 specjudge-0.1.2.tar.gz.
File metadata
- Download URL: specjudge-0.1.2.tar.gz
- Upload date:
- Size: 70.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed0478adb1084ff0a1b7ac46b832279068c0ad1169e11cc1d6e1c29ded357ab5
|
|
| MD5 |
d23f4e3d1e455804a570e74275ec5688
|
|
| BLAKE2b-256 |
ec27be03ea3edd1c53c7231299c428c9ca5d70926208a1ebcc657373a516e815
|
Provenance
The following attestation bundles were made for specjudge-0.1.2.tar.gz:
Publisher:
release.yml on JoaquinRuiz/SpecJudge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
specjudge-0.1.2.tar.gz -
Subject digest:
ed0478adb1084ff0a1b7ac46b832279068c0ad1169e11cc1d6e1c29ded357ab5 - Sigstore transparency entry: 2210921847
- Sigstore integration time:
-
Permalink:
JoaquinRuiz/SpecJudge@b43a5599ce6a5e6bbe6c84bf021b16a16c7b1aad -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/JoaquinRuiz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b43a5599ce6a5e6bbe6c84bf021b16a16c7b1aad -
Trigger Event:
release
-
Statement type:
File details
Details for the file specjudge-0.1.2-py3-none-any.whl.
File metadata
- Download URL: specjudge-0.1.2-py3-none-any.whl
- Upload date:
- Size: 38.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b25001ac4d7e5824cdbcf7bbe2d741ab8dca4fb7615f39498c62ab2feba495c6
|
|
| MD5 |
5c9927627a9a944ef2df61cd8b3356d1
|
|
| BLAKE2b-256 |
adf83e88366d19c99fa222118b09ae3c77d56fdc95f8c4e9b0491087e9cc0f11
|
Provenance
The following attestation bundles were made for specjudge-0.1.2-py3-none-any.whl:
Publisher:
release.yml on JoaquinRuiz/SpecJudge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
specjudge-0.1.2-py3-none-any.whl -
Subject digest:
b25001ac4d7e5824cdbcf7bbe2d741ab8dca4fb7615f39498c62ab2feba495c6 - Sigstore transparency entry: 2210921870
- Sigstore integration time:
-
Permalink:
JoaquinRuiz/SpecJudge@b43a5599ce6a5e6bbe6c84bf021b16a16c7b1aad -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/JoaquinRuiz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b43a5599ce6a5e6bbe6c84bf021b16a16c7b1aad -
Trigger Event:
release
-
Statement type: