Why CI enforcement matters
- Generation-time hooks cover interactive and agentic Claude Code sessions
- Code can also arrive from manual edits, other tools, or agents without hook coverage
- CI enforcement is the backstop — every commit checked regardless of how it was produced
- Positions governance at three layers: generation time → PR review → CI gate
How it works
mneme checkvalidates a file or diff against the decision corpus in.mneme/project_memory.json- Run against changed files in a PR to surface any architectural violations
- Exit code 2 = violation found → CI step fails → PR blocked
- Exit code 0 = no violations → CI step passes
Example workflow
# .github/workflows/mneme-governance.yml
name: Architectural Governance
on:
pull_request:
branches: [main]
jobs:
governance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install mneme-hq
- name: Check changed files
run: |
git diff --name-only origin/main...HEAD | \
xargs -I{} mneme check {}
Status
- CI enforcement gate is Phase 1 current focus — see the roadmap
- The
mneme checkcommand is available today viapip install mneme-hq - The GitHub Actions workflow above is the reference integration pattern
- Managed GitHub Actions workflow artifact coming in Q3 2026
Layered governance model
Layer 1: Generation-time enforcement via Claude Code hooks
Layer 2: PR review (human + AI)
Layer 3: CI gate via Mneme in GitHub Actions
What the gate actually checks
The CI step runs mneme check --mode strict against the PR diff and the project's decision corpus. The check returns a structured verdict per touched file, with three possible outcomes:
- PASS — the diff respects the relevant decisions. Exit code 0, CI green.
- WARN — the diff introduces something the corpus flags as policy-bordering (an unapproved dependency, a scope-boundary edge case). Exit code 0 in default mode, surfaces a structured comment via the action's PR-comment step.
- FAIL — the diff violates a hard architectural decision. Exit code 2 in strict mode, fails the workflow, blocks the PR until resolved or explicitly overridden.
Override events are themselves tracked: an override is a decision record with a rationale, scope, and expiry, committed as part of the same PR. Weakening a constraint costs the same as introducing one — a structured edit reviewers can see, not a quiet bypass.
FAQ
Should we run this on every PR or only on main?
What if a PR needs to override a decision intentionally?
project_memory.json as part of the same PR — with rationale, scope, and expiry. The check picks it up automatically. The override is reviewable in the PR diff like any other change, so weakening a constraint is a visible decision rather than a silent merge.