{"id":43605840,"url":"https://github.com/yonaskolb/verify","last_synced_at":"2026-02-24T13:01:14.239Z","repository":{"id":336382744,"uuid":"1148807067","full_name":"yonaskolb/verify","owner":"yonaskolb","description":"Content-addressed CI caching that lives in your git history, not a cloud service.","archived":false,"fork":false,"pushed_at":"2026-02-12T10:31:42.000Z","size":321,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-12T12:59:31.485Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yonaskolb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-03T11:45:03.000Z","updated_at":"2026-02-12T11:18:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yonaskolb/verify","commit_stats":null,"previous_names":["yonaskolb/verify"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/yonaskolb/verify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yonaskolb%2Fverify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yonaskolb%2Fverify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yonaskolb%2Fverify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yonaskolb%2Fverify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yonaskolb","download_url":"https://codeload.github.com/yonaskolb/verify/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yonaskolb%2Fverify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29783615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T10:45:18.109Z","status":"ssl_error","status_checked_at":"2026-02-24T10:45:09.911Z","response_time":75,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-04T07:12:54.863Z","updated_at":"2026-02-24T13:01:14.233Z","avatar_url":"https://github.com/yonaskolb.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# verify\n\nVerified commits, faster CI. Run checks locally, prove they passed in git, skip them in CI.\n\n## Why verify?\n\n**Trust** — Every commit carries proof that checks passed. You know code was verified *before* it was committed, not just after CI runs. Especially valuable when AI agents are writing code — the commit message itself is a receipt that the work was validated.\n\n**Speed** — CI doesn't re-run what was already proven locally. You save wall-clock time and compute costs, scaling with how many checks you have and how often you push.\n\n### How it does this\n\n- **Standalone** — Works with any project, any language\n- **Simple** — One YAML file, one binary\n- **Fast** — Written in Rust, BLAKE3 hashing, parallel execution\n- **Smart** — Only re-runs checks when relevant files change\n- **Succinct** — Only returns the errors from your verifications, not the whole build output of every step\n- **Open** — JSON output for integration with other tools\n\n## How It Works\n\n1. You define checks (build, lint, test) in `verify.yaml` with glob patterns for the files each check cares about\n2. `verify run` executes unverified checks, hashes the files, and records the results\n3. A check stays verified until its files change, its config changes, or a dependency becomes unverified\n4. Verification state is embedded in the commit message as a `Verified` line — so CI can skip what's already been proven\n\n### Sharing State with CI\n\nA git hook adds a `Verified` line to each commit message containing a hash of each check's configuration and file state:\n\n```\nfeat: add profile page\n\nVerified: build:a1b2c3d4,lint:e5f6a7b8,tests:c9d0e1f2\n```\n\nCI reads this line and compares the hashes against the current files. If they match, the check is skipped.\n\n```bash\n# Pre-commit hook — run checks\nverify run\n\n# Commit-msg hook — embed verification proof in the commit message\nverify sign \"$1\"\n\n# CI — validate the commit's verification proof against current files\nverify check\n```\n\n## Installation\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/yonaskolb/verify/master/install.sh | sh\n```\n\n### From source\n\n```bash\ncargo install --git https://github.com/yonaskolb/verify\n```\n\nOr clone and build:\n\n```bash\ngit clone https://github.com/yonaskolb/verify\ncd verify\ncargo build --release\n# Binary at ./target/release/verify\n\n# Or install to ~/.cargo/bin\ncargo install --path .\n```\n\n## Quick Start\n\n```bash\n# Create a config file\nverify init\n\n# Edit verify.yaml to define your checks\n# Then run:\nverify status  # See what needs to run\nverify         # Run unverified checks\n```\n\n## Configuration\n\nCreate a `verify.yaml` in your project root:\n\n```yaml\nverifications:\n  - name: build\n    command: npm run build\n    cache_paths:\n      - \"src/**/*.ts\"\n      - \"package.json\"\n\n  - name: typecheck\n    command: npm run typecheck\n    cache_paths:\n      - \"src/**/*.ts\"\n      - \"tsconfig.json\"\n\n  - name: test\n    command: npm test\n    depends_on: [build]\n    cache_paths:\n      - \"src/**/*.ts\"\n      - \"tests/**/*.ts\"\n\n  - name: lint\n    command: npm run lint\n    cache_paths:\n      - \"src/**/*.ts\"\n      - \".eslintrc*\"\n```\n\n### Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Unique identifier for the check |\n| `command` | No | Shell command to execute. If omitted, creates an aggregate check whose status is derived from its dependencies |\n| `cache_paths` | No | Glob patterns for files that affect this check. If omitted, check is untracked (always runs) |\n| `depends_on` | No | List of checks or subprojects that must pass first |\n| `metadata` | No | Regex patterns for extracting metrics from output |\n| `per_file` | No | Run command once per changed file (sets `VERIFY_FILE` env var) |\n\n### Aggregate Checks\n\nCreate checks without a command to group related checks. Their status is derived from their dependencies:\n\n```yaml\nverifications:\n  - name: build\n    command: npm run build\n    cache_paths: [\"src/**/*.ts\"]\n\n  - name: test\n    command: npm test\n    cache_paths: [\"src/**/*.ts\", \"tests/**/*.ts\"]\n\n  - name: all\n    depends_on: [build, test]  # verified when both deps are verified\n```\n\n### Subprojects\n\nReference other `verify.yaml` files in subdirectories:\n\n```yaml\nverifications:\n  - name: frontend\n    path: ./packages/frontend\n\n  - name: backend\n    path: ./packages/backend\n\n  - name: integration\n    command: npm run integration\n    depends_on: [frontend, backend]  # Can depend on subprojects\n    cache_paths:\n      - \"tests/**/*.ts\"\n```\n\nSubprojects run their own verifications and can be dependencies for other checks.\n\n### Metadata Extraction\n\nExtract metrics from command output using regex patterns:\n\n```yaml\nverifications:\n  - name: test\n    command: npm test\n    cache_paths:\n      - \"src/**/*.ts\"\n    metadata:\n      passed: \"Tests: (\\\\d+) passed\"\n      failed: \"(\\\\d+) failed\"\n      coverage: \"Coverage: ([\\\\d.]+)%\"\n```\n\nCaptured values are stored in the cache and displayed in status output. Supports:\n- Simple patterns: Extract first capture group\n- Replacement patterns: `[\"(\\\\d+)/(\\\\d+)\", \"$1 of $2\"]` for formatted output\n\n### Per-File Mode\n\nRun a command once for each stale file individually. Useful for test flows, slow operations, or checks that operate on single files:\n\n```yaml\nverifications:\n  - name: flow-tests\n    command: maestro test \"$VERIFY_FILE\"\n    cache_paths:\n      - \"flows/**/*.yaml\"\n    per_file: true\n```\n\nWhen `per_file: true`:\n- The command runs once per stale file with `VERIFY_FILE` environment variable set to the file path\n- Files that haven't changed are skipped (cached)\n- Progress shows each file as it runs:\n  ```\n  ● flow-tests (3 cached)\n  ● flow-tests: flows/login.yaml (2.1s)\n  ● flow-tests: flows/checkout.yaml (1.8s)\n  ```\n- If any file fails, execution stops and the error is reported\n\n## Usage\n\n### Check Status\n\n```bash\nverify status             # Show all checks\nverify status build       # Show status for a specific check\nverify status --verify    # Exit with code 1 if any check is unverified\n```\n\nOutput:\n```\n● build - verified\n● typecheck - verified\n● test - unverified (depends on: build)\n● lint - unverified (3 file(s) changed)\n● e2e - unverified (config changed)\n● integration - unverified (never run)\n● always-run - untracked\n```\n\n### Run Checks\n\n```bash\nverify                    # Run all unverified checks\nverify run build          # Run specific check (and dependencies)\nverify run --force        # Force run even if verified\nverify run --verbose      # Stream command output in real-time\n```\n\n### Commit Verification\n\n```bash\nverify hash              # Print combined hashes for all checks (full 64-char blake3)\nverify hash build        # Print hash for a specific check\nverify sign FILE         # Embed verification proof in a commit message file\nverify check             # Validate the current commit's proof against current files\nverify check build       # Validate a specific check\nverify sync              # Seed local cache from a Verified trailer in recent git history\nverify resign            # Re-sign HEAD commit with fresh verification trailer\n```\n\n### JSON Output\n\nFor tool integration:\n\n```bash\nverify --json status\nverify --json run\n```\n\nExample output:\n```json\n{\n  \"checks\": [\n    {\n      \"name\": \"build\",\n      \"status\": \"verified\"\n    },\n    {\n      \"name\": \"test\",\n      \"status\": \"unverified\",\n      \"reason\": \"dependency_unverified\",\n      \"stale_dependency\": \"build\"\n    },\n    {\n      \"name\": \"lint\",\n      \"status\": \"unverified\",\n      \"reason\": \"config_changed\"\n    },\n    {\n      \"name\": \"always-run\",\n      \"status\": \"untracked\"\n    }\n  ]\n}\n```\n\n### Clear Cache\n\n```bash\nverify clean           # Clear all cached results (resets verify.lock)\nverify clean build     # Clear specific check\n```\n\n## Setup\n\nAdd `verify.lock` to `.gitignore` (it's a local cache):\n\n```bash\necho \"verify.lock\" \u003e\u003e .gitignore\n```\n\nSet up git hooks to automatically run checks and embed proof in each commit:\n\n```bash\n#!/bin/sh\n# .git/hooks/pre-commit\nverify run\n\n#!/bin/sh\n# .git/hooks/commit-msg\nverify sign \"$1\"\n```\n\nIn CI, validate that the commit's checks match the current file state:\n\n```bash\nverify check             # exits 0 if proof matches, 1 if not\nverify check tests       # validate a specific check\n```\n\n### Re-signing a Commit\n\nIf you need to update the verification trailer on an existing commit (e.g. after rebasing, merging in another branch, or running `verify run` post-commit), use `resign` to amend HEAD with a fresh trailer:\n\n```bash\nverify resign\n```\n\nThis computes current hashes from the cache, replaces any existing `Verified` trailer, and amends HEAD. It sets `VERIFY_RESIGNING=1` in the environment so hooks can detect and skip the amend.\n\n### Syncing Cache in New Worktrees\n\nIn a fresh worktree or checkout, `verify sync` bootstraps the local cache from git history:\n\n```bash\nverify sync\n```\n\nThis searches recent commits for a `Verified` trailer, compares the hashes against the current file state, and seeds `verify.lock` with any matching checks. Subsequent `verify run` calls will skip those checks.\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | All checks passed (or skipped as verified) |\n| 1 | One or more checks failed |\n| 2 | Configuration error |\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyonaskolb%2Fverify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyonaskolb%2Fverify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyonaskolb%2Fverify/lists"}