diff --git a/python/robomp/src/prompts/completion_reminder.md b/python/robomp/src/prompts/completion_reminder.md index 8cc1cff8a..064e22764 100644 --- a/python/robomp/src/prompts/completion_reminder.md +++ b/python/robomp/src/prompts/completion_reminder.md @@ -3,12 +3,12 @@ You ended your turn before finishing. Issue: {{repo.full_name}}#{{issue.number}} — {{issue.title}} Branch: `{{workspace.branch}}` -You classified this issue and reproduced the bug, but did NOT reach a terminal action. Acceptable terminal actions for a `bug` / `documentation` issue are exactly one of: +You classified this issue and reproduced the bug, but did NOT reach a turn-ending action. Acceptable turn-ending actions for a `bug` / `documentation` issue are exactly one of: 1. `gh_push_branch` + `gh_open_pr` — you committed the fix, pushed the branch, and opened a PR. -2. `mark_unable_to_reproduce` — you genuinely cannot reproduce or fix and need maintainer input. +2. `mark_unable_to_reproduce` — you genuinely cannot reproduce after a real attempt and need reporter-provided reproduction details. 3. `abort_task` — unrecoverable environment failure. Review your TodoList and the prior tool calls, then continue from where you stopped. Do NOT re-classify, do NOT re-post the same preamble comment. If your fix is already drafted in the worktree, commit, push, and open the PR now. If you have not yet edited any source files, do the fix and continue through to PR. -You MUST end this turn by calling one of the three terminal tools listed above. +You MUST end this turn by calling one of the three turn-ending tools listed above. diff --git a/python/robomp/src/prompts/host_tools.toml b/python/robomp/src/prompts/host_tools.toml index ef28c5fac..4acef18d5 100644 --- a/python/robomp/src/prompts/host_tools.toml +++ b/python/robomp/src/prompts/host_tools.toml @@ -64,7 +64,7 @@ reproduced = "True when the recorded run demonstrates the bug." description = "Ask the reporter for missing reproduction details, mark the issue `needs_info`, and keep the session resumable for the next reply." [abort_task] -description = "Irrecoverably abandon this task WITHOUT posting any visible message. Use ONLY for orchestrator/environment defects you cannot work around (broken filesystem permissions, missing system tools, corrupted git metadata, harness bugs). NEVER for normal workflow problems — failed builds, missing repro info, unclear requests use `gh_post_comment` or `mark_unable_to_reproduce` instead. `reason` is audit-only and NEVER shown to the reporter." +description = "Irrecoverably abandon this task WITHOUT posting any visible message. Use ONLY for orchestrator/environment defects you cannot work around (broken filesystem permissions, missing system tools, corrupted git metadata, harness bugs). NEVER for normal workflow problems: failed builds and unclear maintainer requests use `gh_post_comment`; missing reporter reproduction details use `mark_unable_to_reproduce`. `reason` is audit-only and NEVER shown to the reporter." [abort_task.parameters] reason = "Internal diagnosis for the operator. Concrete, specific, blameless. NEVER shown to the reporter." diff --git a/python/robomp/src/prompts/kickoff_issue.md b/python/robomp/src/prompts/kickoff_issue.md index e0ee2b389..87767775f 100644 --- a/python/robomp/src/prompts/kickoff_issue.md +++ b/python/robomp/src/prompts/kickoff_issue.md @@ -28,4 +28,4 @@ the classification calls for code. Drive the todo list to completion: - `invalid` / `duplicate` → one brief comment, then stop. 3. If `bug` and you cannot reproduce after a real attempt, call - `mark_unable_to_reproduce`. You NEVER guess at fixes. + `mark_unable_to_reproduce` with the exact reporter details needed. You NEVER guess at fixes. diff --git a/python/robomp/src/prompts/system_append.md b/python/robomp/src/prompts/system_append.md index 70b71a36d..bf281aadb 100644 --- a/python/robomp/src/prompts/system_append.md +++ b/python/robomp/src/prompts/system_append.md @@ -46,7 +46,7 @@ NEVER apply `provider` or `platform` speculatively. They REQUIRE explicit eviden 9. **Publish.** Call `gh_push_branch`, then `gh_open_pr`. Both deterministically run `bun run fix` (auto-committing as `style: bun run fix`) then `bun check` before touching the remote. The same gate runs on every follow-up `gh_push_branch`. The tools also refuse dirty trees and commit-author mismatches. - `bun check` failed? Fix at the source, commit, call again. - **Escape hatch — `skip_checks=true`.** ONLY for breakage you have VERIFIED is pre-existing on the default branch. Verify by running the same command against the same paths on a clean checkout of the default branch and confirming the identical failure. NEVER use it to bypass a failure your diff introduced, and NEVER for transient or unclear failures. Document the bypass in the PR's `## Verification` section, one sentence: ``bun check` fails on `main` for unrelated reason X; skipped pre-publish gate.` - - **NEVER tamper with git internals.** No editing `.git`/`gitdir:` pointers, no chown/chmod on worktree files, no `safe.directory` overrides, no pointing HEAD at a fabricated commit. Push refused for reasons you cannot resolve? Ask the maintainer via `gh_post_comment`, or use `mark_unable_to_reproduce`. Environmental/orchestrator defect that's not the reporter's problem (broken permissions, corrupted git metadata, missing tools)? Call `abort_task` with the diagnosis — silent abandonment, no comment leaked to the reporter. NEVER improvise. + - **NEVER tamper with git internals.** No editing `.git`/`gitdir:` pointers, no chown/chmod on worktree files, no `safe.directory` overrides, no pointing HEAD at a fabricated commit. Push refused for reasons you cannot resolve? Ask the maintainer via `gh_post_comment`. Environmental/orchestrator defect that's not the reporter's problem (broken permissions, corrupted git metadata, missing tools)? Call `abort_task` with the diagnosis — silent abandonment, no comment leaked to the reporter. NEVER improvise. - **Two-strikes rule.** Two consecutive `gh_push_branch` rejections with the same error is a workflow bug. Fix the cause, use `skip_checks=true` with justification, or escalate via `gh_post_comment`. NEVER loop. 10. **Link.** After the PR opens, one final `gh_post_comment` linking it. diff --git a/python/robomp/tests/test_persona.py b/python/robomp/tests/test_persona.py index 71dff98d8..fb95695e9 100644 --- a/python/robomp/tests/test_persona.py +++ b/python/robomp/tests/test_persona.py @@ -183,6 +183,16 @@ def test_review_completion_reminder_mentions_submit_only() -> None: assert "gh_open_pr" not in out +def test_completion_reminder_limits_mark_unable_to_reporter_details() -> None: + out = persona.completion_reminder( + repo=_Repo(), + issue=_Issue(), + workspace=_Workspace(), + ) + assert "reporter-provided reproduction details" in out + assert "maintainer input" not in out + + def test_system_append_renders_configured_bot_login() -> None: out = persona.system_append( repo=_Repo(), @@ -196,6 +206,17 @@ def test_system_append_renders_configured_bot_login() -> None: assert "**robomp**" not in out +def test_system_append_routes_push_refusal_to_maintainer_comment_only() -> None: + out = persona.system_append( + repo=_Repo(), + issue=_Issue(), + workspace=_Workspace(), + bot_login="Svitter", + ) + assert "Push refused for reasons you cannot resolve? Ask the maintainer via `gh_post_comment`." in out + assert "or use `mark_unable_to_reproduce`" not in out + + def test_system_append_pr_review_renders_configured_bot_login() -> None: out = persona.system_append_pr_review( repo=_Repo(),