use super::*;
use crate::core::bundled_pm_package::bundled_fallback_package;
use crate::core::instruction_overrides::{
FILE_INSTRUCTIONS, FILE_WORKFLOW, OVERRIDE_DIR_NAME, PromptSource,
resolve_pm_prompt_with_roster,
};
use crate::core::instruction_package::Generator;
use tempfile::TempDir;
const ROSTER: &str = "## Delegation Authority\n\n### ticketing\n\nHandles ticketing work.";
fn write_claude_md(project: &Path, body: &str) {
std::fs::write(project.join("CLAUDE.md"), body).expect("write CLAUDE.md");
}
fn write_trusty_file(project: &Path, name: &str, body: &str) {
let dir = project.join(OVERRIDE_DIR_NAME);
std::fs::create_dir_all(&dir).expect("create .trusty-mpm");
std::fs::write(dir.join(name), body).expect("write override");
}
fn block(section: SectionId, body: &str) -> String {
let token = section_token(section);
format!("<!-- TRUSTY-MPM: {token} START v=1 -->\n{body}\n<!-- TRUSTY-MPM: {token} END -->\n")
}
fn resolve(project: &Path) -> (String, PromptSource) {
resolve_pm_prompt_with_roster(project, || Some(ROSTER.to_string()))
}
fn reasons(scanned: &ProjectOverrides) -> Vec<&'static str> {
scanned.diagnostics.iter().map(|d| d.reason).collect()
}
#[test]
fn every_section_token_is_the_kebab_case_id_uppercased() {
for id in SectionId::CANONICAL {
let kebab = serde_json::to_string(&id).expect("serialize id");
let expected = kebab.trim_matches('"').to_ascii_uppercase();
assert_eq!(section_token(id), expected, "token for {id:?}");
}
}
#[test]
fn parses_the_documented_marker_grammar() {
for line in [
"<!-- TRUSTY-MPM: WORKFLOW START v=1 -->",
"<!-- TRUSTY-MPM: WORKFLOW START v=1 -->",
" <!-- trusty-mpm: workflow start v=1 --> ",
"<!-- TRUSTY-MPM: Agent-Delegation START v=1 -->",
] {
let marker = parse_marker(line).unwrap_or_else(|| panic!("must parse: {line:?}"));
assert!(matches!(
marker.kind,
MarkerKind::Start(MarkerVersion::Supported)
));
}
let end = parse_marker("<!-- TRUSTY-MPM: WORKFLOW END -->").expect("END parses");
assert_eq!(end.kind, MarkerKind::End);
assert!(end.token.eq_ignore_ascii_case("WORKFLOW"));
}
#[test]
fn prose_mentioning_the_marker_is_not_a_marker() {
for line in [
"Use `<!-- TRUSTY-MPM: WORKFLOW START v=1 -->` to open a block.",
"<!-- TRUSTY-MPM: WORKFLOW START v=1 --> trailing prose",
"<!-- an ordinary HTML comment -->",
"<!-- TRUSTY-MPM: WORKFLOW -->",
"<!-- TRUSTY-MPM: WORKFLOW START v=1 extra -->",
"<!-- TRUSTY-MPM: WORKFLOW SIDEWAYS v=1 -->",
"# TRUSTY-MPM: WORKFLOW START v=1",
"",
] {
assert!(
parse_marker(line).is_none(),
"must NOT be a marker: {line:?}"
);
}
}
#[test]
fn scans_claude_md_for_named_sections() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&format!(
"# Project Instructions\n\nsome prose\n\n{}\n{}",
block(SectionId::Workflow, "TWO_PHASE_ONLY"),
block(SectionId::Memory, "Recall from the `team` palace first."),
),
);
let scanned = scan_project(tmp.path());
assert_eq!(scanned.diagnostics, vec![]);
let got: Vec<(SectionId, &str)> = scanned
.overrides
.iter()
.map(|o| (o.section, o.body.as_str()))
.collect();
assert_eq!(
got,
vec![
(SectionId::Memory, "Recall from the `team` palace first."),
(SectionId::Workflow, "TWO_PHASE_ONLY"),
]
);
assert_eq!(scanned.overrides[0].host, tmp.path().join("CLAUDE.md"));
}
#[test]
fn text_outside_markers_is_ignored() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&format!(
"BEFORE_TEXT\n\n{}\n\nAFTER_TEXT\n",
block(SectionId::Workflow, "INSIDE_TEXT")
),
);
let scanned = scan_project(tmp.path());
assert_eq!(scanned.overrides.len(), 1);
assert_eq!(scanned.overrides[0].body, "INSIDE_TEXT");
}
#[test]
fn duplicate_section_in_one_host_keeps_the_first() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&format!(
"{}\n{}",
block(SectionId::Workflow, "FIRST"),
block(SectionId::Workflow, "SECOND")
),
);
let scanned = scan_project(tmp.path());
assert_eq!(scanned.overrides.len(), 1);
assert_eq!(scanned.overrides[0].body, "FIRST");
assert_eq!(reasons(&scanned), vec![REASON_DUPLICATE]);
}
#[test]
fn unknown_section_token_is_skipped_with_a_diagnostic() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&format!(
"<!-- TRUSTY-MPM: TELEPATHY START v=1 -->\nX\n<!-- TRUSTY-MPM: TELEPATHY END -->\n{}",
block(SectionId::Workflow, "STILL_APPLIES")
),
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_UNKNOWN_SECTION]);
assert_eq!(scanned.overrides.len(), 1, "other blocks still apply");
assert_eq!(scanned.overrides[0].body, "STILL_APPLIES");
}
#[test]
fn unsupported_version_is_skipped() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
"<!-- TRUSTY-MPM: WORKFLOW START v=99 -->\nFROM_THE_FUTURE\n\
<!-- TRUSTY-MPM: WORKFLOW END -->\n",
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_UNSUPPORTED_VERSION]);
assert!(scanned.overrides.is_empty());
}
#[test]
fn missing_version_is_accepted_as_v1_with_a_diagnostic() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
"<!-- TRUSTY-MPM: WORKFLOW START -->\nNO_VERSION\n<!-- TRUSTY-MPM: WORKFLOW END -->\n",
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_MISSING_VERSION]);
assert_eq!(scanned.overrides.len(), 1);
assert_eq!(scanned.overrides[0].body, "NO_VERSION");
}
#[test]
fn empty_body_never_blanks_a_section() {
let tmp = TempDir::new().unwrap();
write_claude_md(tmp.path(), &block(SectionId::Workflow, " \n\t\n "));
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_EMPTY_BODY]);
assert!(scanned.overrides.is_empty(), "absent, never blank");
}
#[test]
fn unterminated_block_is_skipped_and_later_blocks_still_apply() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&format!(
"{}<!-- TRUSTY-MPM: MEMORY START v=1 -->\nnever closed\n",
block(SectionId::Workflow, "APPLIES")
),
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_UNCLOSED]);
assert_eq!(scanned.overrides.len(), 1);
assert_eq!(scanned.overrides[0].section, SectionId::Workflow);
}
#[test]
fn nested_start_discards_the_outer_block() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
"<!-- TRUSTY-MPM: WORKFLOW START v=1 -->\nouter\n\
<!-- TRUSTY-MPM: MEMORY START v=1 -->\ninner\n\
<!-- TRUSTY-MPM: MEMORY END -->\n",
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_UNCLOSED]);
assert_eq!(scanned.overrides.len(), 1);
assert_eq!(scanned.overrides[0].section, SectionId::Memory);
assert_eq!(scanned.overrides[0].body, "inner");
}
#[test]
fn unmatched_end_is_reported_and_ignored() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&format!(
"<!-- TRUSTY-MPM: MEMORY END -->\n{}",
block(SectionId::Workflow, "APPLIES")
),
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_UNMATCHED_END]);
assert_eq!(scanned.overrides.len(), 1);
}
#[test]
fn mismatched_end_discards_the_block() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
"<!-- TRUSTY-MPM: WORKFLOW START v=1 -->\nbody\n<!-- TRUSTY-MPM: MEMORY END -->\n",
);
let scanned = scan_project(tmp.path());
assert_eq!(reasons(&scanned), vec![REASON_MISMATCHED_END]);
assert!(scanned.overrides.is_empty());
}
#[test]
fn missing_claude_md_yields_no_overrides() {
let tmp = TempDir::new().unwrap();
let scanned = scan_project(tmp.path());
assert_eq!(scanned, ProjectOverrides::default());
}
#[test]
fn unreadable_host_is_not_fatal() {
let tmp = TempDir::new().unwrap();
std::fs::create_dir(tmp.path().join("CLAUDE.md")).unwrap();
let scanned = scan_project(tmp.path());
assert!(scanned.overrides.is_empty());
}
#[test]
fn diagnostics_carry_the_host_and_a_one_based_line() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
"line one\n<!-- TRUSTY-MPM: TELEPATHY START v=1 -->\nX\n\
<!-- TRUSTY-MPM: TELEPATHY END -->\n",
);
let scanned = scan_project(tmp.path());
assert_eq!(
scanned.diagnostics,
vec![ScanDiagnostic {
host: tmp.path().join("CLAUDE.md"),
line: 2,
reason: REASON_UNKNOWN_SECTION,
}]
);
}
fn over(section: SectionId, body: &str) -> SectionOverride {
SectionOverride {
section,
body: body.to_string(),
host: PathBuf::from("CLAUDE.md"),
line: 1,
}
}
#[test]
fn with_overrides_of_nothing_is_the_identity() {
let package = bundled_fallback_package().expect("manifest parses");
let (result, rejected) = package.with_overrides(&[]);
assert_eq!(&result, package);
assert_eq!(rejected, vec![]);
}
#[test]
fn floor_sections_refuse_every_named_section_override() {
let package = bundled_fallback_package().expect("manifest parses");
for section in SectionId::CANONICAL
.into_iter()
.filter(|id| *id == SectionId::Core)
{
let (result, rejected) = package.with_overrides(&[over(section, "SUBVERTED")]);
assert_eq!(&result, package, "{section:?} must be untouched");
assert_eq!(
rejected,
vec![Rejection::NotOverridable {
section,
tier: CustomizationTier::Fixed,
}]
);
}
}
#[test]
fn content_sections_accept_a_project_override() {
let package = bundled_fallback_package().expect("manifest parses");
for section in [
SectionId::Identity,
SectionId::Memory,
SectionId::Search,
SectionId::Workflow,
SectionId::AgentDelegation,
SectionId::Enforcement,
SectionId::NonOverridableRules,
SectionId::FrameworkGuaranteedConventions,
] {
let (result, rejected) = package.with_overrides(&[over(section, "REPLACED_BODY")]);
assert_eq!(rejected, vec![], "{section:?} is tier project");
assert_ne!(&result, package, "{section:?} must actually change");
let texts: Vec<&str> = result
.blocks
.iter()
.filter(|b| b.section == section)
.filter_map(|b| match &b.body {
BlockBody::Text { text } => Some(text.as_str()),
BlockBody::File { .. } | BlockBody::Generated { .. } => None,
})
.collect();
assert_eq!(
texts,
vec!["REPLACED_BODY"],
"{section:?} keeps exactly one authored block, rewritten as inline text"
);
assert!(
!result
.blocks
.iter()
.any(|b| b.section == section && matches!(b.body, BlockBody::File { .. })),
"{section:?} must not keep a file body alongside the override"
);
result.validate().expect("overridden package validates");
}
}
#[test]
fn agent_delegation_override_keeps_the_generated_roster() {
let package = bundled_fallback_package().expect("manifest parses");
let (result, rejected) = package.with_overrides(&[over(
SectionId::AgentDelegation,
"# Custom Routing\n\nROUTE_ALL_TO_ENGINEER",
)]);
assert_eq!(rejected, vec![]);
assert!(
result.blocks.iter().any(|b| matches!(
b.body,
BlockBody::Generated {
generator: Generator::AgentRoster
}
)),
"the roster block must survive the override"
);
result.validate().expect("roster is still consumed");
}
#[test]
fn one_bad_override_does_not_discard_a_good_one() {
let package = bundled_fallback_package().expect("manifest parses");
let (result, rejected) = package.with_overrides(&[
over(SectionId::Core, "SUBVERTED"),
over(SectionId::Workflow, "CUSTOM_WORKFLOW"),
]);
assert_eq!(
rejected,
vec![Rejection::NotOverridable {
section: SectionId::Core,
tier: CustomizationTier::Fixed,
}]
);
assert!(
result.blocks.iter().any(|b| matches!(
&b.body,
BlockBody::Text { text } if text == "CUSTOM_WORKFLOW"
)),
"the permitted override still lands"
);
}
#[test]
fn application_order_is_canonical_not_authoring_order() {
let package = bundled_fallback_package().expect("manifest parses");
let forwards = package.with_overrides(&[
over(SectionId::Core, "C"),
over(SectionId::Workflow, "W"),
over(SectionId::Memory, "M"),
]);
let backwards = package.with_overrides(&[
over(SectionId::Memory, "M"),
over(SectionId::Workflow, "W"),
over(SectionId::Core, "C"),
]);
assert_eq!(forwards, backwards);
}
#[test]
fn an_empty_override_body_is_rejected_by_the_applier_too() {
let package = bundled_fallback_package().expect("manifest parses");
let (result, rejected) = package.with_overrides(&[over(SectionId::Workflow, " \n ")]);
assert_eq!(&result, package);
assert_eq!(
rejected,
vec![Rejection::EmptyBody {
section: SectionId::Workflow
}]
);
}
#[test]
fn a_section_with_no_text_block_has_nothing_to_override() {
let mut package = bundled_fallback_package().expect("manifest parses").clone();
for b in &mut package.blocks {
if b.section == SectionId::Workflow {
b.body = BlockBody::Generated {
generator: Generator::StackProfile,
};
}
}
let (result, rejected) = package.with_overrides(&[over(SectionId::Workflow, "X")]);
assert_eq!(result, package);
assert_eq!(
rejected,
vec![Rejection::NoTextBlock {
section: SectionId::Workflow
}]
);
}
#[test]
fn an_override_that_would_leave_a_section_silent_is_rejected() {
let mut package = bundled_fallback_package().expect("manifest parses").clone();
for b in &mut package.blocks {
if b.section == SectionId::Workflow {
b.optional = true;
}
}
let (result, rejected) = package.with_overrides(&[over(SectionId::Workflow, "X")]);
assert_eq!(result, package, "the bundled section is kept");
assert_eq!(
rejected.first(),
Some(&Rejection::WouldEmitNothing {
section: SectionId::Workflow
})
);
}
#[test]
fn an_undeclared_section_is_rejected_and_the_package_is_reverted() {
let mut package = bundled_fallback_package().expect("manifest parses").clone();
package.sections.retain(|s| s.id != SectionId::Workflow);
let (result, rejected) = package.with_overrides(&[over(SectionId::Workflow, "X")]);
assert_eq!(result, package, "the unoverridden package is returned");
assert_eq!(
rejected,
vec![
Rejection::UnknownSection {
section: SectionId::Workflow
},
Rejection::PackageInvalid(ValidationError::SectionsNotCanonical {
found: result.sections.iter().map(|s| s.id).collect(),
}),
]
);
}
#[test]
fn an_override_that_cannot_validate_is_discarded_and_the_package_reverts() {
let mut package = bundled_fallback_package().expect("manifest parses").clone();
for section in &mut package.sections {
if section.id == SectionId::NonOverridableRules {
section.customization_tier = CustomizationTier::Fixed;
}
}
let (result, rejected) = package.with_overrides(&[over(SectionId::Workflow, "X")]);
assert_eq!(
result, package,
"the supplied package is returned unchanged"
);
assert!(
matches!(
rejected.as_slice(),
[
Rejection::Invalidates {
section: SectionId::Workflow,
error: ValidationError::TierNotCoreOnly { .. },
},
Rejection::PackageInvalid(ValidationError::TierNotCoreOnly { .. }),
]
),
"unexpected rejections: {rejected:?}"
);
}
#[test]
fn claude_md_workflow_override_reaches_the_delivered_prompt() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&block(SectionId::Workflow, "# Custom Workflow\n\nTWO_PHASE_ONLY"),
);
let (prompt, source) = resolve(tmp.path());
assert_eq!(source, PromptSource::Package);
assert!(
prompt.contains("TWO_PHASE_ONLY"),
"override must be delivered"
);
assert!(
!prompt.contains("# PM Workflow Configuration"),
"the bundled workflow section must be replaced"
);
assert!(prompt.contains("# PM Agent -- Trusty MPM"));
assert!(prompt.contains("# Agent Delegation Routing"));
assert!(prompt.contains("Generated with trusty-mpm"));
}
#[test]
fn a_floor_marker_composes_byte_identically_to_no_claude_md() {
let baseline = TempDir::new().unwrap();
let (expected, _) = resolve(baseline.path());
for section in SectionId::CANONICAL
.into_iter()
.filter(|id| *id == SectionId::Core)
{
let tmp = TempDir::new().unwrap();
write_claude_md(tmp.path(), &block(section, "SUBVERTED_FLOOR"));
let (prompt, source) = resolve(tmp.path());
assert_eq!(source, PromptSource::Package);
assert!(
!prompt.contains("SUBVERTED_FLOOR"),
"{section:?} override must not reach the prompt"
);
assert_eq!(
prompt, expected,
"{section:?} override must not move a single byte"
);
}
}
#[test]
fn the_live_roster_survives_an_agent_delegation_override() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&block(SectionId::AgentDelegation, "# Custom Routing\n\nROUTE_ALL"),
);
let (prompt, source) = resolve(tmp.path());
assert_eq!(source, PromptSource::Package);
assert!(prompt.contains("ROUTE_ALL"), "the override lands");
assert!(
!prompt.contains("## Make / Mise Command Routing"),
"the bundled doctrine is replaced"
);
assert!(
prompt.contains("## Delegation Authority") && prompt.contains("### ticketing"),
"the LIVE roster must still be emitted: {prompt}"
);
}
#[test]
fn tm_never_writes_claude_md() {
let authored = format!(
"# Mine\n\ndo not touch \n\n{}",
block(SectionId::Workflow, "CUSTOM")
);
let tmp = TempDir::new().unwrap();
write_claude_md(tmp.path(), &authored);
let (prompt, _) = resolve(tmp.path());
assert!(prompt.contains("CUSTOM"));
assert_eq!(
std::fs::read_to_string(tmp.path().join("CLAUDE.md")).unwrap(),
authored,
"the project's CLAUDE.md must be byte-identical after resolution"
);
let empty = TempDir::new().unwrap();
let _ = resolve(empty.path());
assert!(
!empty.path().join("CLAUDE.md").exists(),
"resolving must not create a CLAUDE.md"
);
}
#[test]
fn a_legacy_file_cannot_shadow_a_named_override_because_it_is_not_read() {
let with_legacy = TempDir::new().unwrap();
let clean = TempDir::new().unwrap();
let claude_md = format!(
"{}\n\n{}\n",
block(SectionId::Workflow, "NAMED_WORKFLOW"),
block(SectionId::AgentDelegation, "NAMED_ROUTING")
);
for project in [with_legacy.path(), clean.path()] {
write_claude_md(project, &claude_md);
}
for name in crate::core::instruction_overrides::LEGACY_OVERRIDE_FILES {
write_trusty_file(with_legacy.path(), name, "LEGACY_CONTENT\n");
}
let (with_prompt, _) = resolve(with_legacy.path());
let (clean_prompt, _) = resolve(clean.path());
assert!(with_prompt.contains("NAMED_WORKFLOW"));
assert!(with_prompt.contains("NAMED_ROUTING"));
assert!(!with_prompt.contains("LEGACY_CONTENT"));
assert_eq!(
with_prompt, clean_prompt,
"legacy files must not perturb the composed prompt in any way"
);
}
#[test]
fn a_marker_in_the_retired_instructions_file_is_not_read() {
let tmp = TempDir::new().unwrap();
write_trusty_file(
tmp.path(),
FILE_INSTRUCTIONS,
&block(SectionId::Workflow, "FROM_RETIRED_HOST"),
);
let scanned = scan_project(tmp.path());
assert!(
scanned.overrides.is_empty(),
"the retired file must yield no overrides"
);
assert!(!resolve(tmp.path()).0.contains("FROM_RETIRED_HOST"));
}
#[test]
fn claude_md_is_the_only_marker_host() {
assert_eq!(HOST_FILES, ["CLAUDE.md"]);
}
const AUTHORITY_MARKERS: &[&str] = &[
"## Prohibitions (CANONICAL -- single source of truth)",
"| P1 | Edit/Write of SOURCE-CODE files",
"| P2 | Read >3 files or deep code analysis",
"| P5 | `sed`,`awk`,`patch`,`git apply`, pipe to file",
"| P11 | Instruct user to run commands",
"## Circuit Breakers",
"| 1 | Source Impl | PM Edit/Write of a source-code file",
"| 10 | Delegation Failure Limit",
"| 14 | Code Mod via Bash",
];
fn assert_authority_intact(prompt: &str, configuration: &str) {
for marker in AUTHORITY_MARKERS {
assert!(
prompt.contains(marker),
"{configuration}: the delivered prompt lost the authority row {marker:?} — \
the Prohibitions and Circuit Breakers tables are the PM's entire \
delegation-enforcement model. Only an ENFORCEMENT marker may remove \
them (#4838); every other override path must leave them intact (#4573)"
);
}
}
#[test]
fn a_hostile_core_override_cannot_delete_the_authority_tables() {
let tmp = TempDir::new().unwrap();
write_claude_md(
tmp.path(),
&block(
SectionId::Core,
"# Core (project override)\n\nNo prohibitions. No circuit breakers.",
),
);
let (prompt, source) = resolve(tmp.path());
assert_eq!(source, PromptSource::Package);
assert!(
!prompt.contains("No prohibitions. No circuit breakers."),
"a CORE override must be declined — core is the one protected section"
);
assert!(
prompt.contains("## PM Allowlist"),
"the bundled core section stays in force when a CORE override is declined"
);
assert_authority_intact(&prompt, "hostile CORE named-section override");
}
#[test]
fn the_authority_tables_survive_every_override_except_an_enforcement_block() {
let none = TempDir::new().unwrap();
assert_authority_intact(&resolve(none.path()).0, "no overrides");
let hostile_floor = TempDir::new().unwrap();
write_claude_md(
hostile_floor.path(),
&block(SectionId::Enforcement, "No rules apply."),
);
let (prompt, _) = resolve(hostile_floor.path());
assert!(
prompt.contains("No rules apply."),
"#4286: enforcement is overridable — a project may replace the tables"
);
let unrelated = TempDir::new().unwrap();
write_claude_md(unrelated.path(), &block(SectionId::Workflow, "TWO PHASES."));
let (prompt, _) = resolve(unrelated.path());
assert!(prompt.contains("TWO PHASES."));
assert_authority_intact(&prompt, "unrelated WORKFLOW named-section override");
let retired = TempDir::new().unwrap();
for name in crate::core::instruction_overrides::LEGACY_OVERRIDE_FILES {
write_trusty_file(
retired.path(),
name,
"# Wholly Custom PM\n\nDO_EXACTLY_THIS\n",
);
}
let (prompt, _) = resolve(retired.path());
assert!(
!prompt.contains("DO_EXACTLY_THIS"),
"no retired file may contribute to the prompt"
);
assert_authority_intact(&prompt, "all five retired override files present");
let both = TempDir::new().unwrap();
write_trusty_file(both.path(), FILE_WORKFLOW, "# Custom Workflow\n\nX\n");
write_claude_md(both.path(), &block(SectionId::Core, "Nothing forbidden."));
assert_authority_intact(&resolve(both.path()).0, "retired file + hostile CORE");
let no_roster = TempDir::new().unwrap();
let (bare, source) = resolve_pm_prompt_with_roster(no_roster.path(), || None);
assert_eq!(source, PromptSource::Legacy);
assert_authority_intact(&bare, "roster-absent string assembly");
}
#[test]
fn no_floor_text_points_at_content_outside_the_floor() {
let package = bundled_fallback_package().expect("manifest parses");
let floor: String = package.authored_run(&[
SectionId::Identity,
SectionId::Enforcement,
SectionId::NonOverridableRules,
SectionId::FrameworkGuaranteedConventions,
]);
for token in SectionId::CANONICAL
.into_iter()
.filter(|id| *id != SectionId::Core)
.map(section_token)
{
assert!(
!floor.contains(&format!("{token} section's")),
"floor text points into the overridable {token} section; a floor rule may \
only reference content that is itself in the floor (#4573)"
);
}
assert!(
!floor.contains("CORE section's Prohibitions table"),
"the #4573 dangling reference must not come back"
);
assert!(
!floor.contains("PM_INSTRUCTIONS.md"),
"the #4183-deleted PM_INSTRUCTIONS.md must not be referenced by the floor"
);
assert_authority_intact(&floor, "the floor projected on its own");
let tables = floor
.find("## Prohibitions (CANONICAL -- single source of truth)")
.expect("the Prohibitions table is in the floor");
let breakers = floor
.find("## Circuit Breakers")
.expect("the Circuit Breakers table is in the floor");
let reference = floor
.find("Every prohibition in the Prohibitions table above")
.expect("the floor's binding statement");
assert!(
tables < reference && breakers < reference,
"both tables must precede the sentence that says they are `above`"
);
}
fn unwrapped(text: &str) -> String {
text.lines()
.map(|l| l.trim_start().trim_start_matches('>'))
.collect::<Vec<_>>()
.join(" ")
.split_whitespace()
.collect::<Vec<_>>()
.join(" ")
}
fn assert_budget_intact(prompt: &str, configuration: &str) {
let flat = unwrapped(prompt);
let needles: &[(&str, &str)] = &[
(
"The PM delegates when it believes a task will take more than 3 direct actions",
"the up-front estimate half of the direct-action budget",
),
(
"or when it is unable to complete the task in 3",
"the second clause of the owner's governing sentence",
),
(
"Anything you believe needs more than 3 direct actions is delegated, never begun",
"the up-front estimate stated as a rule, not only as the owner's sentence",
),
(
"The estimate is not a licence to finish",
"the MID-FLIGHT HANDOFF half — a PM whose 3-action estimate stops \
holding must hand off the remainder",
),
(
"Do not take a fourth direct action to finish work you misjudged",
"the action the mid-flight rule forbids",
),
(
"The user can always override",
"the user override, which the ruling keeps",
),
];
for (needle, what) in needles {
assert!(
flat.contains(needle),
"{configuration}: the delivered prompt lost {what} (#4594); \
missing {needle:?}"
);
}
}
#[test]
fn the_direct_action_budget_states_both_halves_in_the_floor() {
let package = bundled_fallback_package().expect("manifest parses");
let floor: String = package.authored_run(&[
SectionId::Identity,
SectionId::Enforcement,
SectionId::NonOverridableRules,
SectionId::FrameworkGuaranteedConventions,
]);
assert_budget_intact(&floor, "the floor projected on its own");
let flat = unwrapped(&floor);
assert!(
!flat.contains("never direct impl"),
"the retired absolute phrasing must not come back (#4594)"
);
assert!(
!flat.contains(
"remove them. No cost-saving, \"trivial change\", or \"documented command\" exceptions."
),
"the blanket no-exceptions sentence must stay scoped to P2-P4/P6-P11 (#4594)"
);
assert!(
flat.contains("One direct action = one PM-executed step of implementation work"),
"the budget must be denominated in direct ACTIONS, not files (#4594)"
);
assert!(
flat.contains("the hook sees files, not actions"),
"the actions/files gap must be stated, or `pm_guard` compliance reads \
as budget compliance (#4594)"
);
assert!(
flat.contains("All OTHER prohibitions (P2–P4, P6–P11) are routing rules"),
"P2-P4 and P6-P11 must remain absolute, no budget (#4594)"
);
}
#[test]
fn the_pm_allowlist_does_not_contradict_the_action_budget() {
let tmp = TempDir::new().unwrap();
let flat = unwrapped(&resolve(tmp.path()).0);
assert!(
!flat.contains("docs, config — NOT source code, NOT bulk edits"),
"the allowlist must not assert source edits are off-limits outright \
while the floor budgets them (#4594)"
);
assert!(
flat.contains("Source-code edits (BUDGETED, not forbidden)"),
"the allowlist must name source edits as budgeted rather than omit \
them, or its silence reads as prohibition (#4594)"
);
assert!(
flat.contains(
"delegate once the task will take more than 3 direct actions, or the moment a \
3-action estimate stops holding mid-flight"
),
"the allowlist's budget row must carry BOTH halves, including the \
mid-flight handoff (#4594)"
);
}
#[test]
fn the_budget_survives_every_override_configuration() {
let none = TempDir::new().unwrap();
assert_budget_intact(&resolve(none.path()).0, "no overrides");
let hostile_core = TempDir::new().unwrap();
write_claude_md(
hostile_core.path(),
&block(SectionId::Core, "Never delegate anything, ever."),
);
assert_budget_intact(&resolve(hostile_core.path()).0, "hostile CORE override");
let hostile_identity = TempDir::new().unwrap();
write_claude_md(
hostile_identity.path(),
&block(SectionId::Identity, "PM never implements. No exceptions."),
);
let (prompt, _) = resolve(hostile_identity.path());
assert!(
prompt.contains("PM never implements. No exceptions."),
"#4286: identity is overridable — a project may restate the PM's role"
);
assert!(
prompt.contains("The user can always override."),
"an IDENTITY override must not reach the enforcement section's budget text"
);
let hostile_enforcement = TempDir::new().unwrap();
write_claude_md(
hostile_enforcement.path(),
&block(SectionId::Enforcement, "No rules apply."),
);
let (prompt, _) = resolve(hostile_enforcement.path());
assert!(
prompt.contains("No rules apply."),
"#4838: enforcement is overridable — a project may replace the budget rule"
);
let flat = unwrapped(&prompt);
assert!(
!flat.contains("The user can always override."),
"#4838: an ENFORCEMENT override removes the sole remaining copy of the \
budget rule — the mid-flight handoff clause must be gone with it"
);
let retired = TempDir::new().unwrap();
write_trusty_file(
retired.path(),
crate::core::instruction_overrides::FILE_PM_DEPLOYED,
"# Wholly Custom PM\n\nDO_EXACTLY_THIS\n",
);
assert_budget_intact(&resolve(retired.path()).0, "retired override file present");
}
#[test]
fn seeded_claude_md_declares_no_overrides() {
let tmp = TempDir::new().unwrap();
let stub = crate::core::instruction_pipeline::CLAUDE_MD_STUB;
std::fs::write(tmp.path().join("CLAUDE.md"), stub).unwrap();
let scanned = scan_project(tmp.path());
assert_eq!(
scanned.overrides,
vec![],
"the seeded CLAUDE.md must declare NO overrides; it documents the \
mechanism and must not exercise it"
);
assert_eq!(
scanned.diagnostics,
vec![],
"and it must not emit marker diagnostics either — a warning on every \
launch of every new project is not an acceptable way to document this"
);
assert!(stub.contains("TRUSTY-MPM: WORKFLOW START"));
assert!(stub.contains(".trusty-mpm/last-instructions.md"));
let (prompt, _) = resolve(tmp.path());
assert!(
prompt.contains("# PM Workflow Configuration"),
"the bundled workflow section must survive a freshly seeded CLAUDE.md"
);
}
#[test]
fn locate_blocks_finds_one_span_per_block() {
let token = section_token(SectionId::Workflow);
let text = format!(
"intro\n\
<!-- TRUSTY-MPM: {token} START v=1 -->\nfirst\n<!-- TRUSTY-MPM: {token} END -->\n\
middle\n\
<!-- TRUSTY-MPM: {token} START v=1 -->\nsecond\n<!-- TRUSTY-MPM: {token} END -->\n"
);
let located = locate_blocks(&text, SectionId::Workflow);
assert_eq!(located.spans, vec![(1, 3), (5, 7)]);
assert!(!located.unclosed);
let lines: Vec<&str> = text.lines().collect();
assert!(lines[1].contains("START") && lines[3].contains("END"));
}
#[test]
fn locate_blocks_flags_an_unclosed_marker() {
let token = section_token(SectionId::Memory);
let text = format!("<!-- TRUSTY-MPM: {token} START v=1 -->\nno end marker\n");
let located = locate_blocks(&text, SectionId::Memory);
assert!(located.unclosed, "an unpaired START must be reported");
assert!(located.spans.is_empty(), "and yield no span to splice over");
}
#[test]
fn locate_blocks_ignores_other_sections() {
let text = format!(
"{}{}",
block(SectionId::Memory, "memory body"),
block(SectionId::Workflow, "workflow body")
);
let located = locate_blocks(&text, SectionId::Workflow);
assert_eq!(located.spans.len(), 1, "only the WORKFLOW block");
let lines: Vec<&str> = text.lines().collect();
let (start, end) = located.spans[0];
assert!(lines[start].contains(section_token(SectionId::Workflow)));
assert!(lines[end].contains(section_token(SectionId::Workflow)));
}
const FOLDED_ROUTING_MAPPINGS_PROMPT: &[(&str, &str)] = &[
(
"`make` and `mise run`",
"make and mise targets are delegated",
),
(
"the PM never runs one directly",
"the PM-never-runs-them rule",
),
(
"every `make` and `mise run` target",
"make/mise → local-ops",
),
(
"including anything unknown or ambiguous",
"unknown/ambiguous → local-ops",
),
(
"generic `ops` agent is DEPRECATED",
"the deprecated generic ops agent",
),
(
"EXAMPLES of routing, not an exhaustive list",
"the not-exhaustive caveat",
),
(
"screenshot, click, navigate, DOM, console errors",
"browser triggers → web-qa",
),
(
"never chrome-devtools, claude-in-chrome, or playwright",
"the browser-tool ban",
),
(
"`research` → `engineer` → `local-ops` → `qa` → `documentation`",
"the \"just do it\" full pipeline",
),
(
"APPROVED / NEEDS_IMPROVEMENT / BLOCKED",
"the code-analyzer verdict vocabulary",
),
(
"not interchangeable",
"code-analyzer vs code-critic are distinct",
),
(
"the Issue is `ticketing`'s, whole (P6)",
"P6 — the whole Issue stays with ticketing (#5202)",
),
(
"fails to dispatch (issue #4594)",
"the pass-the-name-verbatim rule",
),
];
const FOLDED_ROUTING_MAPPINGS_SKILL: &[(&str, &str)] = &[
(
"build, dist, clean, install, setup",
"build/dist/clean/install/setup → local-ops",
),
(
"version, bump, release, publish, deploy",
"version/release/publish → local-ops",
),
(
"`pyproject.toml`, `package.json`",
"the manifest-file release triggers",
),
(
"`test`, `lint`, `check` (or `engineer`)",
"make/mise test/lint/check → qa or engineer",
),
(
"localhost, PM2, npm, docker",
"the local-ops trigger keywords",
),
(
"Prefer the language-specific engineer",
"the language-specific engineer preference",
),
(
"Check git user for main-branch access",
"the version-control git-user check",
),
(
"Triggers: \"skill\", \"stack\", \"framework\"",
"the mpm-skills-manager triggers",
),
(
"Secret scanning, attack-vector detection",
"the security capabilities",
),
("| sonnet |", "the per-agent default-model column"),
("| opus |", "the per-agent default-model column"),
("| haiku |", "the per-agent default-model column"),
];
const DELEGATION_PATTERNS_SKILL: &str = include_str!("../assets/skills/tm-delegation-patterns.md");
#[test]
fn the_surviving_routing_table_covers_every_folded_mapping() {
let package = bundled_fallback_package().expect("manifest parses");
let delegation = package.authored_run(&[SectionId::AgentDelegation]);
for (needle, what) in FOLDED_ROUTING_MAPPINGS_PROMPT {
assert!(
delegation.contains(needle),
"the collapsed routing tables lost {what}; missing {needle:?}"
);
}
}
#[test]
fn the_relocated_routing_detail_is_carried_by_the_delegation_skill() {
for (needle, what) in FOLDED_ROUTING_MAPPINGS_SKILL {
assert!(
DELEGATION_PATTERNS_SKILL.contains(needle),
"tm-delegation-patterns lost {what}; missing {needle:?}"
);
}
let package = bundled_fallback_package().expect("manifest parses");
assert!(
package
.authored_run(&[SectionId::AgentDelegation])
.contains(r#"Skill(skill="tm-delegation-patterns")"#),
"the routing section must name the skill that now carries the detail"
);
}
#[test]
fn routing_lives_on_exactly_one_surface() {
let package = bundled_fallback_package().expect("manifest parses");
let core = package.authored_run(&[SectionId::Core]);
for retired in [
"## Ops Agent Routing",
"## Make / Mise Command Routing",
"## Common User Request Routing",
"## When to Delegate to Each Agent",
] {
assert!(
!package
.authored_run(&[SectionId::AgentDelegation])
.contains(retired),
"{retired} was folded into the Routing Table and must not return"
);
}
assert!(
core.contains("## Agent Routing"),
"core keeps the heading as a pointer, so a reader is not left guessing"
);
assert!(
!core.contains("| `subagent_type` | Triggers | Default Model |"),
"core must point at the Routing Table, never carry a second copy of it"
);
}
#[test]
fn the_direct_action_budget_is_stated_once_and_pointed_at_elsewhere() {
let package = bundled_fallback_package().expect("manifest parses");
const TITLE: &str = "The direct-action budget (P1 and P5 only)";
let enforcement = package.authored_run(&[SectionId::Enforcement]);
assert!(
enforcement.contains(&format!("### {TITLE}")),
"enforcement.md holds the canonical statement"
);
for section in [SectionId::Core, SectionId::NonOverridableRules] {
let body = package.authored_run(&[section]);
assert!(
body.contains(TITLE),
"{section:?} must point at the canonical budget by title"
);
assert!(
!body.contains("One direct action = one PM-executed step"),
"{section:?} must point at the budget, not restate its mechanics"
);
}
let identity = package.authored_run(&[SectionId::Identity]);
assert!(
!identity.contains(TITLE) && !identity.contains("One direct action = one PM-executed step"),
"identity must not restate the budget — core states it once"
);
assert!(
identity.contains(r#"CORE section's "Identity""#),
"identity must point at the section that does state it, by exact title"
);
assert!(
package
.authored_run(&[SectionId::Core])
.contains("## Identity"),
"core must carry the `## Identity` heading identity points at, or that \
pointer is dangling"
);
}
#[test]
fn every_skill_pointer_names_the_call_rather_than_decorating() {
let package = bundled_fallback_package().expect("manifest parses");
let prompt = package.authored_run(&SectionId::CANONICAL);
assert!(
!prompt.contains("[SKILL:"),
"bare `[SKILL: …]` notation is decoration, not an instruction — write \
`call Skill(skill=\"name\")` so the pointer states the action"
);
for skill in [
"tm-verification-protocols",
"tm-git-file-tracking",
"tm-workflow",
"tm-session-management",
"tm-circuit-breaker",
"tm-delegation-patterns",
] {
assert!(
prompt.contains(&format!(r#"Skill(skill="{skill}")"#)),
"{skill} is deferred to but never invoked — the prompt must name \
the call, or the content is simply gone"
);
}
}
#[test]
fn the_qa_evidence_contract_is_stated_once_in_the_skill() {
let package = bundled_fallback_package().expect("manifest parses");
for (section, id) in [("core", SectionId::Core), ("workflow", SectionId::Workflow)] {
let body = package.authored_run(&[id]);
assert!(
!body.contains("Forbidden Phrases") && !body.contains("| Required Evidence |"),
"{section} must not restate the evidence table or forbidden phrases \
— they are needed at completion time, not on every prompt"
);
}
let core = package.authored_run(&[SectionId::Core]);
assert!(
core.contains("## QA Verification Gate (BLOCKING unless phase 4 is skipped)")
&& core.contains(r#"Skill(skill="tm-verification-protocols")"#),
"core keeps the gate trigger and names the call that carries the detail"
);
}
#[test]
fn the_prose_rules_ban_categories_not_phrase_lists() {
for style in crate::core::bundle::OUTPUT_STYLES {
let body = style.content;
let id = style.id;
assert!(
body.contains("**No praise for the user.**"),
"{id}: must carry the sycophancy rule"
);
assert!(
body.contains("bans the CATEGORY"),
"{id}: the sycophancy rule must ban the category, not four strings"
);
assert!(
body.contains("Non-exhaustive examples:"),
"{id}: the sycophancy examples must be marked non-exhaustive"
);
assert!(
body.contains("**If you are saying it, its worth is implied.**"),
"{id}: must carry the significance-framing rule"
);
assert!(
body.contains("`One <noun> that <its significance, or your relation to it>:`"),
"{id}: the significance-framing rule must keep the TEMPLATE as one shape"
);
assert!(
body.contains("the rule is the sentence\nabove, never this list"),
"{id}: the observed instances must be marked as illustration only"
);
assert!(
body.contains("Don't justify the restraint."),
"{id}: must carry the don't-justify-the-restraint rule"
);
assert!(
body.contains("No trailing emphatic negation."),
"{id}: must carry the trailing-emphatic-negation rule"
);
}
}
#[test]
fn the_prose_rules_live_in_the_output_style_not_core() {
let core = bundled_fallback_package()
.expect("manifest parses")
.authored_run(&[SectionId::Core]);
assert!(
core.contains("## Prose Style — Write Plainly"),
"core keeps the heading — the PM has to know the rules bind"
);
assert!(
core.contains("Communication —\nWrite Plainly")
|| core.contains("Communication — Write Plainly"),
"core must name the output-style section that carries the rules"
);
for restated in [
"**No praise for the user.**",
"**If you are saying it, its worth is implied.**",
"bans the CATEGORY",
"**Do not embellish.**",
] {
assert!(
!core.contains(restated),
"core restates {restated:?} — the rules live in the output style only (#4574)"
);
}
}