#[test]
fn a_long_parent_body_is_truncated_with_its_source_named() {
let body = repeated_lines("line", 250);
let plan = format!(
"# Rhei: Long\n\n---\nstructure:\n maxLevels: 3\n---\n\n## Tasks\n\n\
### Task 1: Parent\n**State:** pending\n\n{body}\n#### Task 1.1: Child\n\
**State:** review\n"
);
let dir = memory_dir(&[("plan.rhei.md", plan.as_str())]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.1").expect("task 1.1");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "review");
let position = render_position(&context);
assert!(position.contains("line 200\n"), "got:\n{position}");
assert!(!position.contains("line 201\n"), "got:\n{position}");
assert!(
position.contains("\u{2026} truncated; read plan.rhei.md\n"),
"got:\n{position}"
);
}
#[test]
fn a_long_result_file_keeps_its_newest_entries() {
let body = repeated_lines("entry", 150);
let dir = memory_plan_dir(&[
("runtime/state-transitions.log", "plan.1.3 pending@review\n"),
("runtime/results/plan.1.3.md", body.as_str()),
]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.3").expect("task 1.3");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "review");
let visits = render_previous_visits(&context).expect("visits");
assert!(
visits.contains(
"\u{2026} earlier entries omitted; read runtime/results/plan.1.3.md\n"
),
"got:\n{visits}"
);
assert!(visits.contains("entry 150\n"), "got:\n{visits}");
assert!(!visits.contains("entry 50\n"), "got:\n{visits}");
}
#[test]
fn a_long_summary_is_cut_to_120_columns() {
let long = "x".repeat(200);
let body = format!("## Result\n\n{long}\n\nmore detail below\n");
let dir = memory_plan_dir(&[
("runtime/state-transitions.log", "plan.1.1 pending@completed\n"),
("runtime/results/plan.1.1.md", body.as_str()),
]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.4").expect("task 1.4");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
let expected = format!("{}\u{2026}\n", "x".repeat(120));
assert!(history.contains(&expected), "got:\n{history}");
assert!(!history.contains("more detail below"), "got:\n{history}");
}
#[test]
fn the_cap_drops_the_oldest_own_entries_and_names_the_command() {
let mut plan = String::from(
"# Rhei: Wide\n\n---\nstructure:\n maxLevels: 3\n---\n\n## Tasks\n\n\
### Task 1: Parent\n**State:** pending\n\n",
);
let mut ledger = String::new();
for n in 1..=50 {
plan.push_str(&format!("#### Task 1.{n}: Step {n}\n**State:** completed\n\n"));
ledger.push_str(&format!("plan.1.{n} pending@completed\n"));
}
plan.push_str("#### Task 1.51: Last\n**State:** pending\n");
let dir = memory_dir(&[
("plan.rhei.md", plan.as_str()),
("runtime/state-transitions.log", ledger.as_str()),
]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.51").expect("task 1.51");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
assert!(
history.contains(
"\u{2026} 10 earlier tasks not shown \u{2014} rhei list --rhei plan --terminal\n"
),
"got:\n{history}"
);
assert!(!history.contains("Task plan.1.10:"), "the oldest go first; got:\n{history}");
assert!(history.contains("Task plan.1.11:"), "got:\n{history}");
assert_eq!(
history.lines().filter(|line| line.starts_with("- Task ")).count(),
memory_caps::PLAN_HISTORY
);
}
#[test]
fn the_cap_never_drops_a_cross_rhei_prior() {
let mut downstream = String::from("# Rhei: Downstream\n\n## Tasks\n\n");
let mut ledger = String::new();
for n in 1..=45 {
downstream.push_str(&format!("### Task {n}: Step {n}\n**State:** completed\n\n"));
ledger.push_str(&format!("downstream.{n} pending@completed\n"));
}
downstream.push_str("### Task 46: Consume the schema\n**State:** pending\n**Prior:** upstream.1\n");
let dir = memory_dir(&[
("index.panta.md", "# Panta: Backlog\n"),
(
"upstream.rhei.md",
"# Rhei: Upstream\n\n## Tasks\n\n### Task 1: Publish the schema\n\
**State:** completed\n",
),
("downstream.rhei.md", downstream.as_str()),
("runtime/state-transitions.log", ledger.as_str()),
]);
let project = dir.path().to_path_buf();
let loaded = load_plan(&project).expect("project loads");
let mut memory =
prompt_memory(&loaded, &project, &dir.path().join("runtime"), BTreeSet::new());
memory.pastes_task_inputs = false;
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "downstream.46").expect("downstream.46");
let context =
memory_context(dir.path(), &project, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
assert!(
history.contains(
"\u{2026} 6 earlier tasks not shown \u{2014} rhei list --rhei downstream \
--terminal\n"
),
"got:\n{history}"
);
assert!(!history.contains("Task downstream.6:"), "the oldest own go first; got:\n{history}");
assert!(history.contains("- Task downstream.7: Step 7"), "got:\n{history}");
assert!(
history.contains(
"- Task upstream.1: Publish the schema \u{2014} completed \u{2014} (no result) \
(rhei `upstream`, prior)\n"
),
"the prior survives the cap; got:\n{history}"
);
}
#[test]
fn dependents_are_capped_and_name_the_command() {
let mut plan = String::from(
"# Rhei: Fanout\n\n## Tasks\n\n### Task 1: Source\n**State:** pending\n\n",
);
for n in 2..=40 {
plan.push_str(&format!(
"### Task {n}: Reader {n}\n**State:** pending\n**Prior:** 1\n\n"
));
}
let dir = memory_dir(&[("plan.rhei.md", plan.as_str())]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1").expect("task 1");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
assert!(
history.starts_with("\n## Plan History\n\n### Dependents\n"),
"got:\n{history}"
);
let listed = history
.lines()
.filter(|line| line.starts_with("- Task ") && line.ends_with("\u{2014} prior"))
.count();
assert_eq!(listed, memory_caps::DEPENDENTS);
assert!(
history.contains("\u{2026} 9 more \u{2014} rhei list --has-prior plan.1\n"),
"got:\n{history}"
);
}
#[test]
fn a_long_context_block_is_truncated_with_its_source_named() {
let notes = repeated_lines("note", 1200);
let plan = format!(
"# Rhei: Verbose\n\n## Notes\n\n{notes}\n## Tasks\n\n\
### Task 1: Only\n**State:** pending\n"
);
let dir = memory_dir(&[("plan.rhei.md", plan.as_str())]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1").expect("task 1");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let position = render_position(&context);
assert!(position.contains("note 998\n"), "got the tail of the block");
assert!(!position.contains("note 999\n"), "the cap bites");
assert!(
position.contains("\u{2026} truncated; read plan.rhei.md\n"),
"got:\n{position}"
);
}
#[test]
fn siblings_are_capped_and_name_the_command() {
let mut plan = String::from(
"# Rhei: Wide\n\n---\nstructure:\n maxLevels: 3\n---\n\n## Tasks\n\n\
### Task 1: Parent\n**State:** pending\n\n",
);
for n in 1..=40 {
plan.push_str(&format!("#### Task 1.{n}: Step {n}\n**State:** pending\n\n"));
}
let dir = memory_dir(&[("plan.rhei.md", plan.as_str())]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.1").expect("task 1.1");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let position = render_position(&context);
let listed = position.lines().filter(|line| line.starts_with("- Task plan.1.")).count();
assert_eq!(listed, memory_caps::SIBLINGS);
assert!(
position.contains("\u{2026} 9 more \u{2014} rhei list --parent plan.1\n"),
"got:\n{position}"
);
}
#[test]
fn in_flight_is_capped_and_names_the_command() {
let mut plan = String::from("# Rhei: Busy\n\n## Tasks\n\n");
for n in 1..=30 {
plan.push_str(&format!(
"### Task {n}: Step {n}\n**State:** pending\n**Assignee:** worker-{n}\n\n"
));
}
plan.push_str("### Task 31: Mine\n**State:** review\n");
let dir = memory_dir(&[("plan.rhei.md", plan.as_str())]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.31").expect("task 31");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "review");
let history = render_plan_history(&context).expect("history");
let listed = history.lines().filter(|line| line.contains("\u{2014} worker-")).count();
assert_eq!(listed, memory_caps::IN_FLIGHT);
assert!(
history.contains("\u{2026} 10 more \u{2014} rhei list --non-terminal\n"),
"got:\n{history}"
);
}
#[test]
fn a_summary_is_cut_by_characters_not_bytes() {
let long = "\u{e9}".repeat(200);
let body = format!("## Result\n\n{long}\n");
let dir = memory_plan_dir(&[
("runtime/state-transitions.log", "plan.1.1 pending@completed\n"),
("runtime/results/plan.1.1.md", body.as_str()),
]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.4").expect("task 1.4");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
let expected = format!("{}\u{2026}\n", "\u{e9}".repeat(120));
assert!(history.contains(&expected), "got:\n{history}");
}
#[test]
fn an_empty_result_file_reads_no_result() {
let dir = memory_plan_dir(&[
("runtime/state-transitions.log", "plan.1.1 pending@completed\n"),
("runtime/results/plan.1.1.md", "## Result\n\n"),
]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.1.4").expect("task 1.4");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
assert!(
history.contains("- Task plan.1.1: Implement \u{2014} completed \u{2014} (no result)\n"),
"got:\n{history}"
);
}
#[test]
fn a_cancelled_task_is_listed_in_the_history() {
let plan = "# Rhei: Dropped\n\n## Tasks\n\n\
### Task 1: Abandoned approach\n**State:** cancelled\n\n\
### Task 2: The replacement\n**State:** pending\n";
let dir = memory_dir(&[
("plan.rhei.md", plan),
("runtime/state-transitions.log", "plan.1 pending@cancelled\n"),
("runtime/results/plan.1.md", "## Result\n\nSuperseded by Task 2.\n"),
]);
let plan_path = dir.path().join("plan.rhei.md");
let loaded = load_plan(&plan_path).expect("plan loads");
let memory =
prompt_memory(&loaded, &plan_path, &dir.path().join("runtime"), BTreeSet::new());
let machine = memory_machine();
let task = find_task_by_id_str(&loaded.rhei.tasks, "plan.2").expect("task 2");
let context =
memory_context(dir.path(), &plan_path, &loaded, &memory, &machine, task, "pending");
let history = render_plan_history(&context).expect("history");
assert!(
history.contains(
"- Task plan.1: Abandoned approach \u{2014} cancelled \u{2014} Superseded by \
Task 2.\n"
),
"got:\n{history}"
);
}