-
Notifications
You must be signed in to change notification settings - Fork 0
reference configuration
Garnish storage layout, environment variables, and the generated config files. All state lives under a Garnish-owned storage root so the learner's real harness config is never touched.
The storage root defaults to ~/.garnish and is overridable via GARNISH_ROOT. runtimePaths in src/adapter/runtime.ts computes every path under it, and assertGarnishOwnedPaths verifies none escape the root.
<GARNISH_ROOT>/
runtime/pi/omp-16.2.13/bin/omp certified binary copy
agent/ PI_CODING_AGENT_DIR target
config.yml generated gate config (merged with providers)
mcp.json generated MCP gate config
APPEND_SYSTEM.md static tutor framing
extensions/garnish/index.js bundled extension (bun build --target node)
garnish/
events.jsonl append-only event log (source of truth)
state.json derived snapshot
graph.json progression graph
quests.json full quest definitions
packs/ copied quest packs (l0-tutorial-island, l1-first-quest, l2-lore)
home/ isolated HOME for launched sessions
auth/omp-auth-broker-snapshot.enc auth broker snapshot cache
bin/garnish CLI shim for in-session use
sandbox/ default sandbox dir (quests operate here)
garnish init creates this tree. The certified binary lives at runtime/pi/omp-16.2.13/bin/omp, versioned by the certified release. The agent dir is the PI_CODING_AGENT_DIR target. The garnish/ subdir holds the event log, the derived state, the pre-serialized graph and quests the extension reads synchronously at session start, and the copied packs. See architecture for the isolation model and data models for the file schemas.
| Variable | Set by | Purpose |
|---|---|---|
GARNISH_ROOT |
User | Points Garnish at a different storage root (default ~/.garnish). |
GARNISH_OMP_SOURCE |
User | Points ensureRuntime at a binary to copy into Garnish-owned storage when no certified binary is installed. |
GARNISH_BIN |
User | Override for the garnish shim location. |
PI_CODING_AGENT_DIR |
createLaunchSpec |
Points the certified binary at the Garnish-owned agent dir for isolated config, extensions, and auth. |
OMP_AUTH_BROKER_SNAPSHOT_CACHE |
createLaunchSpec |
Points the auth broker at the Garnish-owned snapshot path. |
HOME |
createLaunchSpec |
Overridden to the Garnish-owned home/ dir for launched sessions. |
The launch spec in src/adapter/runtime.ts sets PI_CODING_AGENT_DIR, OMP_AUTH_BROKER_SNAPSHOT_CACHE, and HOME on every launched session so the certified binary runs fully isolated. See Pi adapter and debugging.
renderGateConfig in src/adapter/gates.ts produces the config.yml that physically enables or disables Pi surfaces. The file starts with a generated header and a garnish marker:
# Generated by Garnish. Do not edit; Garnish owns these arrays and replaces them wholesale.
garnish:
owner: garnish
generated: true
arraysReplaceWholesale:
- disabledExtensions
- disabledProviders
- skills.includeSkills
- mcp.disabledServersThe body contains:
-
Tool toggles — per-tool
enabledflags (e.g.bash.enabled,edit.enabled,read.enabled) derived from thetool:bash,tool:file,tool:shellcatalog entries. -
Skills —
skills.enabledandskills.includeSkills(an allowlist of globs) derived from theskillscatalog entry. -
disabledProviders— the providers still locked (derived from thecontextcatalog entry). Unlocked providers are absent from this list. -
disabledExtensions— the extensions still locked (derived from theextensionscatalog entry). -
mcp.enableProjectConfig— whether project-level MCP config is enabled (derived from themcpcatalog entry). -
tools.approvalMode— the strongest unlocked approval mode (always-ask,write, oryolo). -
providers— preserved from the existing file through the read-merge-write path inwriteGateConfig. The learner'sapiKeyReflives here.
Garnish owns the arrays listed in arraysReplaceWholesale and replaces them wholesale on re-render. Non-owned keys (like providers) survive gate re-renders. Serialization is stable: keys are sorted alphabetically and the YAML is regenerated deterministically. See Pi adapter and capability gating.
renderGateConfig also produces the mcp.json:
{
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json",
"garnish": {
"owner": "garnish",
"generated": true,
"arraysReplaceWholesale": ["disabledExtensions", "disabledProviders", "skills.includeSkills", "mcp.disabledServers"]
},
"mcpServers": {},
"disabledServers": ["garnish-demo"]
}Garnish owns mcpServers (empty in v1) and disabledServers (the MCP servers still locked). mcp.enableProjectConfig in config.yml gates whether project-level .omp/mcp.json is read.
garnish init writes a garnish shim into the Garnish-owned bin/ dir. The shim lets the learner run garnish status, garnish quest, and the other CLI commands from within a launched session without needing the dev install on PATH. See CLI commands.
Because Pi config layers replace arrays wholesale, Garnish must own any array it manages. The garnish.generated.arraysReplaceWholesale marker in every generated file declares which arrays Garnish owns: disabledExtensions, disabledProviders, skills.includeSkills, and mcp.disabledServers. User hand-edits to these arrays get clobbered on regeneration; the generated header warns against manual edits. Non-owned keys are preserved. This is ADR-5. See design decisions and security.