Skip to main content

A commitment tripwire for AI-edited decision docs: flags when a tracked commitment disappears, word-for-word, between two versions. MCP server + Python library. A signal, not a judge.

Project description

Aperture MCP

Did an agent quietly drop a commitment from your spec — and no one noticed?

PyPI MCP License status

English · 简体中文

AI agents now rewrite the documents that govern your work — specs, plans, ADRs, charters, AGENTS.md files. Somewhere in the edit, a constraint you set earlier can quietly disappear.

Aperture MCP is a commitment tripwire. You name the commitments you care about; it flags — word for word — when one of them vanishes between two versions of a decision document.

A signal, not a judge. It trips; you investigate. Opt-in · runs locally · never trains on your data.


What it is (and what it is not)

Aperture MCP is a small tool (and plain Python library) that compares two text states of the same decision — an earlier version and a later one — and surfaces a narrow, specific kind of decision drift: when a tracked commitment’s exact text disappeared.

  • It does: flag when a commitment you listed verbatim is present in version A and gone from version B — across commits, sessions, or authors. It returns a structured, comparable result with its own blind spots written on the label.
  • It does not: understand meaning. It matches text as a case-insensitive substring, so it misses a commitment that was reworded / softened / paraphrased (it looks dropped-free even though the promise weakened); it declines/abstains on a commitment that was merely translated (it can’t compare verbatim across scripts, so it returns degraded rather than false-flag); and it can still false-flag a commitment that was merely reformatted (the words moved, the meaning didn’t). It does not rank options, score quality, or tell you a change was wrong. That judgment stays with you.

If you want one sentence: Aperture MCP is grep for vanished commitments, wrapped so an agent can call it mid-task and get a structured answer that admits what it can’t see.


Quickstart (≈2 minutes)

pip install aperture-mcp

Run the bundled example (clone the repo first) — it trips on a dropped commitment against checked-in fixtures, with no setup, no API keys, fully offline:

python3 examples/git_decision_drift/git_decision_drift.py
Aperture MCP · commitment tripwire — a fixture/sample decision-doc edit

  [TRIPPED ] 'ci-gates-green'             (in_before=True, in_after=False)
  [ held  ] 'data-never-leaves-device'   (in_before=True, in_after=True)

  One watched commitment vanished between the two versions; one held.
  Aperture MCP makes the disappearance visible — you decide whether it was intended.

Use it from your own code:

from aperture import compare, Anchor, AnchorKind

result = compare(
    state_a="We commit to: ci-gates-green before release; data-never-leaves-device.",
    state_b="We commit to: data-never-leaves-device.",
    anchors=[Anchor(kind=AnchorKind.COMMITMENT, id="ci-gates-green")],
)
print(result.status)            # DROPPED_SILENTLY
print(result.anchor_violations) # the commitment that vanished

Wire it into an MCP client (Cursor, Cline, Goose, or any stdio-capable host):

{
  "mcpServers": {
    "aperture-mcp": { "command": "aperture-mcp" }
  }
}

Prefer zero-install? Point the client at uvx instead: { "command": "uvx", "args": ["aperture-mcp"] }.


What trips it — and what slips past

Aperture MCP is a heuristic. We measured it on our own gold corpus and we publish the numbers instead of a single flattering score, because knowing where it’s blind is the productrecall 0.375, precision 0.75 on a 41-case corpus (it catches 9 of 24 real drifts; ~1 flag in 4 is noise), full breakdown in docs/measured-limits.md:

Kind of change Does Aperture MCP flag it?
A watched commitment deleted verbatim ✅ Reliably — this is the one thing it’s good at
A commitment reworded / softened (“must” → “should”) Missed — the text still “matches”
A commitment paraphrased / restructured Missed
A number / scope / negation quietly changed Missed
A commitment translated to another language ⚠️ Declines (abstains) for a natural-language anchor — it can’t compare verbatim across scripts, so it returns degraded rather than false-flag (a commitment dropped and translated is missed)

Anchor style matters for that last row: the abstain applies to a natural-language anchor. A code-identifier anchor (the ci-gates-green style the quickstart teaches) is treated as translation-stable — Aperture keeps checking it across languages, so if that exact token disappears it still flags DROPPED_SILENTLY (usually what you want for a stable identifier).

Takeaway: treat every flag as “look here,” never as “this is wrong” — and never assume silence means nothing drifted. Aperture MCP catches the verbatim disappearance case well and is honest that it catches little else. That narrow, reliable signal is useful precisely because it doesn’t pretend to be more.

Hit one of those misses on your own docs? That's the single most useful thing you can send us — report it in ~30s (your wording is optional). Real misses guide what we fix next.

Why not just git diff? You can reproduce the core check with grep. What Aperture MCP adds is that an agent can call it mid-task (over MCP), it returns a structured, directional result (ok / degraded / DROPPED_SILENTLY / …), and it reports its own blind spots in the result so a human can audit the gaps. It’s ergonomics + honesty around a simple, legible check — not a smarter detector.


Why this exists

Long-running and multi-agent workflows drift. A constraint set in turn 3 / session 1 / by agent A gets quietly edited away forty turns later, in another session, by agent B — and nobody notices until it ships. Aperture MCP is a preflight you can put on the documents agents maintain: name the commitments that must not silently vanish, and get a tripwire when one does.

It is deliberately small and legible. It is not an AI that decides for you; it is a signal that helps you stay consistent with yourself.


Who it’s for

Teams and builders who (a) let AI agents edit repo-resident decision documents — specs, plans, ADRs, charters, and AGENTS.md files — and (b) keep those documents under version control. If your agents touch text that encodes promises, Aperture MCP gives you a cheap, honest tripwire on the ones you can’t afford to lose silently.


Privacy

  • Opt-in and local. Aperture MCP runs on your machine. It makes no network calls.
  • Never trains on your data. Your decision text is yours; it never leaves your process.
  • Usage logging is off by default and, when enabled, records only metadata (timestamp, tool, status, counts) — never your decision text or commitment wording.

Honesty about the demo

The repository ships a small hand-authored fixture ADR (a before/after pair under examples/git_decision_drift/fixtures/), where Aperture MCP correctly flags a commitment we deliberately retired and stays quiet on one we kept. It is a faithful illustration of the mechanism — but it is a sample of one that we author and judge ourselves. It demonstrates how the tripwire works, not that the signal is strong. For the latter, see the measured per-family numbers above and in docs/measured-limits.md. We have zero external adopters yet — if you run Aperture MCP on your own decision docs, we’d love to hear what it caught and what it missed.


Project status

Early, pre-1.0, not yet a production gate. The compare contract (v0.2) is frozen and covered by a conformance suite; the package API may still move. See VERSIONING.md for the compatibility policy and CHANGELOG.md for changes.

Hit a miss? Help it improve

Aperture MCP will miss things — that's by design (it's blind to reworded, softened, and translated commitments). When it misses a drift you cared about, or false-flags a rewrite, telling us is the single most valuable contribution:

  • ~30 seconds, no account/usage data, your wording is optionalopen a drift-case report.
  • Real misses tell us which blind spot to fix next, and — only if you choose to share the wording — can become cases in the gold corpus that keeps the numbers in docs/measured-limits.md honest.

We never auto-collect anything (see Privacy); this happens only when you choose to share. Questions, or "is this the right tool for my case?" → GitHub Discussions.

More ways to help: CONTRIBUTING.md.

License

Apache-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aperture_mcp-0.1.0.tar.gz (90.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aperture_mcp-0.1.0-py3-none-any.whl (54.1 kB view details)

Uploaded Python 3

File details

Details for the file aperture_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: aperture_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 90.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aperture_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 237bfad2ef86bf6951f105d8eff06daa17a43c3e9201208f9fa283d23807cafd
MD5 8117bad02b9e688d12c28f807244cab3
BLAKE2b-256 9e5e0dad67d4f567a217e4cf27a98dbdf1c638b1e7db4485bcd6266c904132b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for aperture_mcp-0.1.0.tar.gz:

Publisher: publish.yml on jaysinailabs/aperture-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aperture_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: aperture_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 54.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aperture_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b588af63a420c269afa319061dcd0a787695bbc732a3548fe35009bdedb45de8
MD5 34051dee3b01ee63aa35f4c1584ebb9f
BLAKE2b-256 405add28823c8d75b035ff0d75dac27df1af07131cb5b06ccd5a53f6f7e11511

See more details on using hashes here.

Provenance

The following attestation bundles were made for aperture_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on jaysinailabs/aperture-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page