# Discovery Questions

Use this sequence to fill `mono-agent.config.json` before running anything. Ask one question at a time. Skip questions whose answer is already explicit in the user's request. Each answer maps to concrete config keys.

## 1. Runtime And Backup Models

Question:

```text
Which model should drive the agent, and should any backups take over when the provider fails?

1. `<provider>:<model>` on any provider the agent declares — `openai-codex`, `anthropic`,
   `github-copilot`, `openrouter`, `opencode-go`, local `ollama`/`lmstudio`, ...
2. A custom MonoRuntimeLike supplied programmatically (escape hatch)
```

Fills: `runtime.model`, `runtime.fallbacks[]` (ordered backup routes tried on retryable provider failures, each with optional exact effort), `runtime.effort`, `runtime.maxTurns`, and `providers` (the map declaring which providers this agent supports — it gates what is selectable). `runtime.fallbackModels` and `MONO_AGENT_FALLBACK_MODELS` were retired in 0.21.0 and are rejected at load; never emit them. Every route is Pi-native, so a chain may mix providers freely and native mono-agent sandboxing applies uniformly.

The interactive `mono-agent init` wizard discovers Pi OpenAI-Codex auth, OpenCode models, Ollama models, and LM Studio's local server best-effort. It presents `openai-codex:gpt-5.6-terra` and `openai-codex:gpt-5.6-sol` as concrete selectable candidates, maps discovered OpenCode options to `opencode-go:<model>`, and auto-adds local provider modules when a primary or fallback model uses `ollama:*` or `lmstudio:*`. Recover missing Pi OAuth with `mono-agent auth login <provider>` (and `--pi-auth-path` when required). `ollama` and `lmstudio` are zero-config autodiscovered; declare a `providers` entry only to override an endpoint or credential, or to widen selection to a provider no route uses. Follow-up only if needed: continuous provider session per conversation (`runtime.session.mode: "continuous"`, default) versus stateless per-message.

## 2. Channels Of Communication

Question:

```text
Where should people (or other agents) reach this agent? Pick every channel that applies:

1. Webhook (HTTP POST, zero credentials — good first smoke test)
2. OpenAI-compatible API (OpenWebUI and other API clients)
3. Telegram
4. Slack
5. WhatsApp
6. A2A (agent-to-agent provider/consumer)
7. Cron (scheduled prompts, no inbound channel)
```

Fills one config section per choice: built-in channels use `webhook`, `openaiApi`, `telegram`, `slack`, and `cron`; WhatsApp and A2A are external channel plugins under `channels.plugins[]` with package names `@mono-agent/whatsapp-adapter` and `@mono-agent/a2a-adapter`. Channels are independent: an unconfigured channel reports `waiting_for_config` and never blocks the others. For chat channels collect tokens and allowlists (chat IDs, channel IDs, JIDs). For HTTP channels collect host/port/path and whether non-loopback binding is allowed (default: loopback only); for webhook, offer an optional bearer key on loopback and require it whenever non-loopback is selected, storing it in `MONO_AGENT_WEBHOOK_API_KEY`. For cron, collect the expression, timezone, prompt, and notification destination; ask separately whether the operator may run or runtime-disable jobs from the web console, keeping `cron.operatorActions.enabled` false unless explicitly requested and requiring `tui.apiKey` when enabled. For paid or otherwise non-repeatable A2A dispatches, also collect a reviewed stable `provider.idempotency.namespace` (the authenticated-principal boundary), retention horizon, and lifetime unique-key capacity; callers must supply an existing stable logical key rather than a fresh key per attempt.

## 3. Identity And Existing Knowledge

Question:

```text
What exact text belongs in IDENTITY.md → ## Role, and does this folder already contain knowledge it must respect?
```

Fills: the `## Role` body in the one canonical identity file, `context.identityPath` (default `./IDENTITY.md`), optional `context.soulPath`, and `runtime.workspace`. `mono-agent init` detects `AGENTS.md`, `CLAUDE.md`, `README.md`, and `SOUL.md` and references them from a generated identity — keep those references rather than copying content. If `IDENTITY.md` already exists, preserve it unchanged, say the newly entered Role was not written, and tell the user to add or edit its `## Role` heading manually. Do not assume the heading already exists or store the unused answer elsewhere.

## 4. Skills

Question:

```text
Should this agent load selected skills?

1. Yes, from a `skills/` directory in this folder
2. Yes, from an external skills directory
3. No selected skills for the first pass
```

Fills: `context.skillsRoot`, `context.selectedSkills`, optionally `context.skillMaxBytes` (per-skill byte cap, default 48000). Skill discovery loads immediate child directories only: `<skillsRoot>/<skill-name>/SKILL.md`. Skill files may carry YAML frontmatter (Claude Code style); the description is the first prose paragraph after it.

## 5. Tools And MCP Servers

Question:

```text
What tools does the agent need?

1. Allow all tools (recommended — the default: every built-in + enabled channels' send tools)
2. Allow all, but deny a few by name (tools.disallowedTools)
3. A specific allowlist of built-in / channel tools
4. Chat-only, no tools (explicit tools.allowedTools: [])

Plus, independently: MCP servers from an mcp.json config file?
```

Fills: `tools.allowedTools`, `tools.disallowedTools` (denylist wins, even under allow-all), `tools.mcpConfigPath`. The default is allow-all (`["*"]`) — write that unless the user asks to narrow. Under allow-all the adapter-derived send tools (`SlackSendMessage` / `TelegramSendMessage` / …) and `PublishReplyFile` are auto-available once their host requirements are met; only a **specific** allowlist needs their exact names added. Valid enabled Slack/Telegram adapter config and destination allowlists are required either way. If the user needs MCP Apps, select a Pi-native primary and only Pi-native fallbacks: the host suppresses App registration and advertising when any possible route cannot carry the bridge. On the pi-native runtime `disallowedTools` does not filter external MCP-server tools — to withhold one, don't declare its server.

For Pi process work, prefer the `Exec` built-in for one executable plus literal
argv and offer `Bash` only when shell syntax is required. Offer `NodeRepl` when
the user wants run-scoped JavaScript evaluation. All three execute with the same
sandbox authority.

If the agent needs public-web research, ask whether it should use automatic
local SearXNG → ChatGPT-subscription Codex → keyless fallback, explicit local or
hosted Ollama, strict Codex, strict keyless, or strict SearXNG-only discovery.
Fill `tools.web.search.backend`, optional `tools.web.search.searxng.endpoint`,
optional `tools.web.search.ollama.*`, and optional
`tools.web.search.codex.model` (default `gpt-5.6-luna`). Keep
`tools.web.fetch.render: "never"` unless the user explicitly needs
JavaScript-heavy pages and has `agent-browser` 0.33.1 or newer; then select
config-level `"auto"` plus the direct `browserCommand`. Explain that the agent
can request per-call `WebFetch` `render: "always"` when a known page must be
browser-first; `"always"` is not a config value. Explain that local
SearXNG/Ollama are infrastructure, not offline indexes, both search and fetch
still generate public network traffic, hosted Ollama credentials are accepted
only at the exact official origin, and rendering does not bypass access controls.

## 6. Memory Strategy

Question:

```text
Should the agent remember anything between conversations?

1. No durable memory yet (recommended for first integration)
2. Lite memory — FTS keyword recall + rapid-log capture; zero external deps
3. Journal memory — hybrid recall (BM25+vector) + static salience; requires embeddings
4. BuJo memory — full tier: journal + LLM capture/reconcile + entity graph + auto-scheduled
   consolidation; requires embeddings AND a chat model
```

All tiers share the same `@mono-agent/memory/bujo` substrate. Fills: `memory.mode`
(`lite`/`journal`/`bujo`), `memory.path`, `memory.writeMode`
(`disabled`/`append-host-summary`/`capture`), and tier-specific blocks below.

**Tier 2 — lite (no external deps):**

Write:

```jsonc
"memory": {
  "mode": "lite",
  "path": "./.mono-agent/memory",
  "writeMode": "append-host-summary"
}
```

No prerequisites. No Ollama. SQLite is bundled.

**Tier 3 — journal (embeddings required):**

- Guided init asks for Ollama or LM Studio, service root, exact model, actual dimension,
  and optional auth-env name. Treat this as separate from runtime chat-model discovery.
  - Ollama default root `http://localhost:11434`: enumerate `/api/tags`, retain only
    `/api/show` capabilities containing `embedding`, then prove `/api/embed`.
  - LM Studio default root `http://localhost:1234`: retain exact `type: "embedding"`
    entries from `/api/v1/models`, use their `key`, then prove `/v1/embeddings`.
  - Hand-authored OpenAI remains supported but is not a guided local-memory choice.
- If typed discovery is inconclusive, ask for exact model + positive dimension, while
  explaining that real readiness still must pass. Never substitute another provider.
- LM Studio is keyless when `apiKeyEnv` is omitted. If named, the variable must already
  contain the token in the owner-only agent environment; missing declared auth is `waiting`.

Write:

```jsonc
"memory": {
  "mode": "journal",
  "path": "./.mono-agent/memory",
  "writeMode": "append-host-summary",
  "embeddings": {
    "provider": "ollama",
    "model": "nomic-embed-text:v1.5",
    "endpoint": "http://localhost:11434",
    "dim": 768
  }
}
```

After writing, remind the user to run `mono-agent validate` (checks root writability,
managed provider/model/dimension identity, provider-native model typing, real finite-vector
response, and dimension). Changing any semantic identity field on an existing root requires
stopping the agent and running config-aware `mono-agent memory rebuild --json`.

**Tier 4 — bujo (embeddings + chat model + consolidation):**

Proactively explain what bujo does: capture → reconcile (ADD/UPDATE/SUPERSEDE/NOOP),
hybrid BM25+vector recall, entity graph, scheduled projection-only consolidation, living
`index.md`, and an empty retired `future-log.md` stub. Consolidation refreshes projections
and reports duplicate groups; it never decays salience or automatically supersedes or
rewrites canonical memory. It is **auto-scheduled in-app** — no external cron or launchd
setup needed.

- Ask: which embeddings provider/service-root/model/dimension/auth-env? Use the same
  exclusive choices and real-probe contract as journal.
- Ask: which chat LLM provider/model for LLM pipelines?
  - Ollama: local model string such as `qwen3.6:latest`; pull it first with
    `ollama pull qwen3.6:latest`.
  - agent-host: a canonical runtime model reference such as `openai-codex:gpt-5.6-terra`.
- Ask: should per-turn intelligent capture be enabled (`writeMode: "capture"`), or only
  deterministic rapid-log summaries (`append-host-summary`) plus scheduled consolidation?
- Ask: should we keep the default consolidation schedule (`0 */2 * * *`), customise the
  cron expression, or disable scheduled consolidation?

The embeddings service and capture LLM are independent. Choosing LM Studio embeddings does
not move capture there; guided config keeps an explicit `agent-host` LLM, while an authored
Ollama `memory.llm` remains valid. The in-app scheduler handles routine BuJo consolidation;
the standalone `memory-bujo` maintenance CLI was removed (run `mono-agent memory <subcommand>`
from the agent folder instead).

Write (embeddings + chat model):

```jsonc
"memory": {
  "mode": "bujo",
  "path": "./.mono-agent/memory",
  "writeMode": "capture",
  "embeddings": {
    "provider": "ollama",
    "model": "nomic-embed-text:v1.5",
    "dim": 768
  },
  "llm": {
    "provider": "ollama",
    "model": "qwen3.6:latest"
  }
}
```

For an agent-host memory LLM, write the `llm` block as:

```jsonc
"llm": {
  "provider": "agent-host",
  "model": "openai-codex:gpt-5.6-terra"
}
```

If the user customises the consolidation schedule, add the `consolidation` block:

```jsonc
"consolidation": { "enabled": true, "cron": "0 */4 * * *" }
```

After writing, append a prerequisite note:

```
Before running mono-agent validate, pull the required models:
  ollama pull nomic-embed-text:v1.5
  ollama pull qwen3.6:latest          # only if using llm.provider: "ollama"
```

Then run `mono-agent validate` — the Memory section confirms the root is writable,
provider-specific liveness, and the consolidation cadence.
See `docs/memory/index.md` for the full tier table and config shapes. Memory maintenance
runs via `mono-agent memory <subcommand>` from the agent folder; the standalone `memory-bujo`
CLI was removed.

## 7. Sandbox

Question:

```text
Should Pi-owned runtime commands run inside the native mono-agent sandbox? Every route is Pi-native, so one answer covers the primary, every fallback, and every per-trigger override.

1. No sandbox for the first pass
2. Native sandbox, no network (fail closed)
3. Native sandbox with localhost or an explicit network allowlist
4. Native sandbox with open network (`all`: filesystem containment only — for agents whose tools need broad egress)
5. Native sandbox with custom filesystem scopes (extra readable/writable roots)
```

Fills: the `sandbox` section — `mode`, `network.mode` (`none`/`localhost`/`allowlist`/`all`), `network.allowlist`, `readableRoots`/`writableRoots` (relative entries resolve against the workspace; default: workspace only), `denyWrite` glob patterns (defaults already deny `.env*`, `.git/config`, `.git/hooks/**`), `fallback` (`fail-closed` recommended; `unsafe-host-process` only with explicit consent plus `unsafeAllowHostProcess: true`).

## 8. Observability

Question:

```text
Do you need a browsable trace viewer or just local artifacts?

1. JSONL artifacts plus Phoenix as the trace viewer (recommended; add an `observability.exporters` Phoenix entry)
2. JSONL artifacts only (bounded terminal snapshots; no external viewer)
```

Fills: `artifacts.dir`, `traceability.registryDir` / `sourceId` / `sourceLabel`, and — when Phoenix is wanted — an `observability.exporters` (phoenix) OTLP entry. The local recorder starts with empty events plus a `running` summary, applies sensitive-key redaction, scans retained free text for high-confidence credential shapes, and caps event strings at 4,096 bytes by default. It buffers events in RAM and replaces the artifacts at finish/fail; a pre-terminal crash can lose buffered events. Phoenix adds a best-effort terminal batch, not a crash-safe stream. Artifacts record runtime/tool/message events and summaries, not private chain-of-thought. For a terminal operator console, mention `mono-agent tui` (run from anywhere once the agent is started; live chat with thinking/tool insight, run replay, config view). Config is JSON-first — edit `mono-agent.config.json` directly and run `mono-agent restart` to apply changes.

## 9. Acceptance Smoke Test

Question:

```text
What proves this agent works?

1. A curl POST to the webhook invoke URL
2. A curl to /v1/models and /v1/chat/completions
3. A Telegram/Slack/WhatsApp message from an allowed sender
4. An A2A message to the Agent Card URL
5. A cron tick
```

The answer decides which smoke from `references/validation.md` must pass before the work is done.
