Skip to main content

Matcha logo

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:

  1. Install Ollama.
  2. Start the Ollama application, or run ollama serve and leave it running.
  3. 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

  • json
  • markdown
  • html
  • table

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 passed
  • 10: one or more definitive findings violated the policy
  • 20: the result is inconclusive and the policy uses on_inconclusive: block
  • 30: 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:

  • skipped means the contract is Draft/Retired, or legacy progress marks it planned
  • inconclusive means Matcha did not find enough relevant context
  • analysis_failed means 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)

Source distribution for matcha-core 0.2.0
File Size Uploaded
matcha_core-0.2.0.tar.gz 129.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for matcha-core 0.2.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page