Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 0 additions & 1 deletion pkg/workflow/add_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type AddCommentsConfig struct {
Issues *bool `yaml:"issues,omitempty"` // When false, excludes issues:write permission and issues from event condition. Default (nil or true) includes issues:write.
PullRequests *bool `yaml:"pull-requests,omitempty"` // When false, excludes pull-requests:write permission and PRs from event condition. Default (nil or true) includes pull-requests:write.
Discussions *bool `yaml:"discussions,omitempty"` // When true, includes discussions:write permission. Default (nil or false) excludes discussions:write.
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted but XML markers are kept.
}

// parseCommentsConfig handles add-comment configuration
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/comment_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type CommentMemoryConfig struct {
TargetRepoSlug string `yaml:"target-repo,omitempty"` // Target repository in owner/repo format
AllowedRepos []string `yaml:"allowed-repos,omitempty"` // Additional allowed repositories
MemoryID string `yaml:"memory-id,omitempty"` // Default memory identifier when item does not provide memory_id
Footer *string `yaml:"footer,omitempty"` // Footer visibility control ("true"/"false" templatable string); nil defaults to visible footer
}

const commentMemoryHandlerKey = "comment_memory"
Expand Down
4 changes: 2 additions & 2 deletions pkg/workflow/comment_memory_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ func TestCommentMemoryToolConfig(t *testing.T) {
`,
expectedCommentMemory: &CommentMemoryConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{
Max: strPtr("3"),
Max: strPtr("3"),
Footer: strPtr("false"),
},
MemoryID: "triage",
Target: "42",
TargetRepoSlug: "github/docs",
AllowedRepos: []string{"github/docs", "github/gh-aw"},
Footer: strPtr("false"),
},
},
}
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/create_discussion.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type CreateDiscussionsConfig struct {
RequiredCategory string `yaml:"required-category,omitempty"` // Required category for matching when close-older-discussions is enabled
Expires int `yaml:"expires,omitempty"` // Hours until the discussion expires and should be automatically closed
FallbackToIssue *bool `yaml:"fallback-to-issue,omitempty"` // When true (default), fallback to create-issue if discussion creation fails due to permissions.
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted but XML markers are kept.
}

// parseCreateDiscussionsConfig handles create-discussion configuration
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/create_issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type CreateIssuesConfig struct {
GroupByDay *string `yaml:"group-by-day,omitempty"` // When true, if an open issue was already created today (UTC), post new content as a comment on it instead of creating a duplicate. Works best with close-older-issues: true.
Expires int `yaml:"expires,omitempty"` // Hours until the issue expires and should be automatically closed
Group *string `yaml:"group,omitempty"` // If true, group issues as sub-issues under a parent issue (workflow ID is used as group identifier)
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted but XML markers are kept.
}

// parseCreateIssuesConfig handles create-issue configuration
Expand Down
84 changes: 42 additions & 42 deletions pkg/workflow/create_pull_request.go

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion pkg/workflow/reply_to_pr_review_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type ReplyToPullRequestReviewCommentConfig struct {
BaseSafeOutputConfig `yaml:",inline"`
SafeOutputTargetConfig `yaml:",inline"`
SafeOutputFilterConfig `yaml:",inline"`
Footer *string `yaml:"footer,omitempty"` // Whether to add AI-generated footer to replies
}

// parseReplyToPullRequestReviewCommentConfig handles reply-to-pull-request-review-comment configuration
Expand Down
6 changes: 4 additions & 2 deletions pkg/workflow/safe_outputs_config_generation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1137,13 +1137,15 @@ func TestGenerateSafeOutputsConfigReplyToPullRequestReviewCommentWithTarget(t *t
data := &WorkflowData{
SafeOutputs: &SafeOutputsConfig{
ReplyToPullRequestReviewComment: &ReplyToPullRequestReviewCommentConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{Max: strPtr("10")},
BaseSafeOutputConfig: BaseSafeOutputConfig{
Max: strPtr("10"),
Footer: &footerTrue,
},
SafeOutputTargetConfig: SafeOutputTargetConfig{
Target: "pull_request",
TargetRepoSlug: "org/other-repo",
AllowedRepos: []string{"org/other-repo"},
},
Footer: &footerTrue,
},
},
}
Expand Down
1 change: 1 addition & 0 deletions pkg/workflow/safe_outputs_config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type BaseSafeOutputConfig struct {
GitHubToken string `yaml:"github-token,omitempty"` // GitHub token for this specific output type
GitHubApp *GitHubAppConfig `yaml:"github-app,omitempty"` // GitHub App credentials for minting a per-handler installation access token
Staged *TemplatableBool `yaml:"staged,omitempty"` // Templatable preview-only mode for this specific output type
Footer *string `yaml:"footer,omitempty"` // Controls AI-generated footer behavior. Values vary by handler; false omits the visible footer but keeps XML markers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The shared Footer field silently accommodates two incompatible value vocabularies: most handlers treat it as a templatable bool ("true"/"false"), while submit_pr_review accepts "always"/"none"/"if-body". The comment "Values vary by handler" flags this but doesn't document the semantic divergence — future authors reading only the base struct will have no signal that some handlers reject the bool semantics.

💡 Suggestion

Tighten the comment to explicitly name the special case:

// Controls AI-generated footer behavior.
// Most handlers: templatable bool — false omits the visible footer but keeps XML markers.
// Exception — submit-pull-request-review: "always" (default), "none", or "if-body".
Footer *string `yaml:"footer,omitempty"`

This makes the divergence discoverable without needing to chase individual parsers.

@copilot please address this.

IssueIntent *bool `yaml:"issue-intent,omitempty"` // When true, enable issue-intent rationale/confidence guidance and schema requirements for this output type.
NormalizeClosingKeywords *bool `yaml:"normalize-closing-keywords,omitempty"` // When true for this output type, strip backticks from recognized issue-closing keywords in body fields.
// Samples carries deterministic replay samples for the hidden
Expand Down
6 changes: 4 additions & 2 deletions pkg/workflow/safe_outputs_footer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,10 @@ func TestFooterInHandlerConfig(t *testing.T) {
Name: "Test",
SafeOutputs: &SafeOutputsConfig{
CreateIssues: &CreateIssuesConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{Max: strPtr("1")},
Footer: strPtr("false"),
BaseSafeOutputConfig: BaseSafeOutputConfig{
Max: strPtr("1"),
Footer: strPtr("false"),
},
},
},
}
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/submit_pr_review.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ type SubmitPullRequestReviewConfig struct {
BaseSafeOutputConfig `yaml:",inline"`
SafeOutputTargetConfig `yaml:",inline"`
SafeOutputFilterConfig `yaml:",inline"`
Footer *string `yaml:"footer,omitempty"` // Controls when to show footer in PR review body: "always" (default), "none", or "if-body" (only when review has body text)
AllowedEvents []string `yaml:"allowed-events,omitempty"` // Optional list of allowed review event types: APPROVE, COMMENT, REQUEST_CHANGES. If omitted, all event types are allowed.
SupersedeOlderReviews bool `yaml:"supersede-older-reviews,omitempty"` // When true, dismisses older same-workflow REQUEST_CHANGES reviews after a replacement review is posted.
CommitId string `yaml:"commit-id,omitempty"` // When set, pins the review to this commit SHA instead of the current PR head.
Expand Down
6 changes: 4 additions & 2 deletions pkg/workflow/submit_pr_review_footer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,10 @@ func TestSubmitPRReviewFooterInHandlerConfig(t *testing.T) {
Name: "Test",
SafeOutputs: &SafeOutputsConfig{
SubmitPullRequestReview: &SubmitPullRequestReviewConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{Max: strPtr("1")},
Footer: &footerValue,
BaseSafeOutputConfig: BaseSafeOutputConfig{
Max: strPtr("1"),
Footer: &footerValue,
},
},
CreatePullRequestReviewComments: &CreatePullRequestReviewCommentsConfig{
BaseSafeOutputConfig: BaseSafeOutputConfig{Max: strPtr("10")},
Expand Down
7 changes: 3 additions & 4 deletions pkg/workflow/update_discussion.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ var updateDiscussionLog = logger.New("workflow:update_discussion")
type UpdateDiscussionsConfig struct {
UpdateEntityConfig `yaml:",inline"`
SafeOutputAllowedLabelsConfig `yaml:",inline"`
Title *bool `yaml:"title,omitempty"` // Allow updating discussion title - presence indicates field can be updated
Body *bool `yaml:"body,omitempty"` // Allow updating discussion body - presence indicates field can be updated
Labels *bool `yaml:"labels,omitempty"` // Allow updating discussion labels - presence indicates field can be updated
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted but XML markers are kept.
Title *bool `yaml:"title,omitempty"` // Allow updating discussion title - presence indicates field can be updated
Body *bool `yaml:"body,omitempty"` // Allow updating discussion body - presence indicates field can be updated
Labels *bool `yaml:"labels,omitempty"` // Allow updating discussion labels - presence indicates field can be updated
}

// parseUpdateDiscussionsConfig handles update-discussion configuration
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/update_issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ type UpdateIssuesConfig struct {
Status *bool `yaml:"status,omitempty"` // Allow updating issue status (open/closed) - presence indicates field can be updated
Title *bool `yaml:"title,omitempty"` // Allow updating issue title - presence indicates field can be updated
Body *bool `yaml:"body,omitempty"` // Allow updating issue body - boolean value controls permission (defaults to true)
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted but XML markers are kept.
TitlePrefix string `yaml:"title-prefix,omitempty"` // Required title prefix for issue validation - only issues with this prefix can be updated (deprecated: use required-title-prefix)
RequiredTitlePrefix string `yaml:"required-title-prefix,omitempty"` // Title prefix the issue must have (preferred over title-prefix)
RequiredLabels []string `yaml:"required-labels,omitempty"` // Labels that must ALL be present on the issue
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/update_pull_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ type UpdatePullRequestsConfig struct {
UpdateBranch *bool `yaml:"update-branch,omitempty"` // When true, update PR branch with latest base branch changes before applying other updates. Defaults to false.
UpdateBranchStacks *bool `yaml:"sync-stack,omitempty"` // When true, allow stacked-PR stack-sync fallback if update-branch endpoint is unsupported. Defaults to true.
Operation *string `yaml:"operation,omitempty"` // Default operation for body updates: "append", "prepend", or "replace" (defaults to "replace")
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted.
}

// parseUpdatePullRequestsConfig handles update-pull-request configuration
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/update_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ var updateReleaseLog = logger.New("workflow:update_release")
// UpdateReleaseConfig holds configuration for updating GitHub releases from agent output
type UpdateReleaseConfig struct {
UpdateEntityConfig `yaml:",inline"`
Footer *string `yaml:"footer,omitempty"` // Controls whether AI-generated footer is added. When false, visible footer is omitted but XML markers are kept.
}

// parseUpdateReleaseConfig handles update-release configuration
Expand Down
Loading