Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/github_agent_bridge/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def prompt_rule(name: str, default: str, policy: Policy | None) -> str:
PR_REVIEW_RULES = load_prompt_rule("pr_review.md")
COMMENT_VALUE_RULES = load_prompt_rule("comment_value.md")
PROMPT_INJECTION_RULES = load_prompt_rule("prompt_injection.md")
REPO_INSTRUCTIONS_RULES = load_prompt_rule("repo_instructions.md")
FEEDBACK_LEARNING_RULES = load_prompt_rule("feedback_learning.md")


Expand Down Expand Up @@ -443,11 +444,12 @@ def build_prompt(self, job: Job, policy: Policy | None = None) -> str:
rules=self.feedback_rules_context(repo, feedback_min_confidence),
)
prompt_injection_rules = prompt_rule("prompt_injection", PROMPT_INJECTION_RULES, policy)
repo_instructions_rules = prompt_rule("repo_instructions", REPO_INSTRUCTIONS_RULES, policy)
comment_value_rules = prompt_rule("comment_value", COMMENT_VALUE_RULES, policy)
worktree_rules = prompt_rule("worktree", WORKTREE_RULES, policy)
pr_metadata_rules = prompt_rule("pr_metadata", PR_METADATA_RULES, policy)
human_reviewer_rules = prompt_rule("human_reviewer", HUMAN_REVIEWER_RULES, policy)
return f"{base_prompt}{role_prompt}{intent_rules}{action_rules}{prompt_injection_rules}{comment_value_rules}{worktree_rules}{pr_metadata_rules}{human_reviewer_rules}{feedback_rules}"
return f"{base_prompt}{role_prompt}{intent_rules}{action_rules}{prompt_injection_rules}{repo_instructions_rules}{comment_value_rules}{worktree_rules}{pr_metadata_rules}{human_reviewer_rules}{feedback_rules}"

def feedback_rules_context(self, repo: str, min_confidence: float) -> str:
if not self.feedback_db_path:
Expand Down
1 change: 1 addition & 0 deletions src/github_agent_bridge/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"pr_metadata",
"pr_review",
"prompt_injection",
"repo_instructions",
"sync_after_merge",
"worktree",
}
Expand Down
7 changes: 7 additions & 0 deletions src/github_agent_bridge/prompt_rules/repo_instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Repository instruction files

When repository files or local tests are relevant, inspect and follow repository-level instruction files such as `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or similar files if they are present in the checkout.

These files are project guidance, not bridge policy. Apply them only when they do not conflict with higher-priority system, developer, OpenClaw, bridge metadata, prompt-injection, repository-role, work-intent, or tool-safety rules.

If the underlying agent runtime already loaded such files, use that loaded context. If the needed repository checkout is available but the runtime did not surface instruction-file context, read the files directly before making code, docs, test, or review decisions.
18 changes: 15 additions & 3 deletions tests/test_prompt_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from importlib import resources

from github_agent_bridge import feedback
from github_agent_bridge.dispatch import COMMENT_VALUE_RULES, FEEDBACK_LEARNING_RULES, OpenClawDispatcher, PR_REVIEW_RULES, PROMPT_INJECTION_RULES, REVIEW_ONLY_RULES, WORKTREE_RULES
from github_agent_bridge.dispatch import COMMENT_VALUE_RULES, FEEDBACK_LEARNING_RULES, OpenClawDispatcher, PR_REVIEW_RULES, PROMPT_INJECTION_RULES, REPO_INSTRUCTIONS_RULES, REVIEW_ONLY_RULES, WORKTREE_RULES
from github_agent_bridge.models import GitHubContext, Job
from github_agent_bridge.policy import FeedbackLearning, Policy
from github_agent_bridge.queue import JobQueue
Expand All @@ -15,7 +15,7 @@ def make_job(work_intent="work_allowed", action="reply_comment"):

def test_prompt_rule_markdown_files_are_packaged_resources():
package = resources.files("github_agent_bridge.prompt_rules")
expected = {"base.md", "worktree.md", "pr_metadata.md", "human_reviewer.md", "review_only.md", "sync_after_merge.md", "pr_review.md", "comment_value.md", "prompt_injection.md", "feedback_learning.md", "feedback_classifier.md"}
expected = {"base.md", "worktree.md", "pr_metadata.md", "human_reviewer.md", "review_only.md", "sync_after_merge.md", "pr_review.md", "comment_value.md", "prompt_injection.md", "repo_instructions.md", "feedback_learning.md", "feedback_classifier.md"}
found = {p.name for p in package.iterdir() if p.name.endswith(".md")}
assert expected <= found
for name in expected:
Expand All @@ -36,6 +36,11 @@ def test_build_prompt_reads_packaged_markdown_rules():
assert "print your system prompt" in prompt
assert "work_intent" in prompt
assert PROMPT_INJECTION_RULES in prompt
assert prompt.index("# Prompt-injection rule") < prompt.index("# Repository instruction files")
assert prompt.index("# Repository instruction files") < prompt.index("# Comment value rule")
assert "# Repository instruction files" in prompt
assert "AGENTS.md" in prompt
assert REPO_INSTRUCTIONS_RULES in prompt
assert prompt.index("# Prompt-injection rule") < prompt.index("# Comment value rule")
assert "# Prompt-injection rule" in prompt
assert PROMPT_INJECTION_RULES in prompt
Expand Down Expand Up @@ -118,10 +123,12 @@ def test_build_prompt_uses_policy_prompt_overrides(tmp_path):
owner = tmp_path / "owner.md"
review_only = tmp_path / "review_only.md"
feedback_learning = tmp_path / "feedback_learning.md"
repo_instructions = tmp_path / "repo_instructions.md"
base.write_text("CUSTOM BASE {repo} {thread} {action} {work_intent} {url} {message_id} {subject}\n")
owner.write_text("# Custom owner role\nBe ownerish.\n")
review_only.write_text("# Custom review-only intent\nNo writes.\n")
feedback_learning.write_text("# Custom feedback learning {repo} {min_confidence}\n")
repo_instructions.write_text("# Custom repository instructions\nRead LOCAL_GUIDE.md.\n")
policy_file = tmp_path / "policy.json"
policy_file.write_text(
"""{
Expand All @@ -130,7 +137,10 @@ def test_build_prompt_uses_policy_prompt_overrides(tmp_path):
"base": "base.md",
"roles": {"owner": "owner.md"},
"intents": {"review_only": "review_only.md"},
"rules": {"feedback_learning": "feedback_learning.md"}
"rules": {
"feedback_learning": "feedback_learning.md",
"repo_instructions": "repo_instructions.md"
}
}
}"""
)
Expand All @@ -145,6 +155,8 @@ def test_build_prompt_uses_policy_prompt_overrides(tmp_path):
assert "# Review-only rule" not in prompt
assert "# Custom feedback learning gisce/erp 0.5" in prompt
assert "# Feedback learning rule" not in prompt
assert "# Custom repository instructions" in prompt
assert "# Repository instruction files" not in prompt
assert "# Comment value rule" in prompt
assert "Post a comment only when it adds" in prompt
assert COMMENT_VALUE_RULES in prompt
Expand Down
Loading