[docs]defensure_drvloop_memory(*,repo_dir:Path,user_prompt:str,prompt_file:str|None,)->Path:"""Create or reuse the persistent drvloop memory file."""projects_dir=repo_dir/DRVLOOP_MEMORY_DIRNAMEifprojects_dir.exists()andnotprojects_dir.is_dir():raiseRuntimeError(f"{projects_dir} exists but is not a directory.")projects_dir.mkdir(parents=True,exist_ok=True)memory_path=projects_dir/DRVLOOP_MEMORY_FILENAMEifmemory_path.exists():ifmemory_path.is_dir():raiseRuntimeError(f"{memory_path} exists but is a directory.")returnmemory_pathstarted_at=_utc_now_z()source_line=f"- prompt_source: {prompt_file}\n"ifprompt_fileelse""initial=("# FermiLink Drvloop Memory\n""\n""- schema_version: 1\n"f"- started_at_utc: {started_at}\n"f"- last_updated_utc: {started_at}\n"f"{source_line}""\n""## Original request\n"f"{user_prompt.strip()}\n""\n""## Unified Memory\n""\n""### Major done\n""- initialized\n""\n""### Major needed\n""- Read the goal and choose the next derivation step or route to test.\n""\n""### Major conclusions\n""- No major conclusions recorded yet.\n")memory_path.write_text(initial,encoding="utf-8")returnmemory_path
[docs]defappend_to_memory_section(memory_path:Path,*,heading:str,lines:list[str],)->None:"""Append lines to a markdown section, creating it when absent."""ifnotlines:returnnormalized_heading=heading.strip()ifnotnormalized_heading.startswith("#"):raiseValueError("heading must be a markdown heading")content=memory_path.read_text(encoding="utf-8")block="\n".join(lines).rstrip()+"\n"marker=normalized_heading+"\n"index=content.find(marker)ifindex<0:updated=content.rstrip()+f"\n\n{marker}{block}"else:insert_at=index+len(marker)next_heading=len(content)forprefixin("\n### ","\n## "):candidate=content.find(prefix,insert_at)ifcandidate>=0:next_heading=min(next_heading,candidate)before=content[:next_heading].rstrip()after=content[next_heading:]updated=before+"\n"+block+afterupdated=_replace_last_updated(updated,_utc_now_z())memory_path.write_text(updated,encoding="utf-8")