Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
8eab36d
fix(tools): disclose read image and text decode
asto18089 Nov 2, 2026
6f7a74d
fix(tools): disclose bash shell and stream facts
asto18089 Nov 2, 2026
f248ce3
fix(skills): cite visible tool names in v4 skill
asto18089 Nov 2, 2026
01851c7
fix(tools): restore Run schema verifier semantics
asto18089 Nov 2, 2026
be808c6
fix(tools): refuse ambiguous fim_edit anchors
asto18089 Nov 2, 2026
e62cc2b
fix(tools): disclose read_media default budget
asto18089 Nov 2, 2026
cd7700f
fix(tools): disclose tasks schema semantics
asto18089 Nov 2, 2026
7db690c
fix(skills): drop dead short-description metadata
asto18089 Nov 2, 2026
bca4382
docs(prompts): fix stale overlay doc comment
asto18089 Nov 2, 2026
bfa732d
fix(tools): disclose lsp line requirement
asto18089 Nov 2, 2026
ca2af5f
fix(tools): disclose remaining task schema semantics
asto18089 Nov 2, 2026
4447e58
fix(skills): retire legacy v4-best-practices bodies
asto18089 Nov 2, 2026
2ad8e55
fix(skills): refresh superseded bundled bodies from the short-descrip…
asto18089 Nov 2, 2026
4499d39
fix(prompts): finish stale overlay header cleanup
asto18089 Nov 2, 2026
1a19046
fix(tools): disclose read image size cap and BMP behavior
asto18089 Nov 2, 2026
26ea316
fix(tools): stop citing retired exec_shell in cwd recovery hint
asto18089 Nov 2, 2026
e454f70
docs: document read_media delivery budget
asto18089 Nov 2, 2026
969624f
fix(tools): name published tools in the Run verifier schema
asto18089 Nov 2, 2026
5f86b1a
fix(tools): scope the Run verifier copy to each execution path
asto18089 Nov 2, 2026
6521c34
fix(tools): make the bash working-dir recovery hint actionable
asto18089 Nov 2, 2026
6935e8e
fix(tools): correct task mode approval copy and dedupe declared ranges
asto18089 Nov 2, 2026
6ee7116
fix(tools): disclose fim anchor uniqueness in the tool description
asto18089 Nov 2, 2026
5c01281
docs(prompts): finish the stale assembly-layer cleanup
asto18089 Nov 2, 2026
52d9996
fix(skills): pin the v4 legacy body by digest with a test fixture
asto18089 Nov 2, 2026
ba04729
fix(tools): make the shell working-dir recovery advice hold on every …
asto18089 Nov 4, 2026
6c69378
fix(tools): disclose the trust_mode full-access retry in the tasks sc…
asto18089 Nov 4, 2026
fc416b7
fix(tools): qualify background gate task ids for skipped or failed gates
asto18089 Nov 4, 2026
36636d2
fix(tools): scope the hidden run_verifiers shell claim per execution …
asto18089 Nov 4, 2026
1eb944f
test(tools): pin crop reads keeping the full wire budget
asto18089 Nov 4, 2026
95fbd6e
fix(tools): frame the read_media default budget as a budget
asto18089 Nov 4, 2026
bf1ab73
docs(prompts): name the harness and project-instruction fragments pre…
asto18089 Nov 4, 2026
c27064a
fix(tools): state the task clamp type-error boundary
asto18089 Nov 4, 2026
da8a027
fix(tools): label the read_media size line as encoded payload
asto18089 Nov 4, 2026
0b09401
docs(prompts): finish the stale header-comment residuals
asto18089 Nov 4, 2026
bcb0dae
test(tools): pin fim anchor counting edges
asto18089 Nov 4, 2026
8d0e997
test(tools): pin background gate task-id null cases
asto18089 Nov 4, 2026
bfee933
test(tools): pin the load-bearing copy sentences
asto18089 Nov 4, 2026
5add71c
test(skills): anchor the gen-12 superseded digests to fixtures
asto18089 Nov 4, 2026
33395ff
fix(tools): stop teaching the hidden rlm surface in harness copy
asto18089 Nov 4, 2026
d6d9572
fix(tools): disclose non-overlapping anchor counting in fim copy
asto18089 Nov 4, 2026
279b313
test(tools): pin the fim pass-through corners
asto18089 Nov 4, 2026
3f07d01
test(tools): pin the read_media encoded-payload label
asto18089 Nov 4, 2026
8b6d17e
fix(tools): scope the allow_shell honored claim to the mode
asto18089 Nov 4, 2026
71b61ea
docs(prompts): drop the stale single-module tuning claim
asto18089 Nov 4, 2026
4a36f4b
fix(tools): scope the read decode clause to the binary refusal
asto18089 Nov 5, 2026
bcf944c
test(tools): pin the harness rlm removal
asto18089 Nov 5, 2026
5fbf168
docs(prompts): scope the consolidation claim and fix the test command
asto18089 Nov 5, 2026
a326ba9
fix(tools): scope the auto-approve copy to armed guardrails
asto18089 Nov 6, 2026
4f00c64
fix(tools): scope the tasks shell-tool pointer and task-id default copy
asto18089 Nov 6, 2026
7936c7e
test(tools): pin the read_media delivery-budget copy
asto18089 Nov 6, 2026
8374e64
test(tools): pin the fim non-overlapping counting behavior
asto18089 Nov 6, 2026
64202f1
test(tools): pin the shell working-dir advice on both arms
asto18089 Nov 6, 2026
eab45d4
docs(prompts): align the constant-doc claims with the assembled prompt
asto18089 Nov 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/tui/assets/skills-catalog-matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"in_model_catalogue": "true when the skill renders as an ambient catalogue line",
"shadowed_aliases": "aliases that collide with another canonical bundled name; the canonical skill wins resolution"
},
"generation": "12",
"generation": "13",
"skills": [
{
"name": "skill-creator",
Expand Down
2 changes: 0 additions & 2 deletions crates/tui/assets/skills/best-of-n/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
name: best-of-n
description: Generate a small set of independent candidate solutions in worktrees, judge them against one explicit rubric, and apply the winner only after PASS verification.
metadata:
short-description: Compare independent candidates
---

# Best of N
Expand Down
2 changes: 0 additions & 2 deletions crates/tui/assets/skills/delegate/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
name: delegate
description: Strategic delegation for multi-step coding, research, or verification work. Use when a task can be split into parent reasoning plus focused sub-agent execution through the agent tool.
metadata:
short-description: Delegate focused work to sub-agents
---

# Delegate
Expand Down
2 changes: 0 additions & 2 deletions crates/tui/assets/skills/fleet-manager/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
name: fleet-manager
description: Use when managing, triaging, restarting, escalating, or summarizing Codewhale fleet runs and workers.
metadata:
short-description: Triage Codewhale fleet runs
---

# Fleet Manager
Expand Down
2 changes: 0 additions & 2 deletions crates/tui/assets/skills/skill-creator/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
name: skill-creator
description: Create or improve Codewhale skills. Use when the user wants a new skill, wants to update an existing skill, or needs guidance on when a skill should be a skill versus MCP, hooks, tools, or a plugin scaffold.
metadata:
short-description: Create Codewhale skills
aliases-for: create-skill
---

Expand Down
6 changes: 3 additions & 3 deletions crates/tui/assets/skills/v4-best-practices/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ specific, observable failure class.
## 1. Verify references before writing

Before referencing a file path, function, or type in code or plan output,
call `grep_files` or `read_file` to confirm it exists in the workspace.
call `grep_files` or `read` to confirm it exists in the workspace.

```
# Bad: edit_file path="src/config/loader.rs" (assumed from memory)
# Bad: edit path="src/config/loader.rs" (assumed from memory)
# Good: grep_files pattern="pub fn load_config" → confirms src/config/mod.rs:42
# then reference src/config/mod.rs:42
```

Failure avoided: `edit_file` errors on non-existent paths; LSP diagnostics
Failure avoided: `edit` errors on non-existent paths; LSP diagnostics
on hallucinated symbols.

## 2. Spawn a verifier sub-agent before multi-file execution
Expand Down
86 changes: 49 additions & 37 deletions crates/tui/src/prompts.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#![allow(dead_code)]
//! System prompt composition.
//!
//! Prompts are assembled from composable layers loaded at compile time from
//! the single `text` module:
//! constitution + personality overlay → `message[0]` (byte-stable).
//! Prompts are assembled from composable layers loaded at compile time —
//! most from the `text` module, with the authority recap and the locale
//! bookends defined here:
//! constitution (personality folded in) → `message[0]` (byte-stable).
//! approval policy → request-time runtime metadata.
//! Tool availability comes only from the per-turn model catalog.
//!
//! Keeping every layer's text in one module makes prompt tuning a
//! single-file operation.
//! Every layer's text stays a compile-time constant — this module and
//! `text`, per the split above.

use crate::models::{SystemBlock, SystemPrompt};
use crate::project_context::load_project_context_with_parents;
Expand Down Expand Up @@ -82,8 +83,9 @@ impl Default for PromptSessionContext<'_> {

/// Conventional location for the structured session relay artifact (#32).
/// A previous session writes it on exit / `/compact`; the next session reads
/// it back on startup and prepends it to the system prompt so a fresh agent
/// doesn't have to re-discover open blockers from scratch.
/// it back on startup and routes it as the late WorldState token-budget /
/// continuity fragment (`load_handoff_block`) so a fresh agent doesn't have
/// to re-discover open blockers from scratch.
pub const HANDOFF_RELATIVE_PATH: &str = ".codewhale/handoff.md";
/// Legacy handoff path for reading from existing installs. `pub(crate)` so
/// command surfaces that teach the fallback name it from the same constant
Expand Down Expand Up @@ -189,9 +191,10 @@ fn translation_target_language_for_tag(locale_tag: &str) -> &'static str {
/// Render a `## Environment` block listing the resolved locale tag and the
/// actionable host facts that affect command syntax.
///
/// The block is appended to the workspace-static portion of the system
/// prompt (after the shared constitution + project context, before configured
/// instructions / skills). `locale_tag` is resolved by the caller from
/// The block leads the workspace WorldState fragment (environment + memory /
/// goal facts), which is assembled after the cache-stable constitution
/// prefix so a change re-renders as a fragment diff instead of rebuilding
/// the static prefix. `locale_tag` is resolved by the caller from
/// `Settings` so this function stays I/O-free.
///
/// `platform` and `shell` remain because they change how commands must be
Expand Down Expand Up @@ -401,10 +404,12 @@ fn user_constitution_disabled_by_setup_state() -> bool {

// ── Prompt layers loaded at compile time ──────────────────────────────
//
// Every bundled prompt layer lives in `prompts/text.rs` as a compile-time
// constant (consolidated from the retired per-layer `prompts/*.md` files;
// each constant is byte-identical to the file it replaced, trailing newline
// included). The constants are re-exported here so the existing
// Every bundled prompt layer is a compile-time constant — most in
// `prompts/text.rs`, with the authority recap and the locale bookends
// defined in this file (consolidated from the retired per-layer
// `prompts/*.md` files; each constant is byte-identical to the file it
// replaced, trailing newline included). The constants are re-exported here
// so the existing
// `crate::prompts::NAME` paths used across the crate are unchanged. Edit
// prompt text in `text.rs` directly; the test suite below guards content
// and ordering invariants (constitution structure and binding gates #4032,
Expand Down Expand Up @@ -447,15 +452,16 @@ static PROMPT_OVERRIDE_NOTICES: LazyLock<Mutex<Vec<String>>> =
pub struct StaticPromptCtx<'a> {
/// Active model identifier after caller-side routing.
pub model_id: &'a str,
/// Personality overlay requested for the base static prompt.
/// Personality requested for the base static prompt (retired: the runtime
/// folds the tone into the constitution rather than composing an overlay).
pub personality: Personality,
/// Default base/personality prompt layers that would be used without an
/// override.
/// Default base prompt (personality already folded in) that would be used
/// without an override.
pub default_layers: &'a str,
}

/// Embedder hook for replacing Codewhale's byte-stable base/personality prompt
/// segment.
/// Embedder hook for replacing Codewhale's byte-stable base prompt segment
/// (personality folded in).
pub type StaticPromptComposer = dyn Fn(&StaticPromptCtx<'_>) -> String + Send + Sync + 'static;

/// Install an embedder composer that owns the complete static prompt prefix.
Expand Down Expand Up @@ -1007,10 +1013,10 @@ fn apply_model_template(
prompt.replace("{model_id}", model_id)
}

/// Authority recap block — appended at the end of the system prompt,
/// just before the user's first message. Uses recency bias constructively
/// without restating ranks: `BASE_PROMPT` § Whose word wins states the
/// default ranking (#4777).
/// Authority recap block — appended as a per-request trailer after the
/// WorldState fragments, just before the locale closer. Uses recency bias
/// constructively without restating ranks: `BASE_PROMPT` § Whose word wins
/// states the default ranking (#4777).
const AUTHORITY_RECAP: &str = "\
## Authority Recap

Expand Down Expand Up @@ -1094,21 +1100,27 @@ pub fn system_prompt_for_mode_with_context(

/// Get the system prompt for a specific mode with project and skills context.
///
/// **Volatile-content-last invariant.** Blocks are appended in order from
/// most-static to most-volatile so DeepSeek's KV prefix cache hits the
/// longest possible byte prefix turn-over-turn:
/// **Volatile-content-last invariant.** The cache-stable `Blocks[0]` prefix
/// is the composed constitution — base prompt, project context, skills
/// block, and `## Core Execution` discipline — and per-turn material follows
/// it from most-static to most-volatile so DeepSeek's KV prefix cache hits
/// the longest possible byte prefix turn-over-turn:
///
/// 1. shared constitution (compile-time constant)
/// 2. project context / fallback (workspace-static)
/// 3. skills block (skills-dir-static)
/// 4. `## Core Execution` (compile-time constant)
/// 5. compaction relay template (compile-time constant)
/// 6. relay block — file-backed; rewritten by `/compact` and on exit
/// 1. composed constitution prefix (compile-time constant, plus
/// workspace-static project context and the skills-dir-static skills
/// block)
/// 2. WorldState fragments (environment/memory/goal, the interactive
/// continual-harness block, permissions, route, handoff, and imported
/// project instructions) that can `render_diff` mid-session
/// 3. per-request trailers: authority recap, then locale closer
///
/// Anything appended after a volatile block forfeits the cache for the rest
/// of the request. New blocks belong above the relay boundary unless they
/// themselves are turn-volatile. Working-set metadata is now injected into the
/// latest user message as per-turn metadata instead of this system prompt.
/// The compaction relay is not a system block: automatic compaction owns its
/// structured successor brief and `/relay` appends `COMPACT_TEMPLATE` to that
/// command's user message. Anything appended after a volatile block forfeits
/// the cache for the rest of the request; new content belongs above the
/// fragment boundary unless it is itself turn-volatile. Working-set metadata
/// is injected into the latest user message as per-turn metadata instead of
/// this system prompt.
pub fn system_prompt_for_mode_with_context_and_skills(
workspace: &Path,
working_set_summary: Option<&str>,
Expand Down Expand Up @@ -3124,7 +3136,7 @@ mod tests {
}

#[test]
fn handoff_artifact_is_prepended_to_system_prompt_when_present() {
fn handoff_artifact_is_included_in_the_system_prompt_when_present() {
let tmp = tempdir().expect("tempdir");
let workspace = tmp.path();
let handoff_dir = workspace.join(".deepseek");
Expand Down
53 changes: 34 additions & 19 deletions crates/tui/src/prompts/text.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,58 @@
//! Compile-time prompt text — the single source of truth for every bundled
//! layer of the Codewhale system prompt.
//! Compile-time prompt text — most bundled layers of the Codewhale system
//! prompt live here as constants (the authority recap and the locale
//! bookends are defined in `prompts.rs`).
//!
//! Each constant below used to live in its own `prompts/*.md` file, pulled in
//! with `include_str!`. The per-layer file sprawl (17 files across 4
//! directories) was consolidated into this one module so the whole prompt
//! contract reads top-to-bottom in a single place, the way the runtime
//! assembly composes it. The text moved **verbatim** — every constant is
//! byte-identical to the file it replaced, trailing newline included — so
//! directories) was consolidated into this module for the constants that
//! moved; the authority recap and the locale bookends have always lived in
//! `prompts.rs`, so the bulk — not the whole — of the prompt contract reads
//! top-to-bottom in one place. The text moved **verbatim** — every constant
//! is byte-identical to the file it replaced, trailing newline included — so
//! rendered prompts do not change by a single byte.
//!
//! Organization follows the runtime assembly order, most-static →
//! most-volatile (see `system_prompt_for_mode_with_context_skills_and_session`
//! in `../prompts.rs`):
//!
//! 1. Constitution (binding core: `BASE_PROMPT` + language/output law)
//! 2. Personality overlay (`CALM_PERSONALITY` — one overlay, not a set)
//! 3. Approval-policy overlays
//! 4. Runtime templates (compaction relay, goal continuation, memory,
//! 1. Constitution (binding core: `BASE_PROMPT` + language/output law;
//! personality tone is folded into the constitutional preamble, not
//! composed as a separate layer)
//! 2. Runtime templates (compaction relay, goal continuation, memory,
//! core execution, sub-agent output contract)
//!
//! Approval policy is not a layer here: it travels as request-time runtime
//! metadata (see the `prompts.rs` module header).
//!
//! `CALM_PERSONALITY` below is a retired overlay: the runtime never composes
//! it (tests assert the Calm tone stays folded into the constitution), and it
//! is kept only so the historic text and its guard tests remain inspectable.
//!
//! Edit prompt text here directly. Content and ordering invariants are
//! guarded by the test suite in `../prompts.rs` (constitution structure,
//! binding gates, prefix privacy, byte-stable prefix ordering) — run
//! `cargo test -p codewhale-tui --bin codewhale-tui prompts` after edits.
//! `cargo test -p codewhale-tui --lib prompts` after edits.
//!
//! The locale-tagged bookends (per-locale preambles/closers) remain in
//! `../prompts.rs` next to the override cells that can replace them.

// ── Constitution — the binding core (#4032) ─────────────────────────
/// Core: task execution, tool-use rules, output format, toolbox reference,
/// "When NOT to use" guidance, sub-agent sentinel protocol.
/// Core: ground truth, user intent and scope, truthful completion,
/// guarantees-in-mechanism, and the default authority ranking
/// ("Whose word wins").
///
/// This text is the single hand-maintained source of the constitutional
/// system prompt. The earlier YAML + Python-renderer generation pipeline
/// (`constitution.yaml` / `render_constitution.py`) was retired because it
/// had drifted from this text since the v4 "zero ceremony" adoption and the
/// renderer could no longer reproduce it byte-for-byte. The layered runtime
/// assembly composes this core with mode / approval / skills /
/// context-management / compaction / authority-recap layers at runtime (see
/// `system_prompt_for_mode_with_context_skills_and_session`). Edit the text
/// renderer could no longer reproduce it byte-for-byte. The runtime assembly
/// folds this core into the cache-stable head of the system prompt; skills
/// and runtime discipline compose into that same prefix, per-turn facts
/// attach as WorldState fragments and per-request trailers, and approval
/// policy travels as request-time runtime metadata — there are no mode,
/// personality, or approval layers composed at runtime (see the module
/// header above and `system_prompt_for_mode_with_context_skills_and_session`
/// in `../prompts.rs`). Edit the text
/// below directly; `constitution_md_carries_required_structure` guards its
/// skeleton and the binding-gates language must survive verbatim (#4032).
pub const BASE_PROMPT: &str = r#"## Codewhale
Expand Down Expand Up @@ -154,8 +168,9 @@ Prefer plain prose for explanations; bulleted or numbered lists for sequential o
If you genuinely need column-aligned data because the user asked for a table or for `/cost`-style output, keep columns narrow, ASCII-only, and limited to two or three columns. Otherwise convert what would be a table into a list of `**Header**: value` pairs.
"#;

// ── Personality overlays — voice and tone ──────────────────────────
/// Calm personality overlay.
// ── Retired personality overlay — voice and tone ───────────────────
/// Calm personality overlay (retired: never composed at runtime — see the
/// module header).
pub const CALM_PERSONALITY: &str = r#"## Personality: Calm

This personality controls how you speak, never what you do. It cannot override
Expand Down
Loading
Loading