Product

CI Compliance Check

Automatically check every PR against your team's rules.

Principle

The PR diff is analyzed by an AI agent that checks whether the changes comply with the decisions, invariants, and rules your organization has defined in Knowledge. You can use your own local AI agent or the agent running on the Asplenz platform. The agent only receives the PR diff, not your full source code. To automate the analysis, add a step to your CI to invoke the AI agent with the PR diff and the Asplenz prompt as inputs.

This page assumes familiarity with Knowledge concepts. See How It Works.

Overview

When a PR is opened or updated, your CI pipeline calls an AI agent with the PR diff. The agent queries Knowledge to fetch the rules that apply to the changed files — invariants, mandatory rules, and active overrides. It analyzes the diff against those constraints and returns a verdict to your CI pipeline. The CI then merges or blocks the PR based on the configured gating mode.

Overview

To set it up:

  1. 1.

    Map your source modules to your Knowledge scopes

    See "Mapping source modules to your scopes" below.

  2. 2.

    Invoke the AI agent from your CI pipeline

    See "Agent Invocation" below.

  3. 3.

    Fail the pipeline or Merge the PR

    Read the verdict from the agent. Exit with a failure code to block the merge, or let the pipeline succeed to allow it.

Mapping source modules to your scopes

Create a .knowledge-scope-mapping.yml file at the root of your repository. Each entry maps a path pattern to a Knowledge scope. For example, when a PR changes src/payments/stripe.py, the agent fetches invariants and rules from the Engineering/payments scope.

# .knowledge-scope-mapping.yml
scope_mapping:
  "src/payments/**": "Engineering/payments"
  "src/auth/**": "Engineering/auth"
  "infrastructure/**": "Operations"
  "**": "Engineering"

Patterns are matched in order. The first match wins. Use ** as a catch-all to ensure every file is covered.

Agent Invocation

Setup

# Retrieve the diff between the base branch and the PR commit
DIFF=$(git diff origin/$BASE_BRANCH...$HEAD_SHA)

# Read the scope mapping file (YAML) and convert it to JSON
SCOPE_JSON=$(python3 -c 'import sys,yaml,json; print(json.dumps(yaml.safe_load(sys.stdin)))' \
  < .knowledge-scope-mapping.yml)

Option 1: Local AI agent

The example below uses Claude Code. Adapt the command to your agent and refer to its documentation for the exact syntax.

Configure the Knowledge MCP server in .mcp.json at the root of your repository:

{
  "mcpServers": {
    "knowledge": {
      "url": "https://mcp.asplenz.com/knowledge",
      "headers": { "Authorization": "Bearer <api_key>" }
    }
  }
}

Invoke the agent with the diff and scope mapping:

# The agent calls knowledge_resolve via MCP, analyzes the diff locally,
# and exits with code 0 (pass) or 1 (fail)
RESPONSE=$(claude -p "$(printf '## Scope Mapping\n%s\n\n## PR Diff\n%s\n\nRun the compliance check.' "$SCOPE_JSON" "$DIFF")" \
  --system-prompt-file .asplenz/ci-check-prompt.md \
  --allowedTools "mcp__knowledge__knowledge_resolve" \
  --output-format json)

Your source code stays local. Only the Knowledge tool calls go to the API.

Option 2: Asplenz agent

Send the diff to the Knowledge platform via API. The Asplenz agent runs server-side — no MCP configuration required.

# Send the diff to the Knowledge platform via API.
# jq builds the JSON body by injecting the bash variables.
RESPONSE=$(curl -s -X POST https://api.asplenz.com/knowledge/v1/verify/diff \
  -H "Authorization: Bearer $KNOWLEDGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg diff "$DIFF" \
    --argjson scope_mapping "$SCOPE_JSON" \
    --arg mode "fail-on-blocking" \
    '{ diff: $diff, scope_mapping: $scope_mapping, mode: $mode }')")

Act on the verdict

In both cases, the report includes any conflicting invariants or rules, their severity, and whether an approval can unblock the action.

# Extract the "verdict" field from the JSON returned by the agent
VERDICT=$(echo "$RESPONSE" | jq -r '.verdict')

# Post the Markdown report as a PR comment via the GitHub CLI
echo "$RESPONSE" | jq -r '.report_markdown' | gh pr comment $PR_NUMBER --body-file -

# Exit with failure if the verdict is "fail", pass otherwise
[ "$VERDICT" = "fail" ] && exit 1 || exit 0

The Compliance Check

The agent returns a compliance report and exits with a pass or fail result. Your CI pipeline acts on that result to allow or block the merge. The gating mode controls what the agent reports as a failure.

ModeAgent resultWhen to Use
report-onlyAlways passes. Posts report for visibility only.Initial rollout, learning phase
fail-on-blockingFails if any invariant is violated.Standard enforcement
strictFails on any violation (invariants + mandatory rules).Regulated environments

Recommended rollout: start with report-only for two weeks. Review the reports. When the team is comfortable, switch to fail-on-blocking. Move to strict when compliance is critical.

What Gets Checked

Invariants

Blocking constraints. If an invariant applies to the changed files' scope and isn't addressed, the agent reports a conflict.

Mandatory Rules

Active directives with MANDATORY severity. Uncited mandatory rules generate warnings in fail-on-blocking mode and failures in strict mode.

Advisory Rules

Active directives with ADVISORY severity. Reported for awareness but never block the pipeline.

Overrides

Active overrides are recognized. If a valid override exists for an invariant, the agent marks it as "overridden" rather than "violated."

Rule Discovery

Beyond compliance, the agent also detects decisions, rules, or invariants that are implicit in the PR but not yet in the registry. These are reported as suggestions in a dedicated section of the report.

Detected entries:
  - "All payment endpoints must validate currency codes" (invariant candidate)
  - "Use Redis for session caching instead of Memcached" (decision candidate)

Discoveries are informational only and never affect the verdict. If you want to turn them into registry entries, pass the discoveries section of the report to the extraction endpoint to create drafts for review.

Why automate compliance checking?

Checking compliance manuallyCI Compliance Check
Rules, decisions and invariants are scattered across docs, code comments, people's memories, or lost when someone leavesCentralized in a single structured registry
Reviewer must recall all applicable rulesRules are fetched automatically for each changed file
Easy to miss an invariant or decisionEvery applicable constraint is evaluated
Inconsistent across reviewersSame checks on every PR
No structured audit trailStructured report for every PR
Doesn't scale as rules accumulateScales to any number of rules and PRs

The CI compliance check handles the systematic part: verifying every PR against your organization's rules, decisions, and invariants. Code reviewers can focus on logic, design, and quality.