{"id":50988422,"url":"https://github.com/bitomule/musts","last_synced_at":"2026-06-19T23:01:07.519Z","repository":{"id":357593473,"uuid":"1237600094","full_name":"bitomule/musts","owner":"bitomule","description":"The validation loop that stops AI coding agents from claiming work is done before it actually is.","archived":false,"fork":false,"pushed_at":"2026-05-20T19:26:41.000Z","size":4487,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-20T23:49:24.178Z","etag":null,"topics":["agents","ai-agents","claude-code","cli","developer-tools","dogfooding","rust","testing","validation"],"latest_commit_sha":null,"homepage":"https://blog.bitomule.com","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitomule.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","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":null,"dco":null,"cla":null}},"created_at":"2026-05-13T10:30:07.000Z","updated_at":"2026-05-20T19:18:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bitomule/musts","commit_stats":null,"previous_names":["bitomule/musts"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bitomule/musts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitomule%2Fmusts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitomule%2Fmusts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitomule%2Fmusts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitomule%2Fmusts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitomule","download_url":"https://codeload.github.com/bitomule/musts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitomule%2Fmusts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34550858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["agents","ai-agents","claude-code","cli","developer-tools","dogfooding","rust","testing","validation"],"created_at":"2026-06-19T23:01:06.579Z","updated_at":"2026-06-19T23:01:07.513Z","avatar_url":"https://github.com/bitomule.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"left\"\u003e\n  \u003cimg src=\"assets/logo.png\" alt=\"musts logo\" width=\"240\"\u003e\n\u003c/p\u003e\n\n# musts\n\n[![CI](https://github.com/bitomule/musts/actions/workflows/ci.yml/badge.svg)](https://github.com/bitomule/musts/actions/workflows/ci.yml)\n[![Crates.io](https://img.shields.io/crates/v/musts.svg)](https://crates.io/crates/musts)\n[![MSRV](https://img.shields.io/badge/MSRV-1.88-blue.svg)](rust-toolchain.toml)\n[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](#license)\n\nAI agents are fast at editing code. They are less reliable at knowing when\nverification is actually finished.\n\n`musts` gives your repository a local, enforceable definition of done:\n\n\u003e The task is not done until `musts validate` is empty.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/hero.png\" alt=\"A musts validate output showing two pending tasks with the exact cargo commands needed to resolve them\" width=\"820\"\u003e\n\u003c/p\u003e\n\nInstead of hoping the agent remembers every build, test, UI check, and\narchitecture rule, you declare those checks next to the code they protect.\nWhen files change, `musts validate` reports the exact validation tasks still\npending. The agent runs them, records evidence, and repeats until the report\nis clean.\n\n## Get Started\n\n### 1. Install the CLI\n\n```bash\n# Homebrew (macOS / Linux)\nbrew install bitomule/tap/musts\n\n# Cargo (from crates.io)\ncargo install musts --locked\n\n# Precompiled binaries\ncargo binstall musts        # or download directly from GitHub Releases\n```\n\n### 2. Create your first `MUSTS.yml`\n\nPut a `MUSTS.yml` at the root of your repo:\n\n```yaml\nchecks:\n  test:\n    uses: cargo/test\n```\n\nNow ask what still needs to be validated:\n\n```bash\nmusts validate\n```\n\nIf code covered by that manifest has changed, `musts` returns a concrete task\nfor the agent to complete. After running the requested command, the agent\nrecords evidence:\n\n```bash\ncargo test --workspace 2\u003e\u00261 | tee /tmp/musts-cargo-test.log\n\nmusts evidence cargo-test-root \\\n  --text \"cargo test --workspace passed\" \\\n  --asset /tmp/musts-cargo-test.log\n\nmusts validate\n```\n\nWhen `musts validate` is empty, the repo has fresh evidence for the current\nworkspace state.\n\n### 3. Tell your agent to obey the loop\n\nFor Claude Code, install the plugin. It bundles the `musts` skill and a\n`Stop` hook that runs `musts validate` whenever Claude tries to finish a turn:\n\n```text\n/plugin marketplace add bitomule/musts\n/plugin install musts@musts\n```\n\nSee [`docs/claude-code-plugin.md`](docs/claude-code-plugin.md) for install,\nupdate, uninstall, and private-fork details.\n\nFor other agents, add the rule to your `AGENTS.md`, `CLAUDE.md`, or equivalent\nrepo instructions:\n\n```md\nBefore declaring a code change done, run `musts validate`.\nTreat every reported task as required. Run the task, capture evidence outside\nthe workspace, submit it with `musts evidence`, and repeat until\n`musts validate` is empty.\n```\n\nThe CLI is agent-agnostic. Anything that can run shell commands can participate\nin the loop.\n\n## What You Can Encode\n\n`musts` is not limited to \"run the test suite\". A check can represent any\nvalidation rule your repo needs before an agent is allowed to stop.\n\n### Build and test checks\n\n```yaml\nchecks:\n  fmt:\n    uses: cargo/fmt\n  clippy:\n    uses: cargo/clippy\n  test:\n    uses: cargo/test\n```\n\n### Targeted build checks\n\n```yaml\nchecks:\n  app-build:\n    uses: bazel/build\n    with:\n      target: //App:App\n```\n\n### Product or architecture contracts\n\nUse the built-in `agent` capability when the validation is a judgement call\nthat needs a human-readable answer rather than a command exit code:\n\n```yaml\nchecks:\n  usecase-shape:\n    uses: agent\n    paths:\n      - \"Sources/App/UseCases/**\"\n    with:\n      facts:\n        - \"Every use case has exactly one public entry point.\"\n        - \"The entry point name describes the user action, not implementation detail.\"\n        - \"No use case reaches across module boundaries except through declared ports.\"\n```\n\nWhen a matching use case changes, `musts validate` asks the agent to verify\nthose facts and submit a text explanation. That makes repo-specific rules\nvisible, repeatable, and hard to forget.\n\n### UI and device checks\n\n`musts` can also gate flows that need screenshots, videos, JSON reports, or\nother assets. Built-in and third-party capabilities decide what evidence they\nneed; the agent should follow the `evidence:` and `submit:` lines in the\n`musts validate` report.\n\n## How The Loop Works\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/loop.png\" alt=\"The musts loop: agent edits code, musts validate, run tasks and capture evidence, submit evidence, repeat until empty\" width=\"720\"\u003e\n\u003c/p\u003e\n\n1. You place `MUSTS.yml` files next to the code they protect.\n2. The agent edits code.\n3. `musts validate` fingerprints the relevant files and finds checks whose\n   current scope is no longer covered by accepted evidence.\n4. Each capability turns dirty checks into concrete tasks.\n5. The agent runs those tasks and submits evidence with `musts evidence`.\n6. The loop repeats until `musts validate` is empty.\n\nThe ledger is content-based, not git-based. Comments, generated fixtures,\narchitecture docs, and source files all count if they are inside a check's\nscope. That conservative model is intentional: `musts` does not guess whether\na change was \"semantic enough\" to need validation.\n\n## Why `musts`?\n\n### Why not just run `cargo test` or a Makefile?\n\nBecause the agent has to remember to do it. `make all` is a suggestion;\n`musts validate` is a contract the turn cannot close around. The task list is\ngenerated from what actually changed, so the repo does not need one giant\nscript for every possible validation path.\n\n### Why not a pre-commit hook or CI-only check?\n\nPre-commit hooks can be skipped. CI runs after the agent has already stopped,\nyou have already moved on, and the context needed to fix the issue may be\ngone. `musts` runs in the gap between \"the agent says done\" and \"you believe\nit\".\n\n### Why not just trust the agent?\n\nAgents are good at finishing turns. They are not always good at finishing\nwork. `musts` makes a false \"done\" visible by moving verification into an\nexternal, repo-owned loop.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/before-after.png\" alt=\"A comparison of two terminal sessions: on the left, an agent says 'done' without running any checks. On the right, the same agent runs musts validate, sees a cargo test task is still pending, runs it, and only then closes the turn.\" width=\"820\"\u003e\n\u003c/p\u003e\n\n## Built-In Capabilities\n\nThe reference capabilities are built into the `musts` binary:\n\n| Capability | Use it for |\n| --- | --- |\n| `agent` | Text-backed contracts, architectural checks, manual reasoning tasks |\n| `cargo/fmt` | `cargo fmt --check` |\n| `cargo/clippy` | `cargo clippy --workspace --all-targets -- -D warnings` |\n| `cargo/test` | `cargo test --workspace` |\n| `bazel/build` | Bazel target builds |\n| `mav/expect` | Mobile Agent Verifier flows and device evidence |\n\nThird-party extensions can add new capabilities in any language that speaks\nthe JSON-over-stdio protocol. See [`docs/extensions.md`](docs/extensions.md)\nand the worked example in [`docs/examples/eslint-check/`](docs/examples/eslint-check/).\n\n## Example: This Repo\n\n`musts` validates itself on every PR. Its root manifest gates formatting,\nlinting, and tests; the protocol crate also carries an `agent` contract for\nfacts that should remain true across changes.\n\nThat dogfood loop is intentionally the same loop users run:\n\n```bash\ncargo build --release\n./target/release/musts validate\n# run the reported tasks\n./target/release/musts evidence \u003ctask-id\u003e --text \"...\" --asset /tmp/log\n./target/release/musts validate\n```\n\nFor contributor commands, release rules, and the required pre-PR validation\nsequence, see [`CONTRIBUTING.md`](CONTRIBUTING.md).\n\n## Used At\n\n`musts` runs in production on:\n\n- [Undolly](https://undolly.app) - finding duplicate photos\n- [Boxy](https://boxy-app.com/) - organising physical items\n- [HiddenFace](https://hiddenface.app) - privacy-first face blur\n\n## Commands\n\n```bash\nmusts validate                                 # report pending validation tasks\nmusts validate --json                          # machine-readable report\nmusts evidence \u003ctask-id\u003e --text \"...\" \\        # record evidence for a task\n    --asset path/to/log --asset path/to/screen.png\n```\n\nExit codes:\n\n- `validate`: 0 clean, 1 pending tasks, 2 configuration / stale / lock error, 70 internal error.\n- `evidence`: 0 accepted, 1 rejected by extension, 2 unknown task / stale snapshot / over-claim, 70 internal error.\n\n## Stability\n\n`musts` is pre-1.0. The CLI surface, extension protocol, and `MUSTS.yml`\nschema may change between minor versions until `1.0`. The validation loop is\nalready used by this repository and by production apps, but you should expect\nsome API movement while the format settles.\n\n## Docs\n\nStart at [`docs/README.md`](docs/README.md) for the documentation index.\n\n- [`docs/claude-code-plugin.md`](docs/claude-code-plugin.md) - Claude Code plugin and Stop hook.\n- [`docs/skill.md`](docs/skill.md) - copyable agent instructions for the validation loop.\n- [`docs/extensions.md`](docs/extensions.md) - how to write a third-party extension.\n- [`docs/architecture.md`](docs/architecture.md) - bird's-eye view of the crates.\n- [`docs/musts-design.md`](docs/musts-design.md) - design spec and protocol decisions.\n- [`docs/PLAN.md`](docs/PLAN.md) - implementation plan and historical contract notes.\n\nAdvanced topics:\n\n- [`.mustsignore`](docs/musts-design.md#55-workspace-mustsignore) - exclude committed generated files or canonical fixtures from scope hashes.\n- [`CONTRIBUTING.md`](CONTRIBUTING.md) - build, test, release, and PR-title rules.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitomule%2Fmusts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitomule%2Fmusts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitomule%2Fmusts/lists"}