Make custom system prompts omit built-in docs
- commit
- 7859d9c2e63b2f4ac1d26d3da32adb1412d310cb
- author
- patriceckhart · · 2026-08-06 14:49 UTC
- parent
- a159f47
- signature
- unsigned
3 files · +52 -10
M README.md +3 -3
| @@ -148,7 +148,7 @@ $ZOT_HOME/ | |||
| 148 | 148 | └── logs/ # app log files | |
| 149 | 149 | ``` | |
| 150 | 150 | ||
| 151 | - | Drop a `SYSTEM.md` in `$ZOT_HOME` to replace the built-in identity and guidelines for every run. `--system-prompt` still wins per-invocation. Delete the file to revert to the default. | |
| 151 | + | Drop a `SYSTEM.md` in `$ZOT_HOME` to replace the built-in identity and zot-docs guidance for every run. `--system-prompt` still wins per-invocation. Custom prompts still receive appended instructions and generated context, including `AGENTS.md`, skills, auto-swarm guidance when enabled, and the date/cwd footer. Delete the file to revert to the default. | |
| 152 | 152 | ||
| 153 | 153 | ### HTTP proxy | |
| 154 | 154 | ||
| @@ -185,9 +185,9 @@ Treat questions and discussions as requests for explanation. Do not edit files o | |||
| 185 | 185 | |---|---|---| | |
| 186 | 186 | | `$ZOT_HOME/AGENTS.md` | global, every run | appended to the default prompt | | |
| 187 | 187 | | `./AGENTS.md` (and parent dirs) | project | appended to the default prompt | | |
| 188 | - | | `$ZOT_HOME/SYSTEM.md` | global, every run | replaces the default prompt entirely | | |
| 188 | + | | `$ZOT_HOME/SYSTEM.md` | global, every run | replaces the built-in identity and zot-docs guidance | | |
| 189 | 189 | | `--append-system-prompt <text>` | single run | appends for one invocation (repeatable) | | |
| 190 | - | | `--system-prompt <text>` | single run | replaces the prompt for one invocation | | |
| 190 | + | | `--system-prompt <text>` | single run | replaces the built-in identity and zot-docs guidance | | |
| 191 | 191 | ||
| 192 | 192 | > **Note:** zot does not read a `CLAUDE.md` instruction file. The only Claude-compatible thing it picks up is skills under `.claude/skills/`. If you are migrating from Claude Code, move that content into `AGENTS.md` (global or per-project) and zot will use it. | |
| 193 | 193 | ||
| @@ -148,7 +148,7 @@ $ZOT_HOME/ | |||||
| 148 | └── logs/ # app log files | 148 | └── logs/ # app log files | ||
| 149 | ``` | 149 | ``` | ||
| 150 | 150 | ||||
| 151 | - | Drop a `SYSTEM.md` in `$ZOT_HOME` to replace the built-in identity and guidelines for every run. `--system-prompt` still wins per-invocation. Delete the file to revert to the default. | 151 | + | Drop a `SYSTEM.md` in `$ZOT_HOME` to replace the built-in identity and zot-docs guidance for every run. `--system-prompt` still wins per-invocation. Custom prompts still receive appended instructions and generated context, including `AGENTS.md`, skills, auto-swarm guidance when enabled, and the date/cwd footer. Delete the file to revert to the default. |
| 152 | 152 | ||||
| 153 | ### HTTP proxy | 153 | ### HTTP proxy | ||
| 154 | 154 | ||||
| @@ -185,9 +185,9 @@ Treat questions and discussions as requests for explanation. Do not edit files o | |||||
| 185 | |---|---|---| | 185 | |---|---|---| | ||
| 186 | | `$ZOT_HOME/AGENTS.md` | global, every run | appended to the default prompt | | 186 | | `$ZOT_HOME/AGENTS.md` | global, every run | appended to the default prompt | | ||
| 187 | | `./AGENTS.md` (and parent dirs) | project | appended to the default prompt | | 187 | | `./AGENTS.md` (and parent dirs) | project | appended to the default prompt | | ||
| 188 | - | | `$ZOT_HOME/SYSTEM.md` | global, every run | replaces the default prompt entirely | | 188 | + | | `$ZOT_HOME/SYSTEM.md` | global, every run | replaces the built-in identity and zot-docs guidance | |
| 189 | | `--append-system-prompt <text>` | single run | appends for one invocation (repeatable) | | 189 | | `--append-system-prompt <text>` | single run | appends for one invocation (repeatable) | | ||
| 190 | - | | `--system-prompt <text>` | single run | replaces the prompt for one invocation | | 190 | + | | `--system-prompt <text>` | single run | replaces the built-in identity and zot-docs guidance | |
| 191 | 191 | ||||
| 192 | > **Note:** zot does not read a `CLAUDE.md` instruction file. The only Claude-compatible thing it picks up is skills under `.claude/skills/`. If you are migrating from Claude Code, move that content into `AGENTS.md` (global or per-project) and zot will use it. | 192 | > **Note:** zot does not read a `CLAUDE.md` instruction file. The only Claude-compatible thing it picks up is skills under `.claude/skills/`. If you are migrating from Claude Code, move that content into `AGENTS.md` (global or per-project) and zot will use it. | ||
| 193 | 193 | ||||
M packages/agent/systemprompt.go +6 -7
| @@ -21,7 +21,7 @@ type ToolSummary struct { | |||
| 21 | 21 | type SystemPromptOpts struct { | |
| 22 | 22 | CWD string | |
| 23 | 23 | Tools []ToolSummary | |
| 24 | - | Custom string // if set, replaces the default identity entirely | |
| 24 | + | Custom string // if set, replaces the built-in identity and docs guidance | |
| 25 | 25 | Append []string // extra text appended at the end | |
| 26 | 26 | Now time.Time | |
| 27 | 27 | ZotDocsDir string | |
| @@ -62,12 +62,11 @@ func BuildSystemPrompt(o SystemPromptOpts) string { | |||
| 62 | 62 | sb.WriteString(o.Custom) | |
| 63 | 63 | } else { | |
| 64 | 64 | sb.WriteString(defaultIdentity) | |
| 65 | - | } | |
| 66 | - | ||
| 67 | - | if strings.TrimSpace(o.ZotDocsDir) != "" { | |
| 68 | - | sb.WriteString("\n\nZot's own docs are installed under ") | |
| 69 | - | sb.WriteString(o.ZotDocsDir) | |
| 70 | - | sb.WriteString("; use the read tool there when you need details about zot RPC, extensions, skills, or built-in behaviour.") | |
| 65 | + | if strings.TrimSpace(o.ZotDocsDir) != "" { | |
| 66 | + | sb.WriteString("\n\nZot's own docs are installed under ") | |
| 67 | + | sb.WriteString(o.ZotDocsDir) | |
| 68 | + | sb.WriteString("; use the read tool there when you need details about zot RPC, extensions, skills, or built-in behaviour.") | |
| 69 | + | } | |
| 71 | 70 | } | |
| 72 | 71 | ||
| 73 | 72 | for _, a := range o.Append { | |
| @@ -21,7 +21,7 @@ type ToolSummary struct { | |||||
| 21 | type SystemPromptOpts struct { | 21 | type SystemPromptOpts struct { | ||
| 22 | CWD string | 22 | CWD string | ||
| 23 | Tools []ToolSummary | 23 | Tools []ToolSummary | ||
| 24 | - | Custom string // if set, replaces the default identity entirely | 24 | + | Custom string // if set, replaces the built-in identity and docs guidance |
| 25 | Append []string // extra text appended at the end | 25 | Append []string // extra text appended at the end | ||
| 26 | Now time.Time | 26 | Now time.Time | ||
| 27 | ZotDocsDir string | 27 | ZotDocsDir string | ||
| @@ -62,12 +62,11 @@ func BuildSystemPrompt(o SystemPromptOpts) string { | |||||
| 62 | sb.WriteString(o.Custom) | 62 | sb.WriteString(o.Custom) | ||
| 63 | } else { | 63 | } else { | ||
| 64 | sb.WriteString(defaultIdentity) | 64 | sb.WriteString(defaultIdentity) | ||
| 65 | - | } | 65 | + | if strings.TrimSpace(o.ZotDocsDir) != "" { |
| 66 | - | 66 | + | sb.WriteString("\n\nZot's own docs are installed under ") | |
| 67 | - | if strings.TrimSpace(o.ZotDocsDir) != "" { | 67 | + | sb.WriteString(o.ZotDocsDir) |
| 68 | - | sb.WriteString("\n\nZot's own docs are installed under ") | 68 | + | sb.WriteString("; use the read tool there when you need details about zot RPC, extensions, skills, or built-in behaviour.") |
| 69 | - | sb.WriteString(o.ZotDocsDir) | 69 | + | } |
| 70 | - | sb.WriteString("; use the read tool there when you need details about zot RPC, extensions, skills, or built-in behaviour.") | |||
| 71 | } | 70 | } | ||
| 72 | 71 | ||||
| 73 | for _, a := range o.Append { | 72 | for _, a := range o.Append { | ||
A packages/agent/systemprompt_test.go +43 -0
| @@ -0,0 +1,43 @@ | |||
| 1 | + | package agent | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "strings" | |
| 5 | + | "testing" | |
| 6 | + | "time" | |
| 7 | + | ) | |
| 8 | + | ||
| 9 | + | func TestBuildSystemPromptCustomOmitsBuiltInDocs(t *testing.T) { | |
| 10 | + | got := BuildSystemPrompt(SystemPromptOpts{ | |
| 11 | + | CWD: "/workspace", | |
| 12 | + | Custom: "Custom instructions", | |
| 13 | + | Append: []string{"Additional context"}, | |
| 14 | + | Now: time.Date(2026, time.August, 6, 0, 0, 0, 0, time.UTC), | |
| 15 | + | ZotDocsDir: "/zot/docs", | |
| 16 | + | }) | |
| 17 | + | ||
| 18 | + | if strings.Contains(got, "Zot's own docs") || strings.Contains(got, "/zot/docs") { | |
| 19 | + | t.Fatalf("custom prompt includes built-in docs guidance:\n%s", got) | |
| 20 | + | } | |
| 21 | + | for _, want := range []string{ | |
| 22 | + | "Custom instructions", | |
| 23 | + | "Additional context", | |
| 24 | + | "Current date: 2026-08-06", | |
| 25 | + | "Current working directory: /workspace", | |
| 26 | + | } { | |
| 27 | + | if !strings.Contains(got, want) { | |
| 28 | + | t.Errorf("custom prompt missing %q:\n%s", want, got) | |
| 29 | + | } | |
| 30 | + | } | |
| 31 | + | } | |
| 32 | + | ||
| 33 | + | func TestBuildSystemPromptDefaultIncludesBuiltInDocs(t *testing.T) { | |
| 34 | + | got := BuildSystemPrompt(SystemPromptOpts{ | |
| 35 | + | CWD: "/workspace", | |
| 36 | + | Now: time.Date(2026, time.August, 6, 0, 0, 0, 0, time.UTC), | |
| 37 | + | ZotDocsDir: "/zot/docs", | |
| 38 | + | }) | |
| 39 | + | ||
| 40 | + | if !strings.Contains(got, "Zot's own docs are installed under /zot/docs") { | |
| 41 | + | t.Fatalf("default prompt missing built-in docs guidance:\n%s", got) | |
| 42 | + | } | |
| 43 | + | } | |
| @@ -0,0 +1,43 @@ | |||||
| 1 | + | package agent | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "strings" | |||
| 5 | + | "testing" | |||
| 6 | + | "time" | |||
| 7 | + | ) | |||
| 8 | + | ||||
| 9 | + | func TestBuildSystemPromptCustomOmitsBuiltInDocs(t *testing.T) { | |||
| 10 | + | got := BuildSystemPrompt(SystemPromptOpts{ | |||
| 11 | + | CWD: "/workspace", | |||
| 12 | + | Custom: "Custom instructions", | |||
| 13 | + | Append: []string{"Additional context"}, | |||
| 14 | + | Now: time.Date(2026, time.August, 6, 0, 0, 0, 0, time.UTC), | |||
| 15 | + | ZotDocsDir: "/zot/docs", | |||
| 16 | + | }) | |||
| 17 | + | ||||
| 18 | + | if strings.Contains(got, "Zot's own docs") || strings.Contains(got, "/zot/docs") { | |||
| 19 | + | t.Fatalf("custom prompt includes built-in docs guidance:\n%s", got) | |||
| 20 | + | } | |||
| 21 | + | for _, want := range []string{ | |||
| 22 | + | "Custom instructions", | |||
| 23 | + | "Additional context", | |||
| 24 | + | "Current date: 2026-08-06", | |||
| 25 | + | "Current working directory: /workspace", | |||
| 26 | + | } { | |||
| 27 | + | if !strings.Contains(got, want) { | |||
| 28 | + | t.Errorf("custom prompt missing %q:\n%s", want, got) | |||
| 29 | + | } | |||
| 30 | + | } | |||
| 31 | + | } | |||
| 32 | + | ||||
| 33 | + | func TestBuildSystemPromptDefaultIncludesBuiltInDocs(t *testing.T) { | |||
| 34 | + | got := BuildSystemPrompt(SystemPromptOpts{ | |||
| 35 | + | CWD: "/workspace", | |||
| 36 | + | Now: time.Date(2026, time.August, 6, 0, 0, 0, 0, time.UTC), | |||
| 37 | + | ZotDocsDir: "/zot/docs", | |||
| 38 | + | }) | |||
| 39 | + | ||||
| 40 | + | if !strings.Contains(got, "Zot's own docs are installed under /zot/docs") { | |||
| 41 | + | t.Fatalf("default prompt missing built-in docs guidance:\n%s", got) | |||
| 42 | + | } | |||
| 43 | + | } | |||