From 0b7660ddc536dd414661600573ec2b6bf6856562 Mon Sep 17 00:00:00 2001 From: hexin Date: Thu, 28 May 2026 18:31:29 +0800 Subject: [PATCH] docs(constitution): Tier 5 Local Law covers EngineConfig.instructions paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Article VII Tier 5 currently lists four hard-coded path conventions (AGENTS.md / CLAUDE.md / .codewhale/instructions.md / .deepseek/instructions.md) as the canonical Local Law sources. Embedders that inject instructions via `EngineConfig.instructions` (rather than placing files at one of those four paths) get their files classified by path — and since their paths don't match, the model defaults to treating their imperatives as Tier 7 Memory (the lowest tier per Article VII), overridable by a single user sentence. Adds an explicit clause to Tier 5: '...and any file configured via `EngineConfig.instructions` (rendered as blocks above). ...embedder-declared imperatives are Local Law, not Memory preferences.' Pairs naturally with #2311 (InstructionSource enum) but stands alone — this is a doc/law clarification, not an API change. Adds `local_law_tier_covers_engine_config_instructions` test pinning the new clause's presence. --- crates/tui/src/prompts.rs | 18 ++++++++++++++++++ crates/tui/src/prompts/base.md | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/tui/src/prompts.rs b/crates/tui/src/prompts.rs index 33a7e954..812be616 100644 --- a/crates/tui/src/prompts.rs +++ b/crates/tui/src/prompts.rs @@ -1905,6 +1905,24 @@ mod tests { ); } + /// Tier 5 Local Law must explicitly cover `EngineConfig.instructions` + /// files. Without this clause, embedders that inject instructions via the + /// config field (rather than via the four hard-coded path conventions) + /// get their files classified by path — and since those embedder-supplied + /// paths aren't `AGENTS.md` / `CLAUDE.md` / `.codewhale/instructions.md` / + /// `.deepseek/instructions.md`, the model defaults to treating their + /// imperatives as Tier 7 Memory (the lowest tier per Article VII), + /// overridable by a single user sentence. + #[test] + fn local_law_tier_covers_engine_config_instructions() { + let prompt = compose_prompt(AppMode::Agent, Personality::Calm); + assert!( + prompt.contains("any file configured via `EngineConfig.instructions`"), + "Tier 5 must explicitly cover EngineConfig.instructions so \ + embedder-injected instructions are not default-classified as Tier 7 Memory." + ); + } + #[test] fn workspace_orientation_guidance_present() { let prompt = compose_prompt(AppMode::Agent, Personality::Calm); diff --git a/crates/tui/src/prompts/base.md b/crates/tui/src/prompts/base.md index 83049925..061ff92c 100644 --- a/crates/tui/src/prompts/base.md +++ b/crates/tui/src/prompts/base.md @@ -52,7 +52,7 @@ When directives from different sources conflict, resolve in this order: 4. **Regulations.** Composition patterns, sub-agent strategy, language rules, thinking budget. Best-practice guidance that yields to user intent when the two conflict. -5. **Local Law.** Project instructions — AGENTS.md, CLAUDE.md, `.codewhale/instructions.md`, `.deepseek/instructions.md`. Project-specific rules that are subordinate to all higher tiers. +5. **Local Law.** Project instructions — AGENTS.md, CLAUDE.md, `.codewhale/instructions.md`, `.deepseek/instructions.md`, **and any file configured via `EngineConfig.instructions` (rendered as `` blocks above)**. Project-specific rules that are subordinate to all higher tiers but supersede Memory (Tier 7), even when written in imperative voice — `EngineConfig.instructions` files are declared by the embedder (not user-collected like memory), so their imperatives are Local Law, not Memory preferences. 6. **Evidence.** Tool output, file contents, command results, live repository state. Evidence is truth. Never contradict verified tool output. If memory and evidence conflict, evidence wins.