{
  "markdown": "# assurance\n\n[![tests](https://github.com/i-ops-hq/assurance/actions/workflows/tests.yml/badge.svg)](https://github.com/i-ops-hq/assurance/actions/workflows/tests.yml)\n[![assurance-core](https://img.shields.io/pypi/v/assurance-core?label=assurance-core)](https://pypi.org/project/assurance-core/)\n[![assurance-cli](https://img.shields.io/pypi/v/assurance-cli?label=assurance-cli)](https://pypi.org/project/assurance-cli/)\n[![assurance-mcp](https://img.shields.io/pypi/v/assurance-mcp?label=assurance-mcp)](https://pypi.org/project/assurance-mcp/)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n\n## Did the job cover everything it was supposed to cover?\n\nAn agent, a script or a person tells you the work is done. **This decides whether that is true** —\nfrom declared expectations and observed evidence, by code, with no model anywhere in the answer.\n\nThe one rule everything here follows: **a denominator we cannot establish is refused, never\ninvented.** A tool that answers \"0 of 36\" for a folder it did not understand is worse than one that\nsays it does not know, because you cannot argue with a number that was made up.\n\n## Thirty seconds\n\n```bash\npip install assurance-cli\nassurance check ~/reports\n```\n\n<img src=\"packages/cli/docs/demo.svg\" alt=\"assurance check on a folder of monthly reports: 22 of 24 months, March 2024 and July 2025 named as absent; --fail-on-gap exits 1; a folder with no regular cadence is refused rather than given a denominator\" width=\"860\">\n\nNo config, no corpus file, no setup. It works out the cadence, the span and what is absent from the\nfilenames alone. A folder with no regular cadence is **told so** rather than handed a ratio.\n\n## What is in here\n\n| package | install | what it is |\n|---|---|---|\n| **`assurance-core`** | `pip install assurance-core` | the decision layer as a pure library — no I/O, no model, no framework. Coverage, corpus census, staleness, drift, tool pinning, the rule of two |\n| **`assurance-cli`** | `pip install assurance-cli` | five commands, each a CI gate with no model in it: `check`, `diff`, `pin`, `drift`, `init` |\n| **`assurance-mcp`** | `pip install assurance-mcp` | four MCP tools, read-only by construction, for Cursor / Claude Desktop / any MCP client |\n\nEach ships to PyPI independently and versions on its own — a release tag names its package\n(`cli-v0.5.1`), because a bare version number is ambiguous between three.\n\n### Which one do you want?\n\n- **You have a folder and a question.** `assurance-cli`. Nothing else needed.\n- **You have an agent that should check its own work.** `assurance-mcp`, or the\n  [`report-coverage` skill](skills/report-coverage/SKILL.md).\n- **You are building the check into your own system.** `assurance-core`. It is deliberately\n  dependency-free so it can sit inside anything.\n- **You are worried an agent becomes a way to read things people cannot read.** That is a separate\n  project built on this one: **[assurance-authority](https://github.com/i-ops-hq/assurance-authority)**.\n\n## The two commands people adopt first\n\n```bash\nassurance pin --check      # fail the build when an MCP server changes a tool definition\n                           # after you approved it (CVE-2025-54136)\nassurance drift runs.jsonl # did the failure rate actually shift, or was the week noise?\n```\n\n`drift` reports no labels, no judge and no benchmark — it says whether a change is distinguishable\nfrom noise, and it refuses when there is not enough history to say. Its\n[README](packages/cli/README.md) leads with the false-alarm rates of the textbook methods it\nrejected, because that is the part worth checking.\n\n## Layout\n\n```\npackages/core/     assurance-core   — generated; see below\npackages/cli/      assurance-cli\npackages/mcp/      assurance-mcp\nskills/            agent skills that use the tools above\n```\n\n**`packages/core/` is generated and must not be hand-edited.** It is scrubbed out of a private\nupstream by a publisher that rewrites the whole tree, so an edit made here is destroyed on the next\nrun and never reaches anyone. Everything else in this repo is ordinary hand-written code, and pull\nrequests are welcome against it.\n\n## Honest limits\n\n- **`check` opens `.csv`, `.tsv` and `.xlsx` only.** Anything else in the folder is counted and\n  named, not silently skipped.\n- **The span is inferred from the earliest and latest filenames** unless you pass `--from` / `--to`,\n  which means a report missing from either *end* of the range cannot be detected. Pass the range\n  when you know it.\n- **`expected` is never inferred** in the MCP tools. A denominator nobody can argue with is not an\n  answer.\n- **No cross-document inference.** It produced 21 false positives on a real corpus, so it is refused.\n\n## Licence\n\nApache-2.0.\n",
  "bytes": 4763,
  "sha": "58f0b9db43fd70967a25e8c011017824c066efc7e0328b33c9ea4738e145fb38",
  "repo_slug": "i-ops-hq/assurance",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_i_ops_hq_assurance_mcp_e8c4cdf7/readme"
}