# Configuration

SEED-agent is currently distributed and validated for Linux only. Project
configuration and examples assume a Linux runtime.

SEED-agent loads configuration from:

1. nearest project `.opencode/seed-agent.jsonc` or `.json`
2. `~/.config/opencode/seed-agent.jsonc` or `.json`, only when no project config exists or project isolation opts out
3. plugin options from OpenCode config

Project installs default to `isolation.ignore_user_config: true`, so the target
project is not affected by personal SEED user config. Security-sensitive
environment expansion is not implemented in this version, so project config
cannot broaden secret allowlists.

## OpenCode Provider Credentials

SEED-agent does not define its own model provider and does not ask for API keys.
Generated project config is model-neutral by default: Lab-Representative uses
the model selected in OpenCode, and internal SEED delegation/dynamic
agent-threads inherit that selected model unless project config explicitly pins
`model_profiles` or agent-level `model` values.

For each user machine:

```bash
opencode providers login -p <provider>
```

Alternatively, export provider environment variables before starting OpenCode:

```bash
export OPENAI_API_KEY=...
export ANTHROPIC_API_KEY=...
```

Do not commit real API keys. The repository `.opencode/opencode.jsonc` only
loads the plugin; model routing is recorded in SEED config while API key
material stays in each OpenCode installation.

Example smoke targets can use any OpenCode `provider/model`:

```bash
opencode run --command seed --model anthropic/claude-sonnet-4-5 --variant high "Create a short SEED trace smoke test and stop after reporting the run directory."
opencode run --command seed --model openai/gpt-5.4 --variant medium "Create a short SEED trace smoke test and stop after reporting the run directory."
```

Common fields:

`default_run_agent` uses `lab-representative`, the single SEED OpenCode agent
id for Lab-Representative.

`agent_order` and `agents` are intentionally minimal in current installs.
New generated config should contain only `lab-representative`. The actual team
for a run is the accepted inline spec written under
`.seed-agent/runs/<run_id>/team/specs/`; `team_mode.allowed_capability_profiles`
defines the abstract capabilities Lab-Representative may request in that spec.

For isolated project installs, SEED writes OpenCode-level disable stubs for
native `build`, `plan`, `general`, `explore`, and `scout`, then hides native
Build/Plan from the SEED primary TUI face so the TUI opens on
Lab-Representative instead of a host/native agent face.

When `seed-agent install --project` finds an existing project SEED config, it
normalizes it to the current single Lab-Representative project shape and writes
a `.bak-*` backup beside the previous config.

```jsonc
{
  "$schema": "../schemas/seed-agent.schema.json",
  "default_run_agent": "lab-representative",
  "disabled_tools": ["skill"],
  "disabled_mcps": [],
  "isolation": {
    "ignore_user_config": true,
    "allow_host_agents": false,
    "allow_host_commands": false,
    "allow_host_mcp": false,
    "allow_host_tool_config": false
  },
  "permissions": {
    "execution_mode": "autonomous"
  },
  "agents": {
    "lab-representative": {
      "model_profile": "orchestrator",
      "temperature": 0.2,
      "prompt_append": ""
    }
  },
  "model_profiles": {
    "orchestrator": {},
    "reasoning": {},
    "research": {},
    "coding": {},
    "execution": {},
    "review": {},
    "reporting": {}
  },
  "skills": {
    "enabled": true,
    "allow_project_skills": true,
    "allow_user_skills": false
  },
  "trace": {
    "enabled": true,
    "artifact_root": ".seed-agent/runs",
    "sanitize_outputs": true
  },
  "activity_journal": {
    "enabled": true,
    "interval_minutes": 10,
    "max_inline_chars": 1000,
    "include_prompt_summaries": true,
    "include_tool_args": true
  },
  "team_mode": {
    "enabled": true,
    "max_parallel_members": 4,
    "max_members": 8,
    "max_member_prompt_chars": 12000,
    "allowed_capability_profiles": [
      "orchestration",
      "planning",
      "document_extraction",
      "research",
      "research_analysis",
      "critical_review",
      "coding",
      "execution",
      "verification",
      "review",
      "reporting"
    ],
    "message_payload_max_bytes": 32768,
    "recipient_unread_max_messages": 100
  },
  "continuation": {
    "enabled": true,
    "inject_on_chat": true,
    "inject_on_compaction": true,
    "context_max_chars": 6000,
    "recent_event_limit": 12
  },
  "context_ledger": {
    "enabled": true,
    "max_bundle_body_bytes": 262144,
    "max_inline_chars": 4000,
    "max_digest_chars": 800,
    "metrics_enabled": true
  },
  "context_policy": {
    "stable_contract_inline_on_launch": true,
    "stable_contract_digest_after_launch": true,
    "warm_context_default": "ref",
    "hot_context_max_chars": 2000,
    "max_context_attachments_per_message": 12,
    "duplicate_bundle_warning_threshold": 3
  },
  "run": {
    "max_initial_clarifying_questions": 3,
    "auto_start_when_actionable": true,
    "review_before_final": true,
    "scribe_updates": true
  },
  "reporting": {
    "default_language": "ko"
  },
  "safety": {
    "redact_secrets": true,
    "require_professor_handoff_for_destructive_actions": true
  }
}
```

`reporting.default_language` is the default professor-facing runtime language.
It is injected into Lab-Representative, `/seed` command handling, continuation
context, dynamic team-member launch prompts, Lab Meeting notes, `progress.md`,
and `final_report.md`. Use `ko` for Korean-facing lab work and `en` for
English-facing lab work. SEED leaves code, commands, file paths, package names,
API identifiers, and quoted source text in their original form.

`context_ledger` and `context_policy` control cache-aware context handling.
SEED stores stable member contracts, warm run/team summaries, hot mailbox or
meeting deltas, heavy artifact pointers, and memory checkpoints under each run's
`context/` directory. Later turns receive refs or digests instead of the full
body whenever possible. This does not guarantee provider-side prompt-cache hits,
but it keeps agent-thread prefixes more stable and makes context fanout visible
through `/seed-status` and `seed_context_metrics`.

MCP credentials are separate from model provider credentials. They are read from
environment variables such as `CONTEXT7_API_KEY`, `EXA_API_KEY`, and
`TAVILY_API_KEY`.

`isolation` controls how much host OpenCode configuration is allowed to shape a
SEED run. The default project install keeps Lab-Representative, `/seed`, and
SEED tools authoritative, disables native
OpenCode primary/subagent faces that would otherwise appear in the selector,
ignores personal SEED user config, ignores pre-existing host tool config, and
does not merge host/user MCP servers. A plugin cannot stop another
already-loaded OpenCode plugin hook from running, but normal SEED installs do
not ask users to create a separate OpenCode profile.
Because OpenCode merges parent project configs, a parent `.opencode/opencode.jsonc`
can still affect the current project. If native faces reappear, check parent
directories and remove or update the parent OpenCode config.

`permissions.execution_mode` controls the Lab-Representative's host OpenCode
permission posture. `autonomous` is the default: routine edit/write/bash calls
are allowed, while risky bash patterns are configured as `ask` so OpenCode
prompts the professor before execution. SEED also records a
`professor_handoff_required` trace event for those risky shell attempts. Use
`interactive` to make OpenCode ask for every edit/write/bash call.

Skills may declare MCP requirements in `SKILL.md` frontmatter so SEED can trace
what context was injected and diagnose unavailable tools before a run relies on
them. Use `seed_skill_validate` before relying on project skills in a run; it
checks metadata, duplicate names, empty bodies, and required MCP availability,
and writes an artifact report.

Project installs copy a bundled `.seed-agent/skills/using-superpowers` skill so
Lab-Representative can load general planning, delegation, and verification
discipline through SEED skill tools. This is separate from OpenCode's native
global Skill tool, which SEED disables by default through `disabled_tools` and
static project `tools.skill = false` to avoid unreproducible personal skill
leakage.

Internet lookup can use OpenCode native `websearch`/`webfetch` or SEED's
optional `websearch` MCP. Lab-Representative gets the native search/fetch
permissions by default. The SEED MCP entry is `auto`: it is enabled when
`EXA_API_KEY` or `TAVILY_API_KEY` is present before OpenCode starts. Dynamic team
members only receive internet lookup when their accepted role contract includes
the relevant tools in `tool_policy.allowed_tools`.

```markdown
---
name: browser-review
version: 0.1.0
mcp:
  required: [context7]
  optional:
    - websearch
---
```

Agent-level `model` overrides take priority over `model_profiles`. If an agent
does not set `model`, SEED resolves its `model_profile`. When the resolved
profile is empty, SEED uses the root run's captured OpenCode selected model
when available; otherwise it does not pass an explicit model and lets OpenCode
apply its normal selected/default model. `seed-agent install --model
provider/model --variant <name>` pins the same model across all generated SEED
profiles for projects that want a fixed model instead of OpenCode selection.

`model_profiles.*.fallbacks` and `agents.*.fallbacks` define ordered fallback
chains for delegation. SEED passes explicit `provider/model` values to OpenCode,
records every model attempt in `agent_calls.jsonl`, retries the same model once
for transient transport failures such as timeout, rate limit, overload, or 503,
and then tries the next fallback for retryable model/provider failures. SEED
does not retry permission, policy, auth, or agent-resolution failures.

`activity_journal` controls the human-readable Markdown activity windows under
`.seed-agent/runs/<run_id>/activity/`. The journal is event-driven: SEED appends
raw sanitized entries under `activity/raw/` when command hooks, message hooks,
tool hooks, delegation, evidence, team, background, report, or continuation
activity is recorded, then regenerates `activity/latest.md` and the current
window Markdown/JSON as a Lab-Representative briefing. The default bucket is 10
minutes. Prompt and tool details are sanitized summaries, redaction counts are
visible, and hidden model reasoning is not recorded.

`lab_meeting` stores the manual long-running feedback gate state. Automatic
deadline-triggered meetings are disabled in the professor UX: a Lab Meeting
opens only when the professor runs `/seed-lab-meeting`. SEED stores meeting
state under `.seed-agent/runs/<run_id>/meetings/state.json`, writes
`meetings/<meeting_id>.json` and `.md` summaries, waits for already-running
background sessions to finish, and blocks new internal
delegation/team/write-lease work while the run is wrapping up or awaiting
feedback. `grace_minutes` is retained only as a deprecated compatibility field;
it no longer forces meeting finalization. `require_feedback_before_resume`
means the professor resumes by sending a normal chat message to
Lab-Representative; that message is recorded as Lab Meeting feedback and saved
as professor memory.

`budget` controls long-running safety limits. SEED writes each run's budget
state to `.seed-agent/runs/<run_id>/budget.json`. `max_runtime_hours`,
`max_child_sessions`, and `max_model_calls` block new delegation when exhausted;
`warn_ratio` surfaces an early warning in `/seed-status`; and
`stale_worker_minutes` marks running background workers stale when no heartbeat
or update has been observed for that duration. Token totals are recorded when
OpenCode returns token usage, but provider cost limits are intentionally not
enabled by default because pricing may be unavailable.

`team_mode` controls dynamic team contracts before launch. `max_members` bounds
the generated team size, `max_member_prompt_chars` bounds each mission prompt,
and `allowed_capability_profiles` defines which abstract capabilities the
Lab-Representative may request before SEED resolves them to internal execution
profiles and model settings. Accepted specs are written under
`.seed-agent/runs/<run_id>/team/specs/`; isolated defaults reject host MCP
leakage and personal user skill roots unless the project config explicitly
allows them. Runtime debugging artifacts for these dynamic members are always
under the run directory: `team/runtime.json` for the active roster,
`team/launch-ledger.jsonl` for proposed prompts/context/tool policy, and
`team/conversation.jsonl` for mailbox messages and acknowledgements.

`continuation` controls the compact run context SEED writes to
`.seed-agent/runs/<run_id>/continuation/`. When enabled, SEED can inject pending
tasks, blockers, evidence refs, team state, and background status into future
turns and OpenCode compaction prompts.

`run.review_before_final` controls the final-report evidence gate. When it is
enabled, `seed_report_write` cannot mark a run `completed` unless the report
cites valid `evidence.md#...` anchors for the task evidence refs. Use
`seed_report_check` to inspect the same gate without closing the run.

`safety.redact_secrets` also enables the final-report policy audit on completed
runs. The audit blocks secret-looking values and machine-specific local paths,
and records prompt-injection-like text as a warning so external content remains
evidence rather than operator policy.

`safety.require_professor_handoff_for_destructive_actions` controls command
policy for risky process-spawning tools. When enabled, destructive command
patterns return an `ask` decision and route through professor handoff unless the
tool call explicitly sets `allow_unsafe: true`. Use `seed_tool_policy_check` to
inspect the same decision without executing the command.

For maintainer push/release checks, `npm run audit:release` scans staged files
when files are staged, otherwise tracked product files, using the same policy
audit rules after a build.
