Metadata-Version: 2.5
Name: ferryte
Version: 0.3.0
Summary: Memory debugging for AI agents: trace a wrong answer back to the exact memory that caused it, replay without it, and prove the fix.
Project-URL: Homepage, https://ferryte.dev
Project-URL: Documentation, https://github.com/getferryte/ferryte#readme
Project-URL: Repository, https://github.com/getferryte/ferryte
Project-URL: Issues, https://github.com/getferryte/ferryte/issues
Project-URL: Changelog, https://github.com/getferryte/ferryte/blob/main/CHANGELOG.md
Author: Ferryte contributors
License: Business Source License 1.1
        
        Parameters
        
        Licensor:             Ferryte (and its commercial entity)
        Licensed Work:        Ferryte v0.2.3 or later. The Licensed Work is
                              (c) 2026 Ferryte contributors.
        Additional Use Grant: You may make production use of the Licensed Work,
                              provided that you do not offer the Licensed Work to
                              third parties on a hosted or embedded basis that
                              competes with a Ferryte commercial offering. A
                              "competing offering" is a product or service marketed
                              to third parties that provides debugging,
                              observability, attribution, auditing, or verification
                              of AI agent memory as a managed, hosted, or embedded
                              service.
        Change Date:          Four years from the date each version is first
                              published.
        Change License:       Apache License, Version 2.0
        
        -----------------------------------------------------------------------------
        
        Terms
        
        The Licensor hereby grants you the right to copy, modify, create derivative
        works, redistribute, and make non-production use of the Licensed Work. The
        Licensor may make an Additional Use Grant, above, permitting limited
        production use.
        
        Effective on the Change Date, or the fourth anniversary of the first publicly
        available distribution of a specific version of the Licensed Work under this
        License, whichever comes first, the Licensor hereby grants you rights under
        the terms of the Change License, and the rights granted in the paragraph
        above terminate.
        
        If your use of the Licensed Work does not comply with the requirements
        currently in effect as described in this License, you must purchase a
        commercial license from the Licensor, its affiliated entities, or authorized
        resellers, or you must refrain from using the Licensed Work.
        
        All copies of the original and modified Licensed Work, and derivative works
        of the Licensed Work, are subject to this License. This License applies
        separately for each version of the Licensed Work and the Change Date may vary
        for each version of the Licensed Work released by Licensor.
        
        You must conspicuously display this License on each original or modified copy
        of the Licensed Work. If you receive the Licensed Work in original or
        modified form from a third party, the terms and conditions set forth in this
        License apply to your use of that work.
        
        Any use of the Licensed Work in violation of this License will automatically
        terminate your rights under this License for the current and all other
        versions of the Licensed Work.
        
        This License does not grant you any right in any trademark or logo of
        Licensor or its affiliates (provided that you may use a trademark or logo of
        Licensor as expressly required by this License).
        
        TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
        AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
        EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
        MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
        TITLE.
        
        -----------------------------------------------------------------------------
        
        Covenants of Licensor
        
        In consideration of the right to use this License's text and the "Business
        Source License" name and trademark, Licensor covenants to MariaDB, and to all
        other recipients of the licensed work to be provided by Licensor:
        
        1. To specify as the Change License the GPL Version 2.0 or any later version,
           or a license that is compatible with GPL Version 2.0 or a later version,
           where "compatible" means that software provided under the Change License
           can be included in a program with software provided under GPL Version 2.0
           or a later version. Licensor may specify additional Change Licenses
           without limitation.
        
        2. To either: (a) specify an additional grant of rights to use that does not
           impose any additional restriction on the right granted in this License, as
           the Additional Use Grant; or (b) insert the text "None".
        
        3. To specify a Change Date.
        
        4. Not to modify this License in any other way.
        
        -----------------------------------------------------------------------------
        
        Notice
        
        The Business Source License (this document, or the "License") is not an Open
        Source license. However, the Licensed Work will eventually be made available
        under an Open Source License, as stated in this License.
        
        For more information on the use of the Business Source License for Ferryte,
        please see https://ferryte.dev/license.
        
        For more information on the use of the Business Source License generally,
        please see https://mariadb.com/bsl11/.
License-File: LICENSE
License-File: LICENSE-BSL.txt
License-File: LICENSE-MIT.txt
Keywords: agents,ai,attribution,debugging,lineage,memory,observability,provenance,testing,verification
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Requires-Dist: numpy>=1.26
Requires-Dist: pydantic>=2.6
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Provides-Extra: all
Requires-Dist: chromadb>=0.5; extra == 'all'
Requires-Dist: cryptography>=42.0; extra == 'all'
Requires-Dist: psycopg[binary]>=3.1; extra == 'all'
Requires-Dist: qdrant-client>=1.9; extra == 'all'
Provides-Extra: api
Requires-Dist: fastapi>=0.110; extra == 'api'
Requires-Dist: uvicorn>=0.29; extra == 'api'
Provides-Extra: attest
Requires-Dist: cryptography>=42.0; extra == 'attest'
Provides-Extra: chroma
Requires-Dist: chromadb>=0.5; extra == 'chroma'
Provides-Extra: dev
Requires-Dist: mypy<1.19,>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: mem0
Requires-Dist: mem0ai>=0.1.0; extra == 'mem0'
Provides-Extra: pgvector
Requires-Dist: psycopg[binary]>=3.1; extra == 'pgvector'
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.9; extra == 'qdrant'
Description-Content-Type: text/markdown

# Ferryte

**Memory debugging for AI agents.**
**Source-available (BSL 1.1 → Apache 2.0) · commercial Cloud + Enterprise tiers.**

[Marketing site](https://ferryte.dev) · [Live dashboard demo](https://ferryte.dev/app) · [**$500 Memory Audit**](https://ferryte.dev/audit) · [LICENSING](LICENSING.md) · [COMMERCIAL](COMMERCIAL.md)

Your agent gave a wrong, stale, or leaked answer. Somewhere in its memory is
the artifact that caused it. Ferryte finds that artifact, shows you the
evidence, and proves the fix worked.

```bash
pip install ferryte
ferryte why "your plan includes 24/7 phone support" --tenant acme
```

```
#1  mem_a41f9c2e  ·  confidence 1.00  ·  STALE BELIEF
    shared span: "includes 24/7 phone support"
    superseded by mem_77b0d1 ("phone support was dropped in the March plan change")
    last retrieved 2h ago · written 41 days ago · source: sales-call-0311
    fix: ferryte delete mem_a41f9c2e --cascade
```

## Why this exists

Agent memory is production state, but when it misbehaves there is no
debugger for it. Logs show *what* the agent said; nothing shows *which
memory made it say that*. Teams grep vector stores by hand, guess, delete,
and hope.

Ferryte is the missing layer — think Sentry, but for agent memory:

- **Trace**: one line (`ferryte.instrument()`) records every memory write,
  retrieval, and delete, building a lineage graph from each source to every
  derived artifact.
- **Attribute**: `ferryte why` ranks the memories that caused a given answer
  — IDF-weighted content overlap, shared-span evidence, retrieval traces,
  and exact answer→memory edges when you opt in via `ferryte.record_answer()`.
- **Diagnose**: each suspect is labeled — stale belief (structurally provable
  via supersession edges), zombie memory (deleted but still retrieved),
  cross-tenant leak, phantom memory (source revoked), hub memory
  (poisoning-style retrieval fan-out).
- **Replay & verify**: `ferryte why --replay` re-runs retrieval without the
  suspect and shows what would have entered the context instead. After the
  fix, the same command proves the bad memory is gone.

## Quickstart

```python
import ferryte

ferryte.instrument()          # one line; auto-patches detected memory clients
# ... your agent runs as usual ...

# optional, for exact attribution:
ferryte.record_answer(answer_text, query=user_query, artifact_ids=context_ids)
```

Then, when something goes wrong:

```bash
ferryte why "the bad answer text" --tenant acme --since 2h
ferryte why "the bad answer text" --tenant acme --query "original user query" --replay
```

## Can one tenant reach another's data?

Published measurements put cross-tenant leakage at **83%** in multi-tenant RAG
built on logical isolation without access control at the retrieval layer — which
is the default shape of most AI SaaS, because per-tenant indexes are expensive.
Most teams have no instrument that would tell them either way.

One command, no instrumentation, read-only:

```bash
ferryte isolation-check "postgres://user:pass@host/db" \
  --table memories \
  --tenants acme,globex \
  -q "what are our renewal terms?" \
  --markdown isolation.md
```

Three probes, in increasing order of what they prove:

1. **Filtered** — each tenant's queries run *with* the tenant filter. A foreign
   document here means the filter itself is broken. Hard fail.
2. **Unfiltered blast radius** — the same queries with no filter, measuring what
   a single forgotten `WHERE` clause would expose. Reported as exposure, never
   as a defect, because an unfiltered query is not by itself a bug.
3. **Semantic neighbours** — queries derived from one tenant's own documents,
   run as another tenant. This is reach through *similarity* rather than a
   missing predicate, and it is the path that produces no error in any log.

Exits non-zero on a real leak, so it works as a CI gate as well as a one-off.

## Proving a deletion actually happened

GDPR's accountability principle means it is not enough to delete — you have to be
able to demonstrate it. The EDPB's 2025 coordinated enforcement action on the
right to erasure found most organisations cannot.

```bash
ferryte attest-deletion "postgres://…" \
  --source user_8813 \
  --probe "the distinctive phrase that should now be gone" \
  --sign --markdown attestation.md

ferryte verify-attestation attestation.json
```

You get a dated, hash-chained, Ed25519-signed record of what was deleted, what
was probed afterwards, what those probes returned — and, printed as prominently
as the successes, **what could not be verified**.

> This attests to what Ferryte observed through the connections it was given. It
> is **not** a certificate of regulatory compliance, and it does not claim to be.
> Backups, replicas, downstream exports and model weights are outside its reach,
> and every generated attestation says so on its face.

## CI gate

Fail the build when a change lets one tenant reach another, or when a deletion
cannot be verified:

```yaml
- uses: getferryte/ferryte@v1
  with:
    uri: postgres://…
    tenants: acme,globex
    queries: |
      what are our renewal terms?
      summarise last quarter
```

Or drive the forgetting battery directly:

```bash
ferryte init
ferryte test --scenario source-revocation
ferryte coverage        # what was verified + the honest blind-spot map
```

Scenarios: `source-revocation`, `cross-tenant-isolation`, `stale-fact`,
`memory-poisoning`, `mosaic`.

## Supported backends

| Backend | State | Install |
|---|---|---|
| **pgvector** (PostgreSQL) | shipped | `pip install 'ferryte[pgvector]'` |
| **Chroma** | shipped | `pip install 'ferryte[chroma]'` |
| **Qdrant** | shipped | `pip install 'ferryte[qdrant]'` |
| Mem0 | shipped | `pip install 'ferryte[mem0]'` |
| In-memory reference store | shipped | included |
| Zep · Letta · Cloudflare Agents | beta | included |
| AWS Bedrock AgentCore | benchmark-only — no runtime adapter yet | — |

`pip install 'ferryte[all]'` gets every backend plus attestation signing.

**On embeddings, plainly:** pgvector and Qdrant store vectors from *your* model,
which Ferryte cannot reproduce. Pass an `embedder` and probes run true vector
similarity; omit it and they fall back to a lexical scan, which still catches
exact-token leaks but can miss paraphrased ones — and records a blind spot
saying exactly that. Chroma embeds queries itself, so semantic probing there is
meaningful out of the box. Anything else with write/search/delete can be wrapped
by implementing the five hooks in `adapters/base.py`.

## Project layout

```
ferryte/
├── src/ferryte/            # Python core + CLI (pip install ferryte)
│   ├── instrument.py       # one-line auto-patching
│   ├── adapters/           # memory-backend adapters
│   ├── lineage/            # source → artifact graph, answer lineage, supersessions
│   ├── oracle/             # attribution engine, counterfactual replay, scenarios
│   ├── reports/            # coverage + blind-spot map
│   └── api/                # local HTTP server feeding the dashboard
├── dashboard/              # Next.js marketing site + dashboard
├── benchmark/              # public backend benchmark harness
├── action.yml              # GitHub Action: isolation + forgetting checks in CI
└── tests/
```

## Licensing

Ferryte is **source-available** under the Business Source License 1.1: read,
run, modify, and self-host in production for free. Each version converts to
Apache 2.0 four years after release. The one thing the license does not
permit is reselling Ferryte itself as a competing hosted or embedded service.
Same model as MariaDB, CockroachDB, and HashiCorp.

- **v0.2.3 and later:** BSL 1.1, 4-year conversion — see [LICENSE](LICENSE).
- **v0.2.0 – v0.2.2:** BSL 1.1, 3-year conversion — see [LICENSE-BSL.txt](LICENSE-BSL.txt).
- **v0.1.0:** MIT — see [LICENSE-MIT.txt](LICENSE-MIT.txt).

Details, contributor license, and trademark policy: [LICENSING.md](LICENSING.md).
Commercial tiers (Cloud, Enterprise): [COMMERCIAL.md](COMMERCIAL.md).

## Want us to run this on your stack?

The **[Agent Memory Audit](https://ferryte.dev/audit)** — fixed $500,
48-hour turnaround, runs entirely in your infrastructure. We instrument your
agent with you, run the full forgetting battery, trace your worst wrong
answers to the memories that caused them, and hand you the evidence and the
fix list. Money back if we find nothing actionable.
Email `pranav@ferryte.dev` with subject `Audit`.

## Status

Pre-launch. The source-available engine ships now; Cloud and Enterprise gate
behind design partners. Looking for teams running AI agents with persistent
memory in production who are fighting wrong answers they can't explain.

If that is you: open an issue, email `pranav@ferryte.dev`, or reach out via
the site.
