Skip to main content

repo-assurance

Evidence-driven repository assurance orchestrator.

repo-assurance correlates local Git/filesystem evidence, GitHub governance, GitHub Actions operational history, repository hygiene, and current-baseline evidence around an immutable repository snapshot. It is intentionally read-only: the auditor reports and orders remediation; it does not mutate repositories.

Status

The current MVP vertical slice focuses on:

  • immutable repository snapshot and local/remote drift;
  • repository/language/build-test discovery;
  • GitHub rules/protection/check visibility;
  • GitHub-native security and dependency assurance (CodeQL/code scanning, secret scanning, dependency graph/SBOM, Dependabot);
  • GitHub Actions static and operational health;
  • stale/local-only branch and worktree preservation risks;
  • deterministic correlation, deduplication, completeness, and reports.

External provider assurance now includes a versioned provider-state contract and initial SonarQube Cloud / Socket GitHub-check adapters. Check execution is treated as execution evidence only; provider issue/alert inventories remain explicit gaps until direct provider evidence is available.

Installation

For a published CLI release, pipx is the recommended installation method because it keeps the command isolated from application environments:

pipx install repo-assurance
repo-assurance audit --repo . --mode standard

A regular Python environment can use pip instead:

python -m pip install repo-assurance

Before the first PyPI publication, or when an exact Git release is preferred, install the tagged source directly:

pipx install "git+https://github.com/oaslananka/repo-assurance.git@v0.2.1"

Repository cloning is primarily for development:

git clone https://github.com/oaslananka/repo-assurance.git
cd repo-assurance
python -m pip install -e '.[dev,plugin]'
pytest -q

Requirements

  • Python 3.12+
  • Git
  • gh for GitHub live-state collection (audits degrade explicitly when it is unavailable)
  • actionlint for first-class GitHub Actions syntax/semantic validation (CI-STATIC-001 becomes explicit UNAVAILABLE when it is not installed)

The required CI lane uses a reproducible dependency baseline instead of resolving ranges on every run:

python -m pip install --require-hashes -r requirements/ci.lock
python -m pip install --no-deps --no-build-isolation -e .
pytest -q

See references/reproducibility-policy.md for baseline scope, lock freshness verification, intentional --upgrade regeneration, and the distinction between reproducibility observations and security findings.

GitHub Actions supply-chain policy

Remote step actions are expected to be pinned to full 40-character commit SHAs, including GitHub-authored actions/* references. Reusable workflow references are classified separately. See references/action-reference-policy.md for the threat model, exceptions, and the distinction between immutability and version freshness.

CLI

Discover repository facts without producing findings:

repo-assurance discover --repo .

Build the repository-specific plan:

repo-assurance plan --repo . --mode standard

Run a read-only audit:

repo-assurance audit --repo . --mode standard

Offline audit, using local/static evidence only and skipping GitHub live/API collection and current external baseline resolution:

repo-assurance audit --repo . --mode standard --offline

Validate canonical output:

repo-assurance validate report /path/to/audit-report.json

Render a canonical JSON report as Markdown:

repo-assurance render /path/to/audit-report.json --format markdown

Unless --output is supplied, audit artifacts are written to a temporary directory outside the audited repository so the worktree remains clean.

Architecture boundaries

  • Collector ≠ policy. Collectors report observable facts.
  • Evidence ≠ finding. Controls interpret normalized evidence.
  • Scanner severity ≠ canonical severity. External severities remain evidence inputs.
  • Unknown ≠ pass. Permission, retention, and availability gaps remain explicit.
  • Preservation beats cleanup. Unique/dirty local work blocks cleanup recommendations.
  • Renderer ≠ evaluator. Markdown is rendered from canonical JSON and cannot recompute findings.

See references/ for the audit protocol and extension contracts.

Project layout

  • schemas/ — versioned canonical JSON contracts.
  • controls/ — declarative first-slice control catalog.
  • src/repo_assurance/collectors/ — policy-blind evidence collection.
  • src/repo_assurance/evaluators/ — control evaluation.
  • src/repo_assurance/core/ — planning, correlation, dedupe, findings, completeness, remediation.
  • src/repo_assurance/renderers/ — canonical report presentation.
  • tests/ — unit, integration, golden, safety, and skill-contract tests.

ChatGPT local plugin

Repo Assurance can be packaged as an Agent Plugins 1.0 local plugin for ChatGPT Desktop and other hosts that support local stdio MCP servers.

Install the local runtime dependencies from the repository root:

python -m pip install -e '.[plugin]'

Build the standalone plugin package:

python scripts/build_plugin.py

The package contains plugin.json, mcp.json, the repository-assurance skill, and the read-only Python MCP adapter. The MCP server exposes discover_repository, plan_repository_audit, audit_repository, and render_audit_report; it does not expose arbitrary shell execution or remediation/mutation tools.

Local filesystem access requires a host that can launch the stdio MCP process (for example ChatGPT Desktop). Saving the package to a ChatGPT account does not by itself grant local filesystem access on web or mobile.

Immutable source evidence

Repository profile and workflow-source controls read from the audited Git object (<target SHA>:<path>), not from the current checkout. Dirty working-tree state remains separate drift evidence and is never relabeled as target-SHA source evidence.

When actionlint is installed, CI-STATIC-001 runs it against the exact audited workflow bytes through stdin. The adapter records actionlint version, workflow target, invocation mode, exit state, and normalized diagnostics. It runs in an isolated temporary directory with shellcheck/pyflakes integrations disabled, does not write into the repository, and does not persist raw workflow bytes or diagnostic source snippets. Missing actionlint is reported as UNAVAILABLE, never PASS.

For current-sensitive controls, authoritative baseline evidence can be supplied explicitly:

repo-assurance audit --repo . --baseline-evidence /path/to/baselines.json

baselines.json is a baseline-evidence/v1 object or list. Missing or stale current evidence remains INCONCLUSIVE; the engine does not substitute model memory.

Self-audit acceptance

The ordinary test suite includes a deterministic offline acceptance test that drives the canonical CLI against an immutable Git target while the checkout has later and dirty changes. It validates report schemas, material finding propagation, blind spots, Markdown rendering, and repository read-only invariants.

An authenticated live GitHub acceptance path is opt-in so normal CI does not depend on external API/provider availability. Run it with:

REPO_ASSURANCE_RUN_LIVE_ACCEPTANCE=1 pytest -q -m live_github tests/acceptance/test_live_github_acceptance.py

The live acceptance test is permission-aware and does not require SonarQube, Socket, or other external provider dashboards to be reachable.

Release validation and distribution

Official releases use the Python package version in pyproject.toml as the canonical version. plugin.json must match it exactly, and the official plugin/skill artifacts are built from the same exact tagged commit.

Release validation is deliberately non-publishing. A vX.Y.Z tag (or an explicit manual validation of an existing tag) runs .github/workflows/release.yml, which uses locked dependencies, executes the full validation suite, builds the Python wheel/sdist, plugin ZIP, skill ZIP, and source archive, then emits release-manifest.json plus SHA256SUMS.

For a local validation on a clean tagged checkout:

python scripts/build_release.py --expected-tag v0.2.1 --output dist/release
cd dist/release
sha256sum --check SHA256SUMS

The validation workflow does not publish to package indexes, create a GitHub Release, deploy, or update external plugin registries. Publication is a separate owner-authorized manual workflow that takes the exact release tag and successful validation run ID, then reuses the already validated artifact bytes without rebuilding them.

Publication is intentionally two-stage:

  1. run Publish Validated Release with target testpypi; the workflow publishes the validated wheel/sdist with OIDC Trusted Publishing, verifies their SHA-256 digests against the validated release set, and smoke-tests the staged CLI;
  2. run it again with target production; the workflow re-verifies the TestPyPI stage, publishes the same bytes to PyPI, verifies and smoke-tests the production package, and only then creates the GitHub Release.

TestPyPI uses the GitHub environment testpypi; production PyPI uses pypi. Both Trusted Publisher configurations must name this repository and .github/workflows/publish.yml. No long-lived package-index API token is required. PEP 740 attestations are enabled for both package-index uploads.

See references/release-policy.md, references/release-checklist.md, and CHANGELOG.md.

Cross-agent local use

Repository Assurance uses one canonical skill source at skills/repository-assurance/SKILL.md.

Execution order is intentionally portable:

  1. CLI-first — local coding agents with shell access should run the canonical repo-assurance CLI directly.
  2. MCP-second — use the Repo Assurance MCP adapter only when the CLI is unavailable and MCP is connected.
  3. Skill-only fallback — if neither execution surface can run, use the skill-guided workflow and label the result PARTIAL_SKILL_GUIDED_AUDIT.

Claude Code discovers the generated project skill at .claude/skills/repository-assurance/SKILL.md. OpenCode uses .opencode/skills/repository-assurance/SKILL.md, registered by the minimal project opencode.json. Both host copies are exact generated copies of the same canonical source. Codex and other repository-aware coding agents receive the same contract through AGENTS.md.

The Claude and OpenCode host skills are exact generated copies of the canonical skill. After editing the canonical source, run:

python scripts/sync_agent_assets.py
python scripts/sync_agent_assets.py --check

The second command is enforced in CI to prevent silent drift.

Host discovery can be smoke-tested locally without running an audit:

claude plugin validate .claude/skills
opencode debug skill --pure

The OpenCode output should contain repository-assurance with a location under .opencode/skills/repository-assurance/SKILL.md. Codex and other repository-instruction-aware agents use the root AGENTS.md contract.

For local CLI use:

python -m pip install -e .
repo-assurance audit --repo . --mode standard

Install the plugin extra only when a local stdio MCP host actually needs the MCP adapter:

python -m pip install -e '.[plugin]'

License

Repo Assurance is distributed under the MIT License. See LICENSE.

Metadata

Release files for repo-assurance 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for repo-assurance 0.2.1
File Size Uploaded
repo_assurance-0.2.1.tar.gz 73.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for repo-assurance 0.2.1
File Interpreter ABI Platform
repo_assurance-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 176.7 kB

Release files / repo_assurance-0.2.1.tar.gz

Download URL repo_assurance-0.2.1.tar.gz
Size 73.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ae939b6eb5a190f8544b8efb63c06827e094d09a403e2474bd990c7d076f77ff
BLAKE2b-256 checksum
How to use checksums
46d1189fe01530ad8044d9e219699b807c67483c0b71e1a40e4a850fbd9d2297
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / repo_assurance-0.2.1-py3-none-any.whl

Download URL repo_assurance-0.2.1-py3-none-any.whl
Size 103.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aa95e944db550157a7cf1cc8a2d1cddbf79aa15a3d44411856e2446102103444
BLAKE2b-256 checksum
How to use checksums
f451ad873fdb6f209144d62fc02df575b3eda7c768d59d7111b234577c8db7c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.2

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

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