|
17 | 17 | | `odek skill list` | List all available skills | |
18 | 18 | | `odek skill view <name>` | View a skill's full content | |
19 | 19 | | `odek skill delete <name>` | Delete a skill | |
| 20 | +| `odek skill promote <name>` | Clear `NeedsReview` on a tainted auto-saved skill so it can auto-load | |
20 | 21 | | `odek skill import <uri> [flags]` | Import a skill from file:// or https:// | |
21 | 22 | || `odek skill curate` | Analyze skills for quality, staleness, trigger overlap | |
22 | 23 | || `odek skill curate --apply` | Apply all curation suggestions (merge, delete, prune) | |
23 | 24 | || `odek skill curate --interactive` | Review each suggestion one-by-one | |
24 | 25 | || `odek skill reset-skips [name]` | Reset skip list (all or specific skill) | |
25 | | -|| `odek serve [--addr :8080] [--open]` | Web UI server with WebSocket streaming, `@` resource completion, session history | |
| 26 | +| `odek audit <session-id>` | Print the prompt-injection audit log for a session (JSON) | |
| 27 | +| `odek audit --list` | List sessions with non-zero ingest counts and divergence flags | |
| 28 | +|| `odek serve [--addr :8080] [--open] [--no-sandbox]` | Web UI server. Sandbox is on by default; pass `--no-sandbox` to disable | |
26 | 29 | || `odek subagent --goal <string> [flags]` | Run a focused sub-task; outputs JSON on stdout. Spawned by `delegate_tasks` tool | |
27 | 30 | | `odek init [--global] [--force]` | Create a config file template | |
28 | 31 | | `odek mcp [--sandbox]` | Start MCP server (expose tools to Claude Code) or connect to external MCP servers (via `mcp_servers` config) | |
|
35 | 38 | | `--model <name>` | string | `deepseek-chat` | LLM model — profiles auto-set thinking/timeout (see [Providers](docs/PROVIDERS.md)). Consider using `deepseek-v4-flash` for faster/cheaper tasks. | |
36 | 39 | | `--base-url <url>` | string | `https://api.deepseek.com/v1` | OpenAI-compatible API endpoint | |
37 | 40 | | `--max-iter <n>` | int | `90` | Max think→act cycles | |
38 | | -| `--thinking <level>` | string | profile default | Reasoning depth: `enabled`/`disabled`/`low`/`medium`/`high` | |
| 41 | +| `--thinking <level>` | string | profile default | Reasoning depth: `enabled`/`disabled`/`low`/`medium`/`high`. Requires a model that supports extended thinking. | |
| 42 | +| `--thinking-budget <n>` | int | `5000` | Max thinking tokens for extended thinking (Anthropic budget_tokens). Only applied when `--thinking` is set. | |
39 | 43 | | `--sandbox` | bool | false | Execute shell commands inside Docker container | |
40 | 44 | | `--deliver` | bool | false | Deliver the agent's final response to the configured Telegram `default_chat_id`. Requires `telegram.bot_token` + `telegram.default_chat_id` in config. Use with cron for scheduled agent tasks. | |
41 | 45 | | `--interaction-mode <mode>` | string | `engaging` | Tool-call rendering: `engaging` (emoji narration) or `verbose` (raw tool output) | |
@@ -171,6 +175,14 @@ odek skill view docker-build |
171 | 175 | # Delete a skill |
172 | 176 | odek skill delete docker-build |
173 | 177 |
|
| 178 | +# Promote a tainted auto-saved skill so it can auto-load. |
| 179 | +# Skills derived from sessions that ingested untrusted content |
| 180 | +# (browser fetch, file outside CWD, MCP response, audio) are |
| 181 | +# saved with NeedsReview=true and pinned to the Lazy set. |
| 182 | +# Review the body first, then promote. |
| 183 | +odek skill view my-skill |
| 184 | +odek skill promote my-skill |
| 185 | + |
174 | 186 | # Import a skill from a file or URL |
175 | 187 | odek skill import ./skills/my-skill.md |
176 | 188 | odek skill import https://example.com/skills/deploy.md |
@@ -252,11 +264,40 @@ Use `odek skill reset-skips` to clear the skip list and re-enable suppressed sug |
252 | 264 | | Flag | Default | Description | |
253 | 265 | |------|---------|-------------| |
254 | 266 | | `--sandbox-image <img>` | `alpine:latest` | Docker image | |
255 | | -| `--sandbox-network <mode>` | `none` | Network: `none`/`bridge`/`host` | |
| 267 | +| `--sandbox-network <mode>` | `none` | Network: `none`/`bridge`. `host` rejected. | |
256 | 268 | | `--sandbox-readonly` | false | Mount working directory read-only | |
257 | 269 | | `--sandbox-memory <s>` | — | Memory limit (e.g. `512m`, `2g`) | |
258 | 270 | | `--sandbox-cpus <n>` | — | CPU limit (e.g. `0.5`, `2`) | |
259 | 271 | | `--sandbox-user <s>` | — | Run as user (`uid:gid`) | |
| 272 | +| `--no-sandbox` | — | (serve only) Disable the default-on sandbox. Prints a warning. | |
| 273 | + |
| 274 | +`odek serve` enables `--sandbox` by default. `odek run` and `odek repl` keep sandbox opt-in but print a startup warning when running unsandboxed. Set `ODEK_SUPPRESS_SANDBOX_WARNING=1` to silence the warning if you've made an informed decision. |
| 275 | + |
| 276 | +## Audit log |
| 277 | + |
| 278 | +`odek audit` reads the per-session prompt-injection audit log written under `<sessions>/audit/<id>.json`. Every time the agent ingests externally-sourced content (browser fetch, file read, MCP tool response, audio transcript) the log records: |
| 279 | + |
| 280 | +- the source (URL / path / `mcp:<server>:<tool>`) |
| 281 | +- a 16-hex SHA-256 prefix of the content |
| 282 | +- the turn it landed on |
| 283 | + |
| 284 | +After each turn, odek runs a divergence heuristic and sets `suspicious_divergence=true` when the agent ingested untrusted content **and** the tools called referenced resources (URLs, paths, dotted names) that did not appear in the user's preceding message — the footprint of a successful prompt injection. |
| 285 | + |
| 286 | +```bash |
| 287 | +odek audit --list |
| 288 | +# Session Ingests Turns Suspicious First-Ingest-Source |
| 289 | +# 20260527-a1b2c3 12 4 1 https://example.com/blog |
| 290 | +# 20260527-d4e5f6 3 2 0 /tmp/spec.md |
| 291 | +
|
| 292 | +odek audit 20260527-a1b2c3 |
| 293 | +# JSON: { "session_id": "...", "ingests": [...], "turns": [...] } |
| 294 | +
|
| 295 | +odek audit 20260527-a1b2c3 | jq '.turns[] | select(.suspicious_divergence)' |
| 296 | +``` |
| 297 | + |
| 298 | +The audit log is local-only — nothing in odek transmits it. |
| 299 | + |
| 300 | +See [SECURITY.md](SECURITY.md) for the full threat model. |
260 | 301 |
|
261 | 302 | ## Init flags |
262 | 303 |
|
|
0 commit comments