3636 resolve_entity_types ,
3737)
3838from openkb .lint import list_existing_wiki_targets , strip_ghost_wikilinks
39+ from openkb .locks import atomic_write_text
3940from openkb .schema import INDEX_SEED , get_agents_md
4041
4142logger = logging .getLogger (__name__ )
@@ -779,7 +780,7 @@ def _write_summary(wiki_dir: Path, doc_name: str, summary: str,
779780 fm_lines .append (f"doc_type: { doc_type } " )
780781 fm_lines .append (_yaml_kv_line ("full_text" , f"sources/{ doc_name } .{ ext } " ))
781782 fm_block = "---\n " + "\n " .join (fm_lines ) + "\n ---\n \n "
782- (summaries_dir / f"{ doc_name } .md" ). write_text ( fm_block + summary , encoding = "utf-8" )
783+ atomic_write_text (summaries_dir / f"{ doc_name } .md" , fm_block + summary )
783784
784785
785786_SAFE_NAME_RE = re .compile (r'[^\w\-]' )
@@ -839,7 +840,7 @@ def _write_concept(wiki_dir: Path, name: str, content: str, source_file: str, is
839840 if brief :
840841 fm_lines .append (_yaml_kv_line ("description" , brief ))
841842 existing = frontmatter .block (fm_lines ) + clean
842- path . write_text ( existing , encoding = "utf-8" )
843+ atomic_write_text ( path , existing )
843844 return
844845 # Guarantee type + refresh description on update; remove legacy brief:.
845846 ex_parts2 = frontmatter .split (existing )
@@ -851,7 +852,7 @@ def _write_concept(wiki_dir: Path, name: str, content: str, source_file: str, is
851852 # Drop legacy brief: lines (migrated to description:).
852853 fm_block = frontmatter .drop_line (fm_block , "brief" )
853854 existing = fm_block + body
854- path . write_text ( existing , encoding = "utf-8" )
855+ atomic_write_text ( path , existing )
855856 else :
856857 clean_parts = frontmatter .split (content )
857858 if clean_parts is not None :
@@ -863,7 +864,7 @@ def _write_concept(wiki_dir: Path, name: str, content: str, source_file: str, is
863864 if brief :
864865 fm_lines .append (_yaml_kv_line ("description" , brief ))
865866 fm_block = "---\n " + "\n " .join (fm_lines ) + "\n ---\n \n "
866- path . write_text ( fm_block + content , encoding = "utf-8" )
867+ atomic_write_text ( path , fm_block + content )
867868
868869
869870def _write_entity (
@@ -927,10 +928,10 @@ def _build_entity_frontmatter(sources: list[str]) -> str:
927928 break
928929 merged = [source_file ] + [s for s in recovered if s != source_file ]
929930 existing = _build_entity_frontmatter (merged ) + clean
930- path . write_text ( existing , encoding = "utf-8" )
931+ atomic_write_text ( path , existing )
931932 return
932933
933- path . write_text ( _build_entity_frontmatter ([source_file ]) + clean , encoding = "utf-8" )
934+ atomic_write_text ( path , _build_entity_frontmatter ([source_file ]) + clean )
934935
935936
936937_set_fm_line = frontmatter .set_line
@@ -1041,7 +1042,7 @@ def _add_related_link(
10411042 text = _prepend_source_to_frontmatter (text , source_file )
10421043
10431044 text += f"\n \n See also: { link } "
1044- path . write_text ( text , encoding = "utf-8" )
1045+ atomic_write_text ( path , text )
10451046 return True
10461047
10471048
@@ -1068,7 +1069,7 @@ def _backlink_summary_pages(
10681069 _ensure_h2_section (lines , section , quiet = True )
10691070 for slug in reversed (missing ):
10701071 _insert_section_entry (lines , section , f"- [[{ page_dir } /{ slug } ]]" )
1071- summary_path . write_text ( "\n " .join (lines ), encoding = "utf-8" )
1072+ atomic_write_text ( summary_path , "\n " .join (lines ))
10721073
10731074
10741075def _backlink_pages (
@@ -1089,7 +1090,7 @@ def _backlink_pages(
10891090 lines = text .split ("\n " )
10901091 _ensure_h2_section (lines , "## Related Documents" , quiet = True )
10911092 _insert_section_entry (lines , "## Related Documents" , f"- { link } " )
1092- path . write_text ( "\n " .join (lines ), encoding = "utf-8" )
1093+ atomic_write_text ( path , "\n " .join (lines ))
10931094
10941095
10951096def _backlink_summary (wiki_dir : Path , doc_name : str , concept_slugs : list [str ]) -> None :
@@ -1195,7 +1196,7 @@ def _remove_doc_from_pages(
11951196 path .unlink ()
11961197 deleted .append (path .stem )
11971198 elif new_text != text :
1198- path . write_text ( new_text , encoding = "utf-8" )
1199+ atomic_write_text ( path , new_text )
11991200 modified .append (path .stem )
12001201
12011202 return {"modified" : modified , "deleted" : deleted }
@@ -1291,7 +1292,7 @@ def remove_doc_from_index(wiki_dir: Path, doc_name: str, concept_slugs_deleted:
12911292 while _remove_section_entry (lines , "## Entities" , entity_link ):
12921293 pass
12931294
1294- index_path . write_text ( "\n " .join (lines ), encoding = "utf-8" )
1295+ atomic_write_text ( index_path , "\n " .join (lines ))
12951296
12961297
12971298def _update_index (
@@ -1315,7 +1316,7 @@ def _update_index(
13151316
13161317 index_path = wiki_dir / "index.md"
13171318 if not index_path .exists ():
1318- index_path . write_text ( INDEX_SEED , encoding = "utf-8" )
1319+ atomic_write_text ( index_path , INDEX_SEED )
13191320
13201321 lines = index_path .read_text (encoding = "utf-8" ).split ("\n " )
13211322
@@ -1361,7 +1362,7 @@ def _update_index(
13611362 else :
13621363 _insert_section_entry (lines , "## Entities" , entry )
13631364
1364- index_path . write_text ( "\n " .join (lines ), encoding = "utf-8" )
1365+ atomic_write_text ( index_path , "\n " .join (lines ))
13651366
13661367
13671368# ---------------------------------------------------------------------------
@@ -2035,7 +2036,7 @@ async def compile_long_doc(
20352036 updated = fm_block + body
20362037 if updated != summary_content :
20372038 summary_content = updated
2038- summary_path . write_text ( summary_content , encoding = "utf-8" )
2039+ atomic_write_text ( summary_path , summary_content )
20392040
20402041 # Base context A. cache_control marker on the doc message creates a
20412042 # cache breakpoint covering (system + doc) for every concept call.
0 commit comments