feat: sentinel-based review cleanup + system prompt file + security review
CI / test (pull_request) Successful in 14s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 58s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m35s
CI / test (pull_request) Successful in 14s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 58s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m35s
Sentinel-based cleanup: - Reviews embed <!-- review-bot:NAME --> in body (hidden HTML comment) - Cleanup matches by sentinel, not token identity - Each reviewer-name is a logical identity (sonnet, gpt, security) - Same token can run multiple review types without conflict - No extra API scopes needed System prompt file (--system-prompt-file / SYSTEM_PROMPT_FILE): - Loads a local file with additional review instructions - Appended to system base as "Additional Review Instructions" - Enables specialized reviews (security, performance, etc.) - Partially addresses #5 Security review: - SECURITY_REVIEW.md prompt focused on vulnerabilities - 3rd CI matrix entry using same token, different prompt - Focus: injection, auth, secrets, input validation, crypto, races CI changes: - REVIEWER_NAME passed from matrix.name - SYSTEM_PROMPT_FILE passed from matrix (empty for standard reviews) - 3 reviewers: sonnet (general), gpt (general), security (focused)
This commit is contained in:
@@ -30,6 +30,8 @@ func FormatMarkdown(result *ReviewResult, reviewerName string) string {
|
||||
|
||||
if reviewerName != "" {
|
||||
sb.WriteString(fmt.Sprintf("\n---\n*Review by %s*\n", reviewerName))
|
||||
// Hidden sentinel for identifying this bot's reviews during cleanup
|
||||
sb.WriteString(fmt.Sprintf("\n<!-- review-bot:%s -->\n", reviewerName))
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
|
||||
@@ -116,3 +116,21 @@ func TestGiteaEvent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatMarkdown_Sentinel(t *testing.T) {
|
||||
result := &ReviewResult{
|
||||
Verdict: "APPROVE",
|
||||
Summary: "All good.",
|
||||
Recommendation: "Merge it.",
|
||||
}
|
||||
output := FormatMarkdown(result, "security")
|
||||
if !strings.Contains(output, "<!-- review-bot:security -->") {
|
||||
t.Error("expected sentinel comment in output")
|
||||
}
|
||||
|
||||
// Empty reviewer name should NOT have sentinel
|
||||
output2 := FormatMarkdown(result, "")
|
||||
if strings.Contains(output2, "<!-- review-bot") {
|
||||
t.Error("should not contain sentinel when reviewer name is empty")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user