# Plan: `--extra-system-prompt` option

## Goal

Add a way to **append** extra text to the default system prompt, without replacing it. The existing `--system-prompt` replaces the entire default prompt (and skips instructions, skills, MCP tool docs). The new option keeps everything and just tacks on user-provided text at the end.

## Current behavior

| Flag | Effect |
|------|--------|
| *(none)* | Default prompt + CLAUDE.md instructions + skills + MCP + timestamp |
| `--system-prompt "..."` | Replaces default prompt entirely. Skips instructions, skills, MCP docs. Keeps timestamp + command docs. |
| `--no-system-prompt` | No system message at all |

## Proposed behavior

| Flag | Effect |
|------|--------|
| `--extra-system-prompt "..."` | Default prompt + instructions + skills + MCP + timestamp + **extra text appended at the end** |

- Combinable with the default flow (no `--system-prompt` / `--no-system-prompt`).
- Mutually exclusive with `--system-prompt` and `--no-system-prompt` — if you're replacing or removing the prompt, appending to it makes no sense.
- Supported in config files (`extra_system_prompt` key in `swival.toml` / global config).
- Config merge follows the same precedence as everything else: CLI > project > global > default (`None`).

## Changes

### 1. `config.py`

- Add `"extra_system_prompt": str` to `_CONFIG_SCHEMA`.
- Add `"extra_system_prompt": None` to `_CONFIG_DEFAULTS`.
- Extend mutual-exclusion validation: if `extra_system_prompt` is set alongside `system_prompt` or `no_system_prompt`, raise `ConfigError`.
- Add commented example to the TOML template.

### 2. `session.py`

- Add `extra_system_prompt: str | None = None` parameter to `Session.__init__`.
- Store as `self.extra_system_prompt`.

### 3. `agent.py` — CLI

- Add `--extra-system-prompt` to the existing `prompt_group` mutually exclusive group (alongside `--system-prompt` and `--no-system-prompt`).

  Wait — that won't work. A mutually exclusive group means only one can be provided. But `--extra-system-prompt` should be mutually exclusive with `--system-prompt` *and* `--no-system-prompt`, while those two are already mutually exclusive with each other. argparse only supports flat mutual exclusion groups, so putting all three in one group is actually correct: at most one of the three can be specified on the CLI.

  **Decision:** Add it to the same `prompt_group`.

- Default: `_UNSET`.
- Pass `args.extra_system_prompt` through to `build_system_prompt()`.

### 4. `agent.py` — `build_system_prompt()`

- Add `extra_system_prompt: str | None` parameter.
- After all the normal assembly (default prompt, instructions, skills, MCP, timestamp, commands), if `extra_system_prompt` is not None, append it:
  ```python
  if extra_system_prompt:
      system_content += "\n\n" + extra_system_prompt
  ```
- This runs in the default-prompt branch only (the `system_prompt` and `no_system_prompt` branches are unaffected).

### 5. Tests

Add to `tests/test_config.py`:
- `extra_system_prompt` + `system_prompt` → `ConfigError`
- `extra_system_prompt` + `no_system_prompt` → `ConfigError`
- `extra_system_prompt` alone loads fine from TOML
- Cross-file conflict (one in global, the other in project)

Add to `tests/test_instructions.py`:
- `--extra-system-prompt "Be concise."` → system message contains the default prompt text **and** ends with `"Be concise."`
- Instructions and skills are still present
- Timestamp is still present

### 6. Docs

- Update `docs.md/` if there's a CLI reference section mentioning `--system-prompt`.

## Not in scope

- No `--extra-system-prompt-file` (read from file). Can be added later if wanted; users can do `--extra-system-prompt "$(cat file.txt)"` in the meantime.
