diff options
Diffstat (limited to 'doc/Design.md')
| -rw-r--r-- | doc/Design.md | 787 |
1 files changed, 787 insertions, 0 deletions
diff --git a/doc/Design.md b/doc/Design.md new file mode 100644 index 0000000..f877e3e --- /dev/null +++ b/doc/Design.md @@ -0,0 +1,787 @@ +# AI Agent Sandbox MCP Server — 設計書 + +**文書名:** `Design.md` +**版:** 0.1 Draft +**上位仕様:** `Specifications.md` +**対象:** Windows 11 x64 / C# 14 / .NET 10 LTS + +--- + +## 1. 設計方針 + +### 1.1 基本原則 + +- 仕様で定義された性質を設計が満たすことを最優先する。 +- LLMを信頼境界に置かない。決定的に検査可能なものはC#とWindows機構で検査する。 +- 外部MCP Tool surfaceを2個に固定し、内部機能を外部へ漏らさない。 +- Windows native security primitiveを薄く組み合わせ、独自Sandbox frameworkを作らない。 +- 設定から緩和するホワイトリスト方式を採用する。 +- 一時的なOS変更はtransactionとして扱い、crash recovery可能にする。 +- AI生成実装が勝手に概念・層・依存を増やさないよう、語彙とmodule boundaryを固定する。 +### 1.2 参照するIPAの記述観点 +IPA資料が示す「構造」「機能」「振る舞い」「非機能」を、本設計では Architecture / Interface / State Transition / Quality & Invariant に対応づける。Verificationは `Specifications.md` のRequirement IDと本書の設計要素をtraceすることで行う。 + +--- + +## 2. 技術スタック +| 区分 | 採用 | 理由 | +| --- | --- | --- | +| OS | Windows 11 x64 | AppContainer、NTFS ACL、Job Object、WFPを直接利用するため | +| Language | C# 14 | Windows interopとMCP/JSON/asyncの両立 | +| Runtime | NET 10 LTS | LTS運用 | +| Editor | VS Code + C# Dev Kit | 既定開発環境 | +| Build | dotnet CLI / MSBuild | 追加build systemを不要にする | +| Package | NuGet | C#標準package管理 | +| MCP | 公式 ModelContextProtocol C# SDK | stdio/Streamable HTTP実装 | +| Win32 binding | Microsoft.Windows.CsWin32 | 必要Win32 APIだけ型付き生成 | +| Ollama | HttpClient + REST API | 専用SDK依存を避ける | +| JSON | System.Text.Json | MCP周辺・locale・audit | +| YAML | 小規模YAML parser library 1つ | 主設定のみ。追加依存はこれ以上増やさない | +| IPC | System.IO.Pipes | Sandbox worker連携 | +| Logging | Microsoft.Extensions.Logging | stderr/file sinkを統一 | +| Test | xUnit | unit/integration/security test | +### 2.1 明示的非採用 +- Python +- Node.js / TypeScript +- CMake +- vcpkg +- Docker +- WSL +- ASP.NET Core application framework(MCP SDKが内部利用する部分を除く) +- Database/ORM +- 独自RPC +- 汎用Workflow engine +- 汎用Graph library +- Ollama専用SDK +- Legacy HTTP+SSE compatibility + +--- + +## 3. 論理アーキテクチャ +```text +MCP Client + │ stdio / Streamable HTTP(loopback) + ▼ +MCP Adapter ───────────── Localization + │ + ▼ +Agent Runtime ─── Session Store (memory) + ├── Prompt Composer ── Skill Selector/Loader + ├── Ollama Client ───── Ollama localhost + ├── Token Planner ───── TaskGraph / PERT / CPM + └── Internal Tool Dispatcher + │ + ▼ + Policy Engine + │ + ▼ + Sandbox Broker + ├── AppContainer + ├── NTFS ACL + ├── Job Object + ├── WFP + └── Named Pipe + │ + ▼ + Sandboxed Process Tree +Audit Writer / Recovery Manager は各副作用境界を横断して記録・復旧する。 +``` +### 3.1 信頼境界 +| 領域 | 信頼 | 備考 | +| --- | --- | --- | +| MCP Client | Untrusted | request、image、temperature、session指定を検証する | +| Ollama output | Untrusted | tool argumentもPolicy検査する | +| Skill/User Prompt | Untrusted configuration content | Fixed PromptやPolicyを上書きできない | +| Agent Runtime | Trusted | 状態管理とdeterministic guard | +| Policy Engine | Trusted | allow/deny決定 | +| Sandbox Broker | Highly Trusted | OS副作用を発生させる唯一の境界 | +| Windows Kernel Security | Trusted enforcement | ACL/AppContainer/Job/WFP | + +--- + +## 4. Project構成 +```text +src/ + Agent.App/ # Program, CLI, composition root, configuration + Agent.Mcp/ # MCP transport and two public tools + Agent.Core/ # Agent loop, session, prompt, ollama abstractions + Agent.Planner/ # TaskGraph, TokenPERT, TokenCPM + Agent.Windows/ # SandboxPolicy enforcement and Win32 interop +tests/ + Agent.Core.Tests/ + Agent.Planner.Tests/ + Agent.Windows.Tests/ +config/ + agent.yaml + locales/en.json + locales/ja.json +prompts/ + user-system.md # optional user prompt; fixed prompt is embedded +skills/ +logs/ +state/ + recovery/ # rollback journal; application-owned +``` +### 4.1 dependency方向 +```text +Agent.App -> Agent.Mcp -> Agent.Core -> Agent.Planner +Agent.App -------------------------> Agent.Windows +Agent.Core -> ISandbox/IToolExecutor interfaces +Agent.Windows implements those interfaces +``` +`Agent.Planner` と `Agent.Core` はWin32型、HANDLE、SID、WFP型を参照してはならない。 + +--- +## 5. MCP詳細設計 +### 5.1 Transport +- defaultはstdio。stdioではstdoutをMCP専用、ログをstderrへ出す。 +- Streamable HTTPは `127.0.0.1` または `::1` だけにbind可能。非loopback設定はvalidation error。 +- Streamable HTTPは1つのMCP endpointを持つ。v1はJSON responseのみ使用し、SSE streamを開始しない。 +- HTTP GETによるSSE listenerは提供せず、GETには405を返す。 +- Legacy HTTP+SSEの旧endpoint検出・fallbackを実装しない。 +- Origin headerが存在するHTTP requestはloopback originとして妥当か検査する。 +### 5.2 agent_run JSON Schema +```json +{ + "type": "object", + "properties": { + "request": { "type": "string", "minLength": 1 }, + "session_id": { "type": "string", "format": "uuid" }, + "temperature": { "type": "number", "minimum": 0.0, "maximum": 2.0 }, + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "mime_type": { "type": "string", "enum": ["image/png", "image/jpeg", "image/webp"] }, + "data_base64": { "type": "string", "minLength": 1 } + }, + "required": ["mime_type", "data_base64"], + "additionalProperties": false + } + } + }, + "required": ["request"], + "additionalProperties": false +} +``` +### 5.3 agent_run result +MCP resultはtext content 1件とする。Machine-readable structuredContentはv1では公開しない。本文はlocale templateで次を必ず含める。 +```text +task_id: <UUID> +session_id: <UUID> +status: queued +message: <localized message> +``` +### 5.4 agent_status JSON Schema +```json +{ + "type": "object", + "properties": { + "task_id": { "type": "string", "format": "uuid" }, + "session_id": { "type": "string", "format": "uuid" } + }, + "required": ["task_id"], + "additionalProperties": false +} +``` +### 5.5 agent_status result +```text +task_id: <UUID> +session_id: <UUID> +status: queued|planning|running|completed|failed|cancelled +completed_tasks: <n>/<total> +current_task: <localized summary or empty> +token_usage: input=<n> output=<n> total=<n> +critical_path_tokens: <n> +message: <localized status> +result: <final natural-language answer; completed only> +``` +`result`は選択localeで生成する。内部Tool名、policy internals、chain-of-thoughtは返さない。 +--- +## 6. Ollama統合設計 +### 6.1 APIモデル +- `HttpClient`をsingleton相当で再利用する。 +- Chat APIを会話、Vision、native tool callingに使用する。 +- `stream=false`をv1既定とし、Agent内部でも1call単位の完了responseを扱う。 +- `prompt_eval_count` と `eval_count` を毎callで取得する。 +### 6.2 Option mapping +`OllamaOptions` は既知optionをnullable typed propertyとして持つ。設定されていないpropertyはpayloadへ出さない。`extra_options` は `Dictionary<string, JsonElement>` とし、typed propertyと同名keyがある場合はconfiguration errorとする。 +代表的typed property: +```text +num_ctx, num_keep, num_predict, temperature, seed, +top_k, top_p, min_p, typical_p, tfs_z, +repeat_last_n, repeat_penalty, presence_penalty, frequency_penalty, +mirostat, mirostat_tau, mirostat_eta, stop +``` +Chat API top-levelとして `model`, `think`, `keep_alive`, `format`, `logprobs`, `top_logprobs` を別型で管理する。Ollama API変更時は既知型を更新し、未知optionは `extra_options` で一時対応できる。 +### 6.3 temperature override +```text +effective_temperature = agent_run.temperature ?? config.ollama.options.temperature +``` +overrideはTask objectにcopyし、global configurationを変更しない。Session内の次Taskへも継承しない。 +### 6.4 Vision +- `images[]`をBase64としてOllama messageへ転送する。 +- mime_type、Base64妥当性、設定上限size/countを事前検査する。 +- model capability確認でVision非対応と判定した場合はOllama呼出し前にlocalized error。能力確認不能時は呼出しを行い、Ollama errorを正規化して返す。 +### 6.5 Tool calling +Ollamaに公開するInternal Toolは次の5群に固定する。個々のOS command (`grep.exe`等) をtoolとして増殖させない。 +| Tool | 責務 | 主なoperation | +| --- | --- | --- | +| file_search | 検索 | glob / name / text / regex / tail相当 | +| file_read | 読取 | whole / range / metadata | +| file_edit | 編集 | overwrite / patch / atomic_replace / delete | +| process_run | 承認済Process実行 | exe + args + cwd + timeout | +| task_update | TaskGraph更新 | add / dependency / state / estimate | +--- +## 7. Internal Tool Schema設計 +### 7.1 file_search +```json +{"root":"string","mode":"glob|name|text|regex|tail","query":"string","max_results":100,"tail_lines":100} +``` +- `root`はread許可directory/file配下でなければdeny。 +- `tail`はtext file向け。binaryは拒否する。 +- `max_results`にhard upper boundを設け、context爆発を防ぐ。 +### 7.2 file_read +```json +{"path":"string","mode":"whole|range|metadata","start":0,"length":0} +``` +- wholeはsize上限を超えた場合range利用を要求する。 +- read前にcanonical pathとreparse pointを検査する。 +### 7.3 file_edit +```json +{ + "path":"string", + "operation":"overwrite|patch|atomic_replace|delete", + "content":"string|null", + "patch":"string|null", + "expected_sha256":"string|null" +} +``` +- overwrite/patch/atomic_replaceはwrite permissionを要求する。 +- deleteはdelete permissionを要求する。 +- `expected_sha256` 指定時はoptimistic concurrency guardとして利用する。 +### 7.4 process_run +```json +{ + "executable":"string", + "args":["string"], + "cwd":"string", + "timeout_seconds":300, + "stdin":"string|null" +} +``` +- shell command line 1本ではなくexeとargsを分離する。 +- executableはcanonical path + SHA-256 approval必須。 +- shell category disabled時はcmd/powershell/pwshを拒否する。 +- cwdはfilesystem policy内でなければならない。 +### 7.5 task_update +```json +{ + "operation":"add|add_dependency|set_state|set_estimate", + "task_id":"string|null", + "description":"string|null", + "depends_on":["string"], + "budget_class":"1K|2K|4K|8K|16K|32K|64K|128K|null", + "optimistic_tokens":0, + "most_likely_tokens":0, + "pessimistic_tokens":0, + "state":"queued|running|completed|failed|null" +} +``` +PlannerがDAG、不変条件、completed immutable、max_tasksを再検査してから適用する。 +### 7.6 ToolUseGuard +Taskには `requires_external_effect` をPlanner内部属性として持たせる。trueのTaskで、当該iteration中のtool callが0かつ完了証拠がない場合、LLMへ「未実行」を示すsystem-generated observationを追加して再試行する。同一失敗fingerprintが5回に達したらTaskをfailedにする。 +--- +## 8. Token Planner設計 +### 8.1 Task model +```text +Task + Id: UUID + Description: string + Dependencies: Set<TaskId> + State: queued|running|completed|failed + BudgetClass: TokenBudgetClass + O, M, P: long + ExpectedTokens: double + ActualInputTokens: long + ActualOutputTokens: long + ActualTotalTokens: long + RequiresExternalEffect: bool +``` +### 8.2 PERT計算 +```text +ExpectedTokens = (O + 4*M + P) / 6.0 +VarianceTokens = ((P - O) / 6.0)^2 # 診断値。v1ではscheduler判断に必須ではない +``` +validation: `0 < O <= M <= P <= BudgetClass.MaxTokens`. +### 8.3 CPM +topological sort後にforward passで各Taskの累積expected token costを計算し、最大経路をCritical Pathとする。時間のearliest/latest startという語をそのままUIへ出さず、`cumulative_token_cost`、`critical_path` と表記する。 +### 8.4 再計画 +- 未完了Taskの追加/dependency追加後にDAG validationとCPMを再計算。 +- completed Taskは変更しない。 +- 実績がPを超過しても即失敗にはせず、remaining Taskのestimate見直しをLLMへ要求できる。 +- `max_tasks=32`超過提案は拒否し、既存Taskの統合をLLMへ求める。 +- Budget Classは意味的Taskを分割する唯一の理由にしない。Taskが複数独立成果物を含む場合に分割する。 +### 8.5 Ollama usage集計 +1 Ollama callの `prompt_eval_count` をTask inputへ、`eval_count` をTask outputへ加算する。tool実行そのものにはtoken costを加算しない。context summary生成に使ったtokenはSession maintenance Taskとして別集計する。 +--- +## 9. Session・Context設計 +### 9.1 In-memory store +`ConcurrentDictionary<SessionId, AgentSession>` 相当で保持する。永続化しない。Taskは必ず1 Sessionに所属する。 +```text +AgentSession + SessionId + Conversation + TaskGraph + ExecutionResults + Summary + CreatedAt / LastAccessAt +``` +### 9.2 Context assembly +順序を次に固定する。 +1. Fixed System Prompt +2. User System Prompt +3. locale instruction +4. selected Skills +5. Sandbox capability summary +6. current TaskGraph / current Task +7. previous Summary +8. recent Conversation / Execution Result +### 9.3 Summary policy +`num_ctx`に対する利用率が設定閾値を超えたとき、古いConversation/Execution Resultを要約する。次は削除・曖昧化してはならない。 +- 利用者が明示した制約 +- 未完了Taskとdependency +- completed Taskの重要成果 +- 失敗原因と再試行回数 +- 変更済fileと検証結果 +- security denial +- 承認/Policyそのものではなく現在利用可能なcapability summary +raw chain-of-thoughtは保存・要約対象としない。 +--- +## 10. SandboxPolicy YAML設計 +### 10.1 schema概要 +```yaml +schema_version: 1 +application: + language: en +mcp: + transport: stdio + http: + host: 127.0.0.1 + port: 8080 +agent: + user_system_prompt: prompts/user-system.md + max_iterations: 128 + same_failure_limit: 5 +ollama: + endpoint: http://localhost:11434 + model: qwen3-coder + think: true + keep_alive: 5m + options: + num_ctx: 32768 + temperature: 0.4 + extra_options: {} +planner: + max_tasks: 32 +sandbox: + filesystem: + read: [] + write: [] + execute: [] + delete: [] + process: + allow_shell: true + approvals: [] + max_processes: 16 + network: + mode: deny + allow: [] + resources: + memory_mb: 4096 + process_timeout_seconds: 1800 +file_edit: + memory_backup_limit_mb: 16 +localization: + directory: config/locales + fallback: en +skills: + directory: skills +logging: + directory: logs +``` +### 10.2 Filesystem entry +各list itemはpath文字列とする。起動時に絶対canonical pathへ正規化して保持する。file/directoryは実在時に種別を記録し、未作成write targetは最も近い既存親directoryまで検査する。 +### 10.3 Process approval entry +```yaml +approvals: + - path: C:/Program Files/Git/cmd/git.exe + sha256: "<64 hex chars>" + - path: C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe + sha256: "<64 hex chars>" +``` +署名はaudit metadataとして取得可能だが、v1のallow判定はpath + SHA-256を必須条件とする。 +### 10.4 Network entry +```yaml +network: + mode: allow + allow: + - host: github.com + ports: [443] + - host: api.github.com + ports: [443] +``` +`allow` modeでもlist外はdeny。`deny`ではlistを無視して全denyする。localhostも特別扱いしない。 +--- +## 11. Windows強制設計 +### 11.1 AppContainer +- Application Profileを固定名で作成/取得する。 +- 起動時にprofile SIDを解決する。 +- Taskごとにprofileを作り直さない。 +- AppContainer外の通常user tokenに戻るbreakawayを許可しない。 +### 11.2 NTFS ACL +- Policy Engineが許可pathから必要ACEを導出する。 +- 既存DACL全体を書き換えず、アプリケーションSID向けの必要ACEだけをtransactionalに追加する。 +- 元security descriptorまたは追加ACEの逆操作情報をRecovery Journalへ記録する。 +- Task終了で追加分を除去し、元状態との整合を検査する。 +### 11.3 Job Object +- TaskごとにJob Objectを1つ作成する。 +- root sandbox processをJobへ割り当てる。descendantを同一Jobへ継承させる。 +- breakawayを許可しない。 +- process count / memory limitをJobへ設定する。 +- `KILL_ON_JOB_CLOSE`相当を利用し、application終了時にprocess treeを残さない。 +### 11.4 Process approval +Sandbox Brokerは実行直前にcanonical pathを取得し、ファイルを開いた状態でSHA-256を計算し、approvalと一致確認してから起動する。TOCTOU低減のため、検証対象と実行対象のpath解決がずれないよう実装時にWin32のfile identity確認を追加する。具体API選択は実装時に確定する。 +### 11.5 WFP方針 +WFP実装は複雑な汎用Firewallにしない。設計上の変換規則だけを固定する。 +1. `deny`ならApplication Profile/Task processに対するoutbound blockを作成する。 +2. `allow`ならdefault blockを置き、列挙hostをTask開始時にDNS解決する。 +3. 解決したIP集合とportの組にだけallow filterを作成する。 +4. Task実行中はそのIP snapshotを使用し、複雑な動的DNS追随は行わない。 +5. DNS解決失敗はdeny。 +6. Task終了でTask固有WFP filterを削除する。 +7. localhostはallow-listに明示されない限り許可しない。 +具体的なWFP layer、sublayer、filter condition、transaction APIは実装時にCodexがWindows SDKを確認して決定し、Security Integration Testで仕様を検証する。 +### 11.6 Named Pipe +Sandbox workerとのIPCが必要な場合はtask固有Named Pipeを使用し、DACLをApplication SIDとBrokerだけに限定する。TCP localhostを内部IPCに使わない。 +--- +## 12. ACL / Resource Transaction設計 +### 12.1 ACIDから借用する性質 +| 性質 | 本システムでの意味 | +| --- | --- | +| Atomicity | Task Resource適用が途中失敗した場合、適用済み変更をrollbackする。 | +| Consistency | SandboxPolicyとSecurity Invariantを満たす状態だけを実行可能状態とする。 | +| Isolation | Task固有ResourceをTask IDで識別し、他Task cleanupで誤削除しない。 | +| Durability | Task Resource自体の永続化ではなく、cleanupに必要なjournalをcrashに耐えて保持する。 | +### 12.2 状態機械 +```text +CLEAN + -> PREPARING journal create + -> APPLIED ACL/WFP/Job ready + -> RUNNING sandbox process start + -> CLEANING process stopped / task terminal + -> CLEAN all task resources removed +PREPARING/APPLIED/RUNNING/CLEANING --crash--> RECOVERY_REQUIRED +RECOVERY_REQUIRED -> CLEANING -> CLEAN +``` +### 12.3 Recovery Journal +JournalはTaskごとのJSONとし、操作を実行する**前**にundoに必要な情報をflushする。例: +```json +{ + "schema_version": 1, + "task_id": "...", + "state": "APPLIED", + "acl_changes": [{"path":"...","change_id":"..."}], + "wfp_filter_ids": [123], + "temp_paths": ["..."], + "created_at": "..." +} +``` +起動時にjournalが存在する場合、MCP transport開始前にRecovery Managerが逆順でcleanupし、全項目の不存在/復元を検査してからjournalを削除する。 +--- +## 13. File Transaction設計 +### 13.1 基本フロー +```text +canonicalize + policy check + -> read old identity/hash + -> old content snapshot (memory or temp) + -> edit temp representation + -> syntax/basic validation if available + -> atomic replace when possible + -> post-write hash/readback validation + -> commit: discard snapshot +failure -> rollback snapshot -> verify original hash +``` +### 13.2 backup threshold +`memory_backup_limit_mb`以下はメモリsnapshot、それより大きい場合はTask専用temp directoryへbackupする。16MBをdefault候補とするが、実装時benchmarkで変更可能。これは仕様上の固定値ではない。 +### 13.3 Patch +patchは適用前にtarget hashまたはcontext一致を検査する。曖昧適用を禁止し、複数候補に一致する場合は失敗としてLLMへ返す。 +--- +## 14. Localization設計 +### 14.1 Locale file +`config/locales/en.json` と `ja.json` を完全key集合として配布する。flat objectを採用する。 +```json +{ + "app.starting": "Starting agent.", + "mcp.task_queued": "Task {task} was queued.", + "sandbox.access_denied": "Access denied: {path}", + "ollama.vision_unsupported": "The selected model does not support image input." +} +``` +### 14.2 validation +- JSON parse failure: fatal。 +- baseline key集合にないunknown key: fatal。 +- missing key: 起動は継続し、runtimeでenへfallback。 +- enにもない場合はkey自体を表示する。 +- placeholder名はen baselineと一致しなければfatal。 +### 14.3 Language propagation +`LanguageContext`をrequest/sessionへ渡し、CLI/diagnostic/MCP templateだけでなくPrompt Composerのlocale instructionにも利用する。LLMに入力言語自動判定をさせない。 +--- +## 15. Logging・Audit設計 +### 15.1 Application log +- stdio時はstderr + rolling file。 +- log levelは設定可能だがCLI optionにはしない。 +- stdoutへ通常ログを出すコードはtestで禁止する。 +### 15.2 LLM log +call ID、session ID、task ID、model、request metadata、prompt、response、tool_calls、token usageを記録する。秘密情報の自動継承は禁止だが、利用者入力にsecretが含まれる可能性はあるためlog directoryはuser-only ACLにする。 +### 15.3 Audit JSONL +Auditはappend-only JSONLを採用する。1 event = 1 line。 +```json +{"ts":"...","event":"process.start","session_id":"...","task_id":"...","exe":"...","sha256":"...","args":["..."],"decision":"allow"} +{"ts":"...","event":"file.write","task_id":"...","path":"...","before_sha256":"...","after_sha256":"..."} +{"ts":"...","event":"policy.deny","task_id":"...","kind":"network","target":"example.com:443","reason":"not_allowlisted"} +``` +最低event集合: `task.start`, `task.end`, `tool.call`, `process.start`, `process.exit`, `file.write`, `file.delete`, `policy.deny`, `network.rule.apply`, `network.rule.remove`, `recovery.start`, `recovery.end`. +--- +## 16. Recovery・終了設計 +### 16.1 graceful stop +1. 新規agent_run受付停止。 +2. 実行中Taskをcancelledへ遷移予定としてマーク。 +3. Job Objectを終了しprocess tree停止。 +4. File transaction rollbackが必要なら実施。 +5. WFP filter/ACL/temp resource cleanup。 +6. journal clean確認。 +7. transport終了。 +### 16.2 client disconnect +- stdio: EOFまたはparent process消失をClient切断とみなし、所有Taskをsafe stop。 +- Streamable HTTP: 1回のHTTP response完了は切断ではない。MCP sessionの明示終了、session失効、server shutdownをsafe stop triggerとする。 +### 16.3 Ollama retry +network/temporary errorだけを最大3回retryする。validation error、Vision unsupported、invalid model等の恒久errorは即failed。backoffの具体値は実装時に小さく固定し、汎用retry frameworkを導入しない。 +--- +## 17. 状態遷移 +### 17.1 Task +```text +queued -> planning -> running -> completed + -> planning # replan +queued/planning/running -> failed +queued/planning/running -> cancelled +completed/failed/cancelled are terminal +``` +### 17.2 Session +```text +active -> closing -> closed +``` +closed Sessionは再利用しない。プロセス再起動後に以前のSession IDが指定された場合はnot found。 +--- +## 18. Validation / Verification設計 +### 18.1 起動時validation +- YAML schema_version +- MCP transport value +- HTTP hostがloopback +- locale baseline/placeholder +- Ollama endpoint URI +- Sandbox path canonicalization +- process approval path/hash format +- network host/port syntax +- resource limit range +- Fixed/User prompt file state +- Skill directory +### 18.2 deterministic verification +| 対象 | 検証 | +| --- | --- | +| TaskGraph | cycle、max_tasks、completed immutable | +| TokenPERT | O<=M<=P<=budget、式のunit test | +| TokenCPM | 既知DAGに対するcritical path unit test | +| Filesystem | allow/deny/reparse point integration test | +| Process | hash mismatch、path mismatch、shell toggle | +| Network | deny loopback、allow-list host/port | +| Recovery | 各transaction stateで強制crashして再起動cleanup | +| MCP | stdio purity、Streamable HTTP loopback、GET 405 | +| Localization | fallback、unknown key fatal、placeholder validation | +--- +## 19. Security Test Matrix +| ID | ケース | 期待 | +| --- | --- | --- | +| ST-01 | read許可file | 成功 | +| ST-02 | read未許可file | ACCESS_DENIED | +| ST-03 | write許可file | 成功 | +| ST-04 | delete権限なしdelete | 拒否 | +| ST-05 | junctionで許可外へ脱出 | 拒否 | +| ST-06 | symlink chainで許可外へ脱出 | 拒否 | +| ST-07 | 承認exe/hash一致 | 成功 | +| ST-08 | exe更新/hash不一致 | 拒否 | +| ST-09 | shell disabledでPowerShell | 拒否 | +| ST-10 | 子が未承認exe起動 | 拒否 | +| ST-11 | Job close | 全descendant終了 | +| ST-12 | network denyで127.0.0.1 | 拒否 | +| ST-13 | network allowで許可host:port | 成功 | +| ST-14 | network allowで未許可port | 拒否 | +| ST-15 | MCPからpolicy変更試行 | schema/機能上不可能 | +| ST-16 | Ollama tool arg path脱出 | Policyで拒否 | +| ST-17 | crash after ACL apply | 再起動cleanup | +| ST-18 | crash after WFP apply | 再起動cleanup | +| ST-19 | malformed locale | 起動失敗 | +| ST-20 | non-loopback HTTP bind | 起動失敗 | +--- +## 20. エラー分類 +| Category | 例 | Task結果 | Retry | +| --- | --- | --- | --- | +| validation | invalid config/schema/tool args | failed | No | +| policy_denied | path/network/exe denial | LLMへobservation。回復不能ならfailed | LLM再計画のみ | +| ollama_transient | connection reset/temporary unavailable | running維持 | 最大3 | +| ollama_permanent | model not found/vision unsupported | failed | No | +| tool_failure | process nonzero/patch mismatch | running→replan | 最大同一5 | +| resource_limit | timeout/memory/process limit | failedまたはreplan | 原則No | +| recovery_failure | ACL/WFP cleanup不能 | application fatal | No | +errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MCPにはlocalized textを返す。 +--- +## 21. 実装順序 +| Phase | 実装 | 完了条件 | +| --- | --- | --- | +| 1 | Config/Locale/MCP stdio skeleton | agent_run/statusのstubが動作 | +| 2 | Session/Ollama/Prompt | text-only会話とtoken取得 | +| 3 | Planner | TaskGraph + TokenPERT/CPM unit test | +| 4 | Internal Tool dispatcher | tool schemaとToolUseGuard | +| 5 | Filesystem/Process Sandbox | ACL/AppContainer/Job integration test | +| 6 | Resource Transaction/Recovery | 強制crash recovery test | +| 7 | WFP | deny/allow-list integration test | +| 8 | Vision/Streamable HTTP | image optional、loopback HTTP | +| 9 | Audit/Hardening | security matrix全PASS | +--- +## 22. Codex実装制約 +- 新規NuGet dependencyを勝手に追加しない。追加時は標準ライブラリで不能な理由を示す。 +- MCP Toolを `agent_run` / `agent_status` 以外に増やさない。 +- Internal ToolをOSコマンド名ごとに増やさず、定義済み5群に収める。 +- Legacy HTTP+SSE transport、WebSocket、独自transportを追加しない。 +- Streamable HTTPをnon-loopbackへbind可能にしない。 +- 認証/TLSを「便利だから」という理由でv1へ追加しない。 +- SandboxPolicyをMCP/LLMから変更できるI/Fを作らない。 +- Fixed System Promptを外部ファイルへ移動しない。 +- AppContainer profileをTaskごとに作成・削除しない。 +- WFPを汎用Firewall rule engineへ拡張しない。 +- DatabaseをSession/Journal目的で導入しない。Journalは小さなfile transactionで実装する。 +- Graph library/Workflow engineを導入しない。 +- `Utils`, `Common`, `Infrastructure`, `Manager`等の曖昧な巨大moduleを作らない。 +- 仕様語彙と異なる新名称を導入する場合はDesign.mdを先に更新する。 +- セキュリティ判定をLLM出力だけに依存させない。 +--- +## 23. 未固定の実装詳細 +次は設計方針のみを固定し、実装時にWindows SDK/APIの実状を確認して選択する。仕様変更を意味しない。 +| 項目 | 固定済み方針 | 実装時に決めること | +| --- | --- | --- | +| WFP | deny/default block + hostname resolve + IP/port allow | layer/sublayer/filter condition/API sequence | +| File backup threshold | memory超過時temp rollback | default閾値benchmark | +| Process TOCTOU | path+SHA必須 | file identity handleを用いた最適API | +| Context summary | 重要情報保持 | 要約promptとthreshold | +| Retry backoff | Ollama最大3 | 具体interval | +--- +## 24. 仕様トレーサビリティ +| Specifications.md | Design.md | 主検証 | +| --- | --- | --- | +| 5章 MCP | 5章 | AT-01〜06 | +| 6章 Ollama | 6〜7章 | Ollama integration tests | +| 7章 Agent | 7章/17章 | ToolUseGuard/loop tests | +| 8章 Planner | 8章 | AT-14〜17 | +| 9章 Session | 9章 | session/context tests | +| 11章 Sandbox | 10〜13章 | ST-01〜18 | +| 14章 i18n | 14章 | AT-18〜20 | +| 16〜17章 Audit/Recovery | 15〜16章 | recovery/audit tests | +| 18章 Security Invariant | 11〜19章 | Security Test Matrix | +--- +## 25. 参考資料 +- IPA/SEC「実務家のための形式手法 厳密な仕様記述を志すための形式手法入門 厳密な仕様記述入門」2013年。 +- Model Context Protocol Specification, Transports。stdio / Streamable HTTP、旧HTTP+SSE置換、loopback推奨等を参照。 +- Ollama API Reference, Chat / Generate。tools、images、options、think、keep_alive、prompt/eval token countを参照。 +--- +## 26. 設計変更ルール +- `Specifications.md` と矛盾する設計変更は禁止。 +- Security Invariant、MCP schema、SandboxPolicy schema、Task state transitionを変える場合は仕様書も同時更新する。 +- 実装時にWindows API制約が判明しても、仕様を暗黙緩和しない。実現不能なら明示的に設計レビューへ戻す。 +- 語彙を追加する前に既存用語で表現できないか確認する。 +--- +## 27. Configuration key索引 +| Key | 意味 | +| --- | --- | +| schema_version | 設定schema版 | +| application.language | 既定locale | +| mcp.transport | stdio/http | +| mcp.http.host | loopback address only | +| mcp.http.port | listen port | +| agent.user_system_prompt | 追加prompt path | +| agent.max_iterations | 128 default | +| agent.same_failure_limit | 5 default | +| ollama.endpoint | Ollama URL | +| ollama.model | model name | +| ollama.think | thinking option | +| ollama.keep_alive | model keep alive | +| ollama.options.* | typed runtime options | +| ollama.extra_options.* | future passthrough options | +| planner.max_tasks | 32 default | +| sandbox.filesystem.read | read allow-list | +| sandbox.filesystem.write | write allow-list | +| sandbox.filesystem.execute | execute path allow-list | +| sandbox.filesystem.delete | delete allow-list | +| sandbox.process.allow_shell | shell toggle | +| sandbox.process.approvals | path+sha256 approvals | +| sandbox.process.max_processes | Job process limit | +| sandbox.network.mode | deny/allow | +| sandbox.network.allow | host/port list | +| sandbox.resources.memory_mb | Job memory limit | +| sandbox.resources.process_timeout_seconds | process timeout | +| file_edit.memory_backup_limit_mb | memory/temp threshold | +| localization.directory | locale directory | +| localization.fallback | en | +| skills.directory | Skill directory | +| logging.directory | log directory | +## 28. 主要データ型索引 +- `AgentSession` +- `AgentTask` +- `TaskGraph` +- `TokenEstimate` +- `TokenBudgetClass` +- `OllamaOptions` +- `OllamaChatRequest` +- `OllamaChatResponse` +- `SandboxPolicy` +- `FilesystemPolicy` +- `ProcessPolicy` +- `NetworkPolicy` +- `ResourcePolicy` +- `ExecutableApproval` +- `TaskResourceJournal` +- `AuditEvent` +- `LanguageContext` +- `SkillDescriptor` +- `ToolCallRecord` +## 29. 実装レビュー用チェックリスト +- [ ] public MCP toolは2個だけか。 +- [ ] Legacy SSE endpointが生成されていないか。 +- [ ] HTTPはloopback検証されているか。 +- [ ] Fixed Promptがresource埋め込み等で変更不能か。 +- [ ] Internal Tool argumentが必ずPolicy Engineを通るか。 +- [ ] pathはcanonicalize/reparse検査後に評価しているか。 +- [ ] process hashは実行直前に再計算しているか。 +- [ ] shell有効でもFilesystem/Network policyを迂回できないか。 +- [ ] Job breakawayがないか。 +- [ ] Network allow-list外がdefault denyか。 +- [ ] WFP/ACL変更前にjournalを書いているか。 +- [ ] 起動時Recoveryがserveより前か。 +- [ ] file rollback後にhash検証しているか。 +- [ ] completed Taskを更新するpathがないか。 +- [ ] TokenPERT式がdeterministicか。 +- [ ] Ollama token countsがcallごとに集計されるか。 +- [ ] context summaryが重要情報を保持するか。 +- [ ] locale unknown keyがfatalか。 +- [ ] stdio stdoutがMCP messageだけか。 +- [ ] AuditとApplication Logが分離されているか。 |
