Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
c540421
wiki: log merges of #115 #127 #137 #139 #141 #142 #143
claude Oct 2, 2026
5a6efcd
wiki: decision models and Ollama model research (#148)
claude Oct 2, 2026
aaa033c
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 2, 2026
97992d7
wiki: Hermes model roles, memory embedders and Jev plugins (#148, #149)
claude Oct 2, 2026
f1a3427
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 2, 2026
af2d08f
docs: default local Ollama to qwen3:8b and document Ollama cloud (#148)
claude Oct 2, 2026
9c6f11b
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 2, 2026
45f9ef1
wiki: fix Hermes Jev plugin count and update providers after #152
claude Oct 2, 2026
84e91ab
feat(config): per-role provider chains via models.chat and models.com…
claude Oct 2, 2026
9fd71b7
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 2, 2026
c00a4c7
test, docs: cover models.compress through Agent; clarify omitted-role…
claude Oct 2, 2026
b5a20f1
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 3, 2026
b054cc7
feat(plugins): entry settings, host model access and before_llm_call …
claude Oct 3, 2026
d6b712a
fix(plugins): deep-copy hook messages, honor run abort in models.chat…
claude Oct 3, 2026
ab5df46
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 3, 2026
2b01b6d
wiki: ingest Ollama System One/Clef check; record model roles and plu…
claude Oct 3, 2026
e010ef8
wiki: index one-liners match model roles and plugin host features
claude Oct 3, 2026
4640db2
wiki: bump index updated date
claude Oct 3, 2026
98a2c2b
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 3, 2026
b8266bc
feat(examples): decision_lane plugin for game_bridge action selection
claude Oct 3, 2026
bab4850
fix(decision_lane): zero off-criteria answers, require numeric thresh…
claude Oct 3, 2026
e0237cc
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
c59f5d1
wiki: record the decision_lane prototype (#159)
claude Oct 4, 2026
ca1c05f
wiki: decision_lane egress mentions the Bearer key
claude Oct 4, 2026
dcbb9e6
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
2074964
fix(agent): tools_enabled filters plugin tools; guard hooks fail clos…
claude Oct 4, 2026
4f97ea2
fix(loop): emit tool_call_end for last-turn skipped calls so transcri…
claude Oct 4, 2026
1b2d4d9
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
4840336
wiki: record #161 (plugin-tool allowlist, fail-closed guard hooks, la…
claude Oct 4, 2026
0b3d485
wiki: move the #161 fixed note out of the open-holes list
claude Oct 4, 2026
d7e1e95
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
0930c7d
fix: http_request status, terminal_timeout_ms, .. path guard, OpenAI …
claude Oct 4, 2026
09fc444
fix(openai): treat a null tool-call id as missing; correct http_reque…
claude Oct 4, 2026
1294e6a
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
07d0d3b
docs: webhook binds loopback by default; drop stale version from over…
claude Oct 4, 2026
0608068
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
16c4bdb
refactor(providers): share HTTP/error helpers in providers/http.ts (#…
claude Oct 4, 2026
53962b9
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
fe394bd
fix: Ctrl+C/Esc cancel, atomic config update, test tmp cleanup (#133)
claude Oct 4, 2026
84f62a4
fix: on cancel, drop the unanswered user line and do not reprint the …
claude Oct 4, 2026
3cfddb1
fix: keep this turn's reply when a cancel lands during tools
claude Oct 4, 2026
8c5fe08
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
b941191
wiki: map #113 phase children and related issues
claude Oct 4, 2026
39aade9
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 4, 2026
4c8b180
feat(config): global ~/.lich/config.json merged under the project con…
claude Oct 4, 2026
dc815f3
fix(config): read the legacy user config only when ~/.lich/config.jso…
claude Oct 4, 2026
36f8f87
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 5, 2026
146619b
feat(config): lich init --global and a "save as global" wizard step (…
claude Oct 5, 2026
2faf90c
fix(wizard): write the config once, plugins included, when work_dir i…
claude Oct 5, 2026
eff0ea1
fix(wizard): store absolute plugin paths when writing ~/.lich/config.…
claude Oct 5, 2026
558e3d1
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 5, 2026
eaadb01
feat(config): named profiles in ~/.lich/profiles (#117)
claude Oct 5, 2026
ae7e9d8
fix(profiles): profile over the home config, stable errors, guard lis…
claude Oct 5, 2026
2d64bbf
fix(profiles): keep the legacy base at home; disk_usage skips denied …
claude Oct 5, 2026
e63bd5a
Merge remote-tracking branch 'origin/main' into claude/open-issues-pr…
claude Oct 5, 2026
4957452
wiki: config layers page after #170-#172
claude Oct 5, 2026
0d9590e
wiki: scope config writer and error-path claims on lich-config
claude Oct 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion wiki/SCHEMA.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Raw files carry `source_url`, `ingested` and `sha256`. The hash covers the body
Add a tag here before you use it.

- **Layers:** core, runtime, surface, gateway, serve, ossuary, cli, tui
- **Subsystems:** providers, tools, plugins, mcp, sessions, events, context, memory, skills, security
- **Subsystems:** providers, tools, plugins, mcp, sessions, events, context, memory, skills, security, config
- **Games:** games, npc, play, editor, engines, content
- **Comparisons:** hermes, ecosystem
- **Meta:** decision, roadmap, process, docs, performance, research
Expand Down
4 changes: 3 additions & 1 deletion wiki/concepts/runtime-profile-session.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Runtime / Profile / Session split
created: 2026-09-23
updated: 2026-09-23
updated: 2026-10-05
type: concept
tags: [core, runtime, npc, gateway]
sources: [raw/audits/2026-09-23-core-engine-audit.md, raw/audits/2026-09-23-game-surface-audit.md, "#113"]
Expand Down Expand Up @@ -30,4 +30,6 @@ confidence: medium

**Prerequisites:** remove process-global state (docs root, log level, Ollama id counter), and add the [[event-envelope]].

**Not the same as config profiles:** #117 shipped *config* profiles, named file layers under `~/.lich/profiles` chosen per CLI run ([[lich-config]]). The runtime Profile here is a per-session object inside one process and is not built yet.

Related: [[npc-memory-namespaces]], [[embedded-safety-profile]].
55 changes: 55 additions & 0 deletions wiki/entities/lich-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: Lich config layers (global, profile, project)
created: 2026-10-05
updated: 2026-10-05
type: entity
tags: [config, cli, security]
sources: ["#117", "#170", "#171", "#172"]
confidence: high
---

# Lich config layers

How the CLI turns files into one config before `parse_agent_config`. The user docs are `docs/user-guide/cli.md` (Global config) and `docs/user-guide/profiles.md`. This page records the design and the reasons for it.

## Layers

Without `--config`, `load_layered_config` (`src/cli_config.ts:127@ab0f508`) merges, base first:

1. **Global:** `~/.lich/config.json` (`src/cli_config.ts:44@ab0f508`). The legacy `~/.config/lich/config.json` is read only when the global file is absent, with a one-line note; nothing writes it.
2. **Profile:** `~/.lich/profiles/<name>.json` (`src/cli_config.ts:89@ab0f508`), plus `<name>.md` as `system_prompt` when it is not blank (`src/cli_config.ts:105@ab0f508`).
3. **Project:** `<work_dir>/.lich/config.json`.

`--config <path>` replaces every layer, and combining it with `--profile` is an error.

**Merge** (`merge_config_layers`, `src/cli_config.ts:175@ab0f508`): shallow, later layer wins per key. A later `providers` array replaces the earlier one and drops the earlier `models` unless the later layer sets its own, because role chains name providers.

**Global and profile layers** (`global_layer`, `src/cli_config.ts:190@ab0f508`): `work_dir` and `session_dir` are ignored. Relative `plugins` paths resolve against the file's own directory (`~/.lich` or `~/.lich/profiles`), not the project.

**Profile selection:** `--profile`, then `LICH_PROFILE`, then a `profile` key in the project file, then one in the global file (set by `lich profile use`, `src/cli_profile.ts:107@ab0f508`). The `profile` key is removed from the merged config. `LICH_PROFILE` is ignored when `--config` is given.

**Work_dir = home:** the project file *is* `~/.lich/config.json`. It is not merged over itself, and a selected profile goes over it rather than under it.

## Writers

- `write_lich_config` (`src/cli_config.ts:277@ab0f508`) is the only writer of `.lich/config.json` files (project and global); profile JSON is written by `lich profile create` (`src/cli_profile.ts:101@ab0f508`). Create mode uses an exclusive open; update mode writes a temp file and renames it into place, keeping the file mode (`src/cli_config.ts:307@ab0f508`, #166).
- `lich init` writes the project file; `lich init --global` writes the global one, without `work_dir`/`session_dir` (`src/cli.ts:694@ab0f508`).
- The setup wizard runs only when no file exists anywhere in the chain. Its last question can save the answers globally; discovered project plugins then stay in the project file, or are stored absolute when the project file is the global file (`src/cli.ts:615@ab0f508`).
- `lich profile create` writes a profile through the wizard and never overwrites. `lich mcp` edits only the project file.

## Guard

File tools refuse `.lich/config.json` and `.lich/profiles/` for reads and writes (`src/tools/guard.ts:83@ab0f508`). `list_dir` and `disk_usage` check their root and skip denied entries (`file_tool_denied`, `src/tools/guard.ts:100@ab0f508`). With `work_dir` = home these paths are the global identity files.

## Two kinds of "profile"

- **Config profile (#117, shipped):** a named file layer chosen per CLI run. It holds any config keys, including identity and model.
- **Runtime Profile (#113 §2b, not built):** cheap, data-only, chosen per session inside one Runtime ([[runtime-profile-session]]).

A config profile could later seed a runtime Profile, but today they are separate things. Name new code accordingly.

## Errors

`tui`, `chat`, `serve` and `gateway` give the "no model configured" hint only for that error. Others pass through as `lich <mode>: <message>` (`src/cli.ts:150@ab0f508`). The profile errors (`profile not found`, `profile <name> already exists`) carry no absolute paths (`.cursor/review-rules.md`). `config not found` and `invalid config json` still name the file.

Related: [[lich-tools-and-guardrails]], [[hermes-agent]] (its profiles are separate home directories; Lich layers files instead).
4 changes: 2 additions & 2 deletions wiki/entities/lich-tools-and-guardrails.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Lich tools, executor and guardrails
created: 2026-09-23
updated: 2026-10-04
updated: 2026-10-05
type: entity
tags: [tools, security, runtime]
sources: [raw/audits/2026-09-23-core-engine-audit.md, raw/audits/2026-09-23-game-surface-audit.md, "#161", "#163"]
Expand Down Expand Up @@ -32,7 +32,7 @@ It also:

## Guardrails (the "wards")

- **File tools:** realpath confinement to `work_dir`, and writes to `.lich/config.json` are denied.
- **File tools:** realpath confinement to `work_dir`. `.lich/config.json` and `.lich/profiles/` are denied for reads and writes, and `list_dir`/`disk_usage` skip them (`src/tools/guard.ts:83@ab0f508`, #172; see [[lich-config]]).
- **Network tools:** an SSRF guard blocks private and loopback URLs unless `LICH_ALLOW_PRIVATE_URLS=1`, and redirects are re-checked.
- **`terminal` is not sandboxed.** It runs `bash -lc` in `work_dir` with secret env vars scrubbed. The docs say this plainly.

Expand Down
5 changes: 3 additions & 2 deletions wiki/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Wiki index
type: index
updated: 2026-10-04
updated: 2026-10-05
---

# Lich Wiki: Index
Expand All @@ -15,9 +15,10 @@ Start here. Read [SCHEMA.md](SCHEMA.md) for the conventions and [log.md](log.md)
## Entities: Lich subsystems

- [[lich-agent-loop]]: `run_conversation` + `Agent`. A dependency-injected TAO loop. Its P0 gaps are that events aren't scoped to a run, there is no streaming, it has global state, and each agent is heavyweight.
- [[lich-providers]]: openai_compat, anthropic and ollama clients without SDKs, plus failover and per-role chains (`models.chat` / `models.compress`, #154). They have no streaming, `tool_choice` or cache_control, and ~150 lines of their helpers are duplicated.
- [[lich-providers]]: openai_compat, anthropic and ollama clients without SDKs, plus failover and per-role chains (`models.chat` / `models.compress`, #154). They have no streaming, `tool_choice` or cache_control; their shared HTTP/error helpers live in `providers/http.ts` (#165).
- [[lich-tools-and-guardrails]]: builtins, an executor that never throws, and the wards. Known holes: `terminal` isn't sandboxed and hooks have no timeout; `tools_enabled` covers plugin tools since #161.
- [[lich-plugins-and-hooks]]: tool-call hooks with veto, the gatekeeper's single gated `git_commit`, and (#157) per-plugin settings, granted model roles and a `before_llm_call` note hook. There is no `build_system_prompt` hook yet; a throwing `before_tool_call` blocks the call (#161), other hooks fail open.
- [[lich-config]]: global `~/.lich/config.json` < named profile < project file, shallow merge; `lich init --global`, `lich profile`, and file tools barred from `.lich/profiles` (#170–#172).
- [[lich-sessions]]: JSONL phylacteries used as combat logs. There is no search, and gateway files are supersets of each other.
- [[lich-mcp]]: an MCP client and catalog. Redot is a real entry and Godot has none. The code is spread over 21 micro-files.
- [[lich-gateway]]: familiars routed into one shared Agent. The per-chat bus and read-only defaults make it a good hub.
Expand Down
2 changes: 2 additions & 0 deletions wiki/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ Append-only. One line per action: `- YYYY-MM-DD <op> | <summary> | <pages>`. Ops
- 2026-10-04 update | #161 merged: tools_enabled filters plugin tools and git_commit, throwing before_tool_call blocks, last-turn tool calls not run; holes lists and index updated, code pinned at 029b7e8 | entities/lich-plugins-and-hooks.md, entities/lich-tools-and-guardrails.md, entities/lich-agent-loop.md, index.md
- 2026-10-04 update | #163 merged: S-11 items (http_request status, .. guard, terminal_timeout_ms) moved out of open holes, pinned at 7001e31 | entities/lich-tools-and-guardrails.md
- 2026-10-04 update | Roadmap map lists #113 children and related issues (#133 P0, #134 P1, #117 P2, #144, #148, #149); supersedes stale PR #135 | entities/roadmap-issues.md
- 2026-10-05 create | Config layers page after #170–#172: global < profile < project merge, writers, guard, and config profile vs runtime Profile; pinned at ab0f508 | entities/lich-config.md, index.md, SCHEMA.md (tag: config)
- 2026-10-05 update | Guardrails: file tools deny .lich/profiles (reads too) and list_dir/disk_usage skip it; runtime-profile-session notes the config-profile name clash; index providers line no longer claims duplicated helpers (#165) | entities/lich-tools-and-guardrails.md, concepts/runtime-profile-session.md, index.md
Loading