3535)
3636
3737VERIFIERS_REPO = "primeintellect-ai/verifiers"
38- VERIFIERS_REF = "7d8a522df67308327cb9b8931ce6a5873a99834a "
38+ VERIFIERS_REF = "f43e42c1fabfe2604afc95b9ce62779a8f55d487 "
3939VERIFIERS_CONFIG_REF = "main"
4040DOWNLOAD_ATTEMPTS = 3
4141DOWNLOAD_RETRY_DELAY_SECONDS = 1.0
4444SUPPORTED_AGENTS = known_agent_names ()
4545LAB_GITIGNORE_PATTERNS = (
4646 ".env" ,
47+ "/AGENTS.md" ,
48+ "/CLAUDE.md" ,
49+ "/CLAUDE.local.md" ,
4750 "/outputs/" ,
4851 "/prime-rl/" ,
52+ "/environments/AGENTS.md" ,
4953 "/environments/*/outputs/" ,
5054 "/environments/*/dist/" ,
5155 "/environments/*/*.egg-info/" ,
5559 ".pytest_cache/" ,
5660 ".ruff_cache/" ,
5761)
62+ LOCAL_CLAUDE_MD = "CLAUDE.local.md"
63+ LAB_GUIDANCE_GITIGNORE_PATHS = ("AGENTS.md" , "CLAUDE.md" , LOCAL_CLAUDE_MD , "environments/AGENTS.md" )
64+ LOCAL_CLAUDE_GUIDANCE_TEMPLATE = "\n " .join (
65+ [
66+ "# CLAUDE.local.md" ,
67+ "" ,
68+ "Add personal Claude guidance for this Lab workspace here." ,
69+ "Prime Lab preserves this file during setup and sync." ,
70+ "" ,
71+ ]
72+ )
5873PRIME_SKILLS_MANIFEST = ".prime-managed.json"
5974WORKSPACE_SKILLS_DIR = Path (".prime" ) / "skills"
6075DeprecatedConfigField = tuple [tuple [str , ...], str ]
@@ -220,7 +235,7 @@ def parse_lab_setup_args(args: list[str]) -> LabSetupOptions:
220235 parser .add_argument (
221236 "--skip-agents-md" ,
222237 action = "store_true" ,
223- help = "Skip AGENTS.md, CLAUDE.md, and environments/AGENTS.md." ,
238+ help = "Skip AGENTS.md, CLAUDE.md, CLAUDE.local.md, and environments/AGENTS.md." ,
224239 )
225240 parser .add_argument (
226241 "--skip-install" ,
@@ -269,7 +284,7 @@ def parse_lab_sync_args(args: list[str]) -> LabSyncOptions:
269284 parser .add_argument (
270285 "--skip-docs" ,
271286 action = "store_true" ,
272- help = "Skip AGENTS.md, CLAUDE.md, and environments/AGENTS.md refresh." ,
287+ help = "Skip AGENTS.md, CLAUDE.md, CLAUDE.local.md, and environments/AGENTS.md refresh." ,
273288 )
274289 parser .add_argument (
275290 "--no-agent" ,
@@ -395,6 +410,7 @@ def _run_lab_sync_steps(
395410 workspace .mkdir (parents = True , exist_ok = True )
396411 (workspace / "configs" ).mkdir (exist_ok = True )
397412 (workspace / "environments" ).mkdir (exist_ok = True )
413+ _append_gitignore (workspace )
398414 emit (f"Syncing Lab assets in { workspace } \n " )
399415 agents = _resolve_sync_agents (workspace , options .agents , no_agent = options .no_agent )
400416 guidance_agents = agents
@@ -432,8 +448,9 @@ def _sync_workspace_guidance(
432448 force : bool = False ,
433449) -> None :
434450 _download_file (AGENTS_MD_SRC , workspace / "AGENTS.md" , emit , force = force , quiet = True )
451+ _download_file (CLAUDE_MD_SRC , workspace / "CLAUDE.md" , emit , force = force , quiet = True )
435452 if "claude" in agents :
436- _download_file ( CLAUDE_MD_SRC , workspace / "CLAUDE.md" , emit , force = force , quiet = True )
453+ _ensure_claude_local_guidance ( workspace )
437454 _download_file (
438455 ENVS_AGENTS_MD_SRC ,
439456 workspace / "environments" / "AGENTS.md" ,
@@ -444,6 +461,13 @@ def _sync_workspace_guidance(
444461 emit ("Refreshed workspace guidance\n " )
445462
446463
464+ def _ensure_claude_local_guidance (workspace : Path ) -> None :
465+ path = workspace / LOCAL_CLAUDE_MD
466+ if path .exists () or path .is_symlink ():
467+ return
468+ path .write_text (LOCAL_CLAUDE_GUIDANCE_TEMPLATE , encoding = "utf-8" )
469+
470+
447471def _sync_prime_skills (emit : Emit ) -> tuple [str , ...]:
448472 skills_dir = _global_prime_skills_dir ()
449473 skills_dir .parent .mkdir (parents = True , exist_ok = True )
@@ -864,6 +888,7 @@ def _lab_doctor_checks(options: LabDoctorOptions, workspace: Path) -> list[LabDo
864888 "Run prime lab doctor --fix." ,
865889 ),
866890 _gitignore_check (workspace ),
891+ _lab_guidance_tracking_check (workspace , fix = options .fix ),
867892 _config_validity_check (workspace ),
868893 _config_deprecated_fields_check (workspace ),
869894 _config_environment_reference_check (workspace ),
@@ -1116,15 +1141,61 @@ def _gitignore_check(workspace: Path) -> LabDoctorCheck:
11161141 missing = _missing_gitignore_patterns (existing )
11171142 if not missing :
11181143 return LabDoctorCheck (
1119- name = "Gitignore outputs " ,
1144+ name = "Lab gitignore " ,
11201145 status = "PASS" ,
1121- message = "Standard output and generated source paths are ignored." ,
1146+ message = "Standard Lab generated and local paths are ignored." ,
11221147 )
11231148 return LabDoctorCheck (
1124- name = "Gitignore outputs " ,
1149+ name = "Lab gitignore " ,
11251150 status = "WARN" ,
11261151 message = "Missing " + ", " .join (missing ),
1127- remediation = "Run prime lab doctor --fix to add standard output ignores." ,
1152+ remediation = "Run prime lab doctor --fix to add standard Lab ignores." ,
1153+ )
1154+
1155+
1156+ def _lab_guidance_tracking_check (workspace : Path , * , fix : bool ) -> LabDoctorCheck :
1157+ tracked = _tracked_git_paths (workspace , LAB_GUIDANCE_GITIGNORE_PATHS )
1158+ if tracked and fix :
1159+ _untrack_git_paths (workspace , tracked )
1160+ tracked = _tracked_git_paths (workspace , LAB_GUIDANCE_GITIGNORE_PATHS )
1161+ if not tracked :
1162+ return LabDoctorCheck (
1163+ name = "Lab guidance tracking" ,
1164+ status = "PASS" ,
1165+ message = "Lab generated and local guidance files are untracked." ,
1166+ )
1167+ paths = " " .join (tracked )
1168+ return LabDoctorCheck (
1169+ name = "Lab guidance tracking" ,
1170+ status = "WARN" ,
1171+ message = "Tracked Lab generated/local guidance files: " + ", " .join (tracked ),
1172+ remediation = f"Run git rm --cached { paths } && prime lab sync." ,
1173+ )
1174+
1175+
1176+ def _tracked_git_paths (workspace : Path , paths : tuple [str , ...]) -> tuple [str , ...]:
1177+ try :
1178+ result = subprocess .run (
1179+ ["git" , "ls-files" , "--" , * paths ],
1180+ cwd = workspace ,
1181+ check = False ,
1182+ capture_output = True ,
1183+ text = True ,
1184+ )
1185+ except OSError :
1186+ return ()
1187+ if result .returncode != 0 :
1188+ return ()
1189+ return tuple (line .strip () for line in result .stdout .splitlines () if line .strip ())
1190+
1191+
1192+ def _untrack_git_paths (workspace : Path , paths : tuple [str , ...]) -> None :
1193+ subprocess .run (
1194+ ["git" , "rm" , "--cached" , "--quiet" , "--" , * paths ],
1195+ cwd = workspace ,
1196+ check = False ,
1197+ capture_output = True ,
1198+ text = True ,
11281199 )
11291200
11301201
@@ -1422,10 +1493,11 @@ def _write_lab_docs_index(workspace: Path, agents: tuple[str, ...]) -> None:
14221493 docs_dir .mkdir (parents = True , exist_ok = True )
14231494 guidance_files = [
14241495 "- `AGENTS.md`" ,
1496+ "- `CLAUDE.md`" ,
14251497 "- `environments/AGENTS.md`" ,
14261498 ]
14271499 if "claude" in agents :
1428- guidance_files .insert (1 , "- `CLAUDE.md `" )
1500+ guidance_files .insert (2 , f "- `{ LOCAL_CLAUDE_MD } `" )
14291501 index = docs_dir / "index.md"
14301502 index .write_text (
14311503 "\n " .join (
0 commit comments