test: remove duplicated resource content assertions
This commit is contained in:
@@ -766,21 +766,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_source_names_the_worker_observation_contract() {
|
||||
let catalog = crate::PromptCatalog::builtins_only().unwrap();
|
||||
let source = &catalog.projection().templates["common.worker_observation"];
|
||||
for token in [
|
||||
"WorkerList",
|
||||
"ViewSessionOverview",
|
||||
"SearchSessionEntries",
|
||||
"ReadSessionEntry",
|
||||
"SessionEntryRef",
|
||||
] {
|
||||
assert!(source.contains(token), "missing {token}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_observation_requires_worker_control_service() {
|
||||
let provider = Arc::new(FakeProvider {
|
||||
|
||||
@@ -506,66 +506,9 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn builtin_dcdl_catalog_covers_worker_prompts() {
|
||||
fn builtin_dcdl_catalog_loads() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
for prompt in WorkerPrompt::ALL {
|
||||
assert!(catalog.projection.templates.contains_key(prompt.key()));
|
||||
}
|
||||
assert!(catalog.projection.templates.contains_key("default"));
|
||||
assert!(
|
||||
catalog
|
||||
.projection
|
||||
.templates
|
||||
.contains_key("common.workspace")
|
||||
);
|
||||
assert!(catalog.projection.templates.contains_key("role.coder"));
|
||||
assert!(
|
||||
catalog
|
||||
.projection
|
||||
.templates
|
||||
.contains_key("panel.orchestrator_idle_queue_notice")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commit_capable_roles_classify_commits_by_change_type() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
assert!(catalog.projection.templates.contains_key("common.git"));
|
||||
let context = Value::from_serialize(serde_json::json!({
|
||||
"cwd": "/workspace",
|
||||
"date": "2026-08-16",
|
||||
"language": "match the user's language",
|
||||
"tool_capabilities": {
|
||||
"memory_any": false,
|
||||
"memory_mutation": false,
|
||||
"memory_query": false,
|
||||
"memory_read_document": false
|
||||
}
|
||||
}));
|
||||
|
||||
for prompt in ["default", "role.coder", "role.orchestrator"] {
|
||||
let rendered = catalog.render_name(prompt, context.clone()).unwrap();
|
||||
assert!(rendered.contains("use the change type as the subject prefix"));
|
||||
assert!(rendered.contains("A change made because review"));
|
||||
assert!(rendered.contains("Do not keep reusing a domain prefix"));
|
||||
assert!(rendered.contains("fix: scope merge request foreign key checks"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_render_resolves_catalog_root_dotted_includes() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
let source = &catalog.projection.templates["default"];
|
||||
assert!(source.contains("{% include \"common.workspace\" %}"));
|
||||
assert!(source.contains("{% include \"common.tool_usage\" %}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schema_is_closed_and_materializes_builtin_defaults() {
|
||||
let source = prompt_schema_source().unwrap();
|
||||
assert!(source.starts_with("{ prompts = {"));
|
||||
assert!(source.contains("compact_system = String default"));
|
||||
assert!(source.contains("role = {"));
|
||||
assert!(!catalog.projection.templates.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -591,7 +534,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn workspace_projection_digest_is_stable_and_verified() {
|
||||
let templates = builtin_prompt_templates().unwrap();
|
||||
let templates = BTreeMap::from([
|
||||
("first".to_string(), "FIRST".to_string()),
|
||||
("second".to_string(), "SECOND".to_string()),
|
||||
]);
|
||||
let projection = EffectivePromptCatalog::new(templates, 42, "schema", "toolchain").unwrap();
|
||||
projection.verify_digest().unwrap();
|
||||
let mut tampered = projection.clone();
|
||||
@@ -606,70 +552,38 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn catalog_source_preserves_workspace_projection_for_subworkers() {
|
||||
let mut templates = builtin_prompt_templates().unwrap();
|
||||
templates.insert("common.workspace".into(), "CHILD OVERRIDE".into());
|
||||
let templates = BTreeMap::from([("template".to_string(), "OVERRIDE".to_string())]);
|
||||
let catalog = PromptCatalog::from_projection(
|
||||
EffectivePromptCatalog::new(templates, 9, "schema", "toolchain").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let child = PromptCatalog::load(&catalog.source()).unwrap();
|
||||
assert_eq!(child.projection.config_revision, 9);
|
||||
assert_eq!(
|
||||
child.projection.templates["common.workspace"],
|
||||
"CHILD OVERRIDE"
|
||||
);
|
||||
assert_eq!(child.projection.templates["template"], "OVERRIDE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn orchestrator_role_keeps_review_routing_owned_by_coder() {
|
||||
fn internal_prompt_helpers_load_and_render_arguments() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
let prompt = &catalog.projection.templates["role.orchestrator"];
|
||||
assert!(prompt.contains("assigned Coder owns its review/fix loop"));
|
||||
assert!(prompt.contains("then use `SpawnTicketCoder`"));
|
||||
assert!(prompt.contains("verify its current assignment names that Coder"));
|
||||
assert!(prompt.contains("never route implementation to an unassigned Coder"));
|
||||
assert!(prompt.contains(
|
||||
"Do not spawn, restore, assign, or route work to Backend/Runtime Reviewer Workers"
|
||||
));
|
||||
assert!(prompt.contains("never compensate by creating an independent Reviewer Worker"));
|
||||
assert!(
|
||||
prompt.contains("current linked Merge Request as implementation-completion authority")
|
||||
);
|
||||
assert!(prompt.contains("do not require an `implementation_report`"));
|
||||
assert!(prompt.contains("only the Orchestrator may call `MergeRequestComplete`"));
|
||||
let coder = &catalog.projection.templates["role.coder"];
|
||||
assert!(coder.contains("hand off to the Orchestrator"));
|
||||
assert!(coder.contains("Do not call `MergeRequestComplete`"));
|
||||
assert!(!prompt.contains("sibling Coder/Reviewer Workers"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn existing_internal_prompt_render_contracts_are_preserved() {
|
||||
let catalog = PromptCatalog::builtins_only().unwrap();
|
||||
assert!(catalog.compact_system().unwrap().contains("write_summary"));
|
||||
catalog.compact_system().unwrap();
|
||||
assert!(
|
||||
catalog
|
||||
.memory_extract_system("Japanese")
|
||||
.memory_extract_system("LANGUAGE_MARKER")
|
||||
.unwrap()
|
||||
.contains("`language`: `Japanese`")
|
||||
.contains("LANGUAGE_MARKER")
|
||||
);
|
||||
assert!(
|
||||
catalog
|
||||
.notify_wrapper("changed")
|
||||
.notify_wrapper("NOTIFICATION_MARKER")
|
||||
.unwrap()
|
||||
.contains("changed")
|
||||
.contains("NOTIFICATION_MARKER")
|
||||
);
|
||||
assert!(
|
||||
catalog
|
||||
.working_boundaries_section("Readable: /a")
|
||||
.working_boundaries_section("BOUNDARY_MARKER")
|
||||
.unwrap()
|
||||
.contains("Readable: /a")
|
||||
);
|
||||
assert!(
|
||||
catalog
|
||||
.worker_orchestration_guidance_section()
|
||||
.unwrap()
|
||||
.contains("## SubWorker orchestration")
|
||||
.contains("BOUNDARY_MARKER")
|
||||
);
|
||||
catalog.worker_orchestration_guidance_section().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
#[cfg(test)]
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::{DateTime, SecondsFormat, Utc};
|
||||
@@ -26,8 +24,6 @@ use thiserror::Error;
|
||||
|
||||
use crate::feature::{FeatureInstructionDeclaration, dedupe_instruction_contributions};
|
||||
use crate::prompt::catalog::{CatalogError, PromptCatalog};
|
||||
#[cfg(test)]
|
||||
use crate::prompt::catalog::{EffectivePromptCatalog, builtin_prompt_templates};
|
||||
use crate::prompt::source::PromptCatalogSource;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@@ -319,76 +315,6 @@ fn append_trailing_section(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::TimeZone;
|
||||
use manifest::{Permission, ScopeConfig, ScopeRule};
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn fixed_now() -> DateTime<Utc> {
|
||||
Utc.with_ymd_and_hms(2026, 4, 15, 9, 30, 0).unwrap()
|
||||
}
|
||||
|
||||
fn build_scope(dir: &Path) -> Scope {
|
||||
Scope::from_config(&ScopeConfig {
|
||||
allow: vec![ScopeRule {
|
||||
target: dir.to_path_buf(),
|
||||
permission: Permission::Write,
|
||||
recursive: true,
|
||||
}],
|
||||
deny: Vec::new(),
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn context<'a>(
|
||||
cwd: &'a Path,
|
||||
scope: &'a Scope,
|
||||
prompts: &'a PromptCatalog,
|
||||
) -> SystemPromptContext<'a> {
|
||||
SystemPromptContext {
|
||||
now: fixed_now(),
|
||||
cwd: cwd.to_string_lossy(),
|
||||
tool_names: vec!["Read".into(), "Write".into()],
|
||||
scope,
|
||||
agents_md: Some("PROJECT RULES".into()),
|
||||
resident_summary: Some("DURABLE MEMORY"),
|
||||
language: "Japanese",
|
||||
feature_instructions: &[],
|
||||
prompts,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exact_catalog_name_renders_once_with_trailing_sections() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let scope = build_scope(tmp.path());
|
||||
let prompts = PromptCatalog::builtins_only().unwrap();
|
||||
let template =
|
||||
SystemPromptTemplate::parse("default", PromptCatalogSource::builtins_only()).unwrap();
|
||||
let rendered = template
|
||||
.render(&context(tmp.path(), &scope, &prompts))
|
||||
.unwrap();
|
||||
assert!(rendered.contains("2026-08-14") || rendered.contains("2026-04-15"));
|
||||
assert!(rendered.contains("## Working boundaries"));
|
||||
assert!(rendered.contains("PROJECT RULES"));
|
||||
assert!(rendered.contains("DURABLE MEMORY"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_override_is_visible_through_builtin_static_include() {
|
||||
let mut templates = builtin_prompt_templates().unwrap();
|
||||
templates.insert("common.workspace".into(), "WORKSPACE OVERRIDE".into());
|
||||
let projection = EffectivePromptCatalog::new(templates, 9, "schema", "toolchain").unwrap();
|
||||
let loader =
|
||||
PromptCatalogSource::builtins_only().with_effective_catalog(projection.clone());
|
||||
let prompts = PromptCatalog::from_projection(projection).unwrap();
|
||||
let template = SystemPromptTemplate::parse("default", loader).unwrap();
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let scope = build_scope(tmp.path());
|
||||
let rendered = template
|
||||
.render(&context(tmp.path(), &scope, &prompts))
|
||||
.unwrap();
|
||||
assert!(rendered.contains("WORKSPACE OVERRIDE"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_legacy_prefix_relative_and_missing_names() {
|
||||
@@ -399,20 +325,4 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn role_templates_are_selected_without_filesystem_resolution() {
|
||||
let loader = PromptCatalogSource::builtins_only();
|
||||
for role in [
|
||||
"role.coder",
|
||||
"role.intake",
|
||||
"role.orchestrator",
|
||||
"role.reviewer",
|
||||
] {
|
||||
assert!(
|
||||
SystemPromptTemplate::parse(role, loader.clone()).is_ok(),
|
||||
"{role}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6955,7 +6955,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(rendered.contains("## Resident memory summary"));
|
||||
assert!(rendered.contains("summary body for resident prompt"));
|
||||
assert!(!rendered.contains("updated_at: 2026-01-01T00:00:00Z"));
|
||||
assert!(!rendered.contains("---\nupdated_at"));
|
||||
@@ -6974,7 +6973,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!rendered.contains("Resident memory summary"));
|
||||
assert!(!rendered.contains("disabled summary body"));
|
||||
}
|
||||
|
||||
@@ -6987,7 +6985,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!rendered.contains("Resident memory summary"));
|
||||
assert!(!rendered.contains("memory-disabled summary body"));
|
||||
}
|
||||
|
||||
@@ -7000,8 +6997,7 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(rendered.contains("## Working boundaries"));
|
||||
assert!(!rendered.contains("Resident memory summary"));
|
||||
assert!(!rendered.trim().is_empty());
|
||||
assert!(!rendered.contains("bad summary body"));
|
||||
}
|
||||
|
||||
@@ -7015,7 +7011,6 @@ mod build_summary_prompt_tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(!prompt.contains("Resident memory summary"));
|
||||
assert!(!prompt.contains("resident summary marker"));
|
||||
}
|
||||
|
||||
|
||||
@@ -176,12 +176,9 @@ async fn template_is_not_materialised_before_first_run() {
|
||||
#[tokio::test]
|
||||
async fn materialise_on_first_turn_populates_worker() {
|
||||
let client = MockClient::new(vec![single_text_events("ok")]);
|
||||
let (mut worker, pwd) = make_worker_with_body(
|
||||
"date={{ date }} cwd={{ cwd }} tools={{ tools | join(',') }}",
|
||||
client,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let (mut worker, pwd) = make_worker_with_body("date={{ date }}", client)
|
||||
.await
|
||||
.unwrap();
|
||||
worker.run_text("hi").await.unwrap();
|
||||
let rendered = worker
|
||||
.engine()
|
||||
@@ -189,19 +186,14 @@ async fn materialise_on_first_turn_populates_worker() {
|
||||
.expect("system prompt materialised")
|
||||
.to_string();
|
||||
assert!(rendered.contains("date="));
|
||||
assert!(rendered.contains("cwd="));
|
||||
assert!(rendered.contains(&pwd.display().to_string()));
|
||||
assert!(rendered.starts_with("date="));
|
||||
// Trailing fixed section must be appended.
|
||||
assert!(rendered.contains("## Working boundaries"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn session_start_state_captures_rendered_prompt() {
|
||||
let client = MockClient::new(vec![single_text_events("ok")]);
|
||||
let (mut worker, pwd) = make_worker_with_body("hello cwd={{ cwd }}", client)
|
||||
.await
|
||||
.unwrap();
|
||||
let (mut worker, pwd) = make_worker_with_body("hello", client).await.unwrap();
|
||||
worker.run_text("hi").await.unwrap();
|
||||
|
||||
let entries = worker
|
||||
@@ -212,9 +204,8 @@ async fn session_start_state_captures_rendered_prompt() {
|
||||
match first {
|
||||
LogEntry::SegmentStart { system_prompt, .. } => {
|
||||
let sp = system_prompt.as_deref().expect("system prompt set");
|
||||
assert!(sp.starts_with("hello cwd="));
|
||||
assert!(sp.starts_with("hello"));
|
||||
assert!(sp.contains(&pwd.display().to_string()));
|
||||
assert!(sp.contains("## Working boundaries"));
|
||||
}
|
||||
other => panic!("expected SegmentStart as first entry, got {other:?}"),
|
||||
}
|
||||
@@ -253,21 +244,10 @@ async fn agents_md_is_injected_as_trailing_section_when_present() {
|
||||
worker.run_text("hi").await.unwrap();
|
||||
let rendered = worker.engine().get_system_prompt().unwrap().to_string();
|
||||
assert!(rendered.starts_with("BODY"));
|
||||
assert!(rendered.contains("## Project instructions (AGENTS.md)"));
|
||||
assert!(rendered.contains("# project rules"));
|
||||
assert!(rendered.contains("be kind"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn agents_md_absent_omits_trailing_section() {
|
||||
let client = MockClient::new(vec![single_text_events("ok")]);
|
||||
let (mut worker, _pwd) = make_worker_with_body("BODY", client).await.unwrap();
|
||||
worker.run_text("hi").await.unwrap();
|
||||
let rendered = worker.engine().get_system_prompt().unwrap().to_string();
|
||||
assert!(!rendered.contains("## Project instructions"));
|
||||
assert!(!rendered.contains("AGENTS.md"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn agents_md_not_reread_after_compact() {
|
||||
let client = MockClient::new(vec![
|
||||
|
||||
Reference in New Issue
Block a user