@@ -220,12 +220,13 @@ def test_subscribe_sync_and_unsubscribe_round_trip(self, temp_project_dir, local
220220 args = ["--name" , "alice" , "--remote" , str (local_repo ["bare" ]), "--branch" , "main" ],
221221 evolve_dir = evolve_dir ,
222222 )
223- assert (evolve_dir / "subscribed" / "alice" ).is_dir ()
223+ assert (evolve_dir / "entities" / "subscribed" / "alice" ).is_dir ()
224+ assert not (evolve_dir / "subscribed" / "alice" ).exists ()
224225
225226 run_script (SYNC_SCRIPT , project_dir = temp_project_dir , evolve_dir = evolve_dir )
226- mirrored = evolve_dir / "entities" / "subscribed" / "alice" / "guideline" / "tip-one.md"
227- assert mirrored .exists ()
228- assert "Always write tests." in mirrored .read_text ()
227+ synced = evolve_dir / "entities" / "subscribed" / "alice" / "guideline" / "tip-one.md"
228+ assert synced .exists ()
229+ assert "Always write tests." in synced .read_text ()
229230
230231 run_script (
231232 UNSUBSCRIBE_SCRIPT ,
@@ -283,7 +284,7 @@ def test_subscribe_rejects_empty_or_dot_name(self, temp_project_dir, local_repo,
283284
284285 def test_subscribe_fails_when_destination_already_exists (self , temp_project_dir , local_repo ):
285286 evolve_dir = temp_project_dir / ".evolve"
286- existing_dest = evolve_dir / "subscribed" / "alice"
287+ existing_dest = evolve_dir / "entities" / " subscribed" / "alice"
287288 existing_dest .mkdir (parents = True )
288289
289290 result = run_script (
@@ -393,7 +394,7 @@ def test_sync_skips_invalid_subscription_name(self, temp_project_dir):
393394
394395 def test_sync_uses_workspace_config_with_custom_evolve_dir (self , temp_project_dir , local_repo ):
395396 evolve_dir = temp_project_dir / "custom-evolve"
396- subscribed_dir = evolve_dir / "subscribed"
397+ subscribed_dir = evolve_dir / "entities" / " subscribed"
397398 subscribed_dir .mkdir (parents = True )
398399 subprocess .run (
399400 ["git" , "clone" , "--branch" , "main" , "--depth" , "1" , str (local_repo ["bare" ]), str (subscribed_dir / "alice" )],
@@ -450,6 +451,12 @@ def test_session_start_sync_respects_on_session_start_false(self, temp_project_d
450451 args = ["--name" , "alice" , "--remote" , str (local_repo ["bare" ]), "--branch" , "main" ],
451452 evolve_dir = evolve_dir ,
452453 )
454+ git_env = local_repo ["env" ]
455+ new_entity = local_repo ["work" ] / "guideline" / "tip-two.md"
456+ new_entity .write_text ("---\n type: guideline\n ---\n \n Delete dead code promptly.\n " )
457+ subprocess .run (["git" , "-C" , str (local_repo ["work" ]), "add" , "." ], check = True , env = git_env )
458+ subprocess .run (["git" , "-C" , str (local_repo ["work" ]), "commit" , "-m" , "add tip-two" ], check = True , env = git_env )
459+ subprocess .run (["git" , "-C" , str (local_repo ["work" ]), "push" , "origin" , "main" ], check = True , env = git_env )
453460 (temp_project_dir / "evolve.config.yaml" ).write_text (
454461 f'subscriptions:\n - name: "alice"\n remote: "{ local_repo ["bare" ]} "\n branch: "main"\n sync:\n on_session_start: false\n '
455462 )
@@ -463,8 +470,8 @@ def test_session_start_sync_respects_on_session_start_false(self, temp_project_d
463470 )
464471
465472 assert result .returncode == 0
466- mirrored = evolve_dir / "entities" / "subscribed" / "alice" / "guideline" / "tip-one .md"
467- assert not mirrored .exists ()
473+ synced = evolve_dir / "entities" / "subscribed" / "alice" / "guideline" / "tip-two .md"
474+ assert not synced .exists ()
468475
469476 def test_sync_writes_audit_log (self , temp_project_dir , local_repo ):
470477 evolve_dir = temp_project_dir / ".evolve"
@@ -521,9 +528,20 @@ def test_sync_skips_symlinked_markdown_files(self, temp_project_dir, local_repo)
521528
522529 run_script (SYNC_SCRIPT , project_dir = temp_project_dir , evolve_dir = evolve_dir )
523530
524- mirrored_dir = evolve_dir / "entities" / "subscribed" / "alice" / "guideline"
525- assert (mirrored_dir / "tip-one.md" ).exists ()
526- assert not (mirrored_dir / "tip-link.md" ).exists ()
531+ subscribed_dir = evolve_dir / "entities" / "subscribed" / "alice" / "guideline"
532+ assert (subscribed_dir / "tip-one.md" ).exists ()
533+ assert (subscribed_dir / "tip-link.md" ).exists ()
534+
535+ result = run_script (
536+ RETRIEVE_SCRIPT ,
537+ project_dir = temp_project_dir ,
538+ evolve_dir = evolve_dir ,
539+ stdin = HOOK_INPUT ,
540+ expect_success = False ,
541+ )
542+ assert result .returncode == 0
543+ assert "Always write tests." in result .stdout
544+ assert "tip-link" not in result .stdout
527545
528546 def test_sync_removed_entity_disappears_after_sync (self , temp_project_dir , local_repo ):
529547 evolve_dir = temp_project_dir / ".evolve"
@@ -545,3 +563,29 @@ def test_sync_removed_entity_disappears_after_sync(self, temp_project_dir, local
545563
546564 run_script (SYNC_SCRIPT , project_dir = temp_project_dir , evolve_dir = evolve_dir )
547565 assert not tip_one .exists ()
566+
567+ def test_sync_migrates_legacy_subscribed_repo (self , temp_project_dir , local_repo ):
568+ evolve_dir = temp_project_dir / ".evolve"
569+ legacy_dir = evolve_dir / "subscribed"
570+ legacy_dir .mkdir (parents = True )
571+ subprocess .run (
572+ ["git" , "clone" , "--branch" , "main" , "--depth" , "1" , str (local_repo ["bare" ]), str (legacy_dir / "alice" )],
573+ check = True ,
574+ env = local_repo ["env" ],
575+ )
576+ (temp_project_dir / "evolve.config.yaml" ).write_text (
577+ f'subscriptions:\n - name: "alice"\n remote: "{ local_repo ["bare" ]} "\n branch: "main"\n '
578+ )
579+
580+ result = run_script (
581+ SYNC_SCRIPT ,
582+ project_dir = temp_project_dir ,
583+ evolve_dir = evolve_dir ,
584+ expect_success = False ,
585+ )
586+
587+ assert result .returncode == 0
588+ migrated_repo = evolve_dir / "entities" / "subscribed" / "alice"
589+ assert migrated_repo .is_dir ()
590+ assert not (evolve_dir / "subscribed" / "alice" ).exists ()
591+ assert (migrated_repo / "guideline" / "tip-one.md" ).exists ()
0 commit comments