1717 materialize_evidence_workspace ,
1818 update_evidence_index ,
1919)
20- from .inventory import changed_paths , read_skills_inventory , snapshot_synth_skills , write_published_index
20+ from .inventory import changed_paths , read_skills_inventory , snapshot_skill_docs , snapshot_synth_skills , write_published_index
2121from .paths import build_skill_synthesis_paths , resolve_real_skills_root
2222from .validation import clear_invalid_marker , mark_invalid , validate_synth_skill
2323
@@ -106,8 +106,10 @@ def _run_locked(
106106 evidence_index = evidence_index ,
107107 )
108108 real_before = snapshot_synth_skills (real_skills_root )
109+ real_all_before = snapshot_skill_docs (real_skills_root )
109110 skills_root = Path (tempfile .mkdtemp (prefix = f"csep-skill-synthesis-{ run_id } -" )) / "skills" if dry_run else real_skills_root
110111 before = snapshot_synth_skills (skills_root )
112+ all_before = snapshot_skill_docs (skills_root )
111113 inventory = read_skills_inventory (real_skills_root )
112114 materialize_evidence_workspace (
113115 paths ,
@@ -141,15 +143,19 @@ def _run_locked(
141143
142144 after = snapshot_synth_skills (skills_root )
143145 real_after = snapshot_synth_skills (real_skills_root )
146+ all_after = snapshot_skill_docs (skills_root )
147+ real_all_after = snapshot_skill_docs (real_skills_root )
144148 detected = changed_paths (before , after )
149+ namespace_violations = _non_synth_changed_paths (changed_paths (all_before , all_after ))
145150 changed_real = changed_paths (real_before , real_after ) if dry_run else []
151+ changed_real_all = changed_paths (real_all_before , real_all_after ) if dry_run else []
146152 valid , invalid , retired = _validate_changed (run_id , detected )
147153 result_missing = bool (agent_result .get ("result_missing" ))
148154 result_invalid = bool (agent_result .get ("result_invalid" ))
149155 mismatch = _reported_written (agent_result ) != detected
150156 dry_run_leak = dry_run and bool (changed_real )
151157 status = "success"
152- if error or dry_run_leak :
158+ if error or dry_run_leak or namespace_violations :
153159 status = "error"
154160 elif invalid or mismatch or result_missing or result_invalid :
155161 status = "partial"
@@ -166,7 +172,8 @@ def _run_locked(
166172 "seen_before_count" : sum (1 for item in evidence if item .get ("seen_before" )),
167173 "reported_written" : _reported_written (agent_result ),
168174 "detected_changed" : detected ,
169- "changed_real_paths" : changed_real ,
175+ "changed_real_paths" : changed_real_all or changed_real ,
176+ "namespace_violations" : namespace_violations ,
170177 "valid" : valid ,
171178 "invalid" : invalid ,
172179 "retired" : retired ,
@@ -193,6 +200,13 @@ def _reported_written(agent_result: dict[str, Any]) -> list[str]:
193200 return sorted (out )
194201
195202
203+ def _non_synth_changed_paths (paths : list [str ]) -> list [str ]:
204+ return sorted (
205+ path for path in paths
206+ if not Path (path ).parent .name .startswith ("csep-synth-" )
207+ )
208+
209+
196210def _validate_changed (run_id : str , changed : list [str ]) -> tuple [list [dict [str , Any ]], list [dict [str , Any ]], list [dict [str , Any ]]]:
197211 valid : list [dict [str , Any ]] = []
198212 invalid : list [dict [str , Any ]] = []
0 commit comments