# Context, memory & DNA

Two different things keep a fleet of agents consistent, and they are worth separating. **DNA** is the composed identity an agent starts with — voice, principles, role, and your standards. **Memory** is what the workspace has accumulated — conventions, decisions, and lessons, retrieved when relevant.

## When this matters to you

- Your agents keep re-solving a problem you already decided — that is a memory gap.
- Output from two projects reads like it came from two different companies — that is a DNA question.
- You are evaluating hlix and want to know what compounds over time and what does not.

## DNA — the identity agents are composed from

```text
        DNA.md              the shared identity: voice, principles, refusals
           +
        Persona             the role: orchestrator, planner, reviewer,
                            or one of the six worker roles
           +
        Context             organization · user · project
           ▼
     the instructions ONE agent actually runs with
```

Every prompt an hlix agent runs is composed, never inlined. The shared identity lives in one file; each role is a persona definition with its own inputs; the composition happens at call time with the organization, user, and project in scope. That is what makes "sounds like us" a property of the system rather than of whichever prompt someone last edited.

The practical consequence: changing how *every* agent behaves is one edit in one place, and changing how *one role* behaves does not touch the others.
**What you cannot edit yet:** DNA composition is defined in code, with a per-organization override table behind it in the database. There is **no API or dashboard surface for editing DNA today** — per-user and per-organization DNA are planned, not shipped. Anything you read elsewhere about customizing agent identity from the product is describing the roadmap.

## Memory — what the workspace has learned

Memory is scoped, categorized, and retrieved semantically. A memory is written once and surfaces whenever it is relevant, rather than being pasted into a prompt by hand.

**Five scopes**, from broadest to narrowest:

| Scope | Holds |
| --- | --- |
| `org` | Standards that apply to everything your workspace builds |
| `project` | Decisions specific to one product or engagement |
| `cycle` | Context for one feature or phase |
| `task` | Detail about a single unit of work |
| `agent` | What one agent has learned about doing its job |

**Six categories**, which is what makes retrieval useful rather than noisy:

| Category | Example |
| --- | --- |
| `convention` | "Tables use snake_case; TypeScript uses camelCase." |
| `decision` | "We chose Postgres over DynamoDB for the ledger." |
| `lesson` | "The staging seed script must run before the e2e suite." |
| `preference` | "Prefer composition over inheritance in this codebase." |
| `failure` | "Retrying the webhook without a jitter caused a thundering herd." |
| `heuristic` | "Anything touching billing gets a security review." |

Each memory also carries a `source` (`auto`, `user`, `interview`, `review`), a `confidence` between 0 and 1, and a `status` of `tentative`, `approved`, or `archived`. Agent-extracted memories arrive `tentative`; promoting one to `approved` is how you decide what the workspace actually stands behind.

## Reading and writing memory

In the dashboard, **Global knowledge** browses the `org` scope — the standards that apply to everything.

Over the API:

| Operation | Endpoint |
| --- | --- |
| List | `GET /v1/api/memories` |
| Read one | `GET /v1/api/memories/:id` |
| Create | `POST /v1/api/memories` |
| Update | `PATCH /v1/api/memories/:id` |
| Delete | `DELETE /v1/api/memories/:id` |
| Semantic search in a scope | `GET /v1/api/memories/search/:scope/:scopeId` |
| Extract from a finished cycle | `POST /v1/api/memories/extract/:cycleId` |

```bash
curl -sS -X POST "$HLIX_BASE_URL/v1/api/memories" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID" \
  -H 'content-type: application/json' \
  -d '{
    "scope": "org",
    "scopeId": "'"$HLIX_WORKSPACE_ID"'",
    "category": "convention",
    "key": "database-naming",
    "value": "Database identifiers are snake_case. TypeScript identifiers are camelCase. Never mix them in one file.",
    "status": "approved"
  }'
```
**Not in the published contract:** The memory endpoints are not in `openapi.json` yet, so there is no generated SDK method for them. Use the dashboard or a direct HTTP call.

## How retrieval stays tenant-safe

Long-term memory is stored as semantic embeddings namespaced by organization, scope, and scope id. Retrieval is a vector search inside that namespace, so a query in one workspace cannot surface another workspace's memories — the isolation is structural, not a filter applied after the fact.

## Why agencies care

Consistency is what clients pay for. Memory is how a fleet of agents produces work that reads as one disciplined team rather than ten strangers, and DNA is how that team sounds like *your* team. Both accumulate: the second task in a project is better informed than the first, and the tenth agent inherits what the first nine learned. It is the one asset here that gets more valuable the longer you use it, and no model provider owns it.

## If memory does not show up in a run

- **A memory exists but agents ignore it.** Check its `status`. A memory that is not approved is not composed into a prompt.
- **A memory applies too widely or too narrowly.** The scope is what decides. Re-create it at the scope you meant; `scopeId` must match that scope's object.
- **No SDK method for the memory endpoints.** They are not in `openapi.json` yet, so no client generates them. Use the dashboard or a direct HTTP call.
- `404` on a memory you can see in another workspace — retrieval is namespaced per organization. Absent and not-visible are the same answer.
- **Semantic search returns nothing for an obvious phrase.** Search runs inside one namespace. Confirm the `scope` and `scopeId` in the URL are the ones the memory was written under.
- **Extraction from a cycle produced nothing.** It reads a *finished* cycle. A run still in flight has nothing settled to extract.

## Where to go next

| If you want to… | Read |
| --- | --- |
| See who consumes this context | [Agents & orchestration](/concepts/agents/) |
| Understand the scopes as objects | [Work tree](/concepts/work-tree/) |
| Import a written standard as a skill | [Import skills, agents & MCP servers](/cli/resources/) |
| See what a worker did with it | [Reviewing output](/running/review/) |

## Next steps

[Agents & orchestration](/concepts/agents/)
  [Work tree](/concepts/work-tree/)
  [Import skills, agents & MCP servers](/cli/resources/)
  [Review & QA gates](/concepts/review-gates/)