# Configuration

## Configuration Sources

Remem has two configuration paths:

- the application config generated by `remem init`, used by the CLI and by a plugin entry without
  inline `providers`;
- inline OpenCode plugin options, used when the v2 plugin object or v1 tuple explicitly contains a
  `providers` property.

An explicit `providers` property wins even when it is an empty array. Invalid provider entries are
disabled with sanitized diagnostics; an explicitly malformed provider list enables no providers.

## Paths and Overrides

Default directories:

| Platform | Config directory                                      | Data directory                                           |
| -------- | ----------------------------------------------------- | -------------------------------------------------------- |
| Linux    | `$XDG_CONFIG_HOME/remem`, otherwise `~/.config/remem` | `$XDG_DATA_HOME/remem`, otherwise `~/.local/share/remem` |
| macOS    | `~/Library/Application Support/Remem`                 | `~/Library/Application Support/Remem/data`               |
| Windows  | `%APPDATA%\Remem`                                     | `%LOCALAPPDATA%\Remem`                                   |

Environment overrides:

| Variable             | Effect                                                                |
| -------------------- | --------------------------------------------------------------------- |
| `REMEM_CONFIG_DIR`   | Replaces the configuration directory                                  |
| `REMEM_DATA_DIR`     | Replaces the data and default backup directory                        |
| `REMEM_CONFIG`       | Replaces only the full `config.json` path                             |
| `REMEM_DATABASE_URL` | Overrides the stored database connection when configuration is loaded |
| `OPENCODE_CONFIG`    | Selects the OpenCode file modified by `remem init --opencode`         |

`REMEM_CONFIG` does not relocate generated `.env` or `compose.yaml`; those remain under the config
directory. `REMEM_DATABASE_URL` overrides external mode only. Managed mode ignores it so runtime,
migrations, lifecycle, and backup cannot split across different databases. Use
`remem init --mode external` to change database ownership.

## Generated Application Config

A managed installation writes a protected config similar to:

```json
{
  "version": 1,
  "storage": {
    "mode": "managed",
    "connectionString": "postgres://remem:REDACTED@127.0.0.1:54329/remem",
    "composeFile": "/path/to/config/compose.yaml",
    "environmentFile": "/path/to/config/.env",
    "projectName": "remem-0123456789",
    "database": "remem",
    "user": "remem",
    "port": 54329
  },
  "providers": [
    {
      "type": "postgres",
      "id": "remem-local",
      "connectionString": "postgres://remem:REDACTED@127.0.0.1:54329/remem",
      "primary": true,
      "maxConnections": 5,
      "catalogLimit": 2000
    }
  ],
  "embedding": {
    "provider": "neural",
    "model": "bge-small-en-v1.5",
    "dimensions": 384
  }
}
```

`remem init` writes `provider: "neural"` by default for both `--mode managed` and `--mode external`.
This `embedding` object is the app-config shape (`provider`/`model`/`dimensions`); it is distinct
from the plugin-options `embedding` shape described in
[Embedding Options](#embedding-options) below — see that section for the difference.

Config format `version: 1` is not the database schema version. The current database schema is version 4.

The config and managed `.env` contain credentials. On POSIX platforms Remem writes config, `.env`,
and generated Compose files with mode `0600`, and creates config/data/backup directories with mode
`0700`. It also writes backup artifacts with mode `0600`.

## Session Capture

Capture is disabled by default. `remem init --opencode-v1` enables it and automatically promotes
screened explicit user decisions, preferences, and corrections; rerun that command on an existing
setup to enable the same behavior. Use `remem init --capture` or set `capture.enabled` to `true` for
review-based capture, which leaves candidates pending. A partial inline `capture` configuration
overrides only the supplied capture fields and retains the installed provider configuration when inline
`providers` are omitted.

```json
{
  "capture": {
    "enabled": true,
    "autoPromote": true,
    "queueLimit": 32,
    "maxInputCharacters": 2000,
    "maxCandidateCharacters": 1500,
    "timeoutMs": 1000
  }
}
```

Only screened user-authored durable statements qualify. Direct requests such as `Remember that
Atlas uses PostgreSQL`, plus ordinary decisions, preferences, corrections, project facts, and task
state can be captured without a special trigger phrase. Questions, chitchat, prompts containing reusable
credentials, reported quoted/retrieved text, or tool output are excluded. Capture never reads model or tool
responses as user assertions. Hosts may also submit a normalized resolved-task episode after a
_verified_ success; that path records a bounded `procedure` with session provenance, not a user
assertion, and still redacts credentials. Failed or unverified investigations are dropped. With
`autoPromote: true`, screened statements are immediately consolidated into durable
memory using the same duplicate/conflict handling as the manual flow. With the default `false`, capture
creates pending candidates; inspect them with `remem candidates`, approve or reject each with
`remem review <ID> --approve|--reject`, and promote approved candidates with `remem consolidate`.

## OpenCode v2 Plugin Options

The current beta schema uses `plugins` and an object with `package` and optional `options`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "plugins": [
    {
      "package": "file:///absolute/path/to/remem/dist",
      "options": {
        "providers": [
          {
            "type": "markdown",
            "id": "project-notes",
            "paths": [".remem/memory", "~/notes"],
            "exclude": ["private/**"],
            "scope": "workspace",
            "maxFileBytes": 262144,
            "maxFiles": 2000
          }
        ],
        "budgets": {
          "catalogTokens": 600,
          "recallTokens": 1400,
          "perProviderTokens": 900
        },
        "planner": {
          "minimumConfidence": 0.42,
          "maxTopics": 3,
          "semantic": true,
          "semanticMinimumSimilarity": 0.55,
          "deterministicHighConfidence": 0.82
        },
        "providerTimeoutMs": 2000,
        "maxResults": 8,
        "debug": false
      }
    }
  ]
}
```

Relative Markdown paths resolve from the OpenCode worktree. `~` and `~/...` resolve from the user
home directory. Default exclusions are `**/.git/**`, `**/.trash/**`, and `**/node_modules/**`, with
configured exclusions appended.

If `providers` is omitted from both inline options and installed config, Remem defaults to a
read-only Markdown provider named `workspace-memory` at `.remem/memory`. The generated application
config includes `providers`, so a normal `remem init` installation uses PostgreSQL instead.

## Embedding Options

An optional `embedding` block selects the `EmbeddingModel` used for Stage 1
semantic recall:

```json
{
  "options": {
    "embedding": {
      "backend": "neural",
      "modelPath": "/absolute/path/to/pre-staged/bge-small-en-v1.5"
    }
  }
}
```

- `backend`: `"hash"` (default when omitted) or `"neural"`. `"hash"` uses the
  zero-dependency `remem-local-hash-v1` model; `"neural"` loads
  `bge-small-en-v1.5` via `@huggingface/transformers` and falls back to
  `"hash"` automatically if the model can't be loaded.
- `modelPath` (optional): a local directory of pre-staged model weights,
  for air-gapped installs where downloading from huggingface.co isn't
  possible. Only meaningful with `backend: "neural"`.

This `{ backend, modelPath }` shape is the plugin-options `embedding` block. It is a **separate,
non-interchangeable** object from the app-config `embedding` shape (`{ provider, model, dimensions }`)
shown in [Generated Application Config](#generated-application-config) above — the two happen to
share the key name `embedding` but have no overlapping fields. `remem init` writes the app-config
shape with the neural backend already selected, independent of this plugin-options block. See
[`docs/embeddings.md`](./embeddings.md) for model details and re-embedding behavior, or
[`docs/embeddings.md#if-the-download-is-blocked-firewalls-air-gapped-environments`](./embeddings.md#if-the-download-is-blocked-firewalls-air-gapped-environments)
for the first-time download flow and offline fallback.

## PostgreSQL Provider Options

Inline PostgreSQL configuration accepts a direct connection string or an environment-variable name:

```json
{
  "type": "postgres",
  "id": "team-memory",
  "connectionStringEnv": "TEAM_REMEM_DATABASE_URL",
  "primary": true,
  "maxConnections": 5,
  "catalogLimit": 2000
}
```

`id` must match letters/digits/underscore/hyphen rules and start with a letter or digit. Defaults and
accepted ranges are:

| Setting                     | Default | Range          |
| --------------------------- | ------- | -------------- |
| `maxConnections`            | 5       | 1 to 50        |
| `catalogLimit`              | 2000    | 10 to 20000    |
| `providerTimeoutMs`         | 2000 ms | 50 to 60000 ms |
| `maxResults`                | 8       | 1 to 100       |
| `budgets.catalogTokens`     | 600     | 200 to 20000   |
| `budgets.recallTokens`      | 1400    | 100 to 50000   |
| `budgets.perProviderTokens` | 900     | 100 to 50000   |

Out-of-range numeric values are clamped. Non-numeric values use defaults.

## Recognition Configuration

`planner.minimumConfidence` controls deterministic topic qualification. Semantic Stage 1 runs when
deterministic recognition has no plan or is below `deterministicHighConfidence`. Set
`planner.semantic` to `false` to disable it.

The default local model depends on how Remem was configured. App-generated config from
`remem init --mode managed` or `--mode external` defaults to the neural `bge-small-en-v1.5` model,
384 dimensions, with automatic fail-open fallback to `remem-local-hash-v1` if the neural backend
can't be loaded. Plugin-only installs (no app-generated config, `providers` set inline) default to
`remem-local-hash-v1`, 384 dimensions, deterministic feature hashing with a small concept
vocabulary — not a general neural model — unless `embedding.backend` is set to `"neural"`. See
[Embedding Options](#embedding-options) and [`docs/embeddings.md`](./embeddings.md) for details.
Library consumers can construct `RememOrchestrator` or `PostgresMemoryProvider` with a different
`EmbeddingModel`.

## Debugging

`debug: true` records bounded retrieval traces including matched catalog titles, query topics,
provider timing/counts, selected counts, budgets, and diagnostics. It does not intentionally log raw
memory bodies, but titles and query terms may still be sensitive. Keep debug disabled unless needed.

Run `remem doctor` after changing application configuration. Inline OpenCode options are validated
only when the plugin starts.
