> ## Documentation Index
> Fetch the complete documentation index at: https://cofounder.appeeky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Memory

> How the agent remembers your app, your decisions, and what worked.

The co-founder agent's memory is all in your private database, and it splits in two: what the agent **learned** (facts, episodes, reflections — scored, and evicted when something more relevant arrives) and what you **told it** (profiles and documents — never scored, never evicted). Together they make every run smarter than the last: the agent doesn't start from scratch each morning, it picks up where it left off.

When the two disagree, what you told it wins. See [Company Knowledge Base](./knowledge-base) for the precedence rules.

## Where to see it

You can browse and edit everything in the **[Memory Vault](./vault)** under your dashboard's `Co-founder → Vault` tab. The vault renders the full memory as an interactive graph — apps, facts, and outcome stories with links between them — and lets you add, supersede, export, and import knowledge.

***

## Facts (`cofounder_memory_facts`)

Stable knowledge the agent always remembers. One row per `(scope, key)`. Every fact has these properties:

| Field            | What it means                                                                                    |
| ---------------- | ------------------------------------------------------------------------------------------------ |
| `key` / `value`  | The thing being remembered (e.g. `brand_voice` → "Minimal, premium, no exclamation marks")       |
| `scope`          | Either an app id or **global** (applies to your whole portfolio)                                 |
| `kind`           | `preference`, `constraint`, `observation`, or `anti_pattern` (see below)                         |
| `source`         | `user` (you confirmed) or `agent` (it inferred from runs)                                        |
| `status`         | `active`, `pending` (awaiting your approval), or `superseded` (soft-deleted, kept for history)   |
| `confidence`     | 0–100% — how sure we are. User-typed = 100%, imported = 50%, agent guess = 40%                   |
| `importance`     | 0–100% — how often the agent should surface it. Bumped automatically when the fact proves useful |
| `previous_value` | Whatever the value was before the last overwrite — lets the vault show "was X, now Y" diffs      |

### Fact kinds

The `kind` decides how strongly the agent treats the fact:

* **anti\_pattern** — *"never do this"*. Rendered at the top of the prompt as a **HARD STOP**. The agent will refuse to propose actions that violate it.
* **constraint** — *"must respect this"*. A rule recommendations have to obey (e.g. *"don't change pricing"*).
* **preference** — *"lean this way when in doubt"*. Soft direction.
* **observation** — *"useful background"*. Context the agent can quote but isn't bound by.

You set the kind when you add a fact manually. The agent picks one when it writes a fact during a run.

### How facts make it into the prompt

Every run, the agent picks the top **N** facts using:

```
score = importance × confidence × exp(-ageDays / 60)
```

…with anti-patterns and constraints getting an extra boost so they stay in budget even when newer observations crowd in. This means **old but important** knowledge isn't forgotten just because something fresh arrived yesterday.

***

## Episodes (`cofounder_memory_episodes`)

A record of every applied action with before/after metric snapshots. This is the **learning loop** — the agent reads its own track record before proposing new things.

```
summary                               | metric_before          | metric_after
--------------------------------------+------------------------+----------------
Applied asc_metadata_update: subtitle | { downloads7d: 13 }    | { downloads7d: 28 }
Replied to 3-star review              | { rating: 4.6 }        | { rating: 4.7 }
```

Episodes feed into the prompt as "Past actions and outcomes". When the agent sees a similar opportunity, it knows how the previous attempt landed.

A 14-day follow-up is automatically scheduled when a metadata change is detected (see [A/B Test Memory](../capabilities/ab-test-memory)). Once the follow-up runs, the episode gets its `observed_outcome` populated and the agent can cite the result going forward.

***

## Reflections (`cofounder_memory_reflections`)

Periodic distillation jobs read your recent episodes (those with measured outcomes) and turn them into stable facts. This is what lets the agent move from *"here's what happened last Tuesday"* to *"TR localizations consistently lift downloads \~22% on this kind of app"*.

Reflections run **every Monday at 06:00 UTC** automatically (Trigger.dev cron). They only fire for owners/apps with new outcome data since the last reflection — no work, no cost.

You can also kick one off on demand:

* In the dashboard: **Vault → Reflect now** (top-right of the vault page). Useful right after a big experiment landed and you want the agent to internalize the lesson before tomorrow's run.
* From chat: `/reflect` (Telegram) or `!reflect` (Slack).
* Via API: `POST /v1/cofounder/memory/reflect` with optional `{ "appId": "..." }`.

Every reflection job is itself a row — you can see exactly which facts were created or promoted by which run (the **Recent reflections** strip on top of the vault graph shows the last six). Reflections never overwrite user-typed facts; they only add or strengthen agent-source ones, and every produced fact carries a `reflection_id` so you can roll back individual reflections you disagree with.

### Causal links (`cofounder_memory_links`)

Each reflected fact gets explicit `derived_from` edges back to the episodes it was distilled from. The vault renders these as **purple edges with moving particles** — so for any fact you can see exactly which past actions justified it.

The link table also captures `supersedes`, `contradicts`, `supports`, and `triggered_by` relationships, used as the agent's audit trail and the vault graph's lineage view.

***

## Semantic search (vector embeddings)

Every fact and episode is automatically embedded with `text-embedding-3-small` on insert/update and stored in pgvector. This powers two things:

1. **The agent's `search_memory` and `search_past_outcomes` tools** — when the reasoner thinks *"have we tried something like X?"* it gets back semantically-relevant rows, not just keyword matches. So writing *"price experiment"* surfaces a past *"raised the lifetime tier to \$59.99"* episode even though no word overlaps.
2. **The chat path (Telegram, Slack, Web Ask)** — every question pulls the top-N relevant facts **and** the top-N relevant past episodes into the prompt before the model answers. The agent stops answering "did we try X?" with a guess and starts answering it from real history.

Embeddings are best-effort — if the OpenAI key is unavailable or a row hasn't been embedded yet, search transparently falls back to ilike/recency. Memory writes never fail because of an embedding outage.

***

## Company profile (`cofounder_company_profile`, `cofounder_app_profile`)

The context you give the agent about your business, as opposed to what it worked out for itself. Company name, one-liner, stage, business model, ICP, positioning, brand voice — plus per-app detail like monetization, known weaknesses, and current focus.

This is the one memory layer that is **not** scored. Facts compete for a limited number of prompt slots and can be evicted; whatever you confirm here reaches every single run, verbatim. That makes it the right place for two things in particular:

* **Hard rules** — *"Never recommend removing the free tier."* Treated exactly like an anti-pattern fact: the agent will not propose an action that breaks one.
* **Do not touch** — *"app name", "the free tier", "MX pricing".* Per-app, and the fastest way to stop repeating the same correction in chat every week.

You do not start from a blank form. Shortly after you connect an app, the co-founder drafts a profile from your store listing, reviews, tracked competitors, and your website. Until you confirm it the draft is flagged as low confidence in the prompt, and its hard rules stay switched off — an unreviewed constraint should never block real work.

Edit it under **Settings → Business**, or via `GET`/`PATCH /v1/cofounder/company`. `GET /v1/cofounder/company/preview?appId=` returns the exact text injected into that app's runs.

***

## Documents (`cofounder_documents`)

Prose, for everything a field can't hold. `business_context.md` is read on every briefing; the rest of the **[Library](../capabilities/library)** is retrieved when it matches what the agent is working on — the run's theme on a briefing, your question in chat.

Like profiles, documents are yours: the agent can read and search them, can write into `research/` and `sessions/`, and cannot touch `business_context.md` or `AGENTS.md` at all. Changes to those arrive as **[knowledge patches](../capabilities/knowledge-patches)** you approve.

The full picture of how these layers stack, what's always-on versus retrieved, and the token budget they share is in **[Company Knowledge Base](./knowledge-base)**.

***

## Knowledge sources (`cofounder_knowledge_sources`)

External content you drop in for the co-founder to learn from — an article URL, a pasted note, a transcript. This is how you feed the vault knowledge that didn't come from your own runs.

**Ingest.** In the vault, hit **Ingest** and paste a URL or text. The co-founder fetches the content, distills the durable takeaways, and lands them as **pending facts** (they don't influence runs until you approve them in the graph). Every produced fact gets a `derived_from` edge back to the source, so you can always see *which article a belief came from* — the same provenance model reflections use for episodes.

* API: `POST /v1/cofounder/memory/ingest` with `{ url }` or `{ text, title? }`, optional `appId` (defaults to global/portfolio scope).
* Re-ingesting identical content is a no-op (deduped by content hash).

**Ways to feed it (all land in the same pipeline):**

* **URL / paste** — the base flow above.
* **File upload** — drop a `.txt` / `.md` / `.csv` / `.json` doc. The web reads it in the browser and posts the text; native/API clients can `POST /v1/cofounder/memory/ingest/file` (multipart, field `file`).
* **Notion** — pull a page the connected Notion integration can see: `GET /v1/cofounder/memory/notion/pages?query=` lists shared pages, `POST /v1/cofounder/memory/notion/ingest` with `{ pageId, appId? }` ingests one.
* **Browser clipper** — a bookmarklet (offered in the Ingest dialog) opens the vault with `?ingestUrl=<current page>` prefilled, so you can clip any article under your own session — no API key leaves the browser.
* **Chat** — from Telegram (`/ingest <url|text>`, `/audit`) or Slack (`!ingest <url|text>`, `!audit`). `/audit` re-checks your most recently ingested source.
* **Ask agent** — the conversational agent has a `search_knowledge` tool so "what did that article I saved say?" resolves against ingested sources.

**Does my workflow hold up? (audit).** Once a source is ingested, click **Audit against my workflow** (or `POST /v1/cofounder/memory/sources/:id/audit`). The co-founder compares what the source says against your existing active facts and returns a verdict — `holds` or `needs_changes` — plus a per-fact diff:

* **contradicts** — the source directly conflicts with a fact you hold.
* **update** — the fact is roughly right but should be refined (with a suggested new value).
* **supports** — the source reinforces an existing fact.
* **gap** — the source covers something you have no fact for yet.

Contradictions and supports are written as causal links (`source → contradicts/supports → fact`), so the vault graph renders the tension between a new article and your current SOP as colored edges.

Deleting a source removes its still-**pending** facts; facts you already approved are yours and stay.

**It keeps itself honest.** You don't have to remember to re-audit anything:

* **When reality shifts** — if an anomaly or forecast breach fires for an app, the sources tied to that app are automatically flagged **Review due** ("the ground moved, do my saved playbooks still apply?"). The vault shows the badge; running an audit clears it.
* **On a schedule** — once a week the co-founder re-checks sources that are new or flagged. When an **app-scoped** source ends up `needs_changes`, it raises a `knowledge_drift` signal — so conflicts between what you saved and what the agent believes surface in the same "needs attention" queue as anomalies and forecast breaches, instead of waiting for you to click Audit manually.

The full picture lives in **[Second Brain](../capabilities/second-brain)**.

***

## Stale actions

Not memory exactly, but related: any action proposed ≥ 2 days ago that hasn't been approved/applied/rejected counts as **stale**. The agent surfaces these prominently in the briefing under *"⏰ Still waiting on you"* with proportional urgency:

* `critical` ignored 5+ days → *"You haven't touched this in 5 days — the window is closing."*
* `medium` ignored 2 days → *"Reminder: the keyword optimization from Tuesday is still pending."*

This prevents the agent from quietly re-proposing the same thing while old recommendations rot.

***

## Decision Log

A view across `cofounder_actions` and `cofounder_memory_episodes` that joins what the agent recommended → whether you applied it → what happened. See [Decision Log capability](../capabilities/decision-log) for the full breakdown and the public API.
