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

# Flavours

> A flavour is a top-level container chosen once at launch that scopes agents, threads, memory, and policy into one workspace.

A **flavour** is a top-level container selected once at launch, before user,
agent, and thread. It scopes which agents are visible, which threads exist, and
one shared long-term memory, and it overlays a common policy baseline onto its
member agents.

Think of it as choosing which workspace you are in. An `engineering` flavour
session sees engineering agents, engineering threads, and one engineering memory.

## The bundled flavours

| Flavour       | Agents                                                 | Default agent     | Character                                                                                |
| ------------- | ------------------------------------------------------ | ----------------- | ---------------------------------------------------------------------------------------- |
| `chat`        | `default`, `life_coach`                                | `default`         | Everyday copilot.                                                                        |
| `engineering` | `product_manager`, `architect`, `coder`                | `product_manager` | A software team sharing one memory: web on for all, writes and shell only for the coder. |
| `research`    | `researcher`, `researcher_docker`, `analyst`, `writer` | `researcher`      | Lighter guardrails, web and shell on.                                                    |
| `safe`        | `default`                                              | `default`         | Guardrails forced on.                                                                    |

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
ziro                                                  # flavour picker at launch
python -m app.main --user alice --flavour research
python -m app.cli.chat_once --user alice --flavour research --message "..."
```

## The folder shape

A flavour is a folder, mirroring `packages/ziro-core/src/ziro/agents/<id>/`:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
packages/ziro-core/src/ziro/flavours/engineering/
├── flavour.yaml
└── persona.md      # optional
```

A subdirectory counts as a flavour when it contains `flavour.yaml`. The name
falls back to the folder name.

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
name: engineering
description: A software team sharing one memory
agents: [product_manager, architect, coder]
default_agent: product_manager

shared_policies:
  websearch_policy.yaml:
    enabled: true

policies:
  coder/websearch_policy.yaml:
    enabled: false
  coder/webfetch_policy.yaml:
    enabled: false
```

## The policy overlay

Selecting or switching a flavour is **scope-only**: it never writes a policy
file. The overlay is merged in memory at config-load time.

`flavour_overrides(agent_id, filename)` merges the flavour's
`shared_policies[filename]` with its per-agent `policies["<agent>/<file>"]`.
Per-agent wins on a clash. The merged dict is applied onto the parsed YAML
**before** the config object is built, by `load_shell_config`,
`load_voice_config`, `load_webfetch_config`, `load_websearch_config`, and
`load_policies` (guardrails).

With no active flavour, the overrides are an empty dict and behaviour is
byte-identical to a Ziro with no flavours at all.

<Info>
  The overlay is how a flavour **narrows** a member. In `engineering`, the coder
  loses `web_search` and `web_fetch`; in `research`, the analyst does. That is
  deliberate: the shell-and-write agents do not hold the ingress tools, so
  untrusted web content cannot reach an autonomous shell. The read-only agents
  keep web and hand vetted material over through the shared memory.
</Info>

## Shared memory

Every agent in a flavour shares one long-term memory store, keyed:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
("memory", user_id, flavour)
```

Both the memory loader and the `save_memory` tool key on
`flavour or agent_id`. So a fact the `product_manager` saves is visible to the
`architect` and the `coder`, and switching agents mid-thread never loses or
cross-contaminates memory.

A config with no flavour (subagents, legacy callers) falls back to `agent_id`,
unchanged from before flavours existed.

<Note>
  Flavour keying supersedes the earlier sticky-memory mechanism. The behaviour you
  see is the same: an in-place `/agent` switch keeps the same thread and history.
  Only the memory-key plumbing under it changed.
</Note>

## Thread scoping

Entries in `<DATA_DIR>/threads.json` carry a `flavour` field, written on every
turn (even when it is `None`). Every thread surface filters by the active
flavour: the launch picker, the in-chat `/thread` and `/threads` pickers,
`/thread delete`, the console prompt, and the thread-count gate in the launch
flow.

A `research`-flavour thread is invisible while you are chatting in `chat`.

<Warning>
  On first run against a pre-flavour `threads.json`, Ziro renames the old index to
  `threads.json.pre-flavour.bak` so the flavour-scoped index starts clean. It is an
  atomic rename, never a delete, and it is one-time and idempotent: once the
  `.bak` exists, later launches are a no-op.
</Warning>

## Persona composition

When a flavour's `persona.md` is non-empty, it becomes the **dominant voice** for
every member agent. The flavour persona leads; the agent's own soul prompt is
folded in as a subordinate note:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
<flavour persona>

Your role in this <flavour> workspace: <agent soul>
```

The role note is omitted when the agent has no soul of its own. Persona leads,
agent soul narrows the role.

This applies **only on top-level turns**. The agent node gates on the `flavour`
key, which top-level runnable configs carry and subagent child configs never do,
so `scout`, `reflector`, and the rest keep their own specialized souls
unconditionally.

With no active flavour, or a flavour with no `persona.md`, composition returns
the agent's own soul unchanged.

Four personas ship:

| Flavour       | Voice                                                      |
| ------------- | ---------------------------------------------------------- |
| `chat`        | Warm, concise, everyday.                                   |
| `engineering` | A shared software-team voice for PM, architect, and coder. |
| `research`    | Rigorous, cites sources, separates fact from inference.    |
| `safe`        | Measured, privacy-first, flags uncertainty.                |

## There is no in-chat flavour switch

A flavour is chosen **once at launch** (via the `--flavour` flag, the launch
flow's flavour step, or the flavour picker) and it is **not switchable
mid-chat**. There is deliberately no `/flavour` command.

Typing `/flavour` prints a one-line redirect hint rather than rebuilding the
session. To move to a different flavour, relaunch. Within the current flavour,
use the in-chat `/agent`, `/thread`, and `/user` switches.

This is why there is no `rebuild_for_flavour` on the session objects, and why
`flavour` is absent from the commands that are safe to run mid-turn.

## Resolution order

The flavour resolves as:

<Steps>
  <Step title="The --flavour flag">
    An explicit flag always wins.
  </Step>

  <Step title="The user's last flavour">
    Remembered per user in `~/.ziro/users.json`.
  </Step>

  <Step title="The picker">
    Shown only when unresolved **and** two or more flavours are configured:
    skip-when-trivial, like every other launch step.
  </Step>
</Steps>

Headless resolution mirrors the interactive one (flag, then last flavour, then
unresolved) without ever prompting.

### Defense in depth

An explicit `--agent` (or a background job's `agent_id`) that names an agent
outside the active flavour is **corrected to the flavour's `default_agent`**
rather than run under its policy overlay. The same backstop applies to the
interactive runner, the REPL session, and the background worker pool.

## Known limitation

<Warning>
  `ziro init --flavour` (the separate bake-into-a-project tool) only writes a
  flavour's per-agent `policies` into the scaffolded project. It does **not** apply
  `shared_policies`.

  The scope-only runtime overlay described above is the primary, fully-supported
  path for a flavour's shared policy baseline. Treat `ziro init --flavour` as a
  convenience seed, not a full bake.
</Warning>

## Next steps

<Columns cols={3}>
  <Card title="Agents" icon="boxes" href="/concepts/agents">
    What each member agent is made of.
  </Card>

  <Card title="Memory" icon="brain" href="/concepts/memory">
    How the shared store and project memory differ.
  </Card>

  <Card title="Configuration" icon="settings" href="/guides/configuration">
    Writing your own flavour and policy layers.
  </Card>
</Columns>
