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
96 changes: 93 additions & 3 deletions .github/workflows/ci-doctor.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 26 additions & 12 deletions .github/workflows/ci-doctor.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ safe-outputs:
title-prefix: "[CI Failure Doctor] "
labels: [cookie]
add-comment:
update-issue:
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

safe-outputs.update-issue: is enabled but not configured to actually allow any updates. In this codebase, update permissions are granted by the presence of status:, title:, and/or body: keys, and the default target is triggering (which will be skipped for this workflow since it runs on workflow_run). To make duplicate-closure possible, configure update-issue with at least status: enabled and set target: "*" (so the agent can specify issue_number), and consider raising max above 1 if you expect closing multiple duplicates per run.

Suggested change
update-issue:
update-issue:
status:
target: "*"
max: 10

Copilot uses AI. Check for mistakes.
noop:
messages:
footer: "> 🩺 *Diagnosis provided by [{workflow_name}]({run_url})*"
Expand Down Expand Up @@ -124,18 +125,31 @@ You are the CI Failure Doctor, an expert investigative agent that analyzes faile
2. **Update Pattern Database**: Enhance knowledge with new findings by updating pattern files
3. **Save Artifacts**: Store detailed logs and analysis in the cached directories

### Phase 6: Looking for existing issues

1. **Convert the report to a search query**
- Use any advanced search features in GitHub Issues to find related issues
- Look for keywords, error messages, and patterns in existing issues
2. **Judge each match issues for relevance**
- Analyze the content of the issues found by the search and judge if they are similar to this issue.
3. **Add issue comment to duplicate issue and finish**
- If you find a duplicate issue, add a comment with your findings and close the investigation.
- Do NOT open a new issue since you found a duplicate already (skip next phases).

### Phase 6: Reporting and Recommendations
### Phase 6: Looking for existing issues and closing older ones

1. **Search for existing CI failure doctor issues**
- Use GitHub Issues search to find issues with label "cookie" and title prefix "[CI Failure Doctor]"
- Look for both open and recently closed issues (within the last 7 days)
- Search for keywords, error messages, and patterns from the current failure
2. **Judge each match for relevance**
- Analyze the content of found issues to determine if they are similar to the current failure
- Check if they describe the same root cause, error pattern, or affected components
- Identify truly duplicate issues vs. unrelated failures
3. **Close older duplicate issues**
- If you find older open issues that are duplicates of the current failure:
- Add a comment explaining this is a duplicate of the new investigation
- Use the `update-issue` tool with `state: "closed"` and `state_reason: "not_planned"` to close them
Comment on lines +140 to +141
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

The instructions mention calling update-issue with state and state_reason, but the safe output tool schema uses status (open/closed) and does not support state_reason. As written, the agent will generate invalid tool calls and fail to close duplicates. Update the guidance to use status: "closed" (and add rationale via add-comment) rather than state/state_reason.

Suggested change
- Add a comment explaining this is a duplicate of the new investigation
- Use the `update-issue` tool with `state: "closed"` and `state_reason: "not_planned"` to close them
- Add a comment explaining this is a duplicate of the new investigation and why you're closing it
- Use the `update-issue` tool with `status: "closed"` to close them

Copilot uses AI. Check for mistakes.
- Include a link to the new issue in the comment
- If older issues describe resolved problems that are recurring:
- Keep them open but add a comment linking to the new occurrence
4. **Handle duplicate detection**
- If you find a very recent duplicate issue (opened within the last hour):
- Add a comment with your findings to the existing issue
- Do NOT open a new issue (skip next phases)
- Exit the workflow
- Otherwise, continue to create a new issue with fresh investigation data

### Phase 7: Reporting and Recommendations
1. **Create Investigation Report**: Generate a comprehensive analysis including:
- **Executive Summary**: Quick overview of the failure
- **Root Cause**: Detailed explanation of what went wrong
Expand Down
8 changes: 4 additions & 4 deletions pkg/parser/import_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a
var toolsBuilder strings.Builder
var mcpServersBuilder strings.Builder
var markdownBuilder strings.Builder // Only used for imports WITH inputs (compile-time substitution)
var importPaths []string // NEW: Track import paths for runtime-import macro generation
var importPaths []string // NEW: Track import paths for runtime-import macro generation
var stepsBuilder strings.Builder
var copilotSetupStepsBuilder strings.Builder // Track copilot-setup-steps.yml separately
var runtimesBuilder strings.Builder
Expand Down Expand Up @@ -317,7 +317,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a
} else {
// Has inputs - must inline for compile-time substitution
log.Printf("Agent file has inputs - will be inlined instead of runtime-imported")

// For agent files, extract markdown content (only when inputs are present)
markdownContent, err := processIncludedFileWithVisited(item.fullPath, item.sectionName, false, visited)
if err != nil {
Expand Down Expand Up @@ -489,7 +489,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a
} else {
// Has inputs - must inline for compile-time substitution
log.Printf("Import %s has inputs - will be inlined for compile-time substitution", importRelPath)

// Extract markdown content from imported file (only for imports with inputs)
markdownContent, err := processIncludedFileWithVisited(item.fullPath, item.sectionName, false, visited)
if err != nil {
Expand Down Expand Up @@ -639,7 +639,7 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a
MergedSafeOutputs: safeOutputs,
MergedSafeInputs: safeInputs,
MergedMarkdown: markdownBuilder.String(), // Only imports WITH inputs (for compile-time substitution)
ImportPaths: importPaths, // Import paths for runtime-import macro generation
ImportPaths: importPaths, // Import paths for runtime-import macro generation
MergedSteps: stepsBuilder.String(),
CopilotSetupSteps: copilotSetupStepsBuilder.String(),
MergedRuntimes: runtimesBuilder.String(),
Expand Down
Loading