@kyo-so/cli 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,36 +28,31 @@ All three review tools run the same pipeline: scan for secrets, snapshot the wor
28
28
  <img src="https://raw.githubusercontent.com/hokupod/kyoso/main/docs/assets/kyoso-review-flow.en.svg" alt="Kyo-so review execution flow, from MCP/CLI request through secret scan, snapshot, ensemble review, aggregation, gates, and final decision" width="640">
29
29
  </p>
30
30
 
31
- With a single backend enabled, one agent runs as `combined_reviewer` instead of the two-role ensemble. The Mermaid sources for this diagram live in [docs/assets/](docs/assets/).
31
+ With a single backend enabled, one agent runs as `combined_reviewer` instead of the two-role ensemble (see [Single-backend mode](#single-backend-mode)). The Mermaid sources for this diagram live in [docs/assets/](docs/assets/).
32
32
 
33
33
  ## Quick Start
34
34
 
35
- No global install is required. Run Kyoso through `npx` or `bunx`.
35
+ No global install is required. Run Kyoso through `npx` or `bunx`. Running the packaged CLI requires Node.js 20 or newer.
36
36
 
37
37
  ### Integration modes
38
38
 
39
39
  | Mode | Installs | MCP | Clients |
40
40
  | ------------------- | ---------------------------------- | --: | ------------------- |
41
- | Marketplace Plugin | Skill plus local stdio MCP | Yes | Codex |
41
+ | Marketplace Plugin | Skill plus local stdio MCP | Yes | Codex / Claude Code |
42
42
  | CLI plus Skill-only | npm CLI plus Skill | No | Codex / Claude Code |
43
43
  | Manual setup | Manual MCP registration plus Skill | Yes | Codex / Claude Code |
44
44
 
45
- #### Codex Marketplace Plugin
45
+ When in doubt, pick the Marketplace Plugin: two commands install the Skill and the MCP server together. Follow the [Codex](#codex) or [Claude Code](#claude-code) steps below. To switch between modes later, see [Migration](#migration).
46
46
 
47
- ```bash
48
- codex plugin marketplace add hokupod/kyoso
49
- codex plugin list --marketplace kyoso --available --json
50
- codex plugin add kyoso@kyoso
51
- codex plugin list --marketplace kyoso --json
52
- ```
53
-
54
- You can also select Kyoso from the Codex desktop Plugins page or `/plugins`. Refresh or restart the desktop app if a newly added marketplace is not visible. Remove the Plugin with `codex plugin remove kyoso@kyoso`.
47
+ #### Marketplace Plugin
55
48
 
56
49
  The Plugin bundles the Skill and an MCP definition pinned to an exact published Kyoso CLI version; it does not bundle the CLI itself. Its first MCP start needs network access to npm. A cached package may work offline, but offline startup is not guaranteed. The manifest's `Read` capability is display metadata, not additional filesystem authorization.
57
50
 
58
- The Plugin Skill declares the bundled `kyoso` MCP server as a dependency, so explicit Kyoso reviews are directed through MCP rather than a CLI fallback. In Codex Auto mode, the first MCP invocation can still require approval because Kyoso tools do not declare annotations; choose "Allow and don't ask me again" to retain that approval.
51
+ The `kyoso setup ... --with-openrouter` output and manual setup examples are user-managed client-registration templates; they neither modify nor define the Marketplace Plugin manifest. In Stage A, that manifest remains frozen at its released CLI pin and environment contract; only Stage B promotion changes it.
52
+
53
+ The Plugin Skill declares the bundled `kyoso` MCP server as a dependency, so explicit Kyoso reviews are directed through MCP rather than a CLI fallback. If you disable the bundled Plugin MCP, treat the Plugin Skill as unavailable: re-enable it, or remove the Plugin and install CLI plus Skill-only instead. The Plugin is not a CLI-fallback mode.
59
54
 
60
- If you disable the bundled Plugin MCP, treat the Plugin Skill as unavailable: re-enable it, or remove the Plugin and install CLI plus Skill-only instead. The Plugin is not a CLI-fallback mode.
55
+ Until a future Plugin promotion, the released Marketplace Plugin does **not** forward `OPENROUTER_API_KEY`. Use the CLI/source path with a manual MCP registration for the OpenRouter project opt-in; this limitation will be replaced with the compatible Plugin version after that promotion.
61
56
 
62
57
  #### CLI plus Skill-only
63
58
 
@@ -75,21 +70,6 @@ Replace `codex` with `claude-code` for Claude Code. Dry-run remains the default.
75
70
 
76
71
  Skill-only intentionally does not declare an MCP dependency. When it reaches an `npx` or `bunx` package-runner fallback, Codex Auto mode can request a sandbox network escalation approval; installing `kyoso` on `PATH` avoids that fallback.
77
72
 
78
- #### Migration
79
-
80
- - Manual MCP to CLI plus Skill: install the CLI and Skill first, then run `codex mcp remove kyoso` or `claude mcp remove kyoso --scope local|project|user`.
81
- - CLI plus Skill to Plugin: add the Plugin, confirm it is enabled, then remove the manual MCP registration. Manually copied Skills are not removed automatically.
82
- - Plugin to CLI plus Skill: install the CLI and Skill first, then run `codex plugin remove kyoso@kyoso`.
83
- - CLI plus Skill back to manual MCP: run `kyoso setup codex --write` or `kyoso setup claude-code --write`.
84
-
85
- ### Claude Only / Codex Only
86
-
87
- Kyoso can run when only Claude or only Codex is available. Disable the missing backend in `kyoso.toml` using `examples/claude-only.toml` or `examples/codex-only.toml`.
88
-
89
- In single-agent mode, the remaining backend runs once as `combined_reviewer` and covers both implementation and architecture/security focus areas. JSON output includes `reviewMode: "single_agent"` and `agentsUsed`; Markdown output states that cross-model verification was not performed and marks disagreements as N/A.
90
-
91
- This mode does not provide independent cross-model validation and may retain self-review bias. It still provides a separate read-only review process, temporary snapshots, adversarial review prompts, secret scanning, and deterministic gates.
92
-
93
73
  ### Claude Code
94
74
 
95
75
  1. Prepare Claude authentication.
@@ -100,21 +80,32 @@ claude setup-token
100
80
 
101
81
  Set `CLAUDE_CODE_OAUTH_TOKEN` from that command, or set `ANTHROPIC_API_KEY` for direct API billing.
102
82
 
103
- 2. Register MCP and install the review skill.
83
+ 2. Install the Marketplace Plugin (recommended).
84
+
85
+ ```text
86
+ /plugin marketplace add hokupod/kyoso
87
+ /plugin install kyoso@kyoso
88
+ ```
89
+
90
+ The Plugin installs the Kyoso review Skill and a local stdio MCP server pinned to a released CLI version. When you install the Plugin, `kyoso setup claude-code` is not required.
91
+
92
+ 3. Alternatively, register MCP and install the review skill.
104
93
 
105
94
  ```bash
106
95
  npx @kyo-so/cli setup claude-code --write
107
96
  bunx @kyo-so/cli setup claude-code --write
108
97
  ```
109
98
 
110
- 3. Verify the setup.
99
+ For manual MCP registration, use `examples/claude-code-mcp.json`.
100
+
101
+ 4. Verify the setup.
111
102
 
112
103
  ```bash
113
104
  npx @kyo-so/cli doctor
114
105
  bunx @kyo-so/cli doctor
115
106
  ```
116
107
 
117
- 4. Ask for a review from Claude Code.
108
+ 5. Ask for a review from Claude Code.
118
109
 
119
110
  ```text
120
111
  Use Kyoso plan_review on this plan before implementation.
@@ -128,21 +119,32 @@ Use Kyoso plan_review on this plan before implementation.
128
119
  codex login
129
120
  ```
130
121
 
131
- 2. Register MCP and install the review skill.
122
+ 2. Install the Marketplace Plugin (recommended).
123
+
124
+ ```bash
125
+ codex plugin marketplace add hokupod/kyoso
126
+ codex plugin add kyoso@kyoso
127
+ ```
128
+
129
+ You can also select Kyoso from the Codex desktop Plugins page or `/plugins`; refresh or restart the desktop app if a newly added marketplace is not visible. Check the installation with `codex plugin list --marketplace kyoso --json`, and remove the Plugin with `codex plugin remove kyoso@kyoso`. When you install the Plugin, `kyoso setup codex` is not required.
130
+
131
+ Codex Auto mode may reject Kyoso tool calls that require approval. To pre-approve them for your account, see [Codex approval prompts](#codex-approval-prompts).
132
+
133
+ 3. Alternatively, register MCP and install the review skill.
132
134
 
133
135
  ```bash
134
136
  npx @kyo-so/cli setup codex --write
135
137
  bunx @kyo-so/cli setup codex --write
136
138
  ```
137
139
 
138
- 3. Verify the setup.
140
+ 4. Verify the setup.
139
141
 
140
142
  ```bash
141
143
  npx @kyo-so/cli doctor
142
144
  bunx @kyo-so/cli doctor
143
145
  ```
144
146
 
145
- 4. Ask for a review from Codex.
147
+ 5. Ask for a review from Codex.
146
148
 
147
149
  ```text
148
150
  Use Kyoso diff_review on the current diff. I need a second opinion before merging.
@@ -150,37 +152,9 @@ Use Kyoso diff_review on the current diff. I need a second opinion before mergin
150
152
 
151
153
  Manual setup examples are kept in `examples/codex-config.toml` and `examples/claude-code-mcp.json`.
152
154
 
153
- ## Install / Run
154
-
155
- ```bash
156
- npx @kyo-so/cli mcp
157
- bunx @kyo-so/cli mcp
158
- ```
159
-
160
- Naming note: the npm package is `@kyo-so/cli` (matching the product name Kyo-so), while the installed CLI command is the shorter `kyoso`.
161
-
162
- For local development:
163
-
164
- ```bash
165
- nix develop
166
- safe-chain bun install
167
- safe-chain bun run typecheck
168
- safe-chain bun test
169
- safe-chain bun run build
170
- safe-chain bun run pack:verify
171
- ```
172
-
173
- Requires Node.js 20 or newer when running the packaged CLI.
174
-
175
- The Nix dev shell pins Node.js 24 and the nixpkgs-provided Bun version. After reviewing `.envrc`, you can also run `direnv allow` once and let it load the shell automatically. CI remains pinned to Bun 1.3.14; the current nixpkgs Bun version may differ slightly, but `flake.lock` keeps local shells reproducible.
176
-
177
- The test suite includes credential-free MCP stdio and ACP subprocess integration coverage. `pack:verify` additionally starts the packed `dist/bin/kyoso.js` MCP server and checks the published bundle's protocol handshake.
178
-
179
- Known distribution risk: `@modelcontextprotocol/server` has no stable release yet; Kyoso currently pins a prerelease API, so MCP SDK API changes may require a follow-up release. Run manual real-agent dogfooding before releases that bump `@modelcontextprotocol/server`, `@agentclientprotocol/sdk`, or pinned ACP adapters.
180
-
181
155
  ## CLI
182
156
 
183
- `npx @kyo-so/cli` and `bunx @kyo-so/cli` are the normal execution paths. The examples below abbreviate that prefix as `kyoso`.
157
+ `npx @kyo-so/cli` and `bunx @kyo-so/cli` are the normal execution paths. The examples below abbreviate that prefix as `kyoso`. Naming note: the npm package is `@kyo-so/cli` (matching the product name Kyo-so), while the installed CLI command is the shorter `kyoso`.
184
158
 
185
159
  ```bash
186
160
  kyoso plan --goal "Review this OAuth callback plan" --plan plan.md
@@ -262,45 +236,44 @@ The Skill uses the first available path: Kyoso MCP tools, an installed `kyoso` o
262
236
 
263
237
  Managed installs record the canonical directory digest and CLI version in `.kyoso-install.json`. Exact current or known historical copies are adopted and updated automatically. A changed or unknown copy is reported as a conflict and left untouched; `--force` replaces only that Skill directory and never removes or overwrites MCP configuration.
264
238
 
265
- ## Safety Model
266
-
267
- Kyoso MVP uses a disposable temporary snapshot and policy-level write denial. It is not a full OS sandbox. Do not run Kyoso against untrusted repositories unless you understand the risk.
268
-
269
- Secret detection is best-effort. If Kyoso detects a likely secret in the request, selected files, or diff, it redacts the value and blocks before backend agents run by default.
270
-
271
- Kyoso does not store provider credentials. Child agent environment variables are allowlisted.
239
+ ## Configuration
272
240
 
273
- Repository content, plans, diffs, and selected files are treated as untrusted data in backend prompts. Kyoso wraps them in `<untrusted-content>` tags and tells agents not to follow instructions found inside. Final decisions are derived from schema-constrained findings; agents cannot write files or run commands, and the judge cannot change the deterministic decision.
241
+ ### Files and precedence
274
242
 
275
- Finding titles are normalized to concise English for aggregation; evidence, recommendations, and summaries can remain in the user's language.
276
-
277
- Audit traces use a trusted user state root rather than a workspace-controlled path. On supported POSIX runtimes, Kyoso uses an absolute `$XDG_STATE_HOME` when available, otherwise `$HOME/.local/state`, only after ownership, permission, containment, and symlink checks succeed. It never silently falls back to another location: if verification or safe open fails, Audit writing is disabled for that review and a sanitized warning is returned while the review continues.
243
+ Kyoso loads config in this order:
278
244
 
279
- Windows, and environments where the required filesystem capabilities cannot be proven, disable Audit writing fail closed. A hostile process running as the same OS user that can modify the trusted state root or rename an already verified inode is outside this guarantee; protecting against that threat requires an OS sandbox or native dirfd-based support.
245
+ - built-in defaults
246
+ - user global TOML: `$XDG_CONFIG_HOME/kyoso/config.toml`, or `~/.config/kyoso/config.toml`
247
+ - project TOML: `<cwd>/kyoso.toml`
248
+ - CLI flags such as `--network` and repeatable overrides such as `--set agents.claude.effort=high`
280
249
 
281
- ## Agent Auth
250
+ `plan`, `security`, and `diff` accept repeatable `--set <key>=<value>` overrides. Values set on the CLI take precedence over config files, including when `--ignore-config` is used.
282
251
 
283
- Codex uses the local `codex` login when available. No API key is required for the default subscription-backed path.
252
+ Unknown keys are rejected. Boolean and numeric config keys are converted to their schema types; string keys remain strings. The complete config is then validated.
284
253
 
285
- Claude supports two auth paths:
254
+ Project `kyoso.toml` is declarative and does not require trust approval. It can set safe project-scoped keys such as tool toggles, agent `enabled` / `model` / `effort` / `role` / `timeoutMs`, and the Codex-only `provider` or a model override while OpenRouter is inherited after user-global authorization, workspace byte limits and additive `workspace.deny`, verification settings, advisory judge settings, and tightening-only security/network settings.
286
255
 
287
- - `ANTHROPIC_API_KEY`: direct Anthropic API billing
288
- - `CLAUDE_CODE_OAUTH_TOKEN`: subscription auth from `claude setup-token`
256
+ Global TOML is for user-owned settings that can launch commands or forward environment variables:
289
257
 
290
- If both Claude credentials are set, Kyoso forwards only `CLAUDE_CODE_OAUTH_TOKEN` to the Claude child agent by default. Set `agents.claude.auth.preferApiKey: true` to forward only `ANTHROPIC_API_KEY`.
258
+ ```toml
259
+ [agents.codex]
260
+ command = "bunx"
261
+ args = ["@agentclientprotocol/codex-acp"]
262
+ # Authorize only this exact project directory to select `provider` or override
263
+ # a model while OpenRouter is inherited.
264
+ allowProjectProvider = ["/absolute/path/to/project"]
291
265
 
292
- Default child-agent env allowlist:
266
+ [agents.codex.env]
267
+ CODEX_CONFIG = '{"model":"gpt-5.5"}'
268
+ ```
293
269
 
294
- | Agent | Provider env |
295
- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
296
- | Codex | `CODEX_API_KEY`, `OPENAI_API_KEY`, `CODEX_HOME`, `CODEX_ACCESS_TOKEN` |
297
- | Claude | `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_MODEL`, `ANTHROPIC_BASE_URL`, `CLAUDE_CONFIG_DIR`, `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, `CLAUDE_CODE_USE_FOUNDRY` |
270
+ `kyoso.config.ts` is deprecated but still supported for compatibility. It is loaded only after trust-on-first-use approval; trusted hashes are stored in `~/.kyoso/trusted-configs.json`. If both `kyoso.toml` and `kyoso.config.ts` exist, Kyoso uses TOML and ignores the TypeScript config.
298
271
 
299
- Kyoso also forwards minimal runtime env needed to launch subprocesses: `PATH`, `HOME`, `TMPDIR`, `TEMP`, `TMP`, `LANG`, `LC_ALL`, `SHELL`, `USER`, `USERNAME`, and `SystemRoot`.
272
+ ### Agents
300
273
 
301
- ## Agent Models and Effort
274
+ Agent keys: `agents.<codex|claude>.<enabled|model|effort|role|timeoutMs>`. Codex also supports `agents.codex.provider`: `"openrouter"` selects the external provider, while `"default"` resets an inherited OpenRouter selection to normal Codex behavior; Claude has no provider setting. `agents.codex.allowProjectProvider` is a global-config-only allowlist of absolute project directories: it authorizes only an exact matching project TOML to select `provider` or override `model` while OpenRouter is inherited, with no descendant or glob matching. Project config and `--set` cannot change it, and legacy boolean values are rejected. The `command`, `args`, and `env` keys are also global-config-only (see [Files and precedence](#files-and-precedence)).
302
275
 
303
- Omit `agents.<name>.model` or `agents.<name>.effort` to use each agent's own default. Codex uses the local Codex config, such as `~/.codex/config.toml`; Claude uses the adapter default.
276
+ Omit `agents.<name>.model` or `agents.<name>.effort` to use each agent's own default. Codex uses the local Codex config, such as `~/.codex/config.toml` (or `$CODEX_HOME/config.toml` when `CODEX_HOME` is set); Claude uses the adapter default.
304
277
 
305
278
  For available model names, see the [Claude models overview](https://platform.claude.com/docs/en/about-claude/models/overview) and the [Codex models list](https://developers.openai.com/codex/models).
306
279
 
@@ -321,53 +294,99 @@ Kyoso maps model pins to adapter-supported configuration:
321
294
 
322
295
  Effort works differently: Kyoso does not set an env var for it. Instead, it sends an ACP `session/set_config_option` request to the backend agent once per session, before the first prompt: `configId: "effort"` for Claude, `configId: "reasoning_effort"` for Codex. Valid values depend on the backend agent version and the selected model (for example, Claude only exposes effort levels for models that support them). Kyoso does not validate `effort` values itself; if the backend agent rejects the request or does not support it, Kyoso logs it to stderr and continues the review.
323
296
 
324
- ## Audit
297
+ ### Codex OpenRouter project opt-in
325
298
 
326
- On supported POSIX runtimes, Audit traces are written below the user state base (`$XDG_STATE_HOME` when absolute, otherwise `$HOME/.local/state`):
299
+ First authorize project-level OpenRouter routing in user global config:
327
300
 
328
- ```text
329
- <state-base>/kyoso/workspaces/<sha256(realpath(cwd))>/<logical audit.directory>/<yyyy-mm-dd>/<traceId>.jsonl
301
+ ```toml
302
+ # ~/.config/kyoso/config.toml
303
+ [agents.codex]
304
+ allowProjectProvider = ["/absolute/path/to/project"]
330
305
  ```
331
306
 
332
- `audit.directory` is a logical relative directory (default: `.kyoso/traces`), not a directory in the workspace. Existing workspace `.kyoso/traces` files are not migrated or deleted automatically.
307
+ Then opt in only in the project that needs OpenRouter:
333
308
 
334
- Raw agent output and raw file contents are disabled by default. If `audit.includeRawAgentOutput` is enabled, traces may persist sensitive review output; delete old traces according to your local retention policy. On Windows or an environment without proven safe filesystem capabilities, Audit trace writing stays disabled and the review returns a sanitized warning.
309
+ ```toml
310
+ # <project>/kyoso.toml
311
+ [agents.codex]
312
+ provider = "openrouter"
313
+ model = "openai/o4-mini"
314
+ ```
335
315
 
336
- ## Config
316
+ `model` is required and must not be blank when `provider = "openrouter"`. It is an OpenRouter model ID; Kyoso does not validate the catalog or whether that model supports tool calling, so confirm tool support with the provider.
337
317
 
338
- Kyoso loads config in this order:
318
+ `allowProjectProvider` applies to a project `provider` and to a project `model` override while OpenRouter is inherited; its list must contain the absolute canonical directory containing the resolved project configuration file, not the invocation cwd or a lexical path. A project configuration file (including trusted `kyoso.config.ts`) and an allowlist entry that resolve through symlinks to that directory match; entries resolving elsewhere, or unresolvable paths, fail closed. A user-global `provider = "openrouter"` needs no allowlist entry. An explicit CLI pair of `--set agents.codex.provider=openrouter` and `--set agents.codex.model=<model>` in the same invocation is also allowed without it; a project model cannot supply the CLI override's model. `allowProjectProvider` is not a `--set` path and legacy boolean values are rejected.
339
319
 
340
- - built-in defaults
341
- - user global TOML: `$XDG_CONFIG_HOME/kyoso/config.toml`, or `~/.config/kyoso/config.toml`
342
- - project TOML: `<cwd>/kyoso.toml`
343
- - CLI flags such as `--network` and repeatable overrides such as `--set agents.claude.effort=high`
320
+ When a user-global config selects OpenRouter, a project can explicitly opt out with `provider = "default"`. This reset needs neither a model nor authorization, clears the inherited OpenRouter model unless the same layer explicitly supplies a normal Codex model, and prevents OpenRouter key forwarding for that project.
344
321
 
345
- `plan`, `security`, and `diff` accept repeatable `--set <key>=<value>` overrides. Values set on the CLI take precedence over config files, including when `--ignore-config` is used.
322
+ Set the key in the process environment that starts the Codex or Claude client running Kyoso. A direct environment variable is the primary path; a secret manager such as 1Password is optional and is not a Kyoso dependency:
346
323
 
347
- - Agent keys: `agents.<codex|claude>.<enabled|model|effort|role|timeoutMs>`
348
- - Verification keys: `verification.<enabled|maxFindings|timeoutMs>`
349
- - Judge keys: `judge.<mode|provider|timeoutMs>`
324
+ ```bash
325
+ export OPENROUTER_API_KEY="<secret>"
326
+ ```
350
327
 
351
- Unknown keys are rejected. Boolean and numeric config keys are converted to their schema types; string keys remain strings. The complete config is then validated.
328
+ The key is never stored in `kyoso.toml`, Git-managed configuration, Audit traces, or review output. Kyoso forwards it only to the Codex child when this provider is selected, whether it comes from the Kyoso process or explicit `agents.codex.env`. When `provider` is omitted or `provider = "default"`, Kyoso deliberately withholds both sources; a non-empty explicit `agents.codex.env.OPENROUTER_API_KEY` also produces a sanitized warning that it was withheld. The same warning is emitted for a non-empty key in another child configuration, such as `agents.claude.env`, because only the selected Codex OpenRouter child can receive it. Omitting `provider` preserves the existing Codex login, `OPENAI_API_KEY`, `CODEX_API_KEY`, and `CODEX_CONFIG` behavior; removing the line returns to that behavior.
352
329
 
353
- Project `kyoso.toml` is declarative and does not require trust approval. It can set safe project-scoped keys such as tool toggles, agent `enabled` / `model` / `effort` / `role` / `timeoutMs`, workspace byte limits and additive `workspace.deny`, verification settings, advisory judge settings, and tightening-only security/network settings.
330
+ GUI clients may not inherit a shell export. Create a new manual MCP registration with `kyoso setup <client> --write --with-openrouter`, restart the client, then run `kyoso doctor` to confirm that the Kyoso process can detect the key. `kyoso setup` preserves an existing MCP entry instead of rewriting it, so existing registrations need the opt-in allowlist updated manually from [the examples](examples/codex-config.toml).
354
331
 
355
- Global TOML is for user-owned settings that can launch commands or forward environment variables:
332
+ New manual MCP registrations omit `OPENROUTER_API_KEY` by default. Add it only with `--with-openrouter` after intentionally selecting the provider; existing registrations are never rewritten. In a Claude Code registration, `${OPENROUTER_API_KEY}` must be expanded by the client; Kyoso ignores only a whole unexpanded credential placeholder — `${NAME}`, `$NAME`, or `%NAME%`, with optional surrounding whitespace — and emits a sanitized warning containing only the variable name. Values with any other text are preserved. The same rule applies to custom credential-like names ending in `_KEY`, `_TOKEN`, `_SECRET`, or `_PASSWORD`; non-credential templates are preserved.
356
333
 
357
- ```toml
358
- [agents.codex]
359
- command = "bunx"
360
- args = ["@agentclientprotocol/codex-acp"]
334
+ Prefer this user-authorized project-scoped opt-in. A global `provider = "openrouter"` is inherited by projects until a project sets `provider = "default"`; merely omitting `provider` does not unset it. The fixed OpenRouter Responses API preset is beta; custom endpoints, provider routing, fallbacks, and judge integration are not exposed. To keep the key bound to that preset, OpenRouter mode rejects a `CODEX_CONFIG` with a top-level `profile` or `profiles` field and rejects a non-object `model_providers` value before launching the child. For an object value, it replaces `model_providers` with only the fixed `kyoso-openrouter` entry and emits a sanitized warning with the discarded-entry count only; provider IDs and configuration values never appear. Apart from those rejected fields, it preserves unrelated `CODEX_CONFIG` fields outside `model`, `model_provider`, and `model_providers`, so no foreign provider configuration can select an endpoint with the key. Claude remains on its configured provider, and the judge does not use `OPENROUTER_API_KEY`.
361
335
 
362
- [agents.codex.env]
363
- CODEX_CONFIG = '{"model":"gpt-5.5"}'
336
+ After user-global authorization, a project `kyoso.toml` can select the external provider or override its inherited OpenRouter model and route review context to it. For an untrusted repository, use `--ignore-config` and pass only the needed CLI options explicitly.
337
+
338
+ The real Codex ACP/OpenRouter smoke is release-gated and never runs in tests. Only after explicit network and billing approval, export the key in the client environment and run:
339
+
340
+ ```bash
341
+ KYOSO_OPENROUTER_ACP_SMOKE=release KYOSO_OPENROUTER_MODEL=<model> safe-chain bun run smoke:openrouter:codex-acp
364
342
  ```
365
343
 
366
- `kyoso.config.ts` is deprecated but still supported for compatibility. It is loaded only after trust-on-first-use approval; trusted hashes are stored in `~/.kyoso/trusted-configs.json`. If both `kyoso.toml` and `kyoso.config.ts` exist, Kyoso uses TOML and ignores the TypeScript config.
344
+ It accepts no CLI arguments, uses the pinned Codex ACP adapter, and creates fresh empty temporary workspace, `HOME`, and `CODEX_HOME` directories so it cannot use the calling repository or cached Codex login. It returns only a fixed success or failure message without writing the key or model to config, temporary artifacts, or output.
367
345
 
368
- Default agent timeouts are Codex 120 seconds and Claude 300 seconds. MCP clients should allow at least 360 seconds for tool calls. If `verification.enabled` is true, allow at least 480 seconds because Kyoso may run an additional cross-agent verification round.
346
+ ### Agent auth
347
+
348
+ Codex uses the local `codex` login when available. No API key is required for the default subscription-backed path.
369
349
 
370
- Optional finding verification is disabled by default:
350
+ Claude supports two auth paths:
351
+
352
+ - `ANTHROPIC_API_KEY`: direct Anthropic API billing
353
+ - `CLAUDE_CODE_OAUTH_TOKEN`: subscription auth from `claude setup-token`
354
+
355
+ If both Claude credentials are set, Kyoso forwards only `CLAUDE_CODE_OAUTH_TOKEN` to the Claude child agent by default. Set `agents.claude.auth.preferApiKey: true` to forward only `ANTHROPIC_API_KEY`.
356
+
357
+ Default child-agent env allowlist:
358
+
359
+ | Agent | Provider env |
360
+ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
361
+ | Codex | `CODEX_API_KEY`, `OPENAI_API_KEY`, `CODEX_HOME`, `CODEX_ACCESS_TOKEN` |
362
+ | Claude | `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_MODEL`, `ANTHROPIC_BASE_URL`, `CLAUDE_CONFIG_DIR`, `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, `CLAUDE_CODE_USE_FOUNDRY` |
363
+
364
+ `OPENROUTER_API_KEY` is deliberately absent from the normal Codex allowlist. It is copied from the Kyoso process only for `agents.codex.provider = "openrouter"`; a missing or empty key prevents the Codex child from starting and returns a structured failed agent result, allowing another reviewer to continue in degraded mode.
365
+
366
+ To minimize credential exposure, OpenRouter mode also removes `OPENAI_API_KEY`, `CODEX_API_KEY`, and `CODEX_ACCESS_TOKEN` from the Codex child; `CODEX_HOME` remains available for local adapter state. Its local login cache can therefore still be read by the adapter, so this is defense in depth rather than credential isolation.
367
+
368
+ Kyoso also forwards minimal runtime env needed to launch subprocesses: `PATH`, `HOME`, `TMPDIR`, `TEMP`, `TMP`, `LANG`, `LC_ALL`, `SHELL`, `USER`, `USERNAME`, and `SystemRoot`.
369
+
370
+ Subscription-only setup:
371
+
372
+ - Codex: use local `codex` login
373
+ - Claude: run `claude setup-token`, then set `CLAUDE_CODE_OAUTH_TOKEN`
374
+ - Judge: set no API keys, so Kyoso uses `deterministic_fallback` (see [Judge](#judge))
375
+ - To avoid OpenAI judge calls when `OPENAI_API_KEY` is present, set `judge.provider = "none"`
376
+
377
+ Team admins should also check organization Usage credits. If credits are enabled, billing behavior beyond subscription limits is controlled outside Kyoso.
378
+
379
+ ### Single-backend mode
380
+
381
+ Kyoso can run when only Claude or only Codex is available. Disable the missing backend in `kyoso.toml` using `examples/claude-only.toml` or `examples/codex-only.toml`.
382
+
383
+ In single-agent mode, the remaining backend runs once as `combined_reviewer` and covers both implementation and architecture/security focus areas. JSON output includes `reviewMode: "single_agent"` and `agentsUsed`; Markdown output states that cross-model verification was not performed and marks disagreements as N/A.
384
+
385
+ This mode does not provide independent cross-model validation and may retain self-review bias. It still provides a separate read-only review process, temporary snapshots, adversarial review prompts, secret scanning, and deterministic gates.
386
+
387
+ ### Verification
388
+
389
+ Verification keys: `verification.<enabled|maxFindings|timeoutMs>`. Optional finding verification is disabled by default:
371
390
 
372
391
  ```toml
373
392
  [verification]
@@ -380,7 +399,9 @@ allowDemotion = false
380
399
 
381
400
  When enabled, Kyoso asks the agent that did not report each high/critical single-source finding to try to refute it. Phase 1 is annotate-only: verification can update finding confidence and notes, but it does not change severity or the final decision. `allowDemotion` is reserved for a future opt-in phase and is currently a no-op.
382
401
 
383
- Judge LLMs are optional. Set `OPENAI_API_KEY` or `CODEX_API_KEY` to use the OpenAI judge, or `ANTHROPIC_API_KEY` to use the Anthropic judge. Optional overrides:
402
+ ### Judge
403
+
404
+ Judge keys: `judge.<mode|provider|timeoutMs>`. Judge LLMs are optional. Set `OPENAI_API_KEY` or `CODEX_API_KEY` to use the OpenAI judge, or `ANTHROPIC_API_KEY` to use the Anthropic judge. Optional overrides:
384
405
 
385
406
  - `OPENAI_BASE_URL`: OpenAI-compatible API base URL
386
407
  - `KYOSO_OPENAI_JUDGE_MODEL`: OpenAI judge model, default `gpt-5.4-mini`
@@ -388,23 +409,101 @@ Judge LLMs are optional. Set `OPENAI_API_KEY` or `CODEX_API_KEY` to use the Open
388
409
 
389
410
  Judge defaults intentionally use lightweight models. For a stronger judge, set `KYOSO_ANTHROPIC_JUDGE_MODEL` to a Sonnet-class model such as `claude-sonnet-5`.
390
411
 
391
- Subscription-only setup:
412
+ ### Timeouts
392
413
 
393
- - Codex: use local `codex` login
394
- - Claude: run `claude setup-token`, then set `CLAUDE_CODE_OAUTH_TOKEN`
395
- - Judge: set no API keys, so Kyoso uses `deterministic_fallback`
396
- - To avoid OpenAI judge calls when `OPENAI_API_KEY` is present, set `judge.provider = "none"`
414
+ Default agent timeouts are Codex 120 seconds and Claude 300 seconds; the verification round defaults to 90 seconds. MCP clients should allow at least 360 seconds for tool calls. If `verification.enabled` is true, allow at least 480 seconds because Kyoso may run an additional cross-agent verification round.
397
415
 
398
- Team admins should also check organization Usage credits. If credits are enabled, billing behavior beyond subscription limits is controlled outside Kyoso.
416
+ ### Audit
417
+
418
+ On supported POSIX runtimes, Audit traces are written below the user state base (`$XDG_STATE_HOME` when absolute, otherwise `$HOME/.local/state`):
419
+
420
+ ```text
421
+ <state-base>/kyoso/workspaces/<sha256(realpath(cwd))>/<logical audit.directory>/<yyyy-mm-dd>/<traceId>.jsonl
422
+ ```
423
+
424
+ `audit.directory` is a logical relative directory (default: `.kyoso/traces`), not a directory in the workspace. Existing workspace `.kyoso/traces` files are not migrated or deleted automatically.
425
+
426
+ Raw agent output and raw file contents are disabled by default. If `audit.includeRawAgentOutput` is enabled, traces may persist sensitive review output; delete old traces according to your local retention policy. On Windows or an environment without proven safe filesystem capabilities, Audit trace writing stays disabled and the review returns a sanitized warning (see [Safety Model](#safety-model)).
427
+
428
+ ## Safety Model
429
+
430
+ Kyoso MVP uses a disposable temporary snapshot and policy-level write denial. It is not a full OS sandbox. Do not run Kyoso against untrusted repositories unless you understand the risk.
431
+
432
+ Secret detection is best-effort. If Kyoso detects a likely secret in the request, selected files, or diff, it redacts the value and blocks before backend agents run by default.
433
+
434
+ Kyoso does not store provider credentials. Child agent environment variables are allowlisted.
435
+
436
+ Repository content, plans, diffs, and selected files are treated as untrusted data in backend prompts. Kyoso wraps them in `<untrusted-content>` tags and tells agents not to follow instructions found inside. Final decisions are derived from schema-constrained findings; agents cannot write files or run commands, and the judge cannot change the deterministic decision.
437
+
438
+ Finding titles are normalized to concise English for aggregation; evidence, recommendations, and summaries can remain in the user's language.
439
+
440
+ Audit traces use a trusted user state root rather than a workspace-controlled path. On supported POSIX runtimes, Kyoso uses an absolute `$XDG_STATE_HOME` when available, otherwise `$HOME/.local/state`, only after ownership, permission, containment, and symlink checks succeed. It never silently falls back to another location: if verification or safe open fails, Audit writing is disabled for that review and a sanitized warning is returned while the review continues.
441
+
442
+ Windows, and environments where the required filesystem capabilities cannot be proven, disable Audit writing fail closed. A hostile process running as the same OS user that can modify the trusted state root or rename an already verified inode is outside this guarantee; protecting against that threat requires an OS sandbox or native dirfd-based support.
443
+
444
+ ## Migration
445
+
446
+ - Manual MCP to CLI plus Skill: install the CLI and Skill first, then run `codex mcp remove kyoso` or `claude mcp remove kyoso --scope local|project|user`.
447
+ - CLI plus Skill to Plugin: add the Plugin, confirm it is enabled, then remove the manual MCP registration. Manually copied Skills are not removed automatically.
448
+ - Plugin to CLI plus Skill: install the CLI and Skill first, then run `codex plugin remove kyoso@kyoso`.
449
+ - CLI plus Skill back to manual MCP: run `kyoso setup codex --write` or `kyoso setup claude-code --write`.
399
450
 
400
451
  ## Troubleshooting
401
452
 
402
- - MCP timeout: set client tool timeouts to at least 360 seconds, or at least 480 seconds when `verification.enabled` is true. Kyoso defaults are Codex 120 seconds, Claude 300 seconds, and verification 90 seconds.
453
+ - MCP timeout: set client tool timeouts to at least 360 seconds, or at least 480 seconds when `verification.enabled` is true. See [Timeouts](#timeouts) for the Kyoso defaults.
403
454
  - Fresh npm release: minimum-package-age protection in tools such as safe-chain may briefly block `npx @kyo-so/cli` resolution after publish.
404
455
  - Deprecated TypeScript config: untrusted `kyoso.config.ts` is skipped unless you pass `--trust-config`; prefer `kyoso.toml`.
456
+ - OpenRouter key missing: confirm a non-empty Codex `model`, an `OPENROUTER_API_KEY` forwarded to the Kyoso process, and a restarted client; run `kyoso doctor`. The released Marketplace Plugin does not forward this key until the next Plugin promotion, and existing MCP registrations are not rewritten by setup.
457
+
458
+ ### Codex approval prompts
459
+
460
+ Codex Auto mode may reject Kyoso tool calls that require approval. To pre-approve them for your account, add the following to `~/.codex/config.toml` (or `$CODEX_HOME/config.toml` when `CODEX_HOME` is set). **Only do this if you trust Kyoso and accept that selected code and review context may be sent to the configured external model providers.** The Plugin does not enable this by default.
461
+
462
+ ```toml
463
+ [plugins."kyoso@kyoso".mcp_servers.kyoso.tools.diff_review]
464
+ approval_mode = "approve"
465
+
466
+ [plugins."kyoso@kyoso".mcp_servers.kyoso.tools.plan_review]
467
+ approval_mode = "approve"
468
+
469
+ [plugins."kyoso@kyoso".mcp_servers.kyoso.tools.security_review]
470
+ approval_mode = "approve"
471
+ ```
472
+
473
+ When Kyoso is registered directly as an MCP server (`kyoso setup codex --write` or manual setup) instead of the Plugin, use the `mcp_servers.kyoso` keys without the `plugins."kyoso@kyoso".` prefix:
474
+
475
+ ```toml
476
+ [mcp_servers.kyoso.tools.diff_review]
477
+ approval_mode = "approve"
478
+
479
+ [mcp_servers.kyoso.tools.plan_review]
480
+ approval_mode = "approve"
481
+
482
+ [mcp_servers.kyoso.tools.security_review]
483
+ approval_mode = "approve"
484
+ ```
405
485
 
406
486
  ## Development
407
487
 
488
+ For local development:
489
+
490
+ ```bash
491
+ nix develop
492
+ safe-chain bun install
493
+ safe-chain bun run typecheck
494
+ safe-chain bun test
495
+ safe-chain bun run build
496
+ safe-chain bun run pack:verify
497
+ ```
498
+
499
+ The Nix dev shell pins Node.js 24 and the nixpkgs-provided Bun version. After reviewing `.envrc`, you can also run `direnv allow` once and let it load the shell automatically. CI remains pinned to Bun 1.3.14; the current nixpkgs Bun version may differ slightly, but `flake.lock` keeps local shells reproducible.
500
+
501
+ The test suite includes credential-free MCP stdio and ACP subprocess integration coverage. `pack:verify` additionally starts the packed `dist/bin/kyoso.js` MCP server and checks the published bundle's protocol handshake.
502
+
503
+ Known distribution risk: `@modelcontextprotocol/server` has no stable release yet; Kyoso currently pins a prerelease API, so MCP SDK API changes may require a follow-up release. Run manual real-agent dogfooding before releases that bump `@modelcontextprotocol/server`, `@agentclientprotocol/sdk`, or pinned ACP adapters.
504
+
505
+ Debug environment variables:
506
+
408
507
  - `KYOSO_TEST_FAKE_AGENTS=1`: test-only fake ACP agents; do not set in production.
409
508
  - `KYOSO_KEEP_TEMP=1`: keep temporary snapshots for local debugging.
410
509