1.4 Long-Running Project Memory
Long-running agent work fails when the only project state is the current prompt. A project memory chain should preserve the goal, active plan, completed actions, and a resumable checkpoint. The next session should be able to ask one query and reconstruct where to continue.
The Pattern
- Record a durable
Goalat project start. - Record a
Planthat references the goal. - Record major
ActionTakenmilestones as they happen. - Record a
CheckpointwithThoughtRole::Checkpointbefore stopping. - Resume by querying for the newest checkpoint with the project concept.
use mentisdb::{
BinaryStorageAdapter, MentisDb, ThoughtInput, ThoughtQuery,
ThoughtRole, ThoughtType,
};
fn build_long_running_project_memory() -> io::Result<()> {
let dir = tempfile::tempdir()?;
let adapter = BinaryStorageAdapter::for_chain_key(
dir.path(),
"cookbook-long-project",
);
let mut chain = MentisDb::open_with_storage(Box::new(adapter))?;
chain.upsert_agent(
"planner",
Some("Planner"),
Some("product-team"),
Some("Owns durable project checkpoints"),
None,
)?;
let goal = chain.append_thought(
"planner",
ThoughtInput::new(
ThoughtType::Goal,
"Ship the checkout redesign without breaking invoice export.",
)
.with_concepts(["checkout-redesign", "invoice-export"])
.with_tags(["project", "goal"])
.with_importance(0.95),
)?.index;
let plan = chain.append_thought(
"planner",
ThoughtInput::new(
ThoughtType::Plan,
"Audit current checkout flow, migrate the payment step, then run invoice export regression tests.",
)
.with_refs(vec![goal])
.with_concepts(["checkout-redesign"])
.with_tags(["project", "plan"])
.with_importance(0.85),
)?.index;
let action = chain.append_thought(
"planner",
ThoughtInput::new(
ThoughtType::ActionTaken,
"Moved payment step behind the new feature flag. Invoice export tests still need to run.",
)
.with_refs(vec![plan])
.with_concepts(["checkout-redesign", "feature-flag"])
.with_tags(["project", "progress"])
.with_importance(0.75),
)?.index;
let checkpoint = chain.append_thought(
"planner",
ThoughtInput::new(
ThoughtType::Checkpoint,
"Resume by running invoice export regression tests, then remove the old payment-step branch if green.",
)
.with_role(ThoughtRole::Checkpoint)
.with_refs(vec![goal, plan, action])
.with_concepts(["checkout-redesign", "resume-point"])
.with_tags(["project", "checkpoint"])
.with_importance(0.9),
)?.index;
let resume_points = chain.query(
&ThoughtQuery::new()
.with_roles(vec![ThoughtRole::Checkpoint])
.with_concepts_any(["checkout-redesign"])
.with_limit(1),
);
assert_eq!(resume_points.len(), 1);
assert_eq!(resume_points[0].index, checkpoint);
Ok(())
}
Rule of thumb: a checkpoint should say what is done, what is not done,
and the exact first command or investigation the next session should perform.
Why It Works
refs turn the checkpoint into a compact project map. A future agent can read the
checkpoint first, then follow references back to the goal, plan, and latest action only
when more context is needed.