Matcha Core
matcha-core analyzes a repository against its SPECS.md and produces structured implementation reports.
It can be used in two ways:
- as an installable CLI
- as a Python library
Install
From PyPI:
python3 -m pip install matcha-core
For local development:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e ".[dev]"
CLI
OpenAI:
export OPENAI_API_KEY=...
matcha-core analyze /path/to/repo --output ./report.html
Ollama:
export OLLAMA_MODEL=llama3.2
matcha-core analyze /path/to/repo --provider ollama
If the specs file is not at the repo root:
matcha-core analyze /path/to/repo --specs /path/to/repo/docs/SPECS.md
To analyze only one feature:
matcha-core analyze /path/to/repo --feature FEAT-004 --output report.html
matcha-core infers the report format from --output when possible, so
report.html, report.json, and report.md automatically render the expected
format. If no format is specified and no output file is provided, the CLI
defaults to a terminal table view. You can also use --reporter as an alias
for --format.
Library
from matcha_core import OpenAICompatibleEvaluator, RepositoryAnalyzer
from matcha_core.reporting import report_to_html
evaluator = OpenAICompatibleEvaluator.from_env(provider="openai")
analyzer = RepositoryAnalyzer(evaluator=evaluator)
report = analyzer.analyze_path("/path/to/repo")
html = report_to_html(report)
Onboard an existing repository
Onboarding is local-first because it sends broader repository context than a normal criterion analysis. Ollama is the default provider and does not require an OpenAI API key.
Local prerequisites:
- Install Ollama.
- Start the Ollama application, or run
ollama serveand leave it running. - Download the model used by Matcha and verify that it is available:
ollama pull llama3.2
ollama ls
Then generate the draft:
matcha-core onboard /path/to/repo
This writes /path/to/repo/SPECS.draft.md. It does not create or overwrite the
canonical SPECS.md. Every proposed feature is marked Draft, cites repository
evidence, carries a confidence score, and can include questions that require
product-owner judgment.
One file or one file per feature
The default single layout preserves the existing SPECS.draft.md output. For
larger products, generate a manifest-backed bundle instead:
matcha-core onboard /path/to/repo \
--layout per-feature \
--output /path/to/repo/SPECS.draft
The bundle is written atomically and has this shape:
SPECS.draft/
├── SPECS.md
├── FEAT-001-feature-name.md
├── FEAT-002-another-feature.md
└── REVIEW-QUESTIONS.md
SPECS.md is the ordered manifest, each FEAT-*.md file contains one feature,
and review questions remain outside the executable feature contract. Existing
output is preserved unless --force is explicitly supplied.
After the broad inventory pass, deepen one existing draft without regenerating the bundle:
matcha-core onboard /path/to/repo \
--mode enrich \
--specs /path/to/repo/SPECS.draft \
--feature FEAT-003 \
--provider ollama \
--model llama3:latest \
--language Spanish
Enrichment reads the selected feature, prioritizes its cited components and
related repository evidence, and replaces only that feature document. Its ID,
name, description, and priority remain stable; the manifest and other feature
files are not rewritten. Existing criteria and evidence are merged back
deterministically, so the model can refine or add to them but cannot silently
delete them. New
model-generated review questions are appended without deleting existing
questions. Only features with Status: Draft can be enriched, so a reviewed
product contract is never silently converted back into generated draft text.
Preview the generated change first with --dry-run. The command prints a
unified diff and leaves the bundle untouched:
matcha-core onboard /path/to/repo \
--mode enrich \
--specs /path/to/repo/SPECS.draft \
--feature FEAT-003 \
--dry-run
--include and --exclude can further bound enrichment. --max-context-chars
controls the focused evidence budget. Enrichment is intentionally one feature
per invocation and does not require --force; Matcha aborts if the target file
changes while generation is running.
Both analyze and check accept a traditional Markdown file, a bundle
directory, or a manifest file that links to FEAT-*.md documents:
matcha-core analyze /path/to/repo --specs /path/to/repo/specs
matcha-core check /path/to/repo --specs /path/to/repo/specs
Bundle IDs and acceptance criteria are validated across all feature files, so
duplicate IDs cannot hide in separate documents. Gate artifacts record every
spec file and SHA-256 plus one deterministic aggregate specs_sha256. Default
discovery prefers a root SPECS.md, then a root specs/ directory. Draft
bundles are never promoted or selected automatically.
Onboarding uses the clustered evidence strategy by default. Matcha indexes all
supported repository files, assigns stable evidence IDs for the run, and groups
files that reference related symbols. Each group is analyzed separately before
the candidates are consolidated into one draft. This allows a feature to cite
related UI, state, service, model, and test files instead of depending on a
single alphabetical context slice. Large source files use bounded excerpts
sampled across declarations and behavioral entry points.
The complete file index is visible to discovery, while only the files listed
in each batch's SELECTED FILE CONTENT are valid evidence. Inspect
--debug-llm for exact coverage instead of assuming every byte was analyzed.
Because clustered onboarding can make several model calls, --max-features
limits the consolidated draft rather than the number of intermediate
candidates. Use --debug-llm to inspect the batches, selected files, evidence
ID mapping, provider responses, and consolidation result.
Scope a run with repeatable repository-relative glob patterns:
matcha-core onboard /path/to/repo \
--include "Sources/**" \
--include "Tests/**" \
--exclude "**/Mocks/**"
Use --strategy single-pass when you explicitly want the previous one-request
behavior. --max-context-chars is a per-batch budget in clustered mode.
Choose a different OpenAI-compatible model explicitly when local output is not good enough:
export OPENAI_API_KEY=...
matcha-core onboard /path/to/repo \
--provider openai \
--model gpt-5.6-sol \
--language English
Matcha never silently falls back from Ollama to a remote provider. Files that
look like credentials, private keys, environment files, generated output, and
dependency directories are excluded from onboarding context. Use --force
only when intentionally replacing an existing draft. Ollama defaults to a
smaller per-batch context and eight final features so local models have room to
produce complete structured output. It also allows 180 seconds for each local
generation request. Context, feature count, strategy, scope, and --timeout
can all be overridden.
OpenAI reasoning models default to --reasoning-effort low for structured
onboarding so reasoning does not consume the entire completion budget. Override
it explicitly when an evaluated quality gain justifies the added latency and
cost.
matcha-core bootstrap remains available as a compatibility alias, but
matcha-core onboard is the documented command.
The Python API exposes the same workflow through RepositoryBootstrapper and
OpenAICompatibleSpecGenerator. See docs/ONBOARDING.md for
the review and promotion workflow and the optional Codex skill.
Output formats
jsonmarkdownhtmltable
For terminal output with evidence snippets:
matcha-core analyze /path/to/repo --format table --show-evidence
CI gate
Copy docs/POLICY_TEMPLATE.yml to
.matcha/policy.yml in the repository being checked, then run:
version: 1
fail_on: [not_implemented, implemented_differently, not_specified]
priorities: [critical, high]
min_confidence: 0.75
on_inconclusive: block
allow: []
matcha-core check /path/to/repo --output matcha-gate.json
The gate applies deterministic policy rules after analysis. Model or retrieval failures do not become implementation findings.
Exit codes are stable:
0: policy passed10: one or more definitive findings violated the policy20: the result is inconclusive and the policy useson_inconclusive: block30: configuration or execution error
These values do not overlap with argparse's standard exit code 2 for invalid
command-line usage.
Use baseline in the policy, or --baseline, to grandfather findings from a
previous Matcha JSON report. Only explicit IDs with complete matching contracts are eligible: feature,
criterion ID, versioned fingerprint and status must all match. Legacy positional
IDs or unknown text completeness are diagnosed and cannot waive findings.
Edited requirements invalidate their previous exception.
Temporary exceptions belong in allow. Every exception requires an ISO
expires date and a reason; expired exceptions
no longer apply. Findings below min_confidence make the gate inconclusive
rather than allowing a false pass. Every run writes a JSON gate artifact with
the decision, violations, incomplete findings, waivers, complete analysis,
provider/model identity, repository commit and dirty state, and SHA-256 hashes
for specs, policy, and baseline.
A complete GitHub Actions example is available in docs/CI.md.
Tests
python3 -m unittest discover -s tests
Specs Authoring
Use docs/SPECS_TEMPLATE.md as a starting point when onboarding an existing repository into Matcha.
Matcha validates specs before analysis. Feature headings must include a stable
ID such as ## FEAT-1 User login, IDs must be unique, and every feature must
have at least one acceptance criterion. Fenced Markdown examples are ignored.
Reports distinguish definitive findings from execution state:
skippedmeans the contract is Draft/Retired, or legacy progress marks it plannedinconclusivemeans Matcha did not find enough relevant contextanalysis_failedmeans the evaluator could not produce a valid result
These states are never counted as not_implemented. JSON reports include a
schema_version field so consumers can validate the output contract.
Evidence and analysis coverage
Analysis reports and gate artifacts use schema 1.3. Existing fields
remain available. Each criterion now includes structured evidence, a source
context manifest, evidence_issues, and an optional abstention reason.
The manifest identifies the exact source fragments sent to the evaluator,
original line ranges, file hashes, omitted content, and unresolved references.
referenced_files lists files actually sent; retrieved candidates are recorded
separately in context.selected_files. code_snippets remains a compatibility
representation of verified citations.
The engine checks citations against the snapshot sent for that criterion,
including results from custom evaluators and repaired model responses. Legacy
path/code citations are accepted only when they match a unique source excerpt.
Custom evaluators keep their existing signature but definitive implementation
verdicts now require citations and a rationale. Missing or invalid evidence
produces inconclusive, not a claim that the behavior is absent or different.
not_implemented requires localized evidence of missing behavior; an empty
search is insufficient. not_specified means the requirement is ambiguous.
Provenance checks do not prove that the model interpreted the cited code correctly. Reports describe static source observations, not executed tests, runtime behavior or deployment. Model confidence is not a calibrated probability. Context uses deterministic bounded source windows; related components guide retrieval, while omitted dependencies may still prevent a conclusion.
Reports distinguish criteria in scope, skipped, evaluated (including failed or
inconclusive attempts), and conclusive. The gate recomputes coverage for its
priority scope and counts a result as conclusive only when it meets the policy's
confidence threshold. With on_inconclusive: block, an empty effective scope
or all-skipped run returns 20 with reason no_criteria_evaluated. With
ignore, these reasons and incomplete findings remain visible even if the
exit code is 0. Exit codes and policy version 1 are unchanged.
For the opt-in synthetic real-model evaluation, see docs/SDD_FEEDBACK_VALIDATION.md.
Bootstrap-generated Draft features are also skipped. Change each reviewed
feature to an intentional lifecycle status such as Done or Planned before
using it in a gate.
Release
The package metadata and release flow are documented in RELEASING.md.
License
This project is licensed under the Apache License 2.0. See LICENSE.
Feedback for Spec Driven Development
Use explicit persistent criterion IDs and separate contract approval from implementation progress:
## FEAT-INV Invitations
**Priority**: High
**Contract Status**: Approved
**Implementation Status**: Planned
**Related Components**: `src/invitations.py`
Acceptance Criteria:
- [AC-INV-001] Reject expired invitations before creating a membership.
Approved contracts are analyzed even when implementation is Planned. Draft and
Retired contracts are skipped. Without Contract Status, legacy skip rules
remain in effect. Product review, not observed code, determines approval.
matcha-core specs migrate SPECS.md --output criterion-ids.patch
matcha-core specs review SPECS.md --format json --output spec-review.json
matcha-core analyze . --output current.json
matcha-core compare previous.json current.json --output feedback.md
matcha-core analyze . --test-results executions.json --output with-tests.json
Migration prints a diff for review; it never rewrites specs. Authoring review provides deterministic hints rather than exhaustive semantic validation. Reports contain structured next actions, contract identity, scope, configuration and provenance. Comparisons separate changed requirements from static findings; filters, uncertainty and incompatible configurations never count as resolutions. Test references are labelled as not executed. Imported results retain their caller-supplied provenance and only match a clean analyzed commit and the exact criterion fingerprint; they never override a static verdict.
See docs/SDD_WORKFLOW.md for the complete workflow, import format and compatibility rules.
Metadata
Release files for matcha-core 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| matcha_core-0.2.0.tar.gz | 129.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| matcha_core-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 214.0 kB
Release files / matcha_core-0.2.0.tar.gz
| Download URL | matcha_core-0.2.0.tar.gz |
|---|---|
| Size | 129.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e8f1ff707ffbedc6f45e1620a9744d29518cd25208a0c03a54960bfebe80d9d6
|
|
BLAKE2b-256 checksum How to use checksums |
b80e221b06d873ca3054435dc6eb821c5fdfbf5534a304934ccaaf3dccabe5e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / matcha_core-0.2.0-py3-none-any.whl
| Download URL | matcha_core-0.2.0-py3-none-any.whl |
|---|---|
| Size | 84.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb1c38e3dc9b4f1d0be9ecc76fcbfc496754193064667e2b1a6ed78fa807114f
|
|
BLAKE2b-256 checksum How to use checksums |
6e7129f465ac15f176775c5792707a1b0afeb09fc4f1feb7169bed63918ee9d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|