Ferryte
Product · how Ferryte works

One line.
Zero new mental model.

Ferryte does not ask you to migrate your memory layer or wrap your agent. It instruments what you already run, and tells you the truth about what survives a delete.

How it works

Four steps from install to a broken build.

Step 01

Instrument

One line — ferryte.instrument(). Auto-patches Mem0, pgvector, and custom stores at construction time. Your agent code does not change.

import ferryte
ferryte.instrument()

# the rest of your app stays the same
Step 02

Probe

Plants deterministic canary memories tagged by source and tenant — markers that cannot occur naturally in your data, so a positive is never a coincidence.

# under the hood
oracle.plant(
  tenant="acme",
  source="acme-doc-1",
  marker="ORION-DELTA-77",
)
Step 03

Delete

Calls your backend’s real delete API. Not a mock, not a wrapper. The exact code path your production runs when a tenant revokes a source.

# your code
store.delete_by_source("acme-doc-1")
# returns 1 — primary record removed
Step 04

Verify

Inspects both raw store contents and retrieval traces — not just agent answers, which give false confidence. Fails CI on any surviving marker.

# ferryte gates the build
$ ferryte test --scenario source-revocation
source-revocation       FAIL    3 findings
exit code 1 — build break
What it catches

The leak you can’t see, in two columns.

Without Ferrytesilent leak
› store.delete_by_source("acme-doc-1")
# returns 1 — primary record removed

› agent.ask("acme", "what is the launch code?")
Based on what I remember:
the launch code is ORION-DELTA-77.

# the per-tenant summary absorbed it.
# nothing flagged.
With Ferrytecaught in CI
› ferryte test --scenario source-revocation
source-revocation       FAIL    3 findings

FAIL revoked_marker_in_probe
  Revoked source 'acme-doc-1' still surfaces
  marker 'ORION-DELTA-77' via retrieval on
  tenant 'acme' (kind=summary, id=27dea877…).

exit code 1 — build break
What it proves — and where it’s honest

Coverage you can ship, blind spots you can name.

Covered

  • Source-revocation — deleted-row markers still surfacing via summaries or embeddings.
  • Cross-tenant isolation — tenant A receiving markers planted only in tenant B.
  • Stale-fact overwrite — old fact persisting after the canonical update.
  • Memory poisoning — adversarial writes (ASI06) surviving normal cleanup.

Honest about

  • Stores Ferryte cannot reach through the adapter interface.
  • Retrieval paths that bypass the patched memory client entirely.
  • Probabilistic behaviour that requires more than the configured retry budget.

Blind spots are surfaced in every coverage report. We would rather under-claim than ship a green build that hides a leak.

What we plug into

Adapters.

Mem0stable

First-class adapter. Auto-patch on construction.

pgvectorstable

Generic vector adapter via SQLAlchemy session.

Custom storesstable

Implement the 80-line MemoryAdapter protocol.

Zepbeta

Adapter in design-partner preview.

AWS AgentCorebeta

Adapter in design-partner preview.

LangGraphplanned

Tracing hooks landing next.

Open it up. Patch the leak.