返回 CodeWhale
RUNTIME_SIMPLIFICATION_DESIGN.md
根目录 / docs / RUNTIME_SIMPLIFICATION_DESIGN.md
1 # Codewhale Runtime Simplification Design
2
3 **Status:** Pre-implementation design record for the v0.9.1 cutover, kept for its
4 "Rejected alternatives" provenance. It is **not** current runtime documentation
5 and it shipped differently in two ways:
6
7 - Goal 3 below ("keeping every legacy tool name registered but hidden") was
8 reversed. The per-action file/git/run/web and `exec_shell*` names were
9 **removed**, not hidden — `crates/tui/src/tools/registry.rs:2066-2088` and
10 `:2290-2304` assert they must stay unregistered. Only `apply_patch` and the
11 `task_*` / `github_*` / `automation_*` / `rlm_*` / `checklist_*` families
12 survive as hidden aliases.
13 - The default-active policy is nine names, not ten. `update_plan` and `Web` are
14 not in `DEFAULT_ACTIVE_NATIVE_TOOLS`
15 (`crates/tui/src/core/engine/tool_catalog.rs:44-58`).
16
17 For the current contract see [`TOOL_SURFACE.md`](TOOL_SURFACE.md).
18
19 ## Goal
20
21 Make the model-facing runtime smaller, calmer, and easier for models to use by:
22
23 1. Collapsing the long tail of single-purpose file, git, run, and web tools into
24 a few canonical action-based tools.
25 2. Shrinking the system prompt to durable behavioral invariants and per-turn
26 permission deltas.
27 3. Keeping every legacy tool name registered but hidden so old transcripts,
28 saved sessions, and recorded automation replay without migration.
29
30 ## Target model-facing surface (default active)
31
32 | Tool | Actions / Niche |
33 |---|---|
34 | `Bash` | `run`, `wait`, `interact`, `cancel` (existing) |
35 | `File` | `read`, `list`, `search_name`, `search_content`, `write`, `edit`, `patch` |
36 | `Git` | `status`, `diff`, `log`, `show`, `blame` |
37 | `Run` | `tests`, `verifiers` |
38 | `Web` | `search`, `fetch`, `wait` (deferred unless network is enabled; hidden aliases for legacy names) |
39 | `tasks` | durable task family (existing action-based surface) |
40 | `github` | durable GitHub family (existing; deferred by default) |
41 | `automation` | durable automation family (existing; deferred by default) |
42 | `rlm` | durable RLM family (existing; deferred by default) |
43 | `agent` | sub-agent dispatch |
44 | `remember` | opt-in durable user-memory capture; eager whenever registered |
45 | `work_update` | progress / plan-of-work updates |
46 | `update_plan` | plan artifact updates |
47 | `tool_search` | on-demand discovery of deferred tools |
48
49 Default-active policy: **10 names** (vs. ~18 before the simplification), with
50 `remember` registered only for built-in-memory users and the durable families
51 and `Web` discoverable via `tool_search` when needed. `tool_search` itself is a
52 synthetic always-active catalog entry.
53
54 ## Rejected alternatives
55
56 - **Keep every tool but defer the rare ones.** This only changes what is
57 advertised, not how many distinct schemas the model must learn. It also
58 leaves duplicated guidance in the prompt.
59 - **Route search and git through `Bash`.** `grep_files`, `file_search`, and the
60 git tools return structured, workspace-aware output and respect sandbox,
61 `.gitignore`, and network policy. Shell would force the model to re-parse
62 free-form text and lose those guarantees, so dedicated tools win.
63 - **One mega `File` tool plus a separate `Edit` tool.** A single `File` tool is
64 only slightly larger than a read/edit pair and keeps the boundary the model
65 already understands (`read` is cheap, `edit` requires prior read). Splitting
66 would re-introduce a two-tool alias for the same underlying operations.
67 - **Delete legacy tools.** Saved transcripts and replay tests rely on the old
68 names. Removing them would require a config migration and break reproducibility.
69 Hidden aliases avoid both.
70
71 ## Compatibility
72
73 - Legacy names (`read_file`, `write_file`, `edit_file`, `list_dir`, `file_search`,
74 `grep_files`, `apply_patch`, `git_status`, `git_diff`, `git_log`, `git_show`,
75 `git_blame`, `run_tests`, `run_verifiers`, `web_search`, `fetch_url`,
76 `wait_for_dev_server`) stay registered with `model_visible = false`.
77 - The engine resolves calls by name, so old transcripts replay without changes.
78 - `DEFAULT_ACTIVE_NATIVE_TOOLS` is updated to list the new canonical names only;
79 hidden legacy tools are ignored by catalog construction.
80
81 ## Prompt simplification
82
83 - Replace the tool-calling recipe sections in `AGENT_MODE` and
84 `SUBAGENT_OUTPUT_FORMAT` with short references to the canonical tools.
85 - Reduce mode deltas to permission statements (Act = write requires approval,
86 Plan = no writes or shell, Full Access = auto-approved, Operate = coordinate from
87 ordinary messages).
88 - Keep the `BASE_PROMPT` behavioral invariants, `LANGUAGE_PROMPT`, and
89 `OUTPUT_PROMPT` intact.
90 - Move detailed templates (`COMPACT_TEMPLATE`, sub-agent brief format, planning
91 artifact template) out of the stable prefix and into tool schemas or
92 conditional blocks.
93
94 ## Validation
95
96 - Provider-free: `scripts/measure-runtime-contract.py` reports active tool count
97 and prompt bytes before and after.
98 - Behavior-preserving: targeted unit tests for `File`, `Git`, `Run`, and `Web`
99 dispatch against legacy inputs.
100 - Regression: `cargo fmt`, `cargo clippy --workspace --all-targets --locked`,
101 `cargo test -p codewhale-tui --bin codewhale-tui --locked`, and
102 `cargo test --workspace`.
103
104 ### v0.9.1 receipt
105
106 The source contract and provider-free metric now exercise the complete policy,
107 including opt-in `remember`:
108
109 | Contract | Before | After |
110 |---|---:|---:|
111 | Default active tools | 18 | 10 |
112 | Agent-mode instruction bytes | 4,064 | 663 |
113 | Full system-prompt bytes | 15,842 | 15,368 |
114
115 The final active names are `Bash`, `File`, `Git`, `Run`, `agent`, `remember`,
116 `tasks`, `update_plan`, `work_update`, and `tool_search`. `remember` is present
117 only when built-in memory is enabled; it is eager whenever registered. `File`
118 advertises only read actions in Plan mode, and its `patch` action appears only
119 when the existing apply-patch feature is enabled. Hidden aliases remain
120 executable for transcript replay but are absent from the model catalog.
121
121 lines MARKDOWN