Supporting enforcement example · approved-deps 5 min read WARN

# Dependency policy enforcement

During a refactor, the AI agent reaches for `sqlalchemy` — a sensible choice in isolation, but not on the team's approved dependency list. Mneme catches it during `mneme check` and emits a structured WARN with the originating decision ID, so the diff is flagged for review without hard-blocking the work.

By Theo Valmis · Published May 2026 · All scenarios

## The scenario

Most teams of any size end up maintaining an approved dependency list. Security has audited a small set of packages; the rest are off-limits until reviewed. The list lives in the team's heads, in a Notion doc, in a checklist on the security page — and almost never in a place AI coding agents can read.

This codebase records it explicitly. `project_memory.json` contains a typed rule:

Dependency policy. Python packages may only come from the approved list (FastAPI, Pydantic, httpx, pytest, ruff, plus internal packages prefixed `internal_`). Anything else requires a security review and an explicit decision record before it can land.

An engineer asks the AI assistant to refactor a service module. Somewhere in the diff:

diff snippet
import json
import sqlalchemy
from sqlalchemy import create_engine

The change looks reasonable in the editor. `sqlalchemy` is a real, popular library. Without governance, it would land in the next PR.

## Without Mneme

The model has no signal that `sqlalchemy` is restricted. It treats the import as routine. The PR opens. Reviewers, who themselves rarely maintain a perfect mental copy of the approved list, scan the diff and merge if the logic looks right. The dependency arrives quietly. Three weeks later, the security team notices in the dependency audit and files a ticket asking who introduced it and why.

This is the silent-introduction failure mode. It is not catastrophic on any single PR. It compounds across hundreds.

## With Mneme

The same diff goes through `mneme check`. The dependency rule is fetched from `project_memory.json`, the new import is matched against the approved list, and the verdict is emitted with the originating decision ID:

mneme check · dependency row
WARN
New dependency introduced — `sqlalchemy` not in approved list.

The verdict is structured. A reviewer (or a CI job) can branch on the `WARN` level: surface a comment on the PR, require an explicit override, request a security review, or auto-link to the dependency policy decision record. The verdict carries the decision ID, so the override is itself a tracked event.

## Why WARN and not FAIL

Dependency introductions are policy decisions that often have legitimate reasons. A security audit may approve a previously-rejected library; the team may have updated the approved list and not yet propagated it; an engineer may be deliberately spiking a new tool. Hard-blocking every dependency change creates governance fatigue and trains the team to disable the check.

Mneme's default for dependency policy is WARN — visible, traceable, easy to override with a documented reason. Teams that want strict enforcement can configure dependency policy as FAIL via `mneme check --mode strict`, which is the typical CI configuration for regulated environments.

## How to wire this up in your repo

The approved dependency list lives in `project_memory.json` as a structured rule with `type: "dependency_policy"` and an explicit allowlist. `mneme init` writes a starter template; replace it with your team's list. The list is human-editable and version-controlled with the rest of the repo, so adding or removing a dependency is a tracked decision rather than a quiet config change.

For the CI gate that turns dependency WARN into a PR comment or a hard block, see the GitHub Actions integration. For the design rationale behind structured records over text rule files, see why prompt memory fails at scale.

## FAQ

Why is this a WARN and not a FAIL?
Dependency introductions are policy decisions with often-legitimate reasons. Mneme returns WARN so the diff is flagged without hard-blocking the work. Teams that want strict enforcement can configure dependency policy as FAIL via `mneme check --mode strict`.
How does Mneme know which dependencies are approved?
The approved list lives in `project_memory.json` as a structured rule: type `dependency_policy`, scope (Python packages, JS packages, system binaries), and an explicit allowlist. Adding or removing a dependency is a tracked decision, version-controlled with the rest of the repo.
Can I scope the policy to specific paths?
Yes. Decision records carry a scope field. A dependency policy can apply to the whole repo, a specific service directory, or a particular layer (only the API layer can use HTTP clients, for example). The precedence engine resolves overlapping rules deterministically — see the architectural governance article for the full design rationale.

## Video walkthrough

Prefer video? Watch dependency policy enforcement in action — project memory as enforcement policy.

← Previous · Storage decision (PASS) Next · Repository pattern (FAIL) →
Related governance concepts

- Governance before generation

  Enforcement at the point of AI intent, not at the point of human review.

- Deterministic enforcement

  Same input, same verdict — every run, every agent, every consumer. The precondition for auditability.

- Architectural governance

  The system that turns team decisions into machine-evaluable constraints enforced at generation time.

- Verification contracts

  Pre-registered, machine-evaluable assertions that define what a governance check must prove.