rename: adopt yoi identity

This commit is contained in:
2026-06-01 18:49:23 +09:00
parent 6e133a7229
commit e6c458021c
115 changed files with 945 additions and 732 deletions
+8 -8
View File
@@ -1,4 +1,4 @@
# Insomnia アーキテクチャ
# Yoi アーキテクチャ
## プロジェクトの目的
@@ -12,7 +12,7 @@
### 宣言した層が解決する
ある層が構成を宣言として受け取ったなら、その解決もその層の責務。マニフェストに `[model] ref = "anthropic/claude-sonnet-4-6"`(あるいは `scheme = "anthropic"` + `model_id = ...` の inline 形式)と書いた以上、`ModelManifest``LlmClient` の変換は insomnia 側(`crates/provider`)が行う。逆に llm-worker が `LlmClient` trait だけを受け取るのは正しい — llm-worker はプロバイダの選択を宣言として受け取っていないから。
ある層が構成を宣言として受け取ったなら、その解決もその層の責務。マニフェストに `[model] ref = "anthropic/claude-sonnet-4-6"`(あるいは `scheme = "anthropic"` + `model_id = ...` の inline 形式)と書いた以上、`ModelManifest``LlmClient` の変換は yoi 側(`crates/provider`)が行う。逆に llm-worker が `LlmClient` trait だけを受け取るのは正しい — llm-worker はプロバイダの選択を宣言として受け取っていないから。
### 概念の追加は不在が問題になってから
@@ -20,7 +20,7 @@
### 最小の構造化で最大の自由度
insomnia は環境再現・コンテナ管理・VCS 統合などを自身の責務としない。Pod が動くホストの fs 上で活動する主体を提供し、それにコンテキストを与えてスポーンさせられる仕組みを付与する。構築する環境はユーザー次第。
yoi は環境再現・コンテナ管理・VCS 統合などを自身の責務としない。Pod が動くホストの fs 上で活動する主体を提供し、それにコンテキストを与えてスポーンさせられる仕組みを付与する。構築する環境はユーザー次第。
## Pod
@@ -88,7 +88,7 @@ name = "agent"
ref = "anthropic/claude-sonnet-4-6"
[worker]
instruction = "$insomnia/default"
instruction = "$yoi/default"
max_tokens = 4096
temperature = 0.3
@@ -103,7 +103,7 @@ permission = "write"
通常の Pod 起動は Lua profile discovery/default から `PodManifest` を生成する。bundled `builtin:default` が fallback default で、user/project `profiles.toml` は profile registry と default selection だけを担う。user/project `manifest.toml` の ambient cascade は通常起動では使わない。
`insomnia pod --manifest <PATH>` は explicit one-file compatibility/debug input で、指定 TOML 1 枚だけに builtin defaults を merge し、`PodManifestConfig -> PodManifest` の required validation を通す。
`yoi pod --manifest <PATH>` は explicit one-file compatibility/debug input で、指定 TOML 1 枚だけに builtin defaults を merge し、`PodManifestConfig -> PodManifest` の required validation を通す。
`PodFactory` の user/project/overlay API は低レベル構成部品として残るが、CLI の通常起動 path では generic TOML overlay を公開しない。
@@ -111,11 +111,11 @@ permission = "write"
`worker.instruction` はファイル参照。3 層の prefix addressing でプロンプト資産を解決:
- `$insomnia/...` — バイナリ同梱(`resources/prompts/``include_dir!` で埋め込み)
- `$yoi/...` — バイナリ同梱(`resources/prompts/``include_dir!` で埋め込み)
- `$user/...``<config_dir>/prompts/``manifest::paths` で解決)
- `$workspace/...``<project>/.insomnia/prompts/`
- `$workspace/...``<project>/.yoi/prompts/`
テンプレートは minijinja で評価。`{% include "$insomnia/common/tool-usage" %}` のようにプロンプト間で参照可能(prefix なしの include は現在のファイルからの相対解決)。
テンプレートは minijinja で評価。`{% include "$yoi/common/tool-usage" %}` のようにプロンプト間で参照可能(prefix なしの include は現在のファイルからの相対解決)。
レンダリング結果の末尾に scope summary と AGENTS.md(あれば)がコード側で固定付加される。ユーザーテンプレートからはこれらに触れない。
+1 -1
View File
@@ -115,7 +115,7 @@ If `Yoi` is adopted, the rename should cover at least:
- docs, reports, AGENTS instructions, tickets, and release material;
- socket/runtime path labels and diagnostics where user-visible.
Compatibility aliases should be considered separately, but the public identity should not preserve `insomnia` longer than necessary.
The public identity should move cleanly to Yoi; do not preserve `insomnia` through compatibility aliases.
## Adoption checks
+10 -10
View File
@@ -1,8 +1,8 @@
# 環境変数ポリシー
INSOMNIA では、プロセス境界で本当に必要な場合を除き、環境変数の利用を避ける。新しい ambient な入力を増やすより、明示的な profile / manifest / config file / typed secret reference / CLI argument を優先する。
Yoi では、プロセス境界で本当に必要な場合を除き、環境変数の利用を避ける。新しい ambient な入力を増やすより、明示的な profile / manifest / config file / typed secret reference / CLI argument を優先する。
それでも、path discovery、runtime directory、外部 provider の credential 慣習との移行互換のために、一部の環境変数はまだサポートしている。この文書に載せた通常 runtime 用の環境変数は公開 surface として扱う。ただし、fallback 変数は独立した設定項目ではなく、対応する main key の解決順の一部として扱う。開発・テスト都合だけの環境変数は、通常ユーザー向け configuration として扱わない明確な escape hatch に限る。
それでも、path discovery、runtime directory、外部 provider の credential 慣習のために、一部の環境変数はまだサポートしている。この文書に載せた通常 runtime 用の環境変数は公開 surface として扱う。ただし、fallback 変数は独立した設定項目ではなく、対応する main key の解決順の一部として扱う。開発・テスト都合だけの環境変数は、通常ユーザー向け configuration として扱わない明確な escape hatch に限る。
## 原則
@@ -19,10 +19,10 @@ Path 系の環境変数は論理的な key ごとに立項する。`XDG_*` や `
| 論理 key | Main env | Fallback / 解決順 | 用途と位置付け |
| --- | --- | --- | --- |
| `home` | `INSOMNIA_HOME` | なし | config / data / runtime をまとめて sandbox する root override。設定を細かく分けるより、test や isolated run ではまずこれを使う。 |
| `config_dir` | `INSOMNIA_CONFIG_DIR` | `$INSOMNIA_HOME/config``$XDG_CONFIG_HOME/insomnia``$HOME/.config/insomnia` | 人が書く設定・override の置き場。`profiles.toml`、prompt override、model/provider override など。 |
| `data_dir` | `INSOMNIA_DATA_DIR` | `$INSOMNIA_HOME``$HOME/.insomnia` | プログラムが書く永続データの置き場。session log、Pod metadata など、再起動後も restore / replay の根拠になるもの。通常ユーザー向けの primary knob ではなく、migration、testisolated data store 用の advanced override。 |
| `runtime_dir` | `INSOMNIA_RUNTIME_DIR` | `$INSOMNIA_HOME/run``$XDG_RUNTIME_DIR/insomnia``$HOME/.insomnia/run` | socket、pid/status file、live registry mirror など、再起動で捨ててよい runtime state の置き場。 |
| `home` | `YOI_HOME` | なし | config / data / runtime をまとめて sandbox する root override。設定を細かく分けるより、test や isolated run ではまずこれを使う。 |
| `config_dir` | `YOI_CONFIG_DIR` | `$YOI_HOME/config``$XDG_CONFIG_HOME/yoi``$HOME/.config/yoi` | 人が書く設定・override の置き場。`profiles.toml`、prompt override、model/provider override など。 |
| `data_dir` | `YOI_DATA_DIR` | `$YOI_HOME``$HOME/.yoi` | プログラムが書く永続データの置き場。session log、Pod metadata など、再起動後も restore / replay の根拠になるもの。通常ユーザー向けの primary knob ではなく、testisolated data store 用の advanced override。 |
| `runtime_dir` | `YOI_RUNTIME_DIR` | `$YOI_HOME/run``$XDG_RUNTIME_DIR/yoi``$HOME/.yoi/run` | socket、pid/status file、live registry mirror など、再起動で捨ててよい runtime state の置き場。 |
空の path 環境変数は、`manifest::paths` では原則として unset 相当に扱う。
@@ -36,11 +36,11 @@ Path 系の環境変数は論理的な key ごとに立項する。`XDG_*` や `
### Builtin assets と `config_dir`
Builtin profiles and catalogs are embedded in the binary at build time. User/project-owned overrides remain under `config_dir` and project `.insomnia/` files such as `profiles.toml`; package runtime resource lookup is not a supported configuration surface.
Builtin profiles and catalogs are embedded in the binary at build time. User/project-owned overrides remain under `config_dir` and project `.yoi/` files such as `profiles.toml`; package runtime resource lookup is not a supported configuration surface.
## Credential と外部 auth
Provider API key と WebSearch credential は、通常の runtime では環境変数から読まない。`insomnia keys` で local secret store に論理 id を追加し、profile / manifest / provider catalog / web config がその id を明示的に参照する。
Provider API key と WebSearch credential は、通常の runtime では環境変数から読まない。`yoi keys` で local secret store に論理 id を追加し、profile / manifest / provider catalog / web config がその id を明示的に参照する。
```toml
[model]
@@ -71,7 +71,7 @@ On-disk store は `<data_dir>/secrets/store.json`。secret value は軽量な ob
| 変数 | Context | 備考 |
| --- | --- | --- |
| `INSOMNIA_POD_RUNTIME_COMMAND` | 開発中に起動中の `insomnia` binary が rebuild され、`std::env::current_exe()``target/debug/insomnia (deleted)` のような stale path を返す場合の Pod runtime executable override。 | Unset または empty の場合は既定どおり current executable に `pod` prefix argument を付けて起動する。Non-empty の場合は値を executable path としてそのまま使い、`pod` prefix argument は常に自動追加する。shell parsing や argument splitting は行わないため、値に flags や `pod` を含めない。 |
| `YOI_POD_RUNTIME_COMMAND` | 開発中に起動中の `yoi` binary が rebuild され、`std::env::current_exe()``target/debug/yoi (deleted)` のような stale path を返す場合の Pod runtime executable override。 | Unset または empty の場合は既定どおり current executable に `pod` prefix argument を付けて起動する。Non-empty の場合は値を executable path としてそのまま使い、`pod` prefix argument は常に自動追加する。shell parsing や argument splitting は行わないため、値に flags や `pod` を含めない。 |
## Build / example variables
@@ -83,7 +83,7 @@ On-disk store は `<data_dir>/secrets/store.json`。secret value は軽量な ob
| `PATH` | test / dev command lookup。 | helper executable を探す場合だけ使う。 |
| `TMPDIR` | shell script / test。 | `tickets.sh` が temporary file に使う。 |
| `RUST_LOG` | example / dev diagnostics。 | example CLI が tracing setup 経由で読む場合がある。 |
| `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY` などの provider example vars | `llm-worker` や Pod example / fixture recorder。 | example code が `dotenv::dotenv().ok()` を呼ぶことがある。通常の `insomnia` runtime startup には適用されない。 |
| `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY` などの provider example vars | `llm-worker` や Pod example / fixture recorder。 | example code が `dotenv::dotenv().ok()` を呼ぶことがある。通常の `yoi` runtime startup には適用されない。 |
## 整理方針
+21 -21
View File
@@ -1,15 +1,15 @@
# Manifest profiles
Profiles are reusable Lua-authored recipes for generating an Insomnia runtime manifest. The Rust resolver evaluates a selected `.lua` profile in-process, validates that it is Profile-shaped rather than a complete Manifest, then binds runtime values such as Pod name and concrete scope to produce the persisted `PodManifest` snapshot.
Profiles are reusable Lua-authored recipes for generating a Yoi runtime manifest. The Rust resolver evaluates a selected `.lua` profile in-process, validates that it is Profile-shaped rather than a complete Manifest, then binds runtime values such as Pod name and concrete scope to produce the persisted `PodManifest` snapshot.
Profiles are intentionally not authority-bearing manifests. `pod.name`, concrete `scope.allow` / `scope.deny`, runtime directories, sockets, active session state, and raw secret material do not belong in reusable profiles. Use `insomnia keys` to store provider/WebSearch credentials, then reference explicit secret ids such as `auth = { kind = "secret_ref", ref = "providers/anthropic/default" }` or `web.search.api_key_secret = "web/brave/default"`. Use `--manifest` when you need the explicit low-level complete Manifest escape hatch.
Profiles are intentionally not authority-bearing manifests. `pod.name`, concrete `scope.allow` / `scope.deny`, runtime directories, sockets, active session state, and raw secret material do not belong in reusable profiles. Use `yoi keys` to store provider/WebSearch credentials, then reference explicit secret ids such as `auth = { kind = "secret_ref", ref = "providers/anthropic/default" }` or `web.search.api_key_secret = "web/brave/default"`. Use `--manifest` when you need the explicit low-level complete Manifest escape hatch.
## Minimal profile
```lua
local profile = require("insomnia.profile")
local models = require("insomnia.models")
local scope = require("insomnia.scope")
local profile = require("yoi.profile")
local models = require("yoi.models")
local scope = require("yoi.scope")
return profile {
slug = "coder",
@@ -26,24 +26,24 @@ return profile {
Run an explicit path with:
```sh
insomnia pod --profile ./coder.lua
yoi pod --profile ./coder.lua
# or through the TUI fresh-spawn dialog
insomnia --profile ./coder.lua
yoi --profile ./coder.lua
```
`--profile` accepts an explicit path, `path:<path>`, a discovered profile name, `default`, or a source-qualified name such as `project:coder`, `user:coder`, or `builtin:coder`. Path-like values containing `/`, starting with `.`, or ending in `.lua` are explicit paths. ``.nix` paths are no longer supported as profiles and fail with a diagnostic that points users at Lua profiles or `--manifest`.
`--profile` conflicts with `insomnia pod --manifest` and with restore/session/adopt modes. Use `--profile-pod-name <name>` when a launcher needs a creation-time Pod name override without invoking `--pod` restore semantics. Profile evaluation is a creation-time path; Pod resume restores saved Pod state/resolved snapshots rather than re-evaluating the profile source.
`--profile` conflicts with `yoi pod --manifest` and with restore/session/adopt modes. Use `--profile-pod-name <name>` when a launcher needs a creation-time Pod name override without invoking `--pod` restore semantics. Profile evaluation is a creation-time path; Pod resume restores saved Pod state/resolved snapshots rather than re-evaluating the profile source.
## Controlled Lua environment
Profiles run in a restricted Lua VM. Host virtual modules are available through controlled `require`:
- `require("insomnia")`
- `require("insomnia.profile")`
- `require("insomnia.models")`
- `require("insomnia.compact")`
- `require("insomnia.scope")`
- `require("yoi")`
- `require("yoi.profile")`
- `require("yoi.models")`
- `require("yoi.compact")`
- `require("yoi.scope")`
Profile-local modules may be required by dotted names such as `require("shared")` or `require("shared.models")`; those resolve only under the selected profile file's directory. Unsafe/unrestricted Lua facilities such as `os`, `io`, `debug`, `package`, `dofile`, and `loadfile` are unavailable by default.
@@ -51,7 +51,7 @@ Profile-local modules may be required by dotted names such as `require("shared")
Profile discovery is separate from runtime manifest merging. User/project `profiles.toml` files may declare profile registry metadata, but those files are application/project UX configuration and are not merged into the selected profile artifact.
Example project config at `.insomnia/profiles.toml`:
Example project config at `.yoi/profiles.toml`:
```toml
default = "coder"
@@ -69,19 +69,19 @@ path = "profiles/coder.lua"
description = "Project coding assistant"
```
Relative registry paths are resolved against the `profiles.toml` file that declares them. Discovery checks bundled builtin profiles, then the user registry at `<config_dir>/profiles.toml`, then the nearest project registry at `.insomnia/profiles.toml`. The bundled `builtin:default` profile is the fallback default when no user/project registry declares another default. Later defaults override earlier defaults, so a project default wins over a user default, and either wins over the builtin default. Unqualified defaults resolve within the declaring source by default. Unqualified ambiguous names fail closed:
Relative registry paths are resolved against the `profiles.toml` file that declares them. Discovery checks bundled builtin profiles, then the user registry at `<config_dir>/profiles.toml`, then the nearest project registry at `.yoi/profiles.toml`. The bundled `builtin:default` profile is the fallback default when no user/project registry declares another default. Later defaults override earlier defaults, so a project default wins over a user default, and either wins over the builtin default. Unqualified defaults resolve within the declaring source by default. Unqualified ambiguous names fail closed:
```sh
insomnia --profile coder # fails if both user:coder and project:coder exist
insomnia --profile project:coder # source-qualified selection
insomnia --profile default # selected registry default
yoi --profile coder # fails if both user:coder and project:coder exist
yoi --profile project:coder # source-qualified selection
yoi --profile default # selected registry default
```
The fresh-spawn TUI also uses discovery. The new Pod dialog defaults to the selected registry default, normally `builtin:default` unless a user/project registry overrides it. `Tab`/`Down` cycles forward through discovered profiles and `Shift-Tab`/`Up` cycles backward; there is no ambient manifest-cascade opt-out. Passing `insomnia --profile <selector>` opens the same new Pod dialog with that selector selected and leaves Pod-name editing unchanged.
The fresh-spawn TUI also uses discovery. The new Pod dialog defaults to the selected registry default, normally `builtin:default` unless a user/project registry overrides it. `Tab`/`Down` cycles forward through discovered profiles and `Shift-Tab`/`Up` cycles backward; there is no ambient manifest-cascade opt-out. Passing `yoi --profile <selector>` opens the same new Pod dialog with that selector selected and leaves Pod-name editing unchanged.
## One-file manifests
`insomnia pod --manifest <PATH>` remains as an explicit compatibility/debug path. It reads exactly that TOML file, resolves relative paths against the file's parent directory, merges builtin defaults, and validates through the same `PodManifestConfig -> PodManifest` boundary as profile artifacts. It does not load user or project `manifest.toml` files and conflicts with `--profile`.
`yoi pod --manifest <PATH>` remains as an explicit compatibility/debug path. It reads exactly that TOML file, resolves relative paths against the file's parent directory, merges builtin defaults, and validates through the same `PodManifestConfig -> PodManifest` boundary as profile artifacts. It does not load user or project `manifest.toml` files and conflicts with `--profile`.
Ambient user/project `manifest.toml` cascade startup has been removed. Normal fresh spawns use profile discovery/default selection, with `profiles.toml` acting only as a profile registry/default selector.
@@ -89,4 +89,4 @@ Ambient user/project `manifest.toml` cascade startup has been removed. Normal fr
A Lua profile should return either `profile { ... }` or a plain table containing Profile fields. The resolver converts reusable fields such as `model`, `worker`, `compaction`, `memory`, `web`, `permissions`, `session`, and scope intent into a concrete Manifest. Runtime Pod name and concrete scope authority are supplied by launch context, then the resolved Manifest snapshot is persisted for restore.
Profile and one-file manifest CLI paths currently use builtin prompt assets only. `$insomnia/...` instruction refs work; `$user/...` and `$workspace/...` prompt refs need a future explicit prompt-loader source design instead of reviving ambient manifest discovery.
Profile and one-file manifest CLI paths currently use builtin prompt assets only. `$yoi/...` instruction refs work; `$user/...` and `$workspace/...` prompt refs need a future explicit prompt-loader source design instead of reviving ambient manifest discovery.
+5 -5
View File
@@ -5,7 +5,7 @@
#
# このファイル形式は低レベル runtime manifest。通常起動は profile discovery/default
# (`profiles.toml` と bundled builtin profile) から manifest を生成する。
# `insomnia pod --manifest <path>` の one-file compatibility/debug mode では、
# `yoi pod --manifest <path>` の one-file compatibility/debug mode では、
# 指定した TOML 1 枚に builtin defaults を merge し、required validation を行う。
# user/project `manifest.toml` を暗黙に merge する通常起動 cascade は使わない。
#
@@ -65,7 +65,7 @@ ref = "anthropic/claude-sonnet-4-6"
# 任意 (ref 未指定時は実質必須)。デフォルト: なし。
# kind の値: "none" | "secret_ref" | "api_key" | "codex_oauth"
# - "none" … 認証不要 (ローカル Ollama 等)
# - "secret_ref" … `insomnia keys` の local secret store から key を読む。
# - "secret_ref" … `yoi keys` の local secret store から key を読む。
# `ref` はユーザー設定が明示的に選ぶ論理 secret id。
# store は id -> value のみを持ち、provider 種別を解釈しない。
# - "api_key" … 明示ファイルから key を読む低レベル形式。通常は
@@ -95,10 +95,10 @@ ref = "anthropic/claude-sonnet-4-6"
# ワーカーの生成パラメータ等。セクション自体省略可 (全フィールド任意)。
[worker]
# 任意。デフォルト: "$insomnia/default" (`defaults::DEFAULT_INSTRUCTION`)。
# 任意。デフォルト: "$yoi/default" (`defaults::DEFAULT_INSTRUCTION`)。
# システムプロンプト本体の `PromptLoader` 参照。
# プレフィクス: "$insomnia/..." | "$user/..." | "$workspace/..."
# instruction = "$insomnia/default"
# プレフィクス: "$yoi/..." | "$user/..." | "$workspace/..."
# instruction = "$yoi/default"
# 任意。デフォルト: なし (プロバイダ任せ)。
# 1 レスポンスあたりの出力 token 上限。
+5 -5
View File
@@ -2,7 +2,7 @@
## 目的
AI maintainer は、insomnia リポジトリの開発を継続的に進めるための orchestration role である。単発の `/auto-maintain` より広く、設計相談、work item 整理、実装委譲、レビュー、運用課題の記録、改善提案を一つの maintainer loop として扱う。
AI maintainer は、yoi リポジトリの開発を継続的に進めるための orchestration role である。単発の `/auto-maintain` より広く、設計相談、work item 整理、実装委譲、レビュー、運用課題の記録、改善提案を一つの maintainer loop として扱う。
`/auto-maintain` はこの設計の限定実行形であり、`tickets.sh` / `work-items/` から小さな実装作業を選んで実装・レビューを orchestration する Workflow に留まる。
@@ -16,7 +16,7 @@ AI maintainer は、insomnia リポジトリの開発を継続的に進めるた
- `resolution.md` は close 時の完了記録
- 時系列と状態遷移の最終根拠は git history
- `docs/report/` は観測・所感・改善候補の記録であり、最新仕様の authority ではない
- `.insomnia/memory` は個人/生成 state であり、project record の正本ではない
- `.yoi/memory` は個人/生成 state であり、project record の正本ではない
AI maintainer は project record を勝手に膨らませない。明確な実装単位は work item 化し、小粒な所見は `KNOWN_ISSUES.md`、ドッグフーディング上の障壁やツール問題は `docs/report/` に記録する。
@@ -44,7 +44,7 @@ Maintainer Pod は「便利だから」project record を書き換えない。
制約:
- 指定 scope 外を編集しない
- `.insomnia` や main workspace の control-plane record を勝手に編集しない
- `.yoi` や main workspace の control-plane record を勝手に編集しない
- work item / review / close は maintainer の責務として扱う
- 実装報告には変更点、検証、未解決点を含める
@@ -185,8 +185,8 @@ AI maintainer は以下で人間に戻す。
## Reports / Knowledge / Memory
- `docs/report/`: ドッグフーディングで感じた障壁、改善案、ツール問題の記録。明確な作業単位になったら work item 化する
- `.insomnia/knowledge`: curated project knowledge。正本ではなく補助 context
- `.insomnia/memory`: generated/personal state。project record の代替にしない
- `.yoi/knowledge`: curated project knowledge。正本ではなく補助 context
- `.yoi/memory`: generated/personal state。project record の代替にしない
- `KNOWN_ISSUES.md`: ticket 化するほどではないが、次に近所を触る時に拾いたい小粒所見
## Future extension points
+3 -3
View File
@@ -2,7 +2,7 @@
## Context
INSOMNIA が利用する LLM プロバイダとその認証方式を決める。従量 API 課金の心理的負担を避け、定額サブスク枠(ChatGPT Codex / Ollama Cloud)を活かせる構成にする。
Yoi が利用する LLM プロバイダとその認証方式を決める。従量 API 課金の心理的負担を避け、定額サブスク枠(ChatGPT Codex / Ollama Cloud)を活かせる構成にする。
詳細な現状調査は `docs/ref/llm-provider-landscape.md``docs/ref/llm-pricing-2026-04.md` を参照。
@@ -46,13 +46,13 @@ Ollama は独自 scheme を作らず `scheme/anthropic` を base_url 差し替
- 認証ストアを読むアダプタ(`~/.codex/auth.json` 等)は **llm-worker 直下に置かず上位層に配置**。llm-worker は低レベル基盤に留める方針(`feedback_llm_worker_scope.md`)と整合
- モデル列挙は **auto_discover と宣言型の両輪**。Ollama は `/api/tags` で自動、OpenAI 互換枠はモデルカタログ(`resources/models/builtin.toml` + `<config_dir>/models.toml` の user override、`<config_dir>``manifest::paths` で解決)で宣言
- UI のプロバイダ選択肢も第一級 → 二次の優先順位で並べる
- **`ollama launch insomnia` 対応を視野に**、env 注入(`ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` 等)で起動設定を受け入れる作り
- **`ollama launch yoi` 対応を視野に**、env 注入(`ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` 等)で起動設定を受け入れる作り
## 機能方針
### プロバイダ側の高次ツールは使用しない
`web_search` / `code_interpreter` / `computer_use` / Live Search 等はプロバイダ依存を避けるため不採用。insomnia の自前 Tool 層で統一。fallback や routing もワーカー側で管理するため OpenRouter の `transforms` / `provider routing` も使わない。
`web_search` / `code_interpreter` / `computer_use` / Live Search 等はプロバイダ依存を避けるため不採用。yoi の自前 Tool 層で統一。fallback や routing もワーカー側で管理するため OpenRouter の `transforms` / `provider routing` も使わない。
### 必須 capability
+1 -1
View File
@@ -14,7 +14,7 @@
- ID: timestamp + slug 形式
- Doctor: `./tickets.sh doctor`
`work-items/` は repo-managed な project coordination record であり、`.insomnia/memory` はその代替ではない。
`work-items/` は repo-managed な project coordination record であり、`.yoi/memory` はその代替ではない。
## 現在も残る設計余地
+4 -4
View File
@@ -10,7 +10,7 @@
- `memory/summary.md` は「Always-on サマリ」と設計されているが、通常 Pod の system prompt へ常駐注入されていない
- consolidation は `KnowledgeCandidateReport::empty()` を受け取り、prompt 上も「候補レポートが空なら新規 Knowledge を作るな」としているため、Knowledge の cold-start が起きない
- `decisions/*``requests/*` は記録としては残るが、description / resident injection を持たず、後続 turn で自然に読まれにくい
- bundled prompt に INSOMNIA 開発固有の ticket / TODO 運用を前提にした shadow 禁止が入り、一般ユーザー workspace の管理文脈を過剰に落とす可能性がある
- bundled prompt に Yoi 開発固有の ticket / TODO 運用を前提にした shadow 禁止が入り、一般ユーザー workspace の管理文脈を過剰に落とす可能性がある
この状態で usage metrics を先に実装しても、「使われていない / 発見されない memory」を測るだけになり、Knowledge 化候補や保護閾値の信号が十分に育たない。先に memory が読まれ、Knowledge が最低限生まれる経路を作る。
@@ -78,7 +78,7 @@ Knowledge が空のまま固定される問題を避ける。metrics 実装前
### Problem
bundled memory prompts は、INSOMNIA 自身の ticket / TODO / worktree 運用を一般ユーザーへ押し付けている。ticket はこのプロジェクトの管理手法であり、ユーザー workspace の正本や作業管理の形は project ごとに異なる。
bundled memory prompts は、Yoi 自身の ticket / TODO / worktree 運用を一般ユーザーへ押し付けている。ticket はこのプロジェクトの管理手法であり、ユーザー workspace の正本や作業管理の形は project ごとに異なる。
### Direction
@@ -89,7 +89,7 @@ Default prompt では特定の管理手法名を禁止対象として列挙し
- 既存の authoritative record を逐語的に mirror しない
- ファイル操作ログや VCS 履歴そのものを memory に再保存しない
- ただし、将来の作業判断に効く project-management 上の制約・優先順位理由・プロセス決定・ recurring pattern は抽象化して保存してよい
- INSOMNIA 自身の ticket shadow 回避は bundled default ではなく workspace / user prompt override で表現する
- Yoi 自身の ticket shadow 回避は bundled default ではなく workspace / user prompt override で表現する
### Expected effect
@@ -181,7 +181,7 @@ cold-start gate を緩めると Knowledge が増えすぎる可能性がある
### Prompt override boundary
INSOMNIA 自身の ticket shadow 回避を完全に消すと、この repository の memory は作業ログ寄りに戻る可能性がある。これは bundled default ではなく workspace prompt override で解くべきで、default prompt の責務ではない。
Yoi 自身の ticket shadow 回避を完全に消すと、この repository の memory は作業ログ寄りに戻る可能性がある。これは bundled default ではなく workspace prompt override で解くべきで、default prompt の責務ではない。
### `#<slug>` history representation
+3 -3
View File
@@ -2,7 +2,7 @@
## Context
INSOMNIA がユーザーのプロジェクトに対して提供するメモリ機構。プロジェクトの暗黙知蓄積と同じ失敗を繰り返さないための記憶が目的。エージェントに連続するアイデンティティや自己意識を持たせる方向は対象外。
Yoi がユーザーのプロジェクトに対して提供するメモリ機構。プロジェクトの暗黙知蓄積と同じ失敗を繰り返さないための記憶が目的。エージェントに連続するアイデンティティや自己意識を持たせる方向は対象外。
リサーチは `docs/ref/memory-systems.md`。前提として、**レポジトリがファイルシステム上にある**ケースで設計する(越境・バックエンド抽象は Scope 外)。
@@ -14,7 +14,7 @@ Workflow`/<slug>` で呼び出される制約付き作業フロー)は別 p
### 記録対象の 4 種
本ドキュメント以下のパスはすべて **`<workspace_root>/.insomnia/`** からの相対表記。`.insomnia/` は manifest / prompts と同じく workspace に紐付く insomnia コンテンツのルートで、memory もこの規約に従う。`workspace_root` 既定は Pod の pwd。
本ドキュメント以下のパスはすべて **`<workspace_root>/.yoi/`** からの相対表記。`.yoi/` は manifest / prompts と同じく workspace に紐付く yoi コンテンツのルートで、memory もこの規約に従う。`workspace_root` 既定は Pod の pwd。
| 種別 | パス | 備考 |
| ---------------- | ---------------------------- | ------------------------------------------------------------------------------------------- |
@@ -98,7 +98,7 @@ Linter ルールは 2 系統:
- Decisions / Requests: `created_at`, `updated_at`, `sources`
- Knowledge: `kind`, `description`, `model_invokation`, `user_invocable`, `last_sources`, `created_at`, `updated_at`
- Summary: `updated_at`optional: `last_rewritten_from_range`
- Workflow パス(`.insomnia/workflow/`)への書き込み禁止(sub-Worker context のみ、人間編集は除外)
- Workflow パス(`.yoi/workflow/`)への書き込み禁止(sub-Worker context のみ、人間編集は除外)
- 同 slug での新規作成禁止(既存があれば update に切り替えるサイン)
- `#<slug>` 参照が実在ファイルを指す
- `replaced_by: <slug>` が実在 record を指す
+40 -40
View File
@@ -23,26 +23,26 @@ Pod が連携する等)では、マシン間のメッセージングが必要
## アドレッシング
Pod のネットワークアドレスは `insomnia.pod-name@host` の形式を**論理的な
Pod のネットワークアドレスは `yoi.pod-name@host` の形式を**論理的な
宛先表記**として使う。実際の SSH 接続がこの文字列そのままで行えるかは
transport 方式に依存する(後述)。
- `insomnia` = SSH ユーザー名(固定)
- `yoi` = SSH ユーザー名(固定)
- `host` = 相手マシンのホスト名 or IP
- `pod-name` = 送信先の Pod 名(相手マシン上のローカル workspace 内で一意)
推奨構文は **`insomnia@host:pod-name`**git 方式)。
推奨構文は **`yoi@host:pod-name`**git 方式)。
詳細は後述の「アドレッシング構文」を参照。
## アドレッシング構文
論理的な宛先表記として **`insomnia@host:pod-name`** を推奨する。
論理的な宛先表記として **`yoi@host:pod-name`** を推奨する。
git の `git@github.com:user/repo` と同じ構文で:
- SSH ユーザーは `insomnia` 固定(動的ユーザー名が不要)
- SSH ユーザーは `yoi` 固定(動的ユーザー名が不要)
- `:` 以降がルーティング情報(Pod 名)
- クライアント側が `insomnia@host:pod-name` をパースし、
`ssh insomnia@host "insomnia-route pod-name"` に変換する
- クライアント側が `yoi@host:pod-name` をパースし、
`ssh yoi@host "yoi-route pod-name"` に変換する
git がこの方式で `git-upload-pack user/repo` にルーティングしている
のと同じ仕組み。OS レベルの設定(NSS モジュール等)が一切不要で、
@@ -53,37 +53,37 @@ git がこの方式で `git-upload-pack user/repo` にルーティングして
### A. 単一ユーザー + コマンド引数
```
ssh insomnia@host send pod-name "message"
ssh yoi@host send pod-name "message"
```
- 相手マシンにシステムユーザー `insomnia` を 1 つ作る
- 相手マシンにシステムユーザー `yoi` を 1 つ作る
- `authorized_keys` に接続元 Pod の公開鍵を登録
- ForceCommand または shell スクリプトが第一引数 (`send`) と
第二引数 (`pod-name`) を解釈してローカル workspace のレジストリから
Pod の socket を引き、メッセージをルーティング
- **導入コスト最低**。ユーザー 1 つ + スクリプト 1 つで動く
- 宛先が引数に入るので `insomnia.pod-name@host` の見た目にはならない
- 宛先が引数に入るので `yoi.pod-name@host` の見た目にはならない
### B. 鍵ベースルーティング(gitolite 方式)
```
ssh insomnia@host # 使った鍵でどの Pod 宛か判別
ssh yoi@host # 使った鍵でどの Pod 宛か判別
```
- `~insomnia/.ssh/authorized_keys` に Pod ごとのエントリ:
- `~yoi/.ssh/authorized_keys` に Pod ごとのエントリ:
```
command="insomnia-route pod-a",no-port-forwarding,... ssh-ed25519 AAAA... pod-a@remote
command="insomnia-route pod-b",no-port-forwarding,... ssh-ed25519 AAAA... pod-b@remote
command="yoi-route pod-a",no-port-forwarding,... ssh-ed25519 AAAA... pod-a@remote
command="yoi-route pod-b",no-port-forwarding,... ssh-ed25519 AAAA... pod-b@remote
```
- SSH 接続時に使われた鍵が `command=` で指定されたルーティング先を決定
- gitolite / Gitea / Gogs で実証済みのパターン
- 接続元は `ssh insomnia@host` だけ。**鍵が宛先を決める**
- 接続元は `ssh yoi@host` だけ。**鍵が宛先を決める**
- クライアント側 SSH config で alias を作れば見た目を整えられる:
```
Host pod-a.host-b
HostName host-b
User insomnia
IdentityFile ~/.config/insomnia/keys/pod-a
User yoi
IdentityFile ~/.config/yoi/keys/pod-a
```
- 鍵の登録が相互に必要(Pod A が Pod B に送るなら、B のマシンの
authorized_keys に A の公開鍵 + route 先を登録)
@@ -91,15 +91,15 @@ ssh insomnia@host # 使った鍵でどの Pod 宛か判別
### C. 動的ユーザー名
```
ssh insomnia.pod-name@host
ssh yoi.pod-name@host
```
- `insomnia.pod-name` を OS レベルで有効なユーザー名として解決する:
- `yoi.pod-name` を OS レベルで有効なユーザー名として解決する:
- NSS (Name Service Switch) モジュールを書くか `libnss-extrausers` を利用
- PAM モジュールで認証をフック
- `sshd_config` で `Match User insomnia.*` → `ForceCommand` でルーティング
- `sshd_config` で `Match User yoi.*` → `ForceCommand` でルーティング
- **最も直感的なアドレッシング**だが OS レベルの設定が必要
- insomnia をインストールするだけでは動かない(管理者権限での設定が要る)
- yoi をインストールするだけでは動かない(管理者権限での設定が要る)
- コンテナ環境ではやりやすい(ユーザー管理を自由にできる)
### 推奨
@@ -143,7 +143,7 @@ Pod 協働では:
- broadcast = known-peers を iterate して個別送信
- 規模が数十 Pod なら十分実用的
- 将来的に gossip protocol で peer 発見を自動化できるが、
MVP では手動登録(`insomnia peer add pod-a@host-b`)で十分
MVP では手動登録(`yoi peer add pod-a@host-b`)で十分
## 受信側のルーティング
@@ -151,16 +151,16 @@ SSH 接続を受けた側が、宛先 Pod のローカル socket にルーティ
仕組みが必要。
```
[SSH 接続] → insomnia-route <pod-name>
[SSH 接続] → yoi-route <pod-name>
workspace registry を参照
/run/insomnia/.../pod-name.sock に転送
/run/yoi/.../pod-name.sock に転送
Pod が受信・処理
```
`insomnia-route` は:
`yoi-route` は:
1. workspace のレジストリを読んで pod-name の socket path を引く
2. socket に接続してメッセージを中継
3. 応答を SSH 接続に返す
@@ -172,17 +172,17 @@ unique であれば workspace を指定しなくて済む。
## Daemon-less リモート Pod 生成(SSH-only モデル)
リモートホスト上の Pod 生成は **daemon 無しで SSH だけで成立する**。
remote 側に必要なのは `insomnia` バイナリと SSH アクセスのみ。
remote 側に必要なのは `yoi` バイナリと SSH アクセスのみ。
### 前提
- insomnia は環境再現(git clone, コンテナ構築等)を自身の責務としない。
- yoi は環境再現(git clone, コンテナ構築等)を自身の責務としない。
作業対象のファイルがリモートに既にあるか、ユーザーが任意の手段で
用意する前提(git clone, rsync, 手動配置、CI の checkout 等)
- insomnia が転送するのは**セッション(会話履歴)と manifest overlay**
- yoi が転送するのは**セッション(会話履歴)と manifest overlay**
だけ。コードベースの同期は外部に委ねる
- コンテナ内で動かすか bare metal で動かすかも insomnia は問わない。
`insomnia` バイナリが動くホストの fs 上で活動する主体がある、
- コンテナ内で動かすか bare metal で動かすかも yoi は問わない。
`yoi` バイナリが動くホストの fs 上で活動する主体がある、
それだけが前提
### フロー
@@ -193,7 +193,7 @@ host_a (spawner) host_b (remote)
├── ssh: session データを転送 ────────→ ファイル書き込み
├── ssh: profile / one-file manifest 入力を転送 ─→ 必要ならファイル書き込み
├── ssh: `insomnia pod --profile ... &` ───────→ Pod プロセス起動、socket 作成
├── ssh: `yoi pod --profile ... &` ───────→ Pod プロセス起動、socket 作成
├── ssh -L: socket を tunnel ─────────→ Pod B の unix socket
└── localhost:tunnel に接続 ──────────→ Method::Run / Event stream
@@ -204,16 +204,16 @@ host_a (spawner) host_b (remote)
```bash
# 1. session + profile/manifest input を転送
ssh insomnia@host-b "mkdir -p ~/workspaces/task-123/store"
tar cz session/ | ssh insomnia@host-b "tar xz -C ~/workspaces/task-123/store"
scp profile.lua insomnia@host-b:~/workspaces/task-123/profile.lua
ssh yoi@host-b "mkdir -p ~/workspaces/task-123/store"
tar cz session/ | ssh yoi@host-b "tar xz -C ~/workspaces/task-123/store"
scp profile.lua yoi@host-b:~/workspaces/task-123/profile.lua
# 2. Pod を起動(detach
ssh insomnia@host-b "insomnia pod --store ~/workspaces/task-123/store \
ssh yoi@host-b "yoi pod --store ~/workspaces/task-123/store \
--profile ~/workspaces/task-123/profile.lua &"
# 3. socket を tunnel で引っ張る
ssh -L /tmp/pod-b.sock:/run/insomnia/task-123/pod.sock insomnia@host-b
ssh -L /tmp/pod-b.sock:/run/yoi/task-123/pod.sock yoi@host-b
# 4. あとは /tmp/pod-b.sock にローカルと同じ protocol で繋ぐ
```
@@ -229,7 +229,7 @@ spawner の `SpawnPod` ツールがこの一連を内部で実行する。LLM
成立しないので、workspace の scope 会計は remote には関係しない
- **通知**: SSH tunnel が繋がっている限り `Event` stream がそのまま
流れる。tunnel が切れたら再接続する
- **環境構築は insomnia の責務外**: git clone するか rsync するかは
- **環境構築は yoi の責務外**: git clone するか rsync するかは
Pod の instruction で指示するか、事前に用意されている前提
### daemon が必要になるケース
@@ -251,7 +251,7 @@ SSH-only モデルの制約が、daemon 導入の動機になる:
### リモート側のディレクトリ構成
```
/home/insomnia/ ← insomnia システムユーザーの home
/home/yoi/ ← yoi システムユーザーの home
├── workspaces/
│ ├── <task-or-project-id>/ ← workspace ごとのルート
│ │ ├── repo/ ← ユーザーが用意した作業ファイル群
@@ -261,8 +261,8 @@ SSH-only モデルの制約が、daemon 導入の動機になる:
└── authorized_keys ← 接続元 Pod の公開鍵
```
- `insomnia` システムユーザーが SSH 接続先 + ファイル所有者
- `repo/` 配下の準備は insomnia の責務外(git clone, rsync 等は
- `yoi` システムユーザーが SSH 接続先 + ファイル所有者
- `repo/` 配下の準備は yoi の責務外(git clone, rsync 等は
ユーザーや instruction が指示)
- `store/` は spawner がセッションデータを書き込む場所
+1 -1
View File
@@ -2,7 +2,7 @@
## Context
INSOMNIA はエージェントが扱うツール数の増加 (built-in tools + MCP サーバ + ユーザ定義) を想定する必要がある。すべてを upfront に context へ展開すると以下が問題になる:
Yoi はエージェントが扱うツール数の増加 (built-in tools + MCP サーバ + ユーザ定義) を想定する必要がある。すべてを upfront に context へ展開すると以下が問題になる:
- **入力トークン消費**: 30-50 ツールで 10-20K tokens を消費しうる (Anthropic 公式ガイド)
- **ツール選択精度の低下**: 数十個を超えるとモデルの tool selection accuracy が落ちる
+2 -2
View File
@@ -24,8 +24,8 @@ Workflow は制約付きの強制的な作業フロー。`/<slug>` で明示的
### 格納先とファイル形式
- `.insomnia/workflow/<slug>.md`(ファイル名 = slug がそのまま識別子、`name` field は持たない)
- `.insomnia/memory/` は session-derived state 専用、Workflow は配置しない
- `.yoi/workflow/<slug>.md`(ファイル名 = slug がそのまま識別子、`name` field は持たない)
- `.yoi/memory/` は session-derived state 専用、Workflow は配置しない
- frontmatter + Markdown 本文
- frontmatter フィールド: `description`, `auto_invoke`, `user_invocable`, `requires`
+19 -19
View File
@@ -22,10 +22,10 @@
Profile は Lua で書かれる。Rust resolver は selected profile を restricted Lua VM 内で評価し、返り値が Profile-shaped であることを検証してから `PodManifest` に変換する。
```lua
local profile = require("insomnia.profile")
local models = require("insomnia.models")
local scope = require("insomnia.scope")
local compact = require("insomnia.compact")
local profile = require("yoi.profile")
local models = require("yoi.models")
local scope = require("yoi.scope")
local compact = require("yoi.compact")
local model = models.catalog("codex-oauth/gpt-5.5")
@@ -79,9 +79,9 @@ Profile に入れてはいけないもの:
`.nix` profile files are no longer supported. Reusable profiles are Lua; complete low-level recipes belong behind `--manifest`.
Discovery は bundled builtin profiles、user registry (`<config_dir>/profiles.toml`)、project registry (`<project>/.insomnia/profiles.toml`) を読む。後段の default が前段の default を上書きするため、project default は user/default builtin より優先される。unqualified ambiguous names は source-qualified suggestion を出して失敗する。
Discovery は bundled builtin profiles、user registry (`<config_dir>/profiles.toml`)、project registry (`<project>/.yoi/profiles.toml`) を読む。後段の default が前段の default を上書きするため、project default は user/default builtin より優先される。unqualified ambiguous names は source-qualified suggestion を出して失敗する。
Example `.insomnia/profiles.toml`:
Example `.yoi/profiles.toml`:
```toml
default = "coder"
@@ -103,11 +103,11 @@ Profile evaluation runs with controlled host-provided `require`.
Host virtual modules:
- `require("insomnia")`
- `require("insomnia.profile")`
- `require("insomnia.models")`
- `require("insomnia.compact")`
- `require("insomnia.scope")`
- `require("yoi")`
- `require("yoi.profile")`
- `require("yoi.models")`
- `require("yoi.compact")`
- `require("yoi.scope")`
Profile-local modules can be reused with dotted names such as `require("shared")` or `require("shared.models")`; they resolve only under the selected profile file's directory. Unsafe/unrestricted Lua facilities such as `os`, `io`, `debug`, unrestricted `package`, `dofile`, `loadfile`, `load`, and `collectgarbage` are unavailable by default.
@@ -146,22 +146,22 @@ One-file Manifest deserialization keeps the Manifest compatibility behavior: unk
| Prefix | Resolution |
|---|---|
| `$insomnia` | bundled `resources/prompts/` (`include_dir!`) |
| `$yoi` | bundled `resources/prompts/` (`include_dir!`) |
| `$user` | `<config_dir>/prompts/` |
| `$workspace` | `<project>/.insomnia/prompts/` |
| `$workspace` | `<project>/.yoi/prompts/` |
`.md` extension can be omitted, e.g. `$insomnia/default` resolves to `resources/prompts/default.md`. Missing files are hard errors; prefixes do not fall through.
`.md` extension can be omitted, e.g. `$yoi/default` resolves to `resources/prompts/default.md`. Missing files are hard errors; prefixes do not fall through.
Profile and one-file Manifest CLI paths currently use builtin prompt assets only for initial loader construction. `$insomnia/...` works; `$user/...` and `$workspace/...` prompt refs need a future explicit prompt-loader source design instead of reviving ambient manifest discovery.
Profile and one-file Manifest CLI paths currently use builtin prompt assets only for initial loader construction. `$yoi/...` works; `$user/...` and `$workspace/...` prompt refs need a future explicit prompt-loader source design instead of reviving ambient manifest discovery.
The rendered instruction body is followed by fixed Rust-provided sections for working boundaries and, when present, `AGENTS.md`. User templates cannot remove the scope section.
## `insomnia pod` CLI
## `yoi pod` CLI
Normal fresh startup uses profile discovery/default selection:
```text
insomnia pod [--profile <selector>] [--profile-pod-name <name>] [-s/--store <path>]
yoi pod [--profile <selector>] [--profile-pod-name <name>] [-s/--store <path>]
```
| Flag | Description |
@@ -173,8 +173,8 @@ insomnia pod [--profile <selector>] [--profile-pod-name <name>] [-s/--store <pat
Restore/attach uses Pod/session state and does not re-evaluate profile sources.
```text
insomnia pod --pod <name>
insomnia pod --session <uuid>
yoi pod --pod <name>
yoi pod --session <uuid>
```
Spawn children use hidden `--spawn-config-json`, `--adopt`, and `--callback <path>` flags. These are internal handoff details used by `SpawnPod` after the parent has allocated scope and prepared the child config.
+1 -1
View File
@@ -1,6 +1,6 @@
# Reasoning / Thinking 制御
manifest の `[worker]` セクションで `reasoning` を指定すると、scheme が provider 各社の wire 形式に投影する。文字列なら **effort label**、数値なら **thinking budget tokens** として扱う。insomnia 側は値の妥当性を検証せず、未知ラベルや provider が拒む値は API 応答で初めて検出される。
manifest の `[worker]` セクションで `reasoning` を指定すると、scheme が provider 各社の wire 形式に投影する。文字列なら **effort label**、数値なら **thinking budget tokens** として扱う。yoi 側は値の妥当性を検証せず、未知ラベルや provider が拒む値は API 応答で初めて検出される。
## 書き方
+2 -2
View File
@@ -37,7 +37,7 @@ Tier 3: Full Compact/compact コマンド)
**「十分なトークンを削れる場合にだけ実行」** という判断を行い、
キャッシュ無効化コスト > 節約トークン数 となるケースを避ける。
これは Insomnia における条件付き Prune の直接的な先行事例。
これは Yoi における条件付き Prune の直接的な先行事例。
### キャッシュへの影響
@@ -216,7 +216,7 @@ OpenCodesst/opencode)でも Prune とキャッシュの問題は未解決
---
## Insomnia 設計への示唆
## Yoi 設計への示唆
### 1. Prune は条件付きで実行すべき
+6 -6
View File
@@ -38,12 +38,12 @@
- `packages/opencode/src/session/prompt/anthropic-20250930.txt`Claude Code 風システムプロンプト)
- `opencode-anthropic-auth@0.0.13` ビルトインプラグイン
- `claude-code-20250219` beta ヘッダ
- 代替検討: `claude -p` (Claude Code の headless mode) を subprocess で呼ぶ方式。ACP ではなく素朴な CLI fork であり、insomnia では採用しない
- 代替検討: `claude -p` (Claude Code の headless mode) を subprocess で呼ぶ方式。ACP ではなく素朴な CLI fork であり、yoi では採用しない
- https://code.claude.com/docs/en/legal-and-compliance
- https://github.com/sst/opencode/pull/18186
### OpenAI (Codex CLI / Responses)
- Codex CLI は Apache-2.0 で公開されている。insomnia の Codex OAuth 経路は、Codex CLI と同じ Responses 系 wire behavior に寄せる
- Codex CLI は Apache-2.0 で公開されている。yoi の Codex OAuth 経路は、Codex CLI と同じ Responses 系 wire behavior に寄せる
- Codex CLI の認証ストアと conversation header / request compression / SSE behavior を参考にする
- OpenCode の `/connect` で ChatGPT ブラウザ認証が通る
- コミュニティ評価: 「Anthropic は walled garden、OpenAI はむしろ取り込みに来た」
@@ -54,7 +54,7 @@
- `claude --print` / `claude -p` は Claude Code の非対話(headless)モード。プロンプトを stdin/引数で受け stdout に返す
- **ACP ではなく素朴な subprocess 呼び出し**
- OpenClaw と OpenCode コミュニティフォーク (`griffinmartin/opencode-claude-auth`) が採用
- insomnia では専用 API integration ではないため採用しない
- yoi では専用 API integration ではないため採用しない
## Ollama の統合機構
@@ -177,7 +177,7 @@
## Capability 軸
モデル/プロバイダごとの機能差を表現する軸。**プロバイダ側高次ツール (web_search / code_interpreter / computer_use / Live Search) は insomnia では使用しない方針**のため capability 軸から除外。
モデル/プロバイダごとの機能差を表現する軸。**プロバイダ側高次ツール (web_search / code_interpreter / computer_use / Live Search) は yoi では使用しない方針**のため capability 軸から除外。
### 1. tool calling
parallel tool calls 可否、tool_choice 対応度。DeepSeek reasoner のような「reasoner + tool 非対応」ケースあり。
@@ -221,7 +221,7 @@ parallel tool calls 可否、tool_choice 対応度。DeepSeek reasoner のよう
→ Gemini / Ollama `/v1` は scheme アダプタで「BlockStart → InputJson(全体 1 回) → BlockStop」の**擬似ストリーム化**で共通化可能。
## insomnia での採用方針
## yoi での採用方針
### 第一級サポート(専用アダプタ)
- **Ollama API** — ローカル + `:cloud` サフィックスで透過的にクラウド中継。エンドポイントは `localhost:11434` で統一
@@ -239,4 +239,4 @@ parallel tool calls 可否、tool_choice 対応度。DeepSeek reasoner のよう
### 実装原則
- 認証アダプタ(外部 CLI の認証ストアを読む類)は llm-worker 直下ではなく上位アダプタ層に配置。llm-worker は低レベル基盤に留める原則(project memory)と整合
- モデル列挙は `auto_discover` と宣言型の両輪。Ollama は自動、ルーター系は宣言
- `ollama launch insomnia` 対応を視野に入れ、env 注入 (`ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` 等) で起動設定を受け入れる作り
- `ollama launch yoi` 対応を視野に入れ、env 注入 (`ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` 等) で起動設定を受け入れる作り
+29 -29
View File
@@ -1,6 +1,6 @@
# エージェント向けメモリ機構の外部事例
調査日: 2026-04-21。本ドキュメントはユーザー依頼の3ソース(OpenAI Codex Chronicle / Shann³ の "AI Knowledge Layer" スレッド / Nous Research Hermes Agent)を中心に、直近で公開されたメモリ機構をまとめ、insomnia に入れる際の比較材料とすることを目的とする。2026年前半は各所からメモリ実装が同時多発的に登場しているので、「どの事例がどのレイヤを担っているか」を見失わないよう、各節で**何を記憶するか/いつ書くか/どう引き出すか/何に保存するか**を揃えて整理する。
調査日: 2026-04-21。本ドキュメントはユーザー依頼の3ソース(OpenAI Codex Chronicle / Shann³ の "AI Knowledge Layer" スレッド / Nous Research Hermes Agent)を中心に、直近で公開されたメモリ機構をまとめ、yoi に入れる際の比較材料とすることを目的とする。2026年前半は各所からメモリ実装が同時多発的に登場しているので、「どの事例がどのレイヤを担っているか」を見失わないよう、各節で**何を記憶するか/いつ書くか/どう引き出すか/何に保存するか**を揃えて整理する。
数値・URLは一次ソースで再確認すること。挙動は研究プレビュー段階のものが多く、変わる前提で読む。
@@ -25,7 +25,7 @@ Codex CLI に 2026-03 頃から追加された "Memories" 機能と、2026-04-15
- 生成タイミングは「スレッドが十分アイドルになってから」(age + idle window で判定)
- `memory_summary.md`**5,000 tokens cap** で system prompt に注入される(`MEMORY_TOOL_DEVELOPER_INSTRUCTIONS_SUMMARY_TOKEN_LIMIT`
**非対称の肝**: 抽出 (extract) は structured output で分類を強制、統合 (consolidation) は sub-agent に自由書き込みさせる。分類ブレを extract で封じ、統合の柔軟性は consolidation の agentic 判断に委ねる、という役割分担。insomnia の extract / consolidation 設計の直接の元ネタ。
**非対称の肝**: 抽出 (extract) は structured output で分類を強制、統合 (consolidation) は sub-agent に自由書き込みさせる。分類ブレを extract で封じ、統合の柔軟性は consolidation の agentic 判断に委ねる、という役割分担。yoi の extract / consolidation 設計の直接の元ネタ。
### 保存場所 / 形式
@@ -66,7 +66,7 @@ Codex CLI に 2026-03 頃から追加された "Memories" 機能と、2026-04-15
## 2. Shann³ "AI Knowledge Layer"
https://x.com/shannholmberg/status/2044111115878326444 で提唱している、**エージェントより先に読ませる知識層**という枠組み。エンジニア向けというよりマーケター / コンテンツ運用者向けだが、構造はかなり insomnia に転用しやすい。
https://x.com/shannholmberg/status/2044111115878326444 で提唱している、**エージェントより先に読ませる知識層**という枠組み。エンジニア向けというよりマーケター / コンテンツ運用者向けだが、構造はかなり yoi に転用しやすい。
### 2 層構造
@@ -128,7 +128,7 @@ MindStudio の比較記事が要点をまとめている。
### 設計上の示唆
- **可変 KBL と不変 BF の分離**が強い。insomnia なら前者が Chronicle 的な自動メモリ、後者が `AGENTS.md` / 人間のガイド。
- **可変 KBL と不変 BF の分離**が強い。yoi なら前者が Chronicle 的な自動メモリ、後者が `AGENTS.md` / 人間のガイド。
- **retrieval を埋め込みではなく決定論的 wikilink でやる**アプローチは、少量ドメインで意外と強い。
- エージェントに書かせる `log.md``index.md` の append-only 運用は、後で diff / git で検証しやすい。
@@ -163,7 +163,7 @@ Self-improving agent を名乗るフレーム。メモリ周りは **3 層 + ク
> Review the conversation above and consider saving or updating a skill if appropriate.
> Focus on: was a non-trivial approach used to complete a task that required trial and error...
> **If nothing is worth saving, just say 'Nothing to save.' and stop.**
- 末尾の "Nothing to save." 指示が肝。頻繁発火でも中身ゼロの場合は NOP で抜ける設計。insomnia extract の「空配列許容」の直接ソース
- 末尾の "Nothing to save." 指示が肝。頻繁発火でも中身ゼロの場合は NOP で抜ける設計。yoi extract の「空配列許容」の直接ソース
### 書き込み機構
@@ -180,7 +180,7 @@ Self-improving agent を名乗るフレーム。メモリ周りは **3 層 + ク
### 設計上の示唆
- **"skill" procedural memory として episodic / semantic から分離する**のは insomnia にとっても綺麗。Claude Code の skill と接続できる余地がある。
- **"skill" procedural memory として episodic / semantic から分離する**のは yoi にとっても綺麗。Claude Code の skill と接続できる余地がある。
- **FTS5 + LLM 要約ハイブリッド**で、ベクタを入れずにそこそこ回せる事例として参考価値が高い(少量ドメインなら LLM Wiki 論と同じ示唆)。
- **Honcho 的 user model** を semantic profile として固定注入する運用は、Codex の memory summary と形式的に同じ。
@@ -228,7 +228,7 @@ Self-improving agent を名乗るフレーム。メモリ周りは **3 層 + ク
### OpenClaw
Peter Steinberger が 2025-11 に出したメッセージングファースト agent。2026-02 に本人は OpenAI 入社、プロジェクトは foundation へ移譲。Hermes Agent の `hermes claw migrate` はここからの移行導線。設計は **Markdown ファイルのみに全状態を持つ**という極端な透明性志向で、insomnia の「ファイル + git」方針との親和性が最も高い。
Peter Steinberger が 2025-11 に出したメッセージングファースト agent。2026-02 に本人は OpenAI 入社、プロジェクトは foundation へ移譲。Hermes Agent の `hermes claw migrate` はここからの移行導線。設計は **Markdown ファイルのみに全状態を持つ**という極端な透明性志向で、yoi の「ファイル + git」方針との親和性が最も高い。
Agent Workspace`~/.openclaw/workspace/`)構成:
@@ -263,7 +263,7 @@ Agent Workspace`~/.openclaw/workspace/`)構成:
- **Lock**: `memory/.dreams/short-term-promotion.lock` を `wx` フラグで exclusive create、60s stale 検出 + 10s wait timeout、in-process の Map も併用
- **モデルが "覚えている" のはディスクに書かれた内容だけ**、という明示ポリシー。隠れた state 無し
**insomnia にとって重要**: consolidation を LLM 依存から切り離せる見本。narrative は subagent が生成するが、promotion の判断は純機械(scoring)。insomnia の plan では Scope 外(consolidation は当面 agent 委任)だが、成熟したカテゴリから決定論的 promotion に差し替える upgrade path の参考になる。
**yoi にとって重要**: consolidation を LLM 依存から切り離せる見本。narrative は subagent が生成するが、promotion の判断は純機械(scoring)。yoi の plan では Scope 外(consolidation は当面 agent 委任)だが、成熟したカテゴリから決定論的 promotion に差し替える upgrade path の参考になる。
**GC 観点の追加詳細**`extensions/memory-core/src/short-term-promotion.ts:1518-1652` 実装より):
@@ -278,7 +278,7 @@ OpenClaw は「**削除は人間、script は append と退避まで**」とい
設計上の示唆:
- Workspace = git リポジトリ 1 本で完結、配置もフラット。insomnia の pod workspace 概念にそのまま借用できる。
- Workspace = git リポジトリ 1 本で完結、配置もフラット。yoi の pod workspace 概念にそのまま借用できる。
- 秘密は workspace **外**の `~/.openclaw/` 側(auth / credentials / session transcripts / managed skills)に退避する分離設計は、pod sandbox 境界を越えない運用の手本になる。
- `memory/YYYY-MM-DD.md` の日次切り分け + 「当日+前日のみ load」は、時系列の自然減衰を Markdown で素直に表現できる良い pattern。
@@ -298,7 +298,7 @@ OpenClaw は「**削除は人間、script は append と退避まで**」とい
## 5. Agent Skills 標準(procedural memory の実装単位)
Hermes / OpenClaw / Claude Code / OpenAI Codex / Cursor / GitHub Copilot 等が揃って採用している **`agentskills.io` オープン標準**。Anthropic が 2025-12 に発表し、2026-03 時点で事実上の共通フォーマットになっている。memory 設計の「手続き的記憶 (procedural memory)」のほぼ全てがこの単位で流通するので、insomnia でも独自フォーマットを避けて素直にこれに乗るのが合理的。
Hermes / OpenClaw / Claude Code / OpenAI Codex / Cursor / GitHub Copilot 等が揃って採用している **`agentskills.io` オープン標準**。Anthropic が 2025-12 に発表し、2026-03 時点で事実上の共通フォーマットになっている。memory 設計の「手続き的記憶 (procedural memory)」のほぼ全てがこの単位で流通するので、yoi でも独自フォーマットを避けて素直にこれに乗るのが合理的。
### SKILL.md の最小仕様
@@ -365,7 +365,7 @@ enterprise (managed) > personal (~/.claude/skills/) > project (.claude/skills/)
Skill content のライフサイクルは重要で、**一度発動すると rendered 内容が会話に単一メッセージとして入り、以後再読み込みされない**。auto-compaction 時は各 skill の直近 invocation だけが冒頭 5,000 tokens 維持され、全 skill 合算 25,000 tokens の予算内で新しい順に残す。つまり「skill の本体は session 中ずっと context に居座る」前提で書く必要がある。
### insomnia への示唆
### yoi への示唆
- **procedural memory は SKILL.md で表現**する。`.claude/skills/` に人間手入れの skill を置き、エージェントが自動生成する手続きは別ディレクトリ(例: `memory/skills/`)で分離、混ざらないようにする。BF/KBL 分離の原則に一致。
- **`paths:` によるスコープ絞り**は、前回議論した「Pod の所属スコープ = ディレクトリ階層」と自然に噛む。`paths: ["crates/protocol/**"]` の skill は protocol スコープの pod でだけ発動、という運用が素直にできる。
@@ -382,7 +382,7 @@ Skill content のライフサイクルは重要で、**一度発動すると ren
## 6. プロンプト・スキルの継続的チューニング (empirical prompt tuning pattern)
メモリや skill の**中身を腐らせない**側の話。公開されている prompt tuning pattern として、agent-facing な指示を新規 subagent に実行させ、実行者の自己申告と指示側メトリクスを突き合わせて反復改善する方法がある。insomnia のように skill を蓄積する設計では、**書いた直後に客観的に試す**仕組みが無いと品質が崩れていく。ここへの素直な当てはめ材料として記録。
メモリや skill の**中身を腐らせない**側の話。公開されている prompt tuning pattern として、agent-facing な指示を新規 subagent に実行させ、実行者の自己申告と指示側メトリクスを突き合わせて反復改善する方法がある。yoi のように skill を蓄積する設計では、**書いた直後に客観的に試す**仕組みが無いと品質が崩れていく。ここへの素直な当てはめ材料として記録。
### 基本思想
@@ -425,12 +425,12 @@ Claude Code の Task tool 戻り値から:
> 毎回**新規** AI を dispatch すること。同じセッション再利用は前回の指摘を学習してしまい、指標が腐る。
### insomnia への示唆
### yoi への示唆
- **skill や lessons を新規追加した直後に、同じ insomnia ハーネス内の別 pod で実行して評価**する自動フロー("skill doctor" 的な存在)を作れる。これは insomnia が pod factory を持っている点と相性がいい。
- **skill や lessons を新規追加した直後に、同じ yoi ハーネス内の別 pod で実行して評価**する自動フロー("skill doctor" 的な存在)を作れる。これは yoi が pod factory を持っている点と相性がいい。
- 失敗ログを書いた後、「同じ失敗が再現しないか」を新規 pod で試走する検証ステップが、構造的に**メモリ整備の一部**に組み込める。skill 化しない失敗ログでも有効。
- 評価指標を自前で定義しておくと、後で他人(or 未来の自分)が skill を更新した時に腐敗検知できる。
- 実体は skill 自身として配布されている例がある。insomnia のメンテ用 skill セットのテンプレにも応用できる。
- 実体は skill 自身として配布されている例がある。yoi のメンテ用 skill セットのテンプレにも応用できる。
一次ソースは公開 sanitize branch では省略する。
@@ -450,19 +450,19 @@ Claude Code の Task tool 戻り値から:
| ユーザー編集性 | 不可視 / 読取のみ / 手編集前提 |
| スコープ | per-user / per-project / shared across agents |
insomnia で意思決定すべきポイントはこの対応表:
yoi で意思決定すべきポイントはこの対応表:
- **Pod / Agent の「skill」概念を Hermes 風に明示すべきか**。現状の controller.rs には "sub-agent spawn" はあるが、skill を書き出して再利用する仕組みは無い。
- **Codex Chronicle 風の "consolidation モデルを別途設定" 構成**は、insomnia の llm provider policyOllama / Codex OAuth / Anthropic)と相性が良い。軽量 extract と重い consolidation を別プロバイダに張れる。
- **Codex Chronicle 風の "consolidation モデルを別途設定" 構成**は、yoi の llm provider policyOllama / Codex OAuth / Anthropic)と相性が良い。軽量 extract と重い consolidation を別プロバイダに張れる。
- **LLM Wiki パターンを採用する場合**、既に `docs/` と `tickets/` が Markdown + git で運用されているので、`memory/` ディレクトリを足して Git で可観測にしておくのが自然。RAG やベクトル化より先に、wikilink / index.md / log.md で足りるか見極めるべき。
- **storage 層**: SQLite は既存 crate 構成にもフィット。Cloudflare Agent Memory / Codex の SQLite + 最終 Markdown の 2 段は移植しやすい。
- **prompt injection 対策**: Chronicle が注意書きしている通り、観測チャンネルを増やすと攻撃面が広がる。insomnia では pod の sandbox 境界とメモリ生成を同じ境界で括る必要がある。
- **prompt injection 対策**: Chronicle が注意書きしている通り、観測チャンネルを増やすと攻撃面が広がる。yoi では pod の sandbox 境界とメモリ生成を同じ境界で括る必要がある。
---
## 8. GC 機構の横断比較
`docs/plan/memory.md` §GC は「consolidation とは別経路で memory を再評価し、drop / merge / split / `replaced` chain 整理を行う」ことを決めた段階で、判断主体と処理種別の仕様をこれから詰める。本節は他プロジェクトの GC 設計を共通の 6 軸で並べて、insomnia で採るべき型の材料とする。
`docs/plan/memory.md` §GC は「consolidation とは別経路で memory を再評価し、drop / merge / split / `replaced` chain 整理を行う」ことを決めた段階で、判断主体と処理種別の仕様をこれから詰める。本節は他プロジェクトの GC 設計を共通の 6 軸で並べて、yoi で採るべき型の材料とする。
### 8.1 比較表
@@ -499,7 +499,7 @@ insomnia で意思決定すべきポイントはこの対応表:
3. **cron / scheduled sweep**OpenClaw dreaming default `0 3 * * *`, Codex extension retention: 定期的・予測可能。人間 review との組み合わせがしやすい。
4. **ingest 時の即時**Cloudflare supersession: 書き込みの tx 内で完結、後続 GC 走査が要らない。topic key 設計が前提。
insomnia の plan は (2) consolidation で rewrite 許可を置きつつ、GC は (3) 方向で別経路という構造。これは Codex / OpenClaw の両方と整合する。
yoi の plan は (2) consolidation で rewrite 許可を置きつつ、GC は (3) 方向で別経路という構造。これは Codex / OpenClaw の両方と整合する。
**判断主体の 3 系統**:
@@ -507,13 +507,13 @@ insomnia の plan は (2) consolidation で rewrite 許可を置きつつ、GC
- **決定論 scoring → 閾値 gate → 機械適用**: OpenClaw Deep promotion。LLM の揺れを除き、コストも LLM コールゼロ。ただし対象が append 側のみで、削除には使われていない。
- **LLM agentic**: Codex consolidation / Hermes review / Letta sleep-time。判断の柔軟性(block 内部分削除、context 依存の merge)を LLM に委ねる。
`docs/plan/memory.md` は consolidation が LLM agentic、GC も暫定的に **LLM agentic + Linter Warn 併用**としている。完全に一致する事例は **Codex consolidation の consolidation prompt**836 行)で、「removed thread id を `MEMORY.md` から部分削除し、blockに他の thread が残っている場合は split / rewrite して保持」という手続きを自然言語で指示している。**insomnia は Linter 側に警告カテゴリ(類似 slug / `replaced` 滞留 / sources 過多 / stale)を先に定義し、GC 実行の agent プロンプトはそれを入力にする**構造が素直。
`docs/plan/memory.md` は consolidation が LLM agentic、GC も暫定的に **LLM agentic + Linter Warn 併用**としている。完全に一致する事例は **Codex consolidation の consolidation prompt**836 行)で、「removed thread id を `MEMORY.md` から部分削除し、blockに他の thread が残っている場合は split / rewrite して保持」という手続きを自然言語で指示している。**yoi は Linter 側に警告カテゴリ(類似 slug / `replaced` 滞留 / sources 過多 / stale)を先に定義し、GC 実行の agent プロンプトはそれを入力にする**構造が素直。
**処理種別の選択肢**:
- `drop / merge / split / rewrite` の組み合わせは Codex consolidation が最も自由度高く、Hermes もそれに近い(entry 粒度)。
- `replaced` chain の整理は **Cloudflare だけが自動で版チェーン維持**、他は LLM 任せ。insomnia は decision record に `replaced_by` を入れているので、Cloudflare 方式の forward pointer 概念を **人間可読な `replaced_by:` frontmatter** で既に踏襲している。GC 時に chain をどこまで短く畳むか(長大な `a → b → c → d` を `a → d` に圧縮するか)は未決定論点で、Cloudflare は圧縮せず chain を保持する設計。
- **`split` は Codex だけが明示**。block 内に複数 thread id が混ざった場合に thread id 単位で分ける。insomnia の「1 件 1 ファイル」方針では split = ファイル分割となり、主題の粒度判断は GC agent に委ねる必要がある。
- `replaced` chain の整理は **Cloudflare だけが自動で版チェーン維持**、他は LLM 任せ。yoi は decision record に `replaced_by` を入れているので、Cloudflare 方式の forward pointer 概念を **人間可読な `replaced_by:` frontmatter** で既に踏襲している。GC 時に chain をどこまで短く畳むか(長大な `a → b → c → d` を `a → d` に圧縮するか)は未決定論点で、Cloudflare は圧縮せず chain を保持する設計。
- **`split` は Codex だけが明示**。block 内に複数 thread id が混ざった場合に thread id 単位で分ける。yoi の「1 件 1 ファイル」方針では split = ファイル分割となり、主題の粒度判断は GC agent に委ねる必要がある。
**人間介入点の 3 段**:
@@ -521,7 +521,7 @@ insomnia の plan は (2) consolidation で rewrite 許可を置きつつ、GC
- audit-firstissue を surface し、人間が決断): memory-wiki lint / OpenClaw dreaming-repair
- high-stake 限定 gate: LinkedIn CMA
insomnia の plan は「人間 offer 承認を併用」なので **audit-first に寄る**のが自然。lint 相当の Warn を Linter で出し、LLM consolidation / GC がそれを消費する前に人間が承認 / 拒否できる UI を提供する構造。memory-wiki lint は `reports/lint.md` というシンプルな Markdown 出力なので、そのまま `memory/reports/gc-lint.md` 相当を tick off する実装が参考になる。
yoi の plan は「人間 offer 承認を併用」なので **audit-first に寄る**のが自然。lint 相当の Warn を Linter で出し、LLM consolidation / GC がそれを消費する前に人間が承認 / 拒否できる UI を提供する構造。memory-wiki lint は `reports/lint.md` というシンプルな Markdown 出力なので、そのまま `memory/reports/gc-lint.md` 相当を tick off する実装が参考になる。
**履歴保持の 3 モデル**:
@@ -529,14 +529,14 @@ insomnia の plan は「人間 offer 承認を併用」なので **audit-first
2. **archive 退避(rename**: OpenClaw dreaming-repair
3. **forward pointer / tombstone**: Cloudflare supersession
insomnia は **git 管理下に memory を置く**前提なので、物理削除を選んでも git log で復元できるのが強み。`replaced_by:` frontmatter が forward pointer の役割を果たしているので、Cloudflare 型と git を足した「**現物は物理削除、frontmatter pointer で chain を参照、git で history**」が最も設計コストに合う。archive 退避は git を前提にすると冗長。
yoi は **git 管理下に memory を置く**前提なので、物理削除を選んでも git log で復元できるのが強み。`replaced_by:` frontmatter が forward pointer の役割を果たしているので、Cloudflare 型と git を足した「**現物は物理削除、frontmatter pointer で chain を参照、git で history**」が最も設計コストに合う。archive 退避は git を前提にすると冗長。
### 8.3 insomnia の GC 仕様を詰めるときの示唆
### 8.3 yoi の GC 仕様を詰めるときの示唆
1. **GC trigger は 2 系統に割る**。(a) 決定論: Linter Warn 群 + age / count / size 閾値の sweep、(b) LLM 判定: consolidation とは別 prompt で Linter の issue リストを入力に渡す。両方が `memory/reports/gc-*.md` 相当を書き、それを次回の GC run が読む、というフィードバックループが OpenClaw lint / Codex consolidation input selection の両方と整合する。
2. **Linter に「GC 候補検出」カテゴリを足す**。memory-wiki の lint issue code が参考になる: `stale-page`90d 超)/ `stale-claim` / `low-confidence` / `orphan` / `duplicate-id` / `broken-wikilink` / `contradiction-present` / `open-question`。insomnia 固有の追加候補: `similar-slug`(類似 slug 乱立、既に plan に記載)/ `replaced-chain-long``replaced_by` が 3 段以上)/ `sources-overflow`1 record の sources が閾値超)/ `knowledge-invoke-frequency-low``user_invoke` が一定期間ゼロ)。
3. **処理は rewrite 優先、削除は `status: replaced` 経由**(既に plan 方針と一致)。forward pointer は Cloudflare 流、ただし chain 圧縮ルール(例: 「chain が n 段超えたら中間を drop、端のみ残す」)を決めるかは別論点。Cloudflare は圧縮しない、insomnia は git があるので圧縮してよい。
4. **char limit は採用しない方が筋が良い**。Hermes の hard limit + LLM self-rewrite は設計最小だが、insomnia は 1 record 1 file なのでファイル内 size 制約は薄く、file 数による grep コストの方が支配的になる。file 数閾値 → GC trigger の方が insomnia の形に合う。
2. **Linter に「GC 候補検出」カテゴリを足す**。memory-wiki の lint issue code が参考になる: `stale-page`90d 超)/ `stale-claim` / `low-confidence` / `orphan` / `duplicate-id` / `broken-wikilink` / `contradiction-present` / `open-question`。yoi 固有の追加候補: `similar-slug`(類似 slug 乱立、既に plan に記載)/ `replaced-chain-long``replaced_by` が 3 段以上)/ `sources-overflow`1 record の sources が閾値超)/ `knowledge-invoke-frequency-low``user_invoke` が一定期間ゼロ)。
3. **処理は rewrite 優先、削除は `status: replaced` 経由**(既に plan 方針と一致)。forward pointer は Cloudflare 流、ただし chain 圧縮ルール(例: 「chain が n 段超えたら中間を drop、端のみ残す」)を決めるかは別論点。Cloudflare は圧縮しない、yoi は git があるので圧縮してよい。
4. **char limit は採用しない方が筋が良い**。Hermes の hard limit + LLM self-rewrite は設計最小だが、yoi は 1 record 1 file なのでファイル内 size 制約は薄く、file 数による grep コストの方が支配的になる。file 数閾値 → GC trigger の方が yoi の形に合う。
5. **決定論 scoring を後から差し込む余地を残す**。OpenClaw Deep pass のような「頻度 / 関連度 / 多様性 / 時間減衰 / 整合性 / 概念」の 6 重み + 閾値は、agent LLM の出力が運用で評価可能になった段階で部分的に差し替える upgrade path として最適。初期は consolidation LLM + Linter Warn で十分。
6. **削除は git commit 単位で可逆**という前提を明示する。プロジェクトメモリは git 管理下なので、GC が誤って drop してもユーザーは revert できる。これは Codex が持っていない利点で、GC agent の判断を多少攻めても安全マージンがある。
+1 -1
View File
@@ -85,7 +85,7 @@ reasoning トークンは各ターンの後に破棄される。次ターンに
1. `previous_response_id` パラメータで過去のレスポンスを参照
2. `response.output` の全アイテムを次の `input` に手動で渡す
ステートレス利用(`store=false`、ZDR組織)の場合は `include=["reasoning.encrypted_content"]` を指定すれば暗号化された推論コンテンツを受け取り、次リクエストに渡すことで推論を引き継げる。Insomnia は履歴から復元した reasoning item を通常の API message として扱い、独自の turn-boundary filtering はしない。
ステートレス利用(`store=false`、ZDR組織)の場合は `include=["reasoning.encrypted_content"]` を指定すれば暗号化された推論コンテンツを受け取り、次リクエストに渡すことで推論を引き継げる。Yoi は履歴から復元した reasoning item を通常の API message として扱い、独自の turn-boundary filtering はしない。
同一ターン内の function-call loop でも、`reasoning item → function_call → function_call_output → 次の Responses request` の連続性を保つため、履歴上の reasoning item は通常の API message として保持する。ToolResult は wire 上で user 側 item に見えるが、reasoning item の削除境界としては扱わない。
+25 -25
View File
@@ -1,18 +1,18 @@
# Insomnia × OpenCode 比較レポート
# Yoi × OpenCode 比較レポート
## 概要
Insomnia(Rust製エージェントプラットフォーム、基礎実装段階)と OpenCodeTypeScript/Bun製AIコーディングアシスタント、本番稼働レベル)の設計を比較し、Insomniaの基礎設計に取り込めるパターンを特定する。
Yoi(Rust製エージェントプラットフォーム、基礎実装段階)と OpenCodeTypeScript/Bun製AIコーディングアシスタント、本番稼働レベル)の設計を比較し、Yoiの基礎設計に取り込めるパターンを特定する。
---
## 1. アーキテクチャ概観
### Insomnia(現状)
### Yoi(現状)
```
insomnia (stub)
└─ insomnia-core Pod / Controller / Protocol / SocketServer
yoi (stub)
└─ yoi-core Pod / Controller / Protocol / SocketServer
└─ llm-worker-persistence Session永続化(JSONL + Blob
└─ llm-worker Worker / Tool / Hook / Subscriber
└─ llm-worker-macros #[tool] / #[tool_registry]
@@ -41,13 +41,13 @@ packages/desktop (Tauri) Web UIラッパー
## 2. 設計判断の比較
| 観点 | Insomnia | OpenCode | 評価 |
| 観点 | Yoi | OpenCode | 評価 |
|------|----------|----------|------|
| **DI** | ジェネリクス `<C: LlmClient, St: Store>` | Effect Service + Layer | Insomnia: コンパイル時保証。OpenCode: 実行時合成の柔軟性。方向性は正しい |
| **状態管理** | `RwLock<PodStatus>` + ファイル書き出し | SQLite + Event Bus + SSE | Insomnia: 軽量で正しい。DBは将来の選択肢 |
| **プロトコル** | 自前 JSONL (Method/Event) | Hono HTTP API + SSE | Insomnia: Unix Socketに最適化。目的が違う |
| **DI** | ジェネリクス `<C: LlmClient, St: Store>` | Effect Service + Layer | Yoi: コンパイル時保証。OpenCode: 実行時合成の柔軟性。方向性は正しい |
| **状態管理** | `RwLock<PodStatus>` + ファイル書き出し | SQLite + Event Bus + SSE | Yoi: 軽量で正しい。DBは将来の選択肢 |
| **プロトコル** | 自前 JSONL (Method/Event) | Hono HTTP API + SSE | Yoi: Unix Socketに最適化。目的が違う |
| **ツール** | `Tool` trait + マクロ生成 | Zod schema + execute関数 | 同等のアプローチ。マクロの方が型安全 |
| **フック** | `Hook<K: HookEventKind>` trait 10種 | Plugin hooks (before/after) | Insomnia: 型安全で粒度が細かい。OpenCode: 動的で拡張しやすい |
| **フック** | `Hook<K: HookEventKind>` trait 10種 | Plugin hooks (before/after) | Yoi: 型安全で粒度が細かい。OpenCode: 動的で拡張しやすい |
| **永続化** | JSONL append-only + Blob | SQLite + Drizzle ORM | 方向性が異なる。両方とも正当な選択 |
| **プロバイダ** | 4種(Anthropic/OpenAI/Gemini/Ollama | 20種+ai-sdk経由) | 数は後から追加できる。抽象は同レベル |
@@ -62,9 +62,9 @@ packages/desktop (Tauri) Web UIラッパー
- 3段階: `deny``allow``ask`(ユーザーに確認)
- 「always」応答でパターンを永続的に許可
**Insomniaへの示唆:**
**Yoiへの示唆:**
Insomniaには `Scope`(書き込みディレクトリ制約)があるが、これは静的な境界。
Yoiには `Scope`(書き込みディレクトリ制約)があるが、これは静的な境界。
ツール単位の動的パーミッションが欠落している。
```
@@ -101,12 +101,12 @@ action = "deny"
- 切り捨て分はファイルに保存(7日間保持)
- LLMには「出力が大きすぎた。`grep``read` で絞り込め」とヒント
**Insomniaの現状:**
**Yoiの現状:**
- `llm-worker` に Tool Output の Inline/Stored 閾値(800 bytes)がある
- Stored 出力は Blob Storage に退避し、要約を自動生成
**比較:**
Insomnia の方が洗練されている(要約生成まで組み込み済み)。
Yoi の方が洗練されている(要約生成まで組み込み済み)。
ただし OpenCode の「ヒント付きトランケーション」は追加の視点として有用。
**取り込み案:**
@@ -124,11 +124,11 @@ Insomnia の方が洗練されている(要約生成まで組み込み済み
- 構造化要約: Goal / Instructions / Discoveries / Accomplished / Files
3. **Replay**: 圧縮後に前回のユーザーメッセージを再送して作業継続
**Insomniaの現状:**
**Yoiの現状:**
- Worker は history をそのまま保持
- コンテキスト管理の仕組みは未実装
**これは重要な欠落。** 長時間実行エージェントである Insomnia にとって、コンテキスト管理はコア機能。
**これは重要な欠落。** 長時間実行エージェントである Yoi にとって、コンテキスト管理はコア機能。
**取り込み案:**
@@ -157,13 +157,13 @@ consolidation: CompactAgent ベース)
- Instance スコープ + Global スコープの二段バス
- `publish` / `subscribe` / `subscribeAll` の3操作
**Insomniaの現状:**
**Yoiの現状:**
- `broadcast::Sender<Event>` による単一チャネル
- Event enum で型安全
- Pod 単位のスコープのみ
**比較:**
Insomnia の broadcast channel は Pod 単位では十分。
Yoi の broadcast channel は Pod 単位では十分。
ただし、**複数 Pod の協調**Supervisor)段階で Global Bus が必要になる。
**取り込み案:**
@@ -180,7 +180,7 @@ Insomnia の broadcast channel は Pod 単位では十分。
- ツール実行前にスナップショット取得
- `restore` / `revert` / `diff` 操作
**Insomniaの現状:**
**Yoiの現状:**
- Scope(書き込み制約)はあるが、変更追跡・復元は未実装
**取り込み案:**
@@ -200,13 +200,13 @@ Insomnia の broadcast channel は Pod 単位では十分。
- `steps` パラメータでサブエージェントの反復回数を制限
- 親セッションのコンテキストを子に渡す
**Insomniaの現状:**
**Yoiの現状:**
- Pod は独立実行単位。Pod 間通信は未実装
- 拡張ポイント表に「Supervisor」として記載
**比較:**
OpenCode の Agent は Session 内のモード切り替え。
Insomnia の Pod は完全に独立したプロセス。
Yoi の Pod は完全に独立したプロセス。
**取り込み案:**
- OpenCode の `steps`(最大反復回数)は Pod マニフェストに追加する価値あり
@@ -225,7 +225,7 @@ Insomnia の Pod は完全に独立したプロセス。
- 配列フィールドはマージ(上書きではなく結合)
- Plugin の出自を追跡(PluginOrigin
**Insomniaの現状:**
**Yoiの現状:**
- マニフェスト(TOML)のみ。階層なし
**取り込み案:**
@@ -244,7 +244,7 @@ Insomnia の Pod は完全に独立したプロセス。
- 遅延初期化(必要時にのみ起動)
- graceful degradation(サーバーなし → 無視)
**Insomniaの現状:**
**Yoiの現状:**
- LSP の言及なし
**取り込み案:**
@@ -256,7 +256,7 @@ Insomnia の Pod は完全に独立したプロセス。
## 4. 設計思想の根本的な違い
### Insomnia: 「Pod は独立した実行単位」
### Yoi: 「Pod は独立した実行単位」
- 各 Pod が完結したプロセス
- 協調は外部(Supervisor)が行う
@@ -269,7 +269,7 @@ Insomnia の Pod は完全に独立したプロセス。
- アプリケーションの哲学に近い
**この違いは意図的であり、変える必要はない。**
Insomnia のアプローチは長時間自律実行に適しており、Pod の独立性がフォールトトレランスと拡張性の基盤になる。
Yoi のアプローチは長時間自律実行に適しており、Pod の独立性がフォールトトレランスと拡張性の基盤になる。
---
+1 -1
View File
@@ -16,7 +16,7 @@ Retrieved: 2026-04-28
**必須 (required)**。
`POST /v1/messages` のボディパラメータとして必須指定。
insomnia の現在の実装(`max_tokens: u32`、未指定時 4096 にフォールバック)は仕様と合致している。
yoi の現在の実装(`max_tokens: u32`、未指定時 4096 にフォールバック)は仕様と合致している。
## 3. 型・範囲
+1 -1
View File
@@ -211,7 +211,7 @@ Worker<C, Mutable> Worker<C, Locked>
- **需要がある層か**: yes。rig / swiftide / genai は揃って "もう一段下のキャッシュ整合性プリミティブ" を持っていない
- **既存と被るか**: 上記 3 案でかわせる
- **維持コスト**: API 安定化 + provider 追従が恒常的に乗る。`llm_client/` を外すか genai に寄せるかでだいぶ軽くなる
- **タイミング**: insomnia 本体がリリースされ、`Worker` の API が stress test を受ける前に公開すると、後から破壊的変更を強いられる。**先に insomnia をリリースして、production 使用例として参照させてからライブラリ化する**方が安全
- **タイミング**: yoi 本体がリリースされ、`Worker` の API が stress test を受ける前に公開すると、後から破壊的変更を強いられる。**先に yoi をリリースして、production 使用例として参照させてからライブラリ化する**方が安全
---
@@ -48,7 +48,7 @@ let prompt_cache_key = Some(self.client.state.conversation_id.to_string());
シナリオ(マルチテナント等)で意図しないヒット混線を避ける用途
で使う。少なくとも害は無いので両 backend で同じ値を送って良い。
## 5. insomnia での運用
## 5. yoi での運用
- `Request::cache_key: Option<String>` を provider-agnostic な
キャッシュヒントとして持つ。`cache_anchor` (Anthropic 用 prefix
+1 -1
View File
@@ -84,7 +84,7 @@ LLMAI エージェント時代のコーディングで、Git の粒度が粗
- **永続的位置参照**: Tree-sitter ベースの semantic anchor、Sourcegraph の SCIP、`git-blame` の line tracking。DeltaDB は CRDT identity を使うため理論的にこれらより堅牢な anchor を提供できる。
- **AI エージェント協働基盤**: OpenAI の "evolving spec" 議論、Anthropic の Computer Use 系、各社の MCP。DeltaDB は「エージェント↔コード↔人間の対話」を VCS 層で受ける狙い。
## 8. 自プロジェクト(insomnia)への含意メモ
## 8. 自プロジェクト(yoi)への含意メモ
参考材料として残す(採用の可否ではない)。
+1 -1
View File
@@ -161,7 +161,7 @@ Running 中の rewind request は拒否される。Paused 中は picker を開
`Ctrl-X` は Running 中だけ Cancel、Idle / Paused では Shutdown。`Ctrl-C` は Running 中だけ Pod に `Method::Pause` を送り、それ以外では Pod は落とさず TUI プロセスだけ抜ける。`Ctrl-D` は常に Pod へ制御メソッドを送らず TUI プロセスだけ抜ける。
TUI のダイアログから Pod を起動する経路では、起動した Pod は TUI の子プロセスとして管理・終了されず、独立したプロセスとして残る。TUI 終了後は `insomnia <pod-name>` で再接続できる。
TUI のダイアログから Pod を起動する経路では、起動した Pod は TUI の子プロセスとして管理・終了されず、独立したプロセスとして残る。TUI 終了後は `yoi <pod-name>` で再接続できる。
## 履歴メモ
+1 -1
View File
@@ -2,7 +2,7 @@
gap |
task(if some)| 8 tasks - pending: 2, inprogress:1, completed:5
|-----------------------------------------------------------
status |● insomnia idle 42.1k / 200k (21%)
status |● yoi idle 42.1k / 200k (21%)
input |>
actionbar | ↑ scrolled [normal]
```