# Code architecture: path resolution (DSH-only)

This doc is for readers who want to understand how the plugin resolves the paths it reads and
writes, and for new contributors. Since v3.0.0 the plugin targets **DeepSeek Harness (DSH) only**;
the earlier multi-host abstraction (a `minimax-code` host selected by `HARNESS_EVOLUTION_HOST`)
was an over-declaration — DSH's own source has no such host concept — and has been removed.

## The one-line principle

User-scope paths resolve through a single helper. The data root (`$HARNESS_EVOLUTION_HOME`,
default `~/.harness-evolution/v2`) is per-deployment; the user-scope sub-agent directory is
`<DSH home>/skills/`, and the DSH home mirrors the host's `resolveDshHome` via `dsh_home()`.

## Host-agnostic core

Everything in `src/`:

- `src/mcp/` — JSON-RPC server, schema definitions, fourteen tool handlers, architecture guards.
- `src/scanner/` — plugin discovery, manifest parsing, metrics extraction; default scan roots live here.
- `src/monitor/` — performance event collection, signal detection, statistics, flush.
- `src/engine/` — proposal generation, risk analysis, planning, academic-writing evolution.
- `src/executor/` — DAG execution, sandbox validation, with state-machine guards.
- `src/factory/` — sub-agent definition factory and validation.
- `src/store/` — JSONL storage for proposals, metrics, signals, cache, execution log; path resolution lives in `paths.mbt`.
- `src/types/` — wire types, config types, agent scope, change types.
- `src/util/` — path utilities, time, wire encoding.

## How paths resolve

Two things the runtime reads from configuration:

1. **User-level sub-agent directory** (`src/store/paths.mbt::user_agents_dir`) — `HARNESS_EVOLUTION_USER_DIR` if set, otherwise `dsh_agents_dir()` = `<DSH home>/skills`. The DSH home (`dsh_home()`) mirrors the host's `resolveDshHome`: `explicit > $DSH_HOME > ~/.dsh`, treating a blank `$DSH_HOME` as unset and rejecting non-absolute values (see the function's doc for the two deliberate divergences).
2. **Default plugin scan roots** (`src/scanner/scanner.mbt::default_scan_roots`) — `~/.dsh/profiles/` plus a speculative `~/.agents/plugins`; overridable by `.dsh-plugin/plugin.json::scan_targets`.

The resolution priority for the user directory is `HARNESS_EVOLUTION_USER_DIR` > `dsh_agents_dir()`. The implementation is in `src/store/paths.mbt::user_agents_dir` and is unit-tested with a temporary-directory injection (the test never touches the real home).

## Where to look first when investigating path behavior

| Symptom | File |
|---|---|
| Sub-agent definition lands in the wrong directory | `src/store/paths.mbt::user_agents_dir` / `dsh_home` / `dsh_agents_dir` |
| Scan picks up the wrong set of plugins | `src/scanner/scanner.mbt::default_scan_roots` and the `scan_targets` block in `.dsh-plugin/plugin.json` |
| Plugin fails to load under DSH | `docs/deploy/deepseek-harness.md` — usually a launcher mechanism or a manifest dialect problem |

## Changing paths

To move where user-scope definitions land, edit `dsh_agents_dir()` (or set `HARNESS_EVOLUTION_USER_DIR`)
and update `default_scan_roots` / `scan_targets` together, plus the `.dsh-plugin/plugin.json` mirror. The
name/validation contract that keeps definitions discoverable by DSH is pinned in
`factory/factory_wbtest.mbt` (see "name validation enforces kebab-case").

## What "verified end-to-end" means

A host is verified when, on a fresh install, the following loop completes without intervention beyond the initial human approval:

1. `scan_plugins` returns at least one plugin in the result
2. `propose_evolution` produces a proposal with a non-empty change set
3. `approve_proposal` transitions the proposal to `approved`
4. `execute_evolution` runs the proposal to `completed`
5. `create_sub_agent(scope=user)` writes a file that the host actually loads in a subsequent session

DSH 0.1.6-alpha.1 has this. Nothing is shipped on code paths alone.

## Anti-patterns to avoid

These come from real mistakes in this repo's history. Don't repeat them:

- Hardcoding a host directory literal in more than one file. The DSH user-scope directory is `<DSH home>/skills/`, and its only two literals live side by side in `paths.mbt` (`~/.dsh` in `dsh_home`, `skills` in `dsh_agents_dir`). If you need to mention it elsewhere, reference the helper.
- Treating documentation as the source of truth for host paths. Documentation drifts. Source bundles don't.