prompt: matched-close check + drop dead-code guard (argus #527 nits)
This commit is contained in:
parent
1c8e72c81f
commit
800d9925a5
1 changed files with 44 additions and 9 deletions
|
|
@ -52,7 +52,11 @@ pub fn render(flavor: Flavor, label: &str, operator_pronouns: &str) -> String {
|
|||
/// Walk `template` line-by-line. Inside a `<!-- role:X -->` block,
|
||||
/// suppress all lines unless `X == target`. Marker lines themselves are
|
||||
/// always elided from the output. Unbalanced openers (no matching
|
||||
/// closer) hold the suppression state until end-of-file.
|
||||
/// closer) hold the suppression state until end-of-file. A mismatched
|
||||
/// closer (`<!-- /role:manager -->` inside a `role:agent` block) is
|
||||
/// elided from the output but does NOT reset the active role — keeps
|
||||
/// the suppression conservative so a typo can't dump wrong-flavor
|
||||
/// content (per argus #527 review nit).
|
||||
fn filter_role_blocks(template: &str, target: &str) -> String {
|
||||
let mut out = String::with_capacity(template.len());
|
||||
// None = outside any block; Some(role) = inside role-tagged block.
|
||||
|
|
@ -63,8 +67,12 @@ fn filter_role_blocks(template: &str, target: &str) -> String {
|
|||
active_role = Some(role);
|
||||
continue;
|
||||
}
|
||||
if parse_close_marker(trimmed).is_some() {
|
||||
active_role = None;
|
||||
if let Some(close_role) = parse_close_marker(trimmed) {
|
||||
if active_role == Some(close_role) {
|
||||
active_role = None;
|
||||
}
|
||||
// Mismatched close: elide the marker line but keep the
|
||||
// active role intact so wrong-flavor content stays gated.
|
||||
continue;
|
||||
}
|
||||
let include = match active_role {
|
||||
|
|
@ -82,15 +90,12 @@ fn filter_role_blocks(template: &str, target: &str) -> String {
|
|||
/// `<!-- role:agent -->` → `Some("agent")`. Anything else returns
|
||||
/// None. Whitespace inside the marker is tolerated so a future
|
||||
/// author's `<!--role:foo-->` (no spaces) still parses; the dashboard
|
||||
/// markdown renderer is equally lenient.
|
||||
/// markdown renderer is equally lenient. Close tags (`/role:...`)
|
||||
/// can't accidentally match — the `strip_prefix("role:")` rejects
|
||||
/// the leading slash before we'd ever see it.
|
||||
fn parse_open_marker(line: &str) -> Option<&str> {
|
||||
let inside = line.strip_prefix("<!--")?.strip_suffix("-->")?.trim();
|
||||
let role = inside.strip_prefix("role:")?.trim();
|
||||
// Reject closer-looking content ("/role:..." would start with "/")
|
||||
// so `/role:agent` doesn't accidentally match here.
|
||||
if role.starts_with('/') {
|
||||
return None;
|
||||
}
|
||||
Some(role)
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +187,36 @@ shared closer
|
|||
assert_eq!(parse_close_marker("just text"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatched_close_keeps_active_role() {
|
||||
// `<!-- role:agent -->` block with a stray `<!-- /role:manager -->`
|
||||
// closer inside: the manager-tagged close must NOT pop the agent
|
||||
// gate, else manager-target output would leak the agent block's
|
||||
// text (or vice-versa). Stray marker line itself is still elided.
|
||||
// Per argus #527 review nit.
|
||||
let template = "shared\n\
|
||||
<!-- role:agent -->\n\
|
||||
agent line 1\n\
|
||||
<!-- /role:manager -->\n\
|
||||
agent line 2\n\
|
||||
<!-- /role:agent -->\n\
|
||||
shared end\n";
|
||||
let manager = filter_role_blocks(template, "manager");
|
||||
// Both agent lines stay gated out for the manager target; the
|
||||
// stray close didn't accidentally pop the role. Stray marker
|
||||
// itself elided from the output.
|
||||
assert!(!manager.contains("agent line 1"));
|
||||
assert!(!manager.contains("agent line 2"));
|
||||
assert!(!manager.contains("<!--"));
|
||||
assert!(manager.contains("shared"));
|
||||
assert!(manager.contains("shared end"));
|
||||
// Agent target still sees both lines (matched closer pops at the end).
|
||||
let agent = filter_role_blocks(template, "agent");
|
||||
assert!(agent.contains("agent line 1"));
|
||||
assert!(agent.contains("agent line 2"));
|
||||
assert!(agent.contains("shared end"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unbalanced_opener_suppresses_until_eof() {
|
||||
// Stray opener with no closer — content stays suppressed for
|
||||
|
|
|
|||
Loading…
Reference in a new issue