Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions crates/core/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10038,6 +10038,9 @@ mod tests {
assert!(sessions::save_messages(&core, &id, &messages, &mut persisted, true));
}

// Released first, so the hydration below claims the session over the
// damaged index: a claim that saw it indexed saves without asking.
sessions::detach(&core, &id).unwrap();
let index = core.data_dir.join("sessions").join("index.json");
let intact = std::fs::read(&index).unwrap();
std::fs::write(&index, "{ not json").unwrap();
Expand Down Expand Up @@ -10118,6 +10121,9 @@ mod tests {
sessions::record_resume_point(&core, &id, 3);
sessions::record_resume_point(&core, &id, 4);

// Released first, so the hydration below claims the session over the
// damaged index: a claim that saw it indexed saves without asking.
sessions::detach(&core, &id).unwrap();
let index = core.data_dir.join("sessions").join("index.json");
let intact = std::fs::read(&index).unwrap();
std::fs::write(&index, "{ not json").unwrap();
Expand Down Expand Up @@ -10192,6 +10198,9 @@ mod tests {
// This sitting begins after everything on file.
sessions::record_resume_point(&core, &id, messages.len() as u64);

// Released first, so the hydration below claims the session over the
// damaged index: a claim that saw it indexed saves without asking.
sessions::detach(&core, &id).unwrap();
let index = core.data_dir.join("sessions").join("index.json");
let intact = std::fs::read(&index).unwrap();
std::fs::write(&index, "{ not json").unwrap();
Expand Down Expand Up @@ -10250,6 +10259,9 @@ mod tests {
sessions::record_resume_point(&core, &id, 3);
sessions::record_resume_point(&core, &id, 4);

// Released first, so the hydration below claims the session over the
// damaged index: a claim that saw it indexed saves without asking.
sessions::detach(&core, &id).unwrap();
let index = core.data_dir.join("sessions").join("index.json");
let intact = std::fs::read(&index).unwrap();
std::fs::write(&index, "{ not json").unwrap();
Expand Down
17 changes: 10 additions & 7 deletions crates/core/src/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,13 +779,16 @@ pub(crate) fn check_at(project_root: &Path, data_dir: &Path) -> Vec<Finding> {
// `--continue`, in every project, until it is moved aside. Only damage
// is a finding: a healthy index is state, not configuration. Moving it
// is the whole repair (a missing index is an empty store), but only
// with openmax closed: a running session whose entry leaves with the
// file reads as deleted, and its later saves are dropped silently. The
// target is a name not yet taken, so a second incident never overwrites
// the copy an earlier one moved aside. That name is only free when this
// prints; `-n` keeps it so when the command runs later (rerun from shell
// history, or copied from an older `--check`), and a skipped move leaves
// the index damaged, so the next `--check` names a free target again.
// with openmax closed: a running session's entry leaves with the file.
// One claimed while the index was healthy keeps saving, so its later
// history is written but listed nowhere (invisible to `--continue`,
// `/resume`, and `--recall`); one claimed over the damage, or claimed
// again later, has its saves dropped. The target is a name not yet
// taken, so a second incident never overwrites the copy an earlier one
// moved aside. That name is only free when this prints; `-n` keeps it
// so when the command runs later (rerun from shell history, or copied
// from an older `--check`), and a skipped move leaves the index
// damaged, so the next `--check` names a free target again.
// `-n` skips without a word and exits 0, so the command checks that the
// index left and, when it did not, says so and exits nonzero: a silent
// skip, or a zero status a script checks, reads as a done repair while
Expand Down
Loading
Loading