diff --git a/components/runners/ambient-runner/ambient_runner/platform/prompts.py b/components/runners/ambient-runner/ambient_runner/platform/prompts.py index d30d01031..2e30097b4 100644 --- a/components/runners/ambient-runner/ambient_runner/platform/prompts.py +++ b/components/runners/ambient-runner/ambient_runner/platform/prompts.py @@ -68,6 +68,15 @@ "the feature branch (`{branch}`). If push fails, do NOT fall back to main.\n\n" ) +GIT_SAFETY_INSTRUCTIONS = ( + "## Git Safety\n\n" + "**NEVER embed tokens or credentials in commands** — use environment " + "variables (`$GITHUB_TOKEN`, `$GITLAB_TOKEN`) instead of inline PATs.\n\n" + "**When a git operation fails**: stop, diagnose, report the error to the " + "user, and wait. Do NOT autonomously escalate to force pushes, API " + "workarounds, or more aggressive retry variants.\n\n" +) + RUBRIC_EVALUATION_HEADER = "## Rubric Evaluation\n\n" RUBRIC_EVALUATION_INTRO = ( @@ -215,6 +224,9 @@ def build_workspace_context_prompt( prompt += f"- **repos/{repo_name}/**\n" prompt += GIT_PUSH_STEPS.format(branch=push_branch) + if repos_cfg: + prompt += GIT_SAFETY_INSTRUCTIONS + # Human-in-the-loop instructions prompt += HUMAN_INPUT_INSTRUCTIONS diff --git a/components/runners/ambient-runner/tests/test_auto_push.py b/components/runners/ambient-runner/tests/test_auto_push.py index 7ce0225e3..744fab786 100644 --- a/components/runners/ambient-runner/tests/test_auto_push.py +++ b/components/runners/ambient-runner/tests/test_auto_push.py @@ -317,6 +317,38 @@ def test_prompt_includes_multiple_autopush_repos(self): # repo3 should not be in git instructions since autoPush=false # (but it will be in the general repos list) + def test_prompt_includes_git_safety_with_repos(self): + """Git safety guardrails are included when repos are present.""" + repos_cfg = [ + { + "name": "my-repo", + "url": "https://github.com/owner/my-repo.git", + "branch": "main", + "autoPush": False, + } + ] + prompt = build_workspace_context_prompt( + repos_cfg=repos_cfg, + workflow_name=None, + artifacts_path="artifacts", + ambient_config={}, + workspace_path="/workspace", + ) + assert "Git Safety" in prompt + assert "NEVER embed tokens" in prompt + assert "Do NOT autonomously escalate" in prompt + + def test_prompt_excludes_git_safety_without_repos(self): + """Git safety instructions are excluded when no repos are present.""" + prompt = build_workspace_context_prompt( + repos_cfg=[], + workflow_name=None, + artifacts_path="artifacts", + ambient_config={}, + workspace_path="/workspace", + ) + assert "Git Safety" not in prompt + def test_prompt_without_repos(self): """Test prompt generation when no repos are configured.""" prompt = build_workspace_context_prompt(