diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 0000000..3f1d202
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,61 @@
+name: Docs
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - ".github/workflows/pages.yml"
+ - "docs/requirements.txt"
+ - "mkdocs.yml"
+ - "docs/site/**"
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ build:
+ name: Build static docs
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repo
+ uses: actions/checkout@v4
+
+ - name: Configure Pages
+ uses: actions/configure-pages@v5
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.13"
+
+ - name: Install docs dependencies
+ run: python -m pip install -r docs/requirements.txt
+
+ - name: Build docs site
+ run: mkdocs build --strict
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: _site
+
+ deploy:
+ name: Deploy to GitHub Pages
+ if: github.ref == 'refs/heads/main'
+ needs: build
+ runs-on: ubuntu-latest
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ steps:
+ - name: Deploy Pages artifact
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index 1d36aa7..6e86b2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
# Local scratch output
/tmp/
+/_site/
# Vouch output when dogfooding this repo itself
/.vouch/build/
diff --git a/README.md b/README.md
index 4a7c269..eeb5c2c 100644
--- a/README.md
+++ b/README.md
@@ -1,1133 +1,96 @@
-
+
# Vouch
-Vouch keeps risky AI-written changes from shipping just because the tests passed.
+Vouch is a compiler for release contracts.
-It lets a team say, in code, what must remain true for important parts of a
-repo, then requires evidence for those obligations before an agent change can
-merge or release.
-
-In one sentence: Vouch turns human-owned release intent into stable obligation
-IDs, checks runner artifacts against those obligations, and returns a
-deterministic decision: `block`, `human_escalation`, `canary`, or `auto_merge`.
-
-## The Short Version
-
-Use Vouch when "CI passed" is too weak for agent-authored changes.
-
-Example: an agent changes password reset. The unit tests pass. That still does
-not prove the change preserved the intended behavior, avoided logging reset
-tokens, exposed the right runtime signal, and has a rollback path.
-
-With Vouch:
-
-1. A human-owned contract says what `auth.password_reset` is responsible for.
-2. Vouch compiles that contract into stable behavior, security, test, runtime,
- and rollback obligation IDs.
-3. Existing runners produce JUnit, scanner, probe, metric, verifier, or rollback
- artifacts.
-4. Vouch links those artifacts to the obligation IDs and applies release policy.
-5. CI gets an auditable decision instead of a vague "looks good."
-
-The value is not more AI review. The value is a deterministic release boundary:
-for the contract this change touched, the required evidence exists or the change
-does not ship.
-
-## Contents
-
-- [The Problem](#the-problem)
-- [Why Use It](#why-use-it)
-- [Why Not Just Use Another Agent?](#why-not-just-use-another-agent)
-- [Current Validation](#current-validation)
-- [Real Repo Walkthrough](#real-repo-walkthrough)
-- [Clear Limits](#clear-limits)
-- [Quickstart](#quickstart)
-- [FAQ](#faq)
-- [Project Docs](#project-docs)
-- [Validation Status](#validation-status)
-- [Demo](#demo)
-- [Commands](#commands)
-
-## The Problem
-
-AI agents can produce code faster than humans can carefully review every line.
-CI can tell you whether commands passed, but it usually cannot answer the
-release question that matters for agent changes:
-
-> For the contracts this change touches, are the required behavior, security, test, runtime, and rollback obligations covered by valid evidence?
-
-Vouch adds that missing control plane. Humans declare what must remain true,
-existing runners produce evidence, and Vouch checks whether the evidence is
-complete enough for the repo's release policy.
-
-## Why Use It
-
-Use Vouch when you want:
-
-- A hard rule that risky agent changes need evidence, not just passing tests or
- another model's approval.
-- Human-owned product and release contracts for repo areas such as auth,
- payments, permissions, data deletion, migrations, public APIs, and production
- rollout.
-- Stable obligation IDs that connect intent, changed files, evidence artifacts,
- policy, and release decisions.
-- A CI-friendly gate that consumes existing JUnit, JSON, text, verifier, metric,
- and rollback artifacts instead of replacing your runner.
-- Optional signed evidence checks that bind artifacts to approved runner
- identities.
-
-Do not use Vouch for every small change. For low-risk edits, normal CI and review may be enough. Vouch is useful when the cost of a bad agent change is high enough that "tests passed" and "another agent said it looks fine" are not strong enough release criteria.
-
-## Why Not Just Use Another Agent?
-
-Another agent can review a diff, but it is still an opinion over code. It may miss the same release concerns a human skim misses, and its output is hard to turn into a stable merge rule.
-
-Vouch is different because it asks for explicit release evidence:
-
-| Question | Another Agent | Vouch |
-| --- | --- | --- |
-| Who owns the intended behavior? | Usually inferred from the diff or prompt. | Declared in a human-owned contract. |
-| What must be checked before release? | Whatever the agent decides to inspect. | Compiled into stable obligation IDs. |
-| What happens when tests pass but rollout evidence is missing? | Often depends on reviewer judgment. | Gate blocks or escalates according to policy. |
-| Can the result be audited later? | Usually a prose comment or chat transcript. | Manifest, evidence artifacts, coverage, policy rule, and decision. |
-| Can CI enforce it deterministically? | Not reliably without custom glue. | Yes, `vouch gate` exits non-zero on `block`. |
-
-The benefit is a release boundary that says: for this kind of change, these
-obligations must have these evidence artifacts, or the change does not ship.
-
-That is also why there are several moving parts:
-
-- contracts define intent
-- compile turns intent into stable obligations
-- runners produce evidence
-- gate checks evidence coverage and policy
-
-You only pay that cost where the release risk justifies it: auth, payments, permissions, data deletion, migrations, external side effects, public APIs, production rollout, and other changes where a vague approval is not enough.
-
-## Current Validation
-
-Vouch includes a repo-local acceptance suite, VouchBench, for the current release-gate behavior. It builds the local CLI, runs isolated fixture repos, and fails non-zero if expected decisions, exit codes, coverage counts, missing obligation IDs, invalid evidence codes, policy rules, manifest/spec errors, or selected artifact statuses regress.
-
-The current VouchBench corpus passes 10/10 scenarios and 114/114 assertions:
-
-| Scenario | Baseline | Expected Vouch Decision | Validation Signal |
-| --- | --- | --- | --- |
-| High-risk auth with JUnit only | tests pass | `block` | Tests alone do not cover behavior, security, runtime, or rollback obligations. |
-| High-risk auth with partial release evidence | tests pass | `block` | Partial artifacts are not enough when compiled obligations remain uncovered. |
-| High-risk auth with full evidence but bad manifest traceability | tests pass | `block` | Full obligation coverage can still block when changed files are not owned by touched specs. |
-| High-risk auth with non-zero test artifact | tests fail | `block` | Artifact exit codes are enforced. This is a negative control tests already catch. |
-| High-risk auth with complete evidence and canary | tests pass | `canary` | Complete evidence routes high-risk auth to canary, not auto-merge. |
-| High-risk auth with complete evidence but no canary | tests pass | `human_escalation` | High-risk complete evidence without canary escalates to a human. |
-| Medium/high platform change across auth, payments, and API with partial evidence | tests pass | `block` | A 25-obligation multi-component release blocks when one high-risk component lacks security, runtime, and rollback evidence. |
-| Medium/high platform change across auth, payments, and API with complete evidence | tests pass | `canary` | A larger multi-component release can pass to canary when all obligations are covered. |
-| Medium-risk API-only change inside the platform repo | tests pass | `auto_merge` | Vouch scopes obligations to the touched medium-risk contract instead of gating the whole repo. |
-| Low-risk docs with complete evidence | tests pass | `auto_merge` | Vouch is not just a blocker. Low-risk complete evidence can pass. |
-
-The generic onboarding flow has also been exercised against temp copies of real Python repos (`sundae`, `sago`, and `wooster`) using `init`, `contract suggest`, `contract create`, `manifest create`, JUnit mapping/import, artifact attachment, and `gate`.
-
-This validation is evidence of deterministic gate behavior over the stated corpus. It does not certify arbitrary code. See [Benchmarks](docs/BENCHMARKS.md) for the harness, assertions, and limits.
-
-## Real Repo Walkthrough
-
-This walkthrough uses [Pallets Click](https://github.com/pallets/click), a widely used Python CLI library. Pallets projects use `pytest` for tests, and Click 8.3.2 declares a `tests` dependency group with `pytest`.
-
-The point of this walkthrough is not to claim Vouch understands Click. The point is to show the whole first-run workflow on a real repository:
-
-```text
-repo -> preview draft contracts -> write accepted drafts -> run tests -> import JUnit -> gate
-```
-
-### 1. Clone A Pinned Real Repo
-
-Use a pinned tag so the counts below are reproducible:
-
-```sh
-mkdir -p /tmp/vouch-real-repo
-cd /tmp/vouch-real-repo
-
-git clone --depth 1 --branch 8.3.2 https://github.com/pallets/click.git
-cd click
-```
-
-### 2. Install Test Dependencies
-
-```sh
-python3 -m venv .venv
-. .venv/bin/activate
-
-python -m pip install -U pip
-python -m pip install -e . pytest
-```
-
-### 3. Preview Vouch Without Writing Files
-
-Run Vouch before running tests so generated `__pycache__` files do not become repo signals.
-
-```sh
-vouch try --repo .
-```
-
-This prints a short first-run report with draft count, compiled obligation count, risky drafts to review, and next steps. It uses a temporary snapshot, so the Click checkout is not changed.
-
-### 4. Write And Compile Vouch Drafts
-
-When the preview looks useful:
-
-```sh
-vouch try --repo . --write
-```
-
-On Click 8.3.2, the write run currently compiles:
+The release gate is the first runtime target, not the whole project.
```text
-Compiled 31 contract drafts into 195 obligations.
-```
-
-This means Vouch found repo signals, wrote draft intent files under `.vouch/intents/`, compiled specs under `.vouch/specs/`, and built aggregate obligation IR under `.vouch/build/obligations.ir.json`.
-
-At this point a human should inspect the generated intents. Bootstrap is conservative scaffolding, not product understanding. You should edit owners, risk levels, paths, behavior, security invariants, runtime signals, and rollback expectations before relying on the gate.
-
-For a ranked shortlist:
-
-```sh
-vouch bootstrap --review
+human-owned intent YAML
+ -> typed AST
+ -> spec JSON
+ -> obligation IR
+ -> verification plan and runner artifacts
+ -> evidence and policy input
+ -> block | human_escalation | canary | auto_merge
```
-### 5. Run The Project Tests With JUnit
+Use Vouch when a risky AI-authored change needs more than "CI passed." A
+contract says what a repo area owns; the compiler gives those requirements
+stable obligation IDs; the gate checks whether evidence covers those IDs.
-```sh
-mkdir -p .vouch/artifacts
-python -m pytest --junitxml .vouch/artifacts/pytest.xml
-```
+## Quick Start
-On one local run against Click 8.3.2, pytest reported:
-
-```text
-1384 passed, 22 skipped, 30000 deselected, 1 xfailed
-```
-
-The exact test count can vary with Python and dependency versions. The important artifact is `.vouch/artifacts/pytest.xml`.
-
-### 6. Import Test Evidence
-
-```sh
-vouch evidence import junit .vouch/artifacts/pytest.xml
-```
-
-On the same Click run, Vouch linked:
-
-```text
-Linked obligations: 51
-```
-
-That means JUnit satisfied 51 required-test obligations. It does not satisfy behavior, security, runtime, or rollback obligations.
-
-### 7. Run The Gate
-
-```sh
-vouch gate
-```
-
-Expected first-run result:
-
-```text
-BLOCKED
-
-Release decision: block
-Obligations: 51/195 covered
-
-Missing:
- behavior_trace: ...
- security_check: ...
- runtime_metric: ...
- rollback_plan: ...
-```
-
-That block is expected. It means:
-
-- tests passed
-- Vouch imported test evidence
-- required-test obligations were covered
-- other generated obligations still lack accepted evidence
-
-That is the main difference from plain CI. CI answers "did pytest pass?" Vouch asks "for the contracts touched by this release, are all required evidence classes covered?"
-
-### 8. What You Do Next
-
-For a real adoption pass, do not try to make every generated draft pass blindly. Tighten the contract set:
-
-1. Delete or merge low-value generated intent files.
-2. Assign real owners instead of `unowned`.
-3. Keep contracts that match real release boundaries, for example `click.parser`, `click.termui`, `click.shell_completion`, and `click.testing`.
-4. Replace generated behavior text with human-owned behavior obligations.
-5. Keep required-test obligations mapped to real tests.
-6. Add security, runtime, and rollback evidence only where those obligations matter for the component risk.
-7. Re-run `vouch compile`, `vouch evidence import junit`, and `vouch gate`.
-
-If you only want a non-destructive evaluation of another repo, prefer `vouch try`:
+Preview a repo without writing files:
```sh
vouch try --repo /path/to/repo
```
-For benchmark-style output from the Vouch checkout, use the snapshot evaluator:
+Write the draft `.vouch/` layout when the preview is useful:
```sh
-cd /path/to/vouch
-
-scripts/vouchbench-repo.sh \
- --repo /path/to/repo \
- --test-command "mkdir -p .vouch/artifacts && python -m pytest --junitxml .vouch/artifacts/pytest.xml" \
- --junit .vouch/artifacts/pytest.xml \
- --out /tmp/vouchbench-repo
+vouch try --repo /path/to/repo --write
```
-That copies the target repo into a temp directory and writes Vouch files only inside the snapshot.
-
-## Clear Limits
-
-Vouch is beta infrastructure, not a production-ready assurance system.
-
-It does **not**:
-
-- Review arbitrary diffs or decide whether an implementation is good.
-- Infer product intent automatically. `vouch bootstrap` drafts conservative contracts from repo signals, but humans must accept, edit, or reject them.
-- Run tests, probes, scanners, or deployment checks. External runners produce evidence. Vouch checks how that evidence maps to compiled obligations.
-- Validate a generic JSON or text artifact as truthful beyond structure, status, obligation IDs, path, exit code, optional hash, and optional signature checks.
-- Replace production code review, security review, incident response, rollout ownership, or human ownership of product intent.
-
-## What Vouch Does Today
-
-Vouch drafts conservative release contracts from signals already present in your repo, including tests, CODEOWNERS, OpenAPI specs, CI config, and evidence artifacts. It compiles accepted intent YAML into typed specs, obligation IR, verification plans, and runner/verifier/release artifacts. It then validates a change manifest and linked evidence artifacts to produce a release decision.
-
-Use it today as experimental infrastructure for designing and exercising verification contracts for agent-authored changes.
-
-## Quickstart
-
-Use this when you have an existing repo and want Vouch to produce a release decision for an agent change.
-
-### 0. Install The CLI
-
-Install from GitHub:
-
-```sh
-go install github.com/duriantaco/vouch/cmd/vouch@latest
-```
-
-Or, from the Vouch checkout:
-
-```sh
-go install ./cmd/vouch
-```
-
-After that, try Vouch on a repo without writing anything into it:
+Compile contracts and run the current gate:
```sh
-vouch try --repo /path/to/your/repo
-```
-
-If your shell cannot find `vouch`, make sure Go's bin directory is on `PATH`:
-
-```sh
-export PATH="$(go env GOPATH)/bin:$PATH"
-```
-
-If you are developing Vouch itself and do not want to install the binary, replace `vouch` with `go run ./cmd/vouch` in the commands below.
-
-The first command runs against a temporary snapshot. It shows what contracts Vouch would draft, which risky areas it found, and what to review first.
-
-When the preview looks useful, write the draft Vouch files intentionally:
-
-```sh
-vouch try --repo /path/to/your/repo --write
-```
-
-Then run tests and gate:
-
-```sh
-cd /path/to/your/repo
+cd /path/to/repo
+vouch compile
pytest --junitxml .vouch/artifacts/pytest.xml
vouch evidence import junit .vouch/artifacts/pytest.xml
vouch gate
```
-If you want Vouch to run the test command inside the temporary snapshot, use:
-
-```sh
-vouch try --repo /path/to/your/repo \
- --test-command "pytest --junitxml .vouch/artifacts/pytest.xml" \
- --junit .vouch/artifacts/pytest.xml
-```
+JUnit covers required-test obligations only. Behavior, security, runtime, and
+rollback obligations need their own evidence.
-For a short ranked list of generated drafts:
+## Install
```sh
-vouch bootstrap --review
-```
-
-The mental model:
-
-| Thing | File | What It Means |
-| --- | --- | --- |
-| Contract | `.vouch/intents/*.yaml` and `.vouch/specs/*.json` | Human-owned intent for one part of the repo. |
-| Manifest | `.vouch/manifests/*.json` | What the agent changed in one run. |
-| Evidence | `.vouch/artifacts/*` | Test/probe/scanner output that covers compiled obligation IDs. |
-| Gate result | command output or `.vouch/build/gate-result.json` | Vouch's decision for that manifest. |
-
-### 1. Preview Vouch Without Writing Files
-
-```sh
-vouch try --repo /path/to/your/repo
-```
-
-Default `try` mode snapshots the repo first. Your source repo is not changed.
-
-### 2. Write Drafts Into Your Repo
-
-Run this only after the preview looks useful:
-
-```sh
-vouch try --repo /path/to/your/repo --write
-```
-
-This creates:
-
-- `.vouch/config.json`
-- `.vouch/intents/`
-- `.vouch/specs/`
-- `.vouch/policy/release-policy.json`
-- `.vouch/manifests/`
-- `.vouch/artifacts/`
-- `.vouch/build/`
-
-It also drafts `.vouch/intents/*.yaml` from repo signals and compiles them into specs and obligation IR.
-
-### 3. Ask Vouch What Contract To Start With
-
-```sh
-vouch --repo /path/to/your/repo bootstrap --review
-```
-
-Pick one high-risk or medium-risk draft as a starting point. Vouch drafts are structural. You still need to write the real product intent.
-
-### 4. Create Or Edit A Contract
-
-A contract says what a part of the repo owns and what evidence must exist before changes to that area can ship.
-
-```sh
-vouch --repo /path/to/your/repo contract create \
- --name app.service \
- --owner platform \
- --risk medium \
- --paths "src/app/**,tests/test_app.py" \
- --behavior "service returns stable JSON" \
- --security "service does not expose secrets in responses" \
- --required-test "service json contract is stable" \
- --metric "app.service.requests" \
- --rollback-strategy "revert_change"
-```
-
-This writes:
-
-- `.vouch/intents/app.service.yaml`
-- `.vouch/specs/app.service.json`
-- `.vouch/test-map.json` with empty stubs for required-test obligations
-
-Build the IR once so you can see the exact obligation IDs evidence must reference:
-
-```sh
-vouch ir build \
- --spec /path/to/your/repo/.vouch/specs/app.service.json \
- --out /path/to/your/repo/.vouch/build/app.service.ir.json
-```
-
-Open `.vouch/build/app.service.ir.json` and look for `obligations[].id`. Example IDs look like:
-
-- `app.service.behavior.service_returns_stable_json`
-- `app.service.security.service_does_not_expose_secrets_in_responses`
-- `app.service.required_test.service_json_contract_is_stable`
-- `app.service.runtime_signal.app_service_requests`
-- `app.service.rollback.revert_change`
-
-### 5. Create A Manifest For The Agent Change
-
-The manifest says what changed and which contract the change touches. You can pass changed files explicitly:
-
-```sh
-vouch --repo /path/to/your/repo manifest create \
- --task-id agent-123 \
- --summary "change app service" \
- --agent codex \
- --run-id run-123 \
- --changed-file src/app/service.py \
- --out .vouch/manifests/run-123.json
-```
-
-Check the manifest:
-
-```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- manifest check
-```
-
-At this point, `gate` should usually block because no evidence has been attached yet.
-
-```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- gate
-```
-
-That failure is useful. It tells you which obligations still need evidence.
-
-### 6. Run Your Existing Checks
-
-Vouch does not run your tests yet. Your runner still does that.
-
-For pytest, generate JUnit:
-
-```sh
-cd /path/to/your/repo
-pytest --junitxml .vouch/artifacts/pytest.xml
-```
-
-For the repo-level v0.2 flow, import JUnit evidence directly:
-
-```sh
-vouch --repo /path/to/your/repo evidence import junit .vouch/artifacts/pytest.xml
-vouch --repo /path/to/your/repo gate
-```
-
-This writes `.vouch/evidence/manifest.json` and gates against the compiled obligation IR. JUnit only satisfies required-test obligations, so security, runtime, rollback, and behavior obligations still need their own evidence.
-
-For a simple smoke check, write an artifact that names the obligation IDs it covers:
-
-```json
-{
- "status": "pass",
- "obligations": [
- "app.service.behavior.service_returns_stable_json"
- ]
-}
-```
-
-Save artifacts under `.vouch/artifacts/`.
-
-If an artifact does not include the exact obligation ID, Vouch will not count it as coverage.
-
-### 7. Attach Evidence
-
-Attach behavior, security, test, runtime, and rollback evidence as needed. The artifact kind must match the obligation kind.
-`verifier_output` artifacts are the exception: they may reference any compiled obligation, import structured verifier findings, and do not satisfy required evidence coverage by themselves.
-
-| Obligation ID Contains | Attach With `--kind` |
-| --- | --- |
-| `.behavior.` | `behavior_trace` |
-| `.security.` | `security_check` |
-| `.required_test.` | `test_coverage` |
-| `.runtime_signal.` | `runtime_metric` |
-| `.rollback.` | `rollback_plan` |
-
-```sh
-vouch --repo /path/to/your/repo manifest attach-artifact \
- --manifest .vouch/manifests/run-123.json \
- --id behavior \
- --kind behavior_trace \
- --path .vouch/artifacts/behavior.json \
- --producer pytest \
- --command "pytest --junitxml .vouch/artifacts/pytest.xml" \
- --exit-code 0 \
- --out .vouch/manifests/run-123.json
-```
-
-If your raw JUnit testcase names do not contain Vouch obligation IDs, map them through `.vouch/test-map.json`:
-
-```sh
-vouch --repo /path/to/your/repo manifest attach-artifact \
- --manifest .vouch/manifests/run-123.json \
- --id pytest \
- --kind test_coverage \
- --path .vouch/artifacts/pytest.xml \
- --test-map .vouch/test-map.json \
- --exit-code 0 \
- --out .vouch/manifests/run-123.json
-```
-
-Signature fields are optional in beta. To attach signed evidence, first write a
-`vouch.evidence_bundle.v0` JSON file for the artifact. The bundle binds the
-manifest task, touched specs, artifact ID/kind/path/hash, covered obligation
-IDs, runner identity, and timestamp. Sign that evidence bundle with cosign, then
-include the bundle paths and expected identity when attaching the artifact.
-The signer must also be listed in `.vouch/config.json`:
-
-```json
-{
- "allowed_signers": [
- {
- "identity": "https://github.com/ORG/REPO/.github/workflows/vouch.yml@refs/heads/main",
- "oidc_issuer": "https://token.actions.githubusercontent.com"
- }
- ]
-}
-```
-
-```sh
-cosign sign-blob .vouch/artifacts/behavior.vouch-bundle.json \
- --bundle .vouch/artifacts/behavior.sigstore.json
-
-vouch --repo /path/to/your/repo manifest attach-artifact \
- --manifest .vouch/manifests/run-123.json \
- --id behavior \
- --kind behavior_trace \
- --path .vouch/artifacts/behavior.json \
- --evidence-bundle .vouch/artifacts/behavior.vouch-bundle.json \
- --signature-bundle .vouch/artifacts/behavior.sigstore.json \
- --signer-identity "https://github.com/ORG/REPO/.github/workflows/vouch.yml@refs/heads/main" \
- --signer-oidc-issuer "https://token.actions.githubusercontent.com" \
- --exit-code 0 \
- --out .vouch/manifests/run-123.json
-```
-
-Production-style gates should require signed evidence:
-
-```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- gate --require-signed
-```
-
-`--require-signed` verifies each `evidence_bundle` with `cosign verify-blob`
-using the artifact's `signature_bundle`, `signer_identity`, and
-`signer_oidc_issuer` fields. It also rejects bundles whose manifest identity,
-artifact hash, obligation IDs, runner identity, or runner OIDC issuer do not
-match the manifest and artifact being gated, or whose signer is not present in
-`config.allowed_signers`.
-
-### 8. Gate The Change
-
-```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- gate
-```
-
-Vouch loads release policy from `.vouch/policy/release-policy.json` by default.
-Pass `--policy` to simulate or gate with a different policy file:
-
-```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- policy simulate --policy .vouch/policy/release-policy.json
-
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- gate --policy .vouch/policy/release-policy.json
-```
-
-Possible decisions:
-
-- `block`: required evidence is missing or invalid.
-- `human_escalation`: high-risk change passed evidence checks but has no canary.
-- `canary`: high-risk change passed evidence checks and has canary enabled.
-- `auto_merge`: low/medium-risk change passed required evidence checks.
-
-For machine-readable output:
-
-```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- gate --json
+go install github.com/duriantaco/vouch/cmd/vouch@latest
```
-To preserve a compact gate result artifact for CI upload or required-status checks:
+From this checkout:
```sh
-vouch --repo /path/to/your/repo \
- --manifest .vouch/manifests/run-123.json \
- gate --out .vouch/build/gate-result.json
+go install ./cmd/vouch
```
-## Project Docs
+## Docs
-- [Roadmap](ROADMAP.md) explains where the project is going and what remains before this can be production infrastructure.
-- [Comparison](COMPARISON.md) explains how Vouch composes with Sigstore, SLSA, in-toto, OPA, and Conftest.
-- [Benchmarks](docs/BENCHMARKS.md) explains the repo-local VouchBench harness, assertions, and current validation scope.
-- `scripts/vouchbench-repo.sh --repo /path/to/repo` runs a non-destructive Vouch evaluation against an external repo snapshot.
-- [Contributing](CONTRIBUTING.md) explains how to help and which areas need work.
+Published docs:
-The problem it attempts to solve is:
+https://duriantaco.github.io/vouch/
-> If agents write more code than humans can carefully review line by line, what machine-checkable contract/evidence layer can sit before release?
+The site is deployed from `.github/workflows/pages.yml` after changes land on
+`main`. The source lives in `docs/site/` and is built with MkDocs.
-Vouch's answer is:
+- [Compiler Architecture](docs/COMPILER.md)
+- [GitHub Actions](docs/GITHUB_ACTIONS.md)
+- [Benchmarks](docs/BENCHMARKS.md)
+- [Comparison](COMPARISON.md)
+- [Roadmap](ROADMAP.md)
+- [Contributing](CONTRIBUTING.md)
-1. Human-owned intent
-2. Typed AST
-3. Structured spec
-4. Obligation IR
-5. Verification plan
-6. Generated verifier/test/release artifacts
-7. Evidence manifest
-8. Deterministic evidence checks
-9. Release decision
+## Status
-The output is not generated product code, and it does not certify that the implementation is correct. The output is an auditable answer to a narrower question. For the contracts this change claims to touch, are the required obligations covered by evidence artifacts that pass Vouch's current checks?
+Vouch is beta infrastructure. It is ready for shadow-mode pilots, not blind
+production enforcement.
-## Current Assurance Level
-
-Today, Vouch can check:
-
-- Intent YAML parses into a typed AST with source-span diagnostics.
-- Specs compile into stable semantic obligation IDs.
-- Changed files map to touched contract ownership paths.
-- Manifests cannot lower risk below the touched spec.
-- Evidence artifacts reference known obligations of the right evidence kind.
-- Artifact paths stay inside the repo and files exist.
-- Artifact exit codes are present and zero.
-- Optional artifact SHA-256 values match file contents.
-- Optional `gate --require-signed` mode verifies signed `vouch.evidence_bundle.v0` files, binds manifest identity, artifact hashes, obligation IDs, and runner identity, and requires signer metadata to match `config.allowed_signers`.
-- Release policy is loaded from `.vouch/policy/release-policy.json` or an explicit `--policy` file.
-- Generated verifier packets pin prompt and output schema versions.
-- Structured `verifier_output` artifacts parse as `vouch.verifier_output.v0` and import pass/block findings into release policy.
-- `verifier_output` artifacts do not count as required behavior, security, test, runtime, or rollback evidence.
-- JUnit evidence has no failure/error/skipped testcases and covers required test obligations.
-- Raw pytest/JUnit testcases can be mapped through `.vouch/test-map.json`.
-- Generic JSON/text artifacts contain exact obligation IDs and optional passing status.
-- Compact gate results can be written to a JSON artifact file.
-- Release decisions follow deterministic policy rules.
-
-Today, Vouch cannot check:
-
-- Whether arbitrary code semantically implements the declared behavior.
-- Whether an AI verifier's judgment is correct beyond its structured output, obligation references, model/prompt pins, and artifact provenance.
-- Whether a generic JSON/text artifact is truthful beyond its structure, IDs, status, path, exit code, and optional hash.
-- Whether tests were actually run unless the external runner preserves and signs the artifact chain.
-- Whether product intent was inferred correctly from code.
-- Whether release policy uses a general-purpose policy language such as Rego. The current policy evaluator is a small Vouch JSON rule engine.
-- Whether signer identities should vary by contract owner, path, or risk tier. The current allowlist is repo-level.
-
-## Validation Status
-
-For repeatable local validation, run:
+The local VouchBench harness proves the current compiler/evidence/policy path is
+deterministic over fixture scenarios. It does not prove arbitrary code is correct
+or that real teams will adopt the workflow.
```sh
scripts/vouchbench.sh
```
-That harness compares baseline outcomes with Vouch's gate decision across fixed scenarios. The current corpus checks missing release evidence, manifest traceability, invalid artifact exit codes, high-risk canary routing, high-risk human escalation, and low-risk auto-merge. See [Benchmarks](docs/BENCHMARKS.md) for the exact scenarios, assertions, and limits.
-
-The generic flow has been validated against temp copies of real Python repos:
-
-| Repo | Shape | Evidence Path | Decision |
-| --- | --- | --- | --- |
-| `sundae` | Flat Python package | pytest/JUnit evidence | `auto_merge` |
-| `sago` | Python `src/` layout | high-risk builder contract | `canary` |
-| `wooster` | Flat Python package | raw pytest JUnit mapped through `.vouch/test-map.json` | `auto_merge` |
-
-Those runs exercised `init`, `contract suggest`, `contract create`, `manifest create`, `manifest check`, `junit map`, `manifest attach-artifact`, and `gate`.
-
-This validates the generic workflow plumbing. It does not mean Vouch understands those products automatically. Vouch still needs human-owned contracts. Suggestions are structural starting points based on repo shape and ownership paths.
-
-## What This Solves
-
-Traditional code review relies on humans reading diffs and noticing the important things. That model starts to fail when agents can produce changes faster than humans can inspect them.
-
-Vouch moves part of the release boundary from informal diff reading to explicit contracts:
-
-- Informal model: human reads diff, then decides whether the change is safe enough.
-- Vouch model: human declares intent, Vouch compiles obligations, the runner produces artifacts, Vouch checks evidence coverage, and policy chooses a release posture.
-
-This gives a team a place to enforce:
-
-- What behavior must remain true.
-- What security invariants must hold.
-- What tests must cover.
-- What runtime signals must exist.
-- What rollback path must be available.
-- What release policy applies to the risk.
-
-That is the surface Vouch is aiming at. Vouch does not do semantic judgment over arbitrary code, but contract/evidence enforcement for the behavior humans have explicitly declared.
-
-## Not Just CI
-
-Vouch does not execute project checks today. It consumes a manifest and artifacts after external commands have run.
-
-A normal CI gate answers:
-
-> Did this command pass?
-
-Vouch's job is to answer a different set of questions:
-
-- What human owned contract did this change touch?
-- What obligations did that contract compile into?
-- Which evidence artifact covers each obligation?
-- Is the evidence complete, structurally valid, and tied to this manifest?
-- Does release policy allow `block`, `human_escalation`, `canary`, or `auto_merge`?
-
-If Vouch becomes only a wrapper around `pytest`, `go test`, or a generic "merge or don't merge" check, it is not useful enough. The compiler direction is important because the value is in the typed contract, obligation IR, evidence mapping, and auditable release decision.
-
-## Is It A Compiler?
-
-Yes and no. Yes, in the control-plane architecture sense.
-
-No, in the traditional programming language compiler sense.
-
-Vouch has compiler-like stages:
-
-| Stage | What Vouch Does Today |
-| --- | --- |
-| Source language | Reads intent YAML. |
-| Front end | Parses into a typed AST with source-span diagnostics. |
-| Semantic checks | Validates required fields, risk rules, and spec shape. |
-| Middle end | Lowers specs into obligation IR. |
-| Back end | Emits verification plans and runner/verifier/release artifacts. |
-| Runtime checks | Collects evidence, applies policy, and returns a gate decision. |
-
-Making it more compiler-like is useful because it makes the system more accurate in the areas that matter here. These things include deterministic parsing, typed intermediate representations, structured diagnostics, generated artifacts, and auditable policy decisions.
-
-The current implementation is early. Policy is file-backed but still simple, generic non-JUnit artifacts are shallow, and contract suggestions are structural heuristics. The compiler direction is still the right direction because the value is in deterministic obligations and evidence linkage, not in another generic "merge or don't merge" opinion.
-
-## Current Pipeline
-
-| Command Area | Input | Output |
-| --- | --- | --- |
-| `bootstrap` | repo signals | draft intents plus bootstrap report |
-| `compile` | `.vouch/intents/*.yaml` | specs, aggregate obligation IR, and verification plan |
-| `intent parse` | `.vouch/intents/*.yaml` | `vouch.ast.v0` with source spans and diagnostics |
-| `intent compile` | Intent AST | `vouch.spec.v0` JSON |
-| `ir build` | Spec JSON | `vouch.ir.v0` obligations |
-| `plan build` | IR plus change manifest | `vouch.plan.v0` verification plan |
-| `artifacts build` | Spec JSON | runner/verifier/release artifacts |
-| `junit map` | raw pytest/JUnit and `.vouch/test-map.json` | Vouch-compatible JUnit evidence |
-| `evidence import junit` | raw pytest/JUnit and compiled obligation IR | `.vouch/evidence/manifest.json` |
-| `policy simulate` | manifest, evidence, and release policy | policy input and release decision |
-| `evidence`, `verify`, `gate` | manifest and linked artifacts | findings and release decision |
-| Generic onboarding | repo shape and changed files | `.vouch` layout, contract suggestions, manifests, attached artifacts |
-
-Generated artifact files:
-
-- `verification-plan.json`
-- `verifier-packets.json`
-- `test-obligations.json`
-- `release-policy.json`
-
-## What It Checks Today
-
-The MVP currently handles and checks:
-
-- Schema versions.
-- Repo profile detection for Python, Node, Go, Rust, and fallback repos.
-- Contract suggestion and creation.
-- Manifest creation from changed files and owned paths.
-- Behavior contracts.
-- Security invariants.
-- Required test evidence.
-- Runtime metrics.
-- Rollback plans.
-- Canary requirements.
-- External side effects.
-- Risk classification.
-- Manifest risk downgrades.
-- Compiler diagnostics with source locations.
-- Stable semantic obligation IDs.
-- Evidence artifact references.
-- Evidence artifact file existence.
-- Optional evidence artifact SHA-256.
-- JUnit XML test evidence.
-- Touched-spec compilation stats.
-
-It blocks when:
-
-- The spec or manifest is invalid.
-- The manifest lowers risk below the touched spec.
-- Behavior evidence is missing.
-- Required test evidence is missing.
-- Security evidence is missing.
-- Runtime metrics are missing.
-- Rollback evidence is missing.
-- Canary config is invalid.
-- External side effects have no rollback or compensation.
-- Tests are reported as failing.
-- Evidence artifacts reference unknown obligations.
-- Evidence artifact files are missing.
-- Evidence artifact hashes do not match.
-- JUnit evidence has failing or missing obligation testcases.
-- Changed files are not owned by any touched spec.
-- Raw JUnit cannot be mapped to required-test obligations.
-
-For high-risk changes with complete evidence, it chooses `canary`, not `auto_merge`.
-
-## Demo
-
-The demo uses a synthetic high-risk `auth.password_reset` change because it exercises the core risk classes:
-
-- Account enumeration.
-- Token storage.
-- Rate limiting.
-- Token logging.
-- Token replay tests.
-- Runtime metrics.
-- Feature-flag rollback.
-- Email side effects.
-
-The demo exercises the compiler plumbing and failure modes. It does not mean Vouch can infer or verify password reset correctness from application code.
-
-Run the repo-level compiler pipeline:
-
-```sh
-vouch --repo demo_repo compile
-vouch --repo demo_repo compile --emit ir
-```
-
-Parse intent into a typed AST:
-
-```sh
-vouch intent parse --intent demo_repo/.vouch/intents/auth.password_reset.yaml --out /tmp/auth.password_reset.ast.json
-```
-
-Compile human intent into a structured spec:
-
-```sh
-vouch intent compile --intent demo_repo/.vouch/intents/auth.password_reset.yaml --out /tmp/auth.password_reset.json
-```
-
-Build an intermediate representation from the spec:
-
-```sh
-vouch ir build --spec demo_repo/.vouch/specs/auth.password_reset.json --out /tmp/auth.password_reset.ir.json
-```
-
-Build a verification plan from spec + manifest:
-
-```sh
-vouch plan build --spec demo_repo/.vouch/specs/auth.password_reset.json --manifest demo_repo/.vouch/manifests/pass.json --out /tmp/auth.password_reset.plan.json
-```
-
-Generate runner/verifier/release artifacts:
-
-```sh
-vouch artifacts build --spec demo_repo/.vouch/specs/auth.password_reset.json --out /tmp/vouch-artifacts
-```
-
-Run a blocked change:
-
-```sh
-vouch --repo demo_repo --manifest demo_repo/.vouch/manifests/blocked.json evidence
-```
-
-Expected:
-
-```console
-Decision: block
-IR obligations covered: 10/16
-```
-
-Run a passing high-risk change:
-
-```sh
-vouch --repo demo_repo --manifest demo_repo/.vouch/manifests/pass.json evidence
-```
-
-Expected:
-
-```console
-Decision: canary
-IR obligations covered: 16/16
-```
-
-It canaries because the change is high-risk auth behavior even though evidence is complete.
-
-## Generic Repo Onboarding
-
-Vouch is generic at the compiler layer. The repo supplies contracts. Vouch compiles and gates them.
-
-The Quickstart above is the recommended path. The main idea is:
-
-1. `init` creates `.vouch/`.
-2. `contract suggest` gives structural starting points.
-3. `contract create` writes intent and spec files.
-4. `manifest create` links changed files to touched contracts.
-5. Your runner produces test/probe/scanner artifacts.
-6. `manifest attach-artifact` links artifacts to compiled obligation IDs.
-7. `gate` returns `block`, `human_escalation`, `canary`, or `auto_merge`.
-
-For normal JUnit output, map real testcases to Vouch required-test obligations with `.vouch/test-map.json`. `contract create` writes empty stubs for new required-test obligations:
-
-```json
-{
- "version": "vouch.test_map.v0",
- "mappings": {
- "app.service.required_test.service_json_contract_is_stable": [
- "tests/test_app.py::test_service_json_contract"
- ]
- }
-}
-```
-
-Map raw JUnit explicitly:
-
-```sh
-vouch --repo /path/to/repo junit map \
- --manifest .vouch/manifests/run-123.json \
- --junit .vouch/artifacts/pytest.xml \
- --test-map .vouch/test-map.json \
- --out .vouch/artifacts/vouch-junit.xml
-```
-
-Or map and attach in one step:
-
-```sh
-vouch --repo /path/to/repo manifest attach-artifact \
- --manifest .vouch/manifests/run-123.json \
- --id pytest \
- --kind test_coverage \
- --path .vouch/artifacts/pytest.xml \
- --test-map .vouch/test-map.json \
- --exit-code 0 \
- --out .vouch/manifests/run-123.json
-```
-
-For the repo-level v0.2 path, import raw JUnit into an evidence manifest:
-
-```sh
-vouch --repo /path/to/repo evidence import junit .vouch/artifacts/pytest.xml
-vouch --repo /path/to/repo gate
-```
-
-## GitHub PR Summary
-
-Use `gate --github-summary` in GitHub Actions to append a Markdown decision report to the pull request job summary:
-
-```sh
-vouch gate --github-summary
-```
-
-The command writes to `$GITHUB_STEP_SUMMARY` and still exits non-zero when the release decision is `block`. A copyable workflow example lives at [`docs/github-action-example.yml`](docs/github-action-example.yml).
-
-## Commands
-
-```sh
-vouch try --repo DIR [--junit FILE] [--test-command CMD] [--write] [--keep]
-vouch --repo DIR init
-vouch --repo DIR bootstrap [--dry-run] [--check] [--aggressive] [--review [--limit N|--all]]
-vouch --repo DIR compile [--emit ast|spec|ir|plan]
-vouch --repo DIR contract suggest
-vouch --repo DIR contract create --name ID --owner OWNER --risk RISK --paths GLOB --behavior TEXT --required-test TEXT
-vouch intent parse --intent FILE --out FILE
-vouch intent compile --intent FILE --out FILE
-vouch ir build --spec FILE --out FILE
-vouch --manifest FILE plan build --spec FILE --out FILE
-vouch artifacts build --spec FILE --out DIR
-vouch --repo DIR spec lint
-vouch --repo DIR --manifest FILE manifest check
-vouch --repo DIR manifest create --task-id ID --summary TEXT --agent NAME --run-id ID [--runner-identity ID --runner-oidc-issuer URL] --out FILE
-vouch --repo DIR --manifest FILE manifest attach-artifact --id ID --kind KIND --path FILE --exit-code N [--evidence-bundle FILE --signature-bundle FILE --signer-identity ID --signer-oidc-issuer URL] --out FILE
-vouch --repo DIR --manifest FILE junit map --junit FILE --test-map FILE --out FILE
-vouch --repo DIR evidence import junit [--out FILE] FILE
-vouch --repo DIR --manifest FILE policy simulate [--policy FILE] [--require-signed]
-vouch --repo DIR --manifest FILE verify [--policy FILE]
-vouch --repo DIR --manifest FILE gate [--policy FILE] [--out FILE] [--github-summary] [--require-signed] [--verbose] [--explain]
-vouch --repo DIR --manifest FILE evidence [--policy FILE]
-```
-
-`--json` emits machine-readable evidence for commands that collect evidence. For `gate`, `--json` emits the compact gate result to stdout and `--out FILE` writes the same gate-result shape as a JSON artifact.
-
-## FAQ
-
-### Why is this more complicated than normal CI?
-
-Because Vouch is checking a different thing. CI usually answers whether commands passed. Vouch asks whether the change has the required evidence for the contracts it touches. That needs contracts, compiled obligations, evidence artifacts, and policy.
-
-For low-risk changes, this ceremony may not be worth it. For auth, payments, permissions, migrations, public APIs, external side effects, and production rollout, the extra structure is the point.
-
-### Why does `vouch try` use a snapshot?
-
-First runs should be safe. By default, `vouch try --repo PATH` copies tracked and unignored files into a temporary directory, drafts contracts there, compiles them, and prints a report. Your source repo is not changed.
-
-### What does `vouch try --write` do?
-
-It runs the same first-run pipeline directly in the source repo. Use it when the preview looks useful and you are ready to create `.vouch/` files.
-
-### How do I choose the first contract to review?
-
-Run `vouch bootstrap --review`. Start with one high-risk or medium-risk draft that matches a real release boundary. Good first targets are auth, billing, permissions, migrations, public APIs, and deployment-critical code.
-
-### Why not just ask another agent to review the code?
-
-An agent review is still an opinion over a diff. Vouch produces a deterministic gate result from declared obligations and evidence artifacts. You can audit which obligation was required, which artifact covered it, which policy rule fired, and why the gate returned `block`, `human_escalation`, `canary`, or `auto_merge`.
-
-### Does Vouch replace tests?
-
-No. Tests are one evidence source. Vouch consumes test output, currently JUnit, and checks whether it covers required-test obligations. It does not run your test suite itself.
-
-### Why did `vouch gate` block even though tests passed?
-
-Usually because JUnit only covers required-test obligations. Behavior, security, runtime, and rollback obligations require their own accepted evidence. That is expected on a first run.
-
-### Does Vouch infer product intent from code?
-
-No. `vouch bootstrap` drafts conservative contracts from repo signals such as tests, paths, CODEOWNERS, and CI files. Humans still own the intent and must accept, edit, merge, or delete generated contracts.
-
-### What do I have to write myself?
-
-You need to review or write the release contract:
-
-- component ownership
-- risk level
-- behavior obligations
-- security invariants
-- required tests
-- runtime signals
-- rollback expectations
-
-Bootstrap can create a starting point, but the contract is only useful once a human makes it match the product.
-
-### What is the first useful adoption step?
-
-Pick one high-risk component instead of trying to cover the whole repo. Good first targets are auth, billing, permissions, data deletion, migrations, public APIs, and deployment-critical code.
-
-Create or edit one contract, map its required tests, run JUnit import, and let `vouch gate` show which evidence is still missing.
-
-### Is Vouch production-ready?
-
-No. Treat it as beta infrastructure for experimenting with contract/evidence release gates. It is not a replacement for code review, security review, incident response, or production ownership.
-
-### What does VouchBench actually validate?
-
-VouchBench validates deterministic release-gate behavior over a fixed corpus. It checks expected decisions, exit codes, coverage counts, missing obligations, invalid evidence, policy rules, and manifest/spec errors.
-
-It does not validate arbitrary product correctness.
-
-### Can I run it against my own repo without modifying it?
-
-Yes:
-
-```sh
-scripts/vouchbench-repo.sh --repo /path/to/repo --out /tmp/vouchbench-repo
-```
-
-That copies your repo into a temp snapshot and runs Vouch there.
-
-### What should I look at after bootstrap?
-
-Start with:
-
-```text
-.vouch/intents/*.yaml
-.vouch/build/obligations.ir.json
-.vouch/build/verification-plan.json
-.vouch/evidence/manifest.json
-```
-
-The intent files are the human-editable contract drafts. The IR and plan show what Vouch will require. The evidence manifest shows which test artifacts linked to which obligations.
-
-## Test
-
-The sandbox may not allow Go to use the default cache path, so use a temp cache:
+## Development
```sh
GOCACHE=/private/tmp/vouch-gocache go test ./...
@@ -1135,14 +98,4 @@ GOCACHE=/private/tmp/vouch-gocache go test ./...
## License
-Vouch is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE).
-
-## Why This Exists
-
-**The compiler analogy is a direction, not a maturity claim.**
-
-Mature software delivery relies on toolchains. These include language semantics, type systems, tests, validation, reproducible builds, monitoring, and rollback. Agent-written code needs a similar toolchain around intent and evidence.
-
-Vouch is an early piece of that toolchain. Source intent -> AST -> spec -> obligations -> plan -> evidence -> release decision.
-
-The output is not trust by assertion. It is a deterministic record of which declared obligations were required, which evidence artifacts covered them, what failed, and what release posture the current policy selected.
+Apache-2.0. See [LICENSE](LICENSE).
diff --git a/docs/COMPILER.md b/docs/COMPILER.md
new file mode 100644
index 0000000..90b0f72
--- /dev/null
+++ b/docs/COMPILER.md
@@ -0,0 +1,186 @@
+
+
+
+
+# Compiler Architecture
+
+Vouch is a compiler for release contracts. The current gate is the runtime that
+consumes the compiler output.
+
+This is the split:
+
+```text
+compiler: intent -> AST -> spec -> obligation IR -> verification plan/artifacts
+runtime: manifest + evidence + policy -> release decision
+```
+
+Calling Vouch only a gate is incomplete. Calling it a compiler without naming
+the current runtime is also incomplete.
+
+## Source Language
+
+The source language is human-owned YAML under `.vouch/intents/`.
+
+Example:
+
+```yaml
+version: vouch.intent.v0
+feature: auth.password_reset
+owner: platform
+owned_paths:
+ - src/auth/**
+ - tests/auth/**
+risk: high
+goal: Preserve password-reset safety during agent changes.
+
+behavior:
+ - user can request password reset by email
+ - response does not reveal whether account exists
+
+security:
+ - reset token is stored hashed
+ - reset token is never logged
+
+required_tests:
+ - token expires
+ - unknown email receives same response shape
+
+runtime_metrics:
+ - password_reset.requested
+ - password_reset.failed
+
+rollback:
+ strategy: feature_flag
+ flag: password_reset_v2
+```
+
+The parser accepts only the intent keys implemented in
+[`internal/vouch/intent.go`](../internal/vouch/intent.go): `version`, `feature`,
+`owner`, `owned_paths`, `risk`, `goal`, `behavior`, `security`,
+`required_tests`, `runtime_metrics`, `runtime_alerts`, and `rollback`.
+
+## Compiler Stages
+
+| Stage | Command | Main code | Output |
+| --- | --- | --- | --- |
+| Parse intent | `vouch intent parse` | [`ParseIntentASTFile`](../internal/vouch/intent.go) | `vouch.ast.v0` with source spans and diagnostics |
+| Analyze intent | repo compile path | [`AnalyzeIntentAST`](../internal/vouch/intent.go) | typed intent values |
+| Compile spec | `vouch intent compile` | [`SpecFromIntent`](../internal/vouch/intent.go) | `vouch.spec.v0` JSON |
+| Build IR | `vouch ir build` | [`IRFromSpec`](../internal/vouch/ir.go) | `vouch.ir.v0` obligations |
+| Build plan | `vouch plan build` | [`VerificationPlanFromIR`](../internal/vouch/plan.go) | `vouch.plan.v0` verification plan |
+| Build artifacts | `vouch artifacts build` | [`BuildArtifacts`](../internal/vouch/artifacts.go) | verifier packets, test obligations, release policy artifact |
+| Compile repo | `vouch compile` | [`CompileRepo`](../internal/vouch/compile.go) | `.vouch/build/` compiler outputs |
+
+The CLI dispatcher for these commands is
+[`Main`](../internal/vouch/cli.go).
+
+## Repo Compile Output
+
+`vouch compile` reads `.vouch/intents/*.yaml` and writes:
+
+- `.vouch/build/ast/*.ast.json`
+- `.vouch/specs/*.spec.json`
+- `.vouch/build/obligations.ir.json`
+- `.vouch/build/verification-plan.json`
+
+The repo-level compiler output structs live in
+[`internal/vouch/compile.go`](../internal/vouch/compile.go).
+
+## Obligation IR
+
+`IRFromSpec` lowers a spec into stable obligation IDs. The current obligation
+kinds are defined in [`internal/vouch/types.go`](../internal/vouch/types.go):
+
+| Obligation kind | Required evidence kind |
+| --- | --- |
+| `behavior` | `behavior_trace` |
+| `security` | `security_check` |
+| `required_test` | `test_coverage` |
+| `runtime_signal` | `runtime_metric` |
+| `rollback` | `rollback_plan` |
+
+Example IDs:
+
+```text
+auth.password_reset.behavior.user_can_request_password_reset_by_email
+auth.password_reset.security.reset_token_is_never_logged
+auth.password_reset.required_test.token_expires
+auth.password_reset.runtime_signal.password_reset_failed
+auth.password_reset.rollback.feature_flag_password_reset_v2
+```
+
+The ID format is intentional: evidence artifacts must reference exact obligation
+IDs.
+
+## Runtime Gate
+
+The runtime starts after compilation.
+
+`CollectEvidenceWithOptions` in
+[`internal/vouch/evidence.go`](../internal/vouch/evidence.go) loads:
+
+- compiled specs
+- a change manifest
+- generated IR and verification plans for touched specs
+- linked evidence artifacts
+- release policy
+
+It then builds coverage, imports verifier findings, and applies policy.
+
+Default policy is implemented in
+[`DefaultReleasePolicy`](../internal/vouch/policy.go). The current decisions
+are:
+
+- `block`
+- `human_escalation`
+- `canary`
+- `auto_merge`
+
+`gate` exits non-zero only when the final decision is `block`.
+
+## Evidence Model
+
+Vouch can use manifest-attached artifacts or the simpler repo-level JUnit import
+path.
+
+Manifest-backed artifacts are attached with:
+
+```sh
+vouch --repo DIR manifest attach-artifact \
+ --manifest .vouch/manifests/run-123.json \
+ --id pytest \
+ --kind test_coverage \
+ --path .vouch/artifacts/pytest.xml \
+ --exit-code 0 \
+ --out .vouch/manifests/run-123.json
+```
+
+The simpler JUnit path is:
+
+```sh
+vouch --repo DIR evidence import junit .vouch/artifacts/pytest.xml
+vouch --repo DIR gate
+```
+
+JUnit covers `required_test` obligations only. Missing behavior, security,
+runtime, or rollback evidence can still block.
+
+## What Is Proven
+
+The repo-local benchmark is VouchBench:
+
+```sh
+scripts/vouchbench.sh
+```
+
+It proves the current compiler/evidence/policy path is deterministic over the
+fixture corpus. See [Benchmarks](BENCHMARKS.md).
+
+It does not prove:
+
+- arbitrary code correctness
+- automatic product-intent inference
+- production incident reduction
+- product-market fit
+
+That broader claim needs shadow-mode pilots on real repos.
diff --git a/docs/GITHUB_ACTIONS.md b/docs/GITHUB_ACTIONS.md
new file mode 100644
index 0000000..004394b
--- /dev/null
+++ b/docs/GITHUB_ACTIONS.md
@@ -0,0 +1,169 @@
+
+
+
+
+# GitHub Actions
+
+This repo uses GitHub Actions for two things:
+
+1. publishing the Vouch docs site to GitHub Pages
+2. running the current Vouch gate in pull request workflows
+
+Published docs URL:
+
+https://duriantaco.github.io/vouch/
+
+Pages is configured with `build_type: workflow`, so content is published by
+`.github/workflows/pages.yml` after changes land on `main`.
+
+## Docs Deployment
+
+The Pages workflow follows GitHub's custom Actions publishing flow:
+
+- `actions/configure-pages`
+- `actions/upload-pages-artifact`
+- `actions/deploy-pages`
+
+Workflow file:
+
+```text
+.github/workflows/pages.yml
+```
+
+Source files:
+
+```text
+mkdocs.yml
+docs/requirements.txt
+docs/site/
+docs/site/assets/vouch.png
+```
+
+The workflow builds the MkDocs site into `_site/`, uploads that artifact, and
+deploys it to the `github-pages` environment.
+
+Official references:
+
+- https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site
+- https://github.com/actions/upload-pages-artifact
+- https://github.com/actions/deploy-pages
+
+## Vouch PR Workflow
+
+The relevant code paths are:
+
+- CLI command and `--github-summary` flag:
+ [`internal/vouch/cli.go`](../internal/vouch/cli.go)
+- `$GITHUB_STEP_SUMMARY` handling:
+ [`appendGitHubSummary`](../internal/vouch/cli.go)
+- Markdown summary rendering:
+ [`RenderGitHubSummary`](../internal/vouch/render.go)
+- Final gate result shape:
+ [`GateResultFromEvidence`](../internal/vouch/render.go)
+- Default release policy:
+ [`DefaultReleasePolicy`](../internal/vouch/policy.go)
+
+### Shadow Mode
+
+Use this first. It shows Vouch's decision in the job summary but does not block
+the pull request.
+
+```yaml
+name: Vouch
+
+on:
+ pull_request:
+
+jobs:
+ vouch:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: "1.26"
+
+ - name: Install Vouch
+ run: go install github.com/duriantaco/vouch/cmd/vouch@latest
+
+ - name: Compile Vouch contracts
+ run: vouch compile
+
+ - name: Run tests
+ run: pytest --junitxml .vouch/artifacts/pytest.xml
+
+ - name: Import JUnit evidence
+ run: vouch evidence import junit .vouch/artifacts/pytest.xml
+
+ - name: Gate PR
+ continue-on-error: true
+ run: vouch gate --github-summary --out .vouch/build/gate-result.json
+
+ - name: Upload Vouch result
+ uses: actions/upload-artifact@v4
+ with:
+ name: vouch-gate-result
+ path: .vouch/build/gate-result.json
+```
+
+Use shadow mode until reviewers agree that Vouch is catching real
+release-readiness gaps and the false-block rate is acceptable.
+
+### Enforced Mode
+
+After a shadow-mode pilot, remove `continue-on-error: true` from the gate step:
+
+```yaml
+ - name: Gate PR
+ run: vouch gate --github-summary --out .vouch/build/gate-result.json
+```
+
+`vouch gate` exits non-zero only when the release decision is `block`.
+`human_escalation`, `canary`, and `auto_merge` are non-blocking process exits.
+
+### What The Summary Shows
+
+`gate --github-summary` appends a Markdown report to `$GITHUB_STEP_SUMMARY`.
+The report includes:
+
+- final decision
+- risk
+- obligation coverage
+- policy path
+- reasons
+- component-level covered and missing obligations
+- verifier findings and required fixes
+
+The renderer is [`RenderGitHubSummary`](../internal/vouch/render.go).
+
+### Contracts In CI
+
+Do not silently generate new contracts in an enforced workflow. Commit reviewed
+`.vouch/intents/*.yaml`, `.vouch/specs/*.json`, and
+`.vouch/policy/release-policy.json`.
+
+For pilots, it is acceptable to run:
+
+```sh
+vouch bootstrap --review
+```
+
+Use generated contracts as scaffolding only. A human should edit owners, paths,
+risk, behavior, security, runtime signals, and rollback expectations before
+Vouch becomes an enforced gate.
+
+### Signed Evidence
+
+For stricter runs, use:
+
+```sh
+vouch gate --require-signed --github-summary
+```
+
+The signed-evidence checks are wired through `CollectEvidenceWithOptions` and
+artifact linking in [`internal/vouch/evidence.go`](../internal/vouch/evidence.go).
+Allowed signers are loaded from `.vouch/config.json`.
+
+Use this only after your runners are producing Vouch evidence bundles and cosign
+signature bundles.
diff --git a/docs/github-action-example.yml b/docs/github-action-example.yml
index 5fbb85d..e7c91ba 100644
--- a/docs/github-action-example.yml
+++ b/docs/github-action-example.yml
@@ -16,9 +16,6 @@ jobs:
- name: Install Vouch
run: go install github.com/duriantaco/vouch/cmd/vouch@latest
- - name: Bootstrap Vouch contracts
- run: vouch bootstrap --check || vouch bootstrap
-
- name: Compile Vouch obligations
run: vouch compile
@@ -29,4 +26,11 @@ jobs:
run: vouch evidence import junit .vouch/artifacts/pytest.xml
- name: Gate PR
- run: vouch gate --github-summary
+ continue-on-error: true
+ run: vouch gate --github-summary --out .vouch/build/gate-result.json
+
+ - name: Upload Vouch result
+ uses: actions/upload-artifact@v4
+ with:
+ name: vouch-gate-result
+ path: .vouch/build/gate-result.json
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000..83a4198
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1 @@
+mkdocs-material==9.7.6
diff --git a/docs/site/.nojekyll b/docs/site/.nojekyll
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/docs/site/.nojekyll
@@ -0,0 +1 @@
+
diff --git a/docs/site/assets/vouch.png b/docs/site/assets/vouch.png
new file mode 100644
index 0000000..7de6589
Binary files /dev/null and b/docs/site/assets/vouch.png differ
diff --git a/docs/site/benchmarks.md b/docs/site/benchmarks.md
new file mode 100644
index 0000000..cdc57bf
--- /dev/null
+++ b/docs/site/benchmarks.md
@@ -0,0 +1,31 @@
+# Benchmarks
+
+VouchBench is the repo-local acceptance harness for the current
+compiler/evidence/policy behavior.
+
+```sh
+scripts/vouchbench.sh
+```
+
+Full benchmark documentation lives in
+[`docs/BENCHMARKS.md`](https://github.com/duriantaco/vouch/blob/main/docs/BENCHMARKS.md).
+
+## Current Acceptance Floor
+
+- 10 required scenarios
+- 114 scenario assertions
+- at least 4 tests-passed scenarios blocked by Vouch-specific checks
+- at least 2 medium/high multi-component scenarios with 25 obligations
+- canary, human escalation, and auto-merge routes all exercised
+- at least 1 invalid-evidence negative control
+- at least 1 full-coverage manifest traceability block
+
+## Valid Claim
+
+Vouch links compiled obligations to evidence deterministically for the fixture
+corpus and routes the resulting policy decisions as expected.
+
+## Invalid Claim
+
+VouchBench does not prove arbitrary code correctness, automatic product
+understanding, incident reduction, or product-market fit.
diff --git a/docs/site/compiler.md b/docs/site/compiler.md
new file mode 100644
index 0000000..c05478e
--- /dev/null
+++ b/docs/site/compiler.md
@@ -0,0 +1,112 @@
+# Compiler Architecture
+
+Vouch is a compiler for release contracts. The current gate is the runtime that
+consumes the compiler output.
+
+```text
+compiler: intent -> AST -> spec -> obligation IR -> verification plan/artifacts
+runtime: manifest + evidence + policy -> release decision
+```
+
+Calling Vouch only a gate is incomplete. Calling it a compiler without naming
+the current runtime is also incomplete.
+
+## Source Language
+
+Source files live under `.vouch/intents/*.yaml`. The parser accepts the keys
+implemented in
+[`internal/vouch/intent.go`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/intent.go):
+`version`, `feature`, `owner`, `owned_paths`, `risk`, `goal`, `behavior`,
+`security`, `required_tests`, `runtime_metrics`, `runtime_alerts`, and
+`rollback`.
+
+```yaml
+version: vouch.intent.v0
+feature: auth.password_reset
+owner: platform
+owned_paths:
+ - src/auth/**
+ - tests/auth/**
+risk: high
+behavior:
+ - response does not reveal whether account exists
+security:
+ - reset token is never logged
+required_tests:
+ - token expires
+runtime_metrics:
+ - password_reset.failed
+rollback:
+ strategy: feature_flag
+ flag: password_reset_v2
+```
+
+## Compiler Stages
+
+| Stage | Command | Code path | Output |
+| --- | --- | --- | --- |
+| Parse intent | `vouch intent parse` | [`ParseIntentASTFile`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/intent.go) | `vouch.ast.v0` with source spans and diagnostics |
+| Analyze intent | repo compile path | [`AnalyzeIntentAST`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/intent.go) | typed intent values |
+| Compile spec | `vouch intent compile` | [`SpecFromIntent`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/intent.go) | `vouch.spec.v0` JSON |
+| Build IR | `vouch ir build` | [`IRFromSpec`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/ir.go) | `vouch.ir.v0` obligations |
+| Build plan | `vouch plan build` | [`VerificationPlanFromIR`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/plan.go) | `vouch.plan.v0` verification plan |
+| Build artifacts | `vouch artifacts build` | [`BuildArtifacts`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/artifacts.go) | verifier packets, test obligations, release-policy artifact |
+| Compile repo | `vouch compile` | [`CompileRepo`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/compile.go) | `.vouch/build/` compiler outputs |
+
+The CLI dispatcher for these commands is
+[`Main`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/cli.go).
+
+## Repo Compile Output
+
+`vouch compile` reads `.vouch/intents/*.yaml` and writes:
+
+- `.vouch/build/ast/*.ast.json`
+- `.vouch/specs/*.spec.json`
+- `.vouch/build/obligations.ir.json`
+- `.vouch/build/verification-plan.json`
+
+## Obligation IR
+
+`IRFromSpec` lowers a spec into stable obligation IDs. The current obligation
+kinds are defined in
+[`internal/vouch/types.go`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/types.go).
+
+| Obligation kind | Required evidence kind |
+| --- | --- |
+| `behavior` | `behavior_trace` |
+| `security` | `security_check` |
+| `required_test` | `test_coverage` |
+| `runtime_signal` | `runtime_metric` |
+| `rollback` | `rollback_plan` |
+
+Example IDs:
+
+```text
+auth.password_reset.behavior.user_can_request_password_reset_by_email
+auth.password_reset.security.reset_token_is_never_logged
+auth.password_reset.required_test.token_expires
+auth.password_reset.runtime_signal.password_reset_failed
+auth.password_reset.rollback.feature_flag_password_reset_v2
+```
+
+Evidence artifacts must reference exact obligation IDs.
+
+## Runtime Gate
+
+The runtime starts after compilation.
+
+[`CollectEvidenceWithOptions`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/evidence.go)
+loads compiled specs, a change manifest, generated IR/plans for touched specs,
+linked evidence artifacts, and release policy. It then builds coverage, imports
+verifier findings, and applies policy.
+
+Default policy is implemented in
+[`DefaultReleasePolicy`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/policy.go).
+The current decisions are:
+
+- `block`
+- `human_escalation`
+- `canary`
+- `auto_merge`
+
+`gate` exits non-zero only when the final decision is `block`.
diff --git a/docs/site/github-actions.md b/docs/site/github-actions.md
new file mode 100644
index 0000000..6e3f41a
--- /dev/null
+++ b/docs/site/github-actions.md
@@ -0,0 +1,108 @@
+# GitHub Actions
+
+This repo uses GitHub Actions for two things:
+
+1. publishing the Vouch docs site to GitHub Pages
+2. running the current Vouch gate in pull request workflows
+
+Published docs URL:
+
+```text
+https://duriantaco.github.io/vouch/
+```
+
+GitHub Pages is configured with `build_type: workflow`, so content is published
+by `.github/workflows/pages.yml` after changes land on `main`.
+
+## Docs Deployment
+
+The Pages workflow follows GitHub's custom Actions publishing flow:
+
+- `actions/configure-pages`
+- `actions/upload-pages-artifact`
+- `actions/deploy-pages`
+
+Workflow file:
+
+```text
+.github/workflows/pages.yml
+```
+
+Source files:
+
+```text
+mkdocs.yml
+docs/site/
+docs/site/assets/vouch.png
+```
+
+The workflow builds the MkDocs site into `_site/`, uploads that artifact, and
+deploys it to the `github-pages` environment.
+
+Official references:
+
+- [Configuring a publishing source for your GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site)
+- [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact)
+- [actions/deploy-pages](https://github.com/actions/deploy-pages)
+
+## Vouch PR Workflow
+
+The current Vouch PR workflow should start in shadow mode. It appends a job
+summary and uploads `.vouch/build/gate-result.json` without blocking the PR.
+
+```yaml
+name: Vouch
+
+on:
+ pull_request:
+
+jobs:
+ vouch:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: "1.26"
+
+ - name: Install Vouch
+ run: go install github.com/duriantaco/vouch/cmd/vouch@latest
+
+ - name: Compile Vouch contracts
+ run: vouch compile
+
+ - name: Run tests
+ run: pytest --junitxml .vouch/artifacts/pytest.xml
+
+ - name: Import JUnit evidence
+ run: vouch evidence import junit .vouch/artifacts/pytest.xml
+
+ - name: Gate PR
+ continue-on-error: true
+ run: vouch gate --github-summary --out .vouch/build/gate-result.json
+
+ - name: Upload Vouch result
+ uses: actions/upload-artifact@v4
+ with:
+ name: vouch-gate-result
+ path: .vouch/build/gate-result.json
+```
+
+## Code References
+
+- CLI command and `--github-summary` flag:
+ [`internal/vouch/cli.go`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/cli.go)
+- `$GITHUB_STEP_SUMMARY` handling:
+ [`appendGitHubSummary`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/cli.go)
+- Markdown summary rendering:
+ [`RenderGitHubSummary`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/render.go)
+- Gate result JSON:
+ [`GateResultFromEvidence`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/render.go)
+- Default release policy:
+ [`DefaultReleasePolicy`](https://github.com/duriantaco/vouch/blob/main/internal/vouch/policy.go)
+
+## Enforced Mode
+
+After a shadow-mode pilot, remove `continue-on-error: true` from the gate step.
+The CLI exits non-zero only when the final decision is `block`.
diff --git a/docs/site/index.md b/docs/site/index.md
new file mode 100644
index 0000000..790f148
--- /dev/null
+++ b/docs/site/index.md
@@ -0,0 +1,59 @@
+# Vouch
+
+Vouch is a compiler for release contracts.
+
+The release gate is the first runtime target, not the whole project.
+
+```text
+human-owned intent YAML
+ -> typed AST
+ -> spec JSON
+ -> obligation IR
+ -> verification plan and runner artifacts
+ -> evidence and policy input
+ -> block | human_escalation | canary | auto_merge
+```
+
+Use Vouch when a risky AI-authored change needs more than "CI passed." A
+contract says what a repo area owns; the compiler gives those requirements
+stable obligation IDs; the gate checks whether evidence covers those IDs.
+
+## Quick Start
+
+Preview a repo without writing files:
+
+```sh
+vouch try --repo /path/to/repo
+```
+
+Write the draft `.vouch/` layout when the preview is useful:
+
+```sh
+vouch try --repo /path/to/repo --write
+```
+
+Compile contracts and run the current gate:
+
+```sh
+cd /path/to/repo
+vouch compile
+pytest --junitxml .vouch/artifacts/pytest.xml
+vouch evidence import junit .vouch/artifacts/pytest.xml
+vouch gate
+```
+
+JUnit covers required-test obligations only. Behavior, security, runtime, and
+rollback obligations need their own evidence.
+
+## Status
+
+Vouch is beta infrastructure. It is ready for shadow-mode pilots, not blind
+production enforcement.
+
+The local VouchBench harness proves the current compiler/evidence/policy path is
+deterministic over fixture scenarios. It does not prove arbitrary code is
+correct or that real teams will adopt the workflow.
+
+```sh
+scripts/vouchbench.sh
+```
diff --git a/docs/site/stylesheets/extra.css b/docs/site/stylesheets/extra.css
new file mode 100644
index 0000000..c747b5a
--- /dev/null
+++ b/docs/site/stylesheets/extra.css
@@ -0,0 +1,49 @@
+:root {
+ --md-default-bg-color: #ffffff;
+ --md-default-fg-color: #151515;
+ --md-primary-fg-color: #ffffff;
+ --md-primary-bg-color: #111827;
+ --md-accent-fg-color: #007f72;
+}
+
+.md-header,
+.md-tabs {
+ background: #ffffff;
+ color: #111827;
+ border-bottom: 1px solid #e5e7eb;
+ box-shadow: none;
+}
+
+.md-header__button.md-logo img,
+.md-header__button.md-logo svg {
+ width: 2.1rem;
+ height: 2.1rem;
+}
+
+.md-header__title,
+.md-tabs__link {
+ color: #111827;
+}
+
+.md-search__form {
+ background-color: #f3f4f6;
+}
+
+.md-typeset h1,
+.md-typeset h2,
+.md-typeset h3 {
+ color: #111827;
+ letter-spacing: 0;
+}
+
+.md-typeset a {
+ color: #006b60;
+}
+
+.md-typeset code {
+ border-radius: 4px;
+}
+
+.md-typeset pre > code {
+ border-radius: 8px;
+}
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..d37efa8
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,34 @@
+site_name: Vouch
+site_url: https://duriantaco.github.io/vouch/
+repo_url: https://github.com/duriantaco/vouch
+repo_name: duriantaco/vouch
+docs_dir: docs/site
+site_dir: _site
+
+theme:
+ name: material
+ logo: assets/vouch.png
+ favicon: assets/vouch.png
+ palette:
+ scheme: default
+ primary: white
+ accent: teal
+ features:
+ - navigation.sections
+ - navigation.tabs
+ - content.code.copy
+
+extra_css:
+ - stylesheets/extra.css
+
+markdown_extensions:
+ - admonition
+ - tables
+ - toc:
+ permalink: true
+
+nav:
+ - Home: index.md
+ - Compiler: compiler.md
+ - GitHub Actions: github-actions.md
+ - Benchmarks: benchmarks.md