From 71c763355e7f244139d5f0a41d245161935b4eba Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 15 Mar 2026 19:08:50 +0000
Subject: [PATCH 1/3] Initial plan
From 0de607fe5b82900cbde1fce51de64ef252219be0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 15 Mar 2026 19:40:18 +0000
Subject: [PATCH 2/3] refactor: extract daily audit discussion pattern into
shared component (#1234)
- Add field-level merge support for create-discussion in imports.go
- Create shared/daily-audit-discussion.md with base config
- Update 42 workflows to import the shared component
- Add 3 tests for create-discussion field-level merging
- Recompile all 173 workflow lock files
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/audit-workflows.lock.yml | 81 ++++++-
.github/workflows/audit-workflows.md | 4 +-
.github/workflows/auto-triage-issues.lock.yml | 81 ++++++-
.github/workflows/auto-triage-issues.md | 4 +-
.github/workflows/blog-auditor.lock.yml | 81 ++++++-
.github/workflows/blog-auditor.md | 4 +-
.../claude-code-user-docs-review.lock.yml | 81 ++++++-
.../workflows/claude-code-user-docs-review.md | 4 +-
.../workflows/copilot-agent-analysis.lock.yml | 81 ++++++-
.github/workflows/copilot-agent-analysis.md | 4 +-
.../copilot-pr-merged-report.lock.yml | 81 ++++++-
.github/workflows/copilot-pr-merged-report.md | 4 +-
.../copilot-pr-nlp-analysis.lock.yml | 81 ++++++-
.github/workflows/copilot-pr-nlp-analysis.md | 4 +-
.../copilot-pr-prompt-analysis.lock.yml | 81 ++++++-
.../workflows/copilot-pr-prompt-analysis.md | 4 +-
.../copilot-session-insights.lock.yml | 81 ++++++-
.github/workflows/copilot-session-insights.md | 4 +-
.github/workflows/daily-code-metrics.lock.yml | 81 ++++++-
.github/workflows/daily-code-metrics.md | 4 +-
.../workflows/daily-compiler-quality.lock.yml | 81 ++++++-
.github/workflows/daily-compiler-quality.md | 4 +-
.../daily-copilot-token-report.lock.yml | 81 ++++++-
.../workflows/daily-copilot-token-report.md | 4 +-
.../workflows/daily-firewall-report.lock.yml | 81 ++++++-
.github/workflows/daily-firewall-report.md | 4 +-
.../workflows/daily-issues-report.lock.yml | 6 +-
.github/workflows/daily-issues-report.md | 6 +-
.../daily-observability-report.lock.yml | 6 +-
.../workflows/daily-observability-report.md | 6 +-
.../daily-performance-summary.lock.yml | 6 +-
.../workflows/daily-performance-summary.md | 6 +-
.github/workflows/daily-regulatory.lock.yml | 6 +-
.github/workflows/daily-regulatory.md | 6 +-
.../workflows/daily-secrets-analysis.lock.yml | 6 +-
.github/workflows/daily-secrets-analysis.md | 6 +-
.../daily-team-evolution-insights.lock.yml | 81 ++++++-
.../daily-team-evolution-insights.md | 4 +-
.github/workflows/delight.lock.yml | 81 ++++++-
.github/workflows/delight.md | 5 +-
.../developer-docs-consolidator.lock.yml | 81 ++++++-
.../workflows/developer-docs-consolidator.md | 5 +-
.github/workflows/docs-noob-tester.lock.yml | 81 ++++++-
.github/workflows/docs-noob-tester.md | 3 +-
.../example-workflow-analyzer.lock.yml | 81 ++++++-
.../workflows/example-workflow-analyzer.md | 3 +-
.github/workflows/firewall-escape.lock.yml | 84 ++++++-
.github/workflows/firewall-escape.md | 4 +-
.../github-mcp-structural-analysis.lock.yml | 81 ++++++-
.../github-mcp-structural-analysis.md | 4 +-
.../github-mcp-tools-report.lock.yml | 81 ++++++-
.github/workflows/github-mcp-tools-report.md | 5 +-
.../github-remote-mcp-auth-test.lock.yml | 84 ++++++-
.../workflows/github-remote-mcp-auth-test.md | 5 +-
.github/workflows/go-fan.lock.yml | 81 ++++++-
.github/workflows/go-fan.md | 4 +-
.github/workflows/issue-arborist.lock.yml | 81 ++++++-
.github/workflows/issue-arborist.md | 3 +-
.github/workflows/lockfile-stats.lock.yml | 81 ++++++-
.github/workflows/lockfile-stats.md | 4 +-
.github/workflows/mcp-inspector.lock.yml | 81 ++++++-
.github/workflows/mcp-inspector.md | 4 +-
.github/workflows/portfolio-analyst.lock.yml | 81 ++++++-
.github/workflows/portfolio-analyst.md | 3 +-
.../workflows/pr-nitpick-reviewer.lock.yml | 81 ++++++-
.github/workflows/pr-nitpick-reviewer.md | 3 +-
.../prompt-clustering-analysis.lock.yml | 81 ++++++-
.../workflows/prompt-clustering-analysis.md | 4 +-
.../workflows/repo-audit-analyzer.lock.yml | 81 ++++++-
.github/workflows/repo-audit-analyzer.md | 4 +-
.../repository-quality-improver.lock.yml | 81 ++++++-
.../workflows/repository-quality-improver.md | 4 +-
.github/workflows/safe-output-health.lock.yml | 81 ++++++-
.github/workflows/safe-output-health.md | 4 +-
.../schema-consistency-checker.lock.yml | 81 ++++++-
.../workflows/schema-consistency-checker.md | 4 +-
.github/workflows/sergo.lock.yml | 81 ++++++-
.github/workflows/sergo.md | 4 +-
.../shared/daily-audit-discussion.md | 45 ++++
.github/workflows/terminal-stylist.lock.yml | 81 ++++++-
.github/workflows/terminal-stylist.md | 4 +-
.github/workflows/typist.lock.yml | 81 ++++++-
.github/workflows/typist.md | 4 +-
.../workflows/weekly-issue-summary.lock.yml | 81 ++++++-
.github/workflows/weekly-issue-summary.md | 3 +-
pkg/workflow/imports.go | 59 ++++-
pkg/workflow/safe_outputs_import_test.go | 210 ++++++++++++++++++
87 files changed, 3231 insertions(+), 292 deletions(-)
create mode 100644 .github/workflows/shared/daily-audit-discussion.md
diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml
index cb4fbbe3ccb..822d61e1206 100644
--- a/.github/workflows/audit-workflows.lock.yml
+++ b/.github/workflows/audit-workflows.lock.yml
@@ -25,11 +25,12 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
# - shared/trending-charts-simple.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"e687ed6ea9c097f90e8e0c3181f674b2bf92734fd253c3408f6775da1b76e745","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"6556f9744bd2ca5ec79310ade16237457807aaebfea54618e37fec3aa848606b","strict":true}
name: "Agentic Workflow Audit Agent"
"on":
@@ -141,7 +142,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -178,6 +179,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/jqschema.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -468,7 +472,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -508,6 +512,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -645,6 +691,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1479,7 +1552,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,cdn.playwright.dev,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,static.crates.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/audit-workflows.md b/.github/workflows/audit-workflows.md
index a1fc1350491..fe062012d8b 100644
--- a/.github/workflows/audit-workflows.md
+++ b/.github/workflows/audit-workflows.md
@@ -22,11 +22,9 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/jqschema.md
- shared/reporting.md
- shared/trending-charts-simple.md
diff --git a/.github/workflows/auto-triage-issues.lock.yml b/.github/workflows/auto-triage-issues.lock.yml
index eb54d5c99d0..9ca63125bde 100644
--- a/.github/workflows/auto-triage-issues.lock.yml
+++ b/.github/workflows/auto-triage-issues.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"6d5ae739b2ba3b6bbba0566b0e444cf837a7639539ddad0361430acf57eee28c","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"cef1dca3145dc35ebd518ca413823f7b7ee48fc910cb75f8c9bbee7be9e4ffb2","strict":true}
name: "Auto-Triage Issues"
"on":
@@ -148,7 +149,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, add_labels, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, add_labels, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -183,6 +184,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -346,7 +350,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"add_labels":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"add_labels":{"max":10},"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -386,6 +390,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Add labels to an existing GitHub issue or pull request for categorization and filtering. Labels must already exist in the repository. For creating new issues with labels, use create_issue with the labels property instead. CONSTRAINTS: Maximum 10 label(s) can be added.",
"inputSchema": {
@@ -531,6 +577,33 @@ jobs:
}
}
},
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1240,7 +1313,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_labels\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Auto-Triage] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_labels\":{\"max\":10},\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Auto-Triage] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/auto-triage-issues.md b/.github/workflows/auto-triage-issues.md
index a626587605d..a9216f75be3 100644
--- a/.github/workflows/auto-triage-issues.md
+++ b/.github/workflows/auto-triage-issues.md
@@ -18,6 +18,7 @@ network:
- defaults
- github
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
tools:
github:
@@ -31,9 +32,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[Auto-Triage] "
- category: "audits"
- close-older-discussions: true
- max: 1
timeout-minutes: 15
features:
copilot-requests: true
diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml
index cf475fdef9b..7bfe16bc5d7 100644
--- a/.github/workflows/blog-auditor.lock.yml
+++ b/.github/workflows/blog-auditor.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"878b2619a7ef728ee36423c6ded4bda471ba66d830dc760d5437153fdc594dc1"}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"795b50eace5751cc0141ce749040b30c1205eb91c2d4815281b762d3f2e17990"}
name: "Blog Auditor"
"on":
@@ -138,7 +139,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -173,6 +174,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -343,7 +347,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -383,6 +387,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -480,6 +526,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1237,7 +1310,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,githubnext.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.githubnext.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[audit] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[audit] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/blog-auditor.md b/.github/workflows/blog-auditor.md
index c893e277003..e066748d4a6 100644
--- a/.github/workflows/blog-auditor.md
+++ b/.github/workflows/blog-auditor.md
@@ -30,11 +30,9 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[audit] "
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 10
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/claude-code-user-docs-review.lock.yml b/.github/workflows/claude-code-user-docs-review.lock.yml
index 265f44a2fcb..d3861b259ba 100644
--- a/.github/workflows/claude-code-user-docs-review.lock.yml
+++ b/.github/workflows/claude-code-user-docs-review.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"5a9409064f385fdf708c176795fd7d445018ce3d6239a9e39f5de5be2aa1e20b","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"94e4dc42cfbe69fbb2dcc9bab98995ce5c31843a0e88f46620757806130a4b6f","strict":true}
name: "Claude Code User Documentation Review"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -358,7 +362,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -398,6 +402,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -495,6 +541,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1205,7 +1278,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/claude-code-user-docs-review.md b/.github/workflows/claude-code-user-docs-review.md
index 5fa6ef6286d..92e2facdd7d 100644
--- a/.github/workflows/claude-code-user-docs-review.md
+++ b/.github/workflows/claude-code-user-docs-review.md
@@ -25,9 +25,6 @@ network:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
tools:
cache-memory: true
@@ -39,6 +36,7 @@ tools:
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
features:
diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml
index 34d8a1158f8..3a0563f4f2e 100644
--- a/.github/workflows/copilot-agent-analysis.lock.yml
+++ b/.github/workflows/copilot-agent-analysis.lock.yml
@@ -26,11 +26,12 @@
# Resolved workflow manifest:
# Imports:
# - shared/copilot-pr-data-fetch.md
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
# - shared/copilot-pr-analysis-base.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"8f9db38275e2f6a90812dd7c6943929ca732b8b75a0aefa841599e29f81db7c0","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"e5d40daefc477f2f0b7e972f1f8bf3524f941e41e05f221c3ecb3436c313ab69","strict":true}
name: "Copilot Agent PR Analysis"
"on":
@@ -142,7 +143,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -177,6 +178,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/copilot-pr-analysis-base.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -399,7 +403,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -439,6 +443,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -551,6 +597,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1342,7 +1415,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[copilot-agent-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[copilot-agent-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/copilot-agent-analysis.md b/.github/workflows/copilot-agent-analysis.md
index aa509b6f886..0c0a1a80664 100644
--- a/.github/workflows/copilot-agent-analysis.md
+++ b/.github/workflows/copilot-agent-analysis.md
@@ -25,11 +25,9 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[copilot-agent-analysis] "
- category: "audits"
- max: 1
- close-older-discussions: true
imports:
+ - shared/daily-audit-discussion.md
- shared/copilot-pr-analysis-base.md
- shared/reporting.md
diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml
index 2b5e4b820fc..d9eb0132340 100644
--- a/.github/workflows/copilot-pr-merged-report.lock.yml
+++ b/.github/workflows/copilot-pr-merged-report.lock.yml
@@ -26,12 +26,13 @@
# Resolved workflow manifest:
# Imports:
# - shared/copilot-pr-data-fetch.md
+# - shared/daily-audit-discussion.md
# - shared/gh.md
# - shared/jqschema.md
# - shared/reporting.md
# - shared/copilot-pr-analysis-base.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"754e064128a0338fe1c412f4a91f45096dfaf541ad245d2b3d777300ca200916"}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"13fe1100a63e093494139c5f08d8b4e6b7d30797a5216b4f77f44dc25ba75d40"}
name: "Daily Copilot PR Merged Report"
"on":
@@ -134,7 +135,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -169,6 +170,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/gh.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -372,7 +376,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -412,6 +416,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -509,6 +555,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1283,7 +1356,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[copilot-pr-merged-report] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[copilot-pr-merged-report] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/copilot-pr-merged-report.md b/.github/workflows/copilot-pr-merged-report.md
index 3ad642a5585..7d31e9dfe2e 100644
--- a/.github/workflows/copilot-pr-merged-report.md
+++ b/.github/workflows/copilot-pr-merged-report.md
@@ -23,9 +23,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[copilot-pr-merged-report] "
- category: "audits"
- max: 1
- close-older-discussions: true
network:
allowed:
@@ -34,6 +31,7 @@ network:
- api.github.com
imports:
+ - shared/daily-audit-discussion.md
- shared/gh.md
- shared/copilot-pr-analysis-base.md
- shared/reporting.md
diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml
index 4a932f8df26..1567c6c429b 100644
--- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml
+++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml
@@ -26,12 +26,13 @@
# Resolved workflow manifest:
# Imports:
# - shared/copilot-pr-data-fetch.md
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/python-dataviz.md
# - shared/reporting.md
# - shared/copilot-pr-analysis-base.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"f2b6098d37f2490aa73983346ec72a1b9b929981244ae63b5af8099ce04a78b8","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"910f15ba3798b86c48633d964e46d707f94f1592df160d3031a00a5aa07c8b92","strict":true}
name: "Copilot PR Conversation NLP Analysis"
"on":
@@ -136,7 +137,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -173,6 +174,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/copilot-pr-analysis-base.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -427,7 +431,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -467,6 +471,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -604,6 +650,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1365,7 +1438,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.jsr.io,*.pythonhosted.org,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,bun.sh,cdn.jsdelivr.net,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,files.pythonhosted.org,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.anaconda.com,repo.continuum.io,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,static.crates.io,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[nlp-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[nlp-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/copilot-pr-nlp-analysis.md b/.github/workflows/copilot-pr-nlp-analysis.md
index 7e9d89a3d18..5048633deb6 100644
--- a/.github/workflows/copilot-pr-nlp-analysis.md
+++ b/.github/workflows/copilot-pr-nlp-analysis.md
@@ -27,11 +27,9 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[nlp-analysis] "
- category: "audits"
- max: 1
- close-older-discussions: true
imports:
+ - shared/daily-audit-discussion.md
- shared/copilot-pr-analysis-base.md
- shared/python-dataviz.md
- shared/reporting.md
diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml
index 5d9e098c9f8..650284327f6 100644
--- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml
+++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml
@@ -26,11 +26,12 @@
# Resolved workflow manifest:
# Imports:
# - shared/copilot-pr-data-fetch.md
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
# - shared/copilot-pr-analysis-base.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"d2adad35b52f026f410211a01c25a088c742c6aa9ac08d9f892a3edea90ab43e","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"814c8d655ba8a02be414c7dd56b04527833b74b2de5833a2a09268356d7c170c","strict":true}
name: "Copilot PR Prompt Pattern Analysis"
"on":
@@ -136,7 +137,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -171,6 +172,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/copilot-pr-analysis-base.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -393,7 +397,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -433,6 +437,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -545,6 +591,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1281,7 +1354,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[prompt-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[prompt-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/copilot-pr-prompt-analysis.md b/.github/workflows/copilot-pr-prompt-analysis.md
index da092d20de7..996f4731913 100644
--- a/.github/workflows/copilot-pr-prompt-analysis.md
+++ b/.github/workflows/copilot-pr-prompt-analysis.md
@@ -26,11 +26,9 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[prompt-analysis] "
- category: "audits"
- max: 1
- close-older-discussions: true
imports:
+ - shared/daily-audit-discussion.md
- shared/copilot-pr-analysis-base.md
- shared/reporting.md
diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml
index cb30651fcaa..ae890ee772e 100644
--- a/.github/workflows/copilot-session-insights.lock.yml
+++ b/.github/workflows/copilot-session-insights.lock.yml
@@ -25,6 +25,7 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/copilot-session-data-fetch.md
# - shared/python-dataviz.md
@@ -32,7 +33,7 @@
# - shared/session-analysis-charts.md
# - shared/session-analysis-strategies.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"0e97b7dc1f36ccddaef55702eb1a54e51b2c23280be5b5c6c5f21199230a34b4","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"498e87b8f917c9af8994d0450c1693a6f7faffa1bd12e9037e5c01040da47984","strict":true}
name: "Copilot Session Insights"
"on":
@@ -145,7 +146,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -182,6 +183,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/jqschema.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -436,7 +440,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -476,6 +480,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -613,6 +659,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1429,7 +1502,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,cdn.playwright.dev,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,static.crates.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[copilot-session-insights] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[copilot-session-insights] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/copilot-session-insights.md b/.github/workflows/copilot-session-insights.md
index 2a190088e37..2f063850a4f 100644
--- a/.github/workflows/copilot-session-insights.md
+++ b/.github/workflows/copilot-session-insights.md
@@ -27,9 +27,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[copilot-session-insights] "
- category: "audits"
- max: 1
- close-older-discussions: true
tools:
repo-memory:
@@ -48,6 +45,7 @@ tools:
- "date *"
imports:
+ - shared/daily-audit-discussion.md
- shared/jqschema.md # Must come before copilot-session-data-fetch.md (dependency)
- shared/copilot-session-data-fetch.md
- shared/session-analysis-charts.md
diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml
index ae04ed5f80e..32695bf2a09 100644
--- a/.github/workflows/daily-code-metrics.lock.yml
+++ b/.github/workflows/daily-code-metrics.lock.yml
@@ -25,11 +25,12 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/python-dataviz.md
# - shared/reporting.md
# - shared/trends.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"b991cb66b5ef15cfab292acb7b27c302e5435b94b2aa486ca69d3954d12d84bc","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"82d7d7b8ecfa98174864b51dfd09b6702a4e13e860acf90608cecc4e8baec9ce","strict":true}
name: "Daily Code Metrics and Trend Tracking Agent"
"on":
@@ -141,7 +142,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -178,6 +179,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -410,7 +414,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":72,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":51200}]},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":72,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":51200}]},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -450,6 +454,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -587,6 +633,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1408,7 +1481,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,cdn.playwright.dev,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,static.crates.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":72,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":72,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/daily-code-metrics.md b/.github/workflows/daily-code-metrics.md
index 37702df4c79..e80f52ab861 100644
--- a/.github/workflows/daily-code-metrics.md
+++ b/.github/workflows/daily-code-metrics.md
@@ -21,12 +21,10 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 3d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 30
strict: true
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/python-dataviz.md
- shared/trends.md
diff --git a/.github/workflows/daily-compiler-quality.lock.yml b/.github/workflows/daily-compiler-quality.lock.yml
index 0ea68e1933f..ca0d425eae2 100644
--- a/.github/workflows/daily-compiler-quality.lock.yml
+++ b/.github/workflows/daily-compiler-quality.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"43b61ccd4023929211202d467bd670da7af659d6869c4582f175822d3493c087","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"ead0175cdcee78574d7c36bceb9a757dd430dbdb69200dd7b7bff1fa3fe111f9","strict":true}
name: "Daily Compiler Quality Check"
"on":
@@ -132,7 +133,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -167,6 +168,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/mcp/serena-go.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -352,7 +356,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -392,6 +396,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -489,6 +535,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1173,7 +1246,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/daily-compiler-quality.md b/.github/workflows/daily-compiler-quality.md
index e785371f4e3..94ff9947235 100644
--- a/.github/workflows/daily-compiler-quality.md
+++ b/.github/workflows/daily-compiler-quality.md
@@ -11,6 +11,7 @@ permissions:
tracker-id: daily-compiler-quality
engine: copilot
imports:
+ - shared/daily-audit-discussion.md
- shared/mcp/serena-go.md
- shared/reporting.md
tools:
@@ -28,9 +29,6 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 30
strict: true
features:
diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml
index 06a5928d87b..359e7017de0 100644
--- a/.github/workflows/daily-copilot-token-report.lock.yml
+++ b/.github/workflows/daily-copilot-token-report.lock.yml
@@ -26,10 +26,11 @@
# Resolved workflow manifest:
# Imports:
# - copilot-setup-steps.yml
+# - shared/daily-audit-discussion.md
# - shared/python-dataviz.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"62ed9373b2a71bd045f90201268707bb8c2044f67b98fb93de8ac325d21d3613","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"ea510a5b3537f1257e8d0dc0ca844a46682b7a430459a871a47dee80b7bda189","strict":true}
name: "Daily Copilot Token Consumption Report"
"on":
@@ -134,7 +135,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -171,6 +172,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -435,7 +439,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":72,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":72,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -475,6 +479,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -612,6 +658,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1378,7 +1451,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.pythonhosted.org,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":72,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":72,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/daily-copilot-token-report.md b/.github/workflows/daily-copilot-token-report.md
index fdaed633c0a..e3e92467692 100644
--- a/.github/workflows/daily-copilot-token-report.md
+++ b/.github/workflows/daily-copilot-token-report.md
@@ -39,11 +39,9 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 3d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 20
imports:
+ - shared/daily-audit-discussion.md
- copilot-setup-steps.yml # Import setup steps from copilot-setup-steps.yml
- shared/reporting.md
- shared/python-dataviz.md
diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml
index 67a49718c7a..46394438e46 100644
--- a/.github/workflows/daily-firewall-report.lock.yml
+++ b/.github/workflows/daily-firewall-report.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
# - shared/trending-charts-simple.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"575da188e33143c8c5b5e07660a4f4d3302695314638124a21ac50fec6fd4b3a","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"d8948e33ae60bbcd4c6a0b0ae488aef2eec1b8426a2c1a503435ddaed9a1300f","strict":true}
name: "Daily Firewall Logs Collector and Reporter"
"on":
@@ -138,7 +139,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -175,6 +176,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -437,7 +441,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":72,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":72,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -477,6 +481,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -599,6 +645,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1292,7 +1365,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.pythonhosted.org,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":72,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":72,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/daily-firewall-report.md b/.github/workflows/daily-firewall-report.md
index b4e87394a6f..5f122d3cca8 100644
--- a/.github/workflows/daily-firewall-report.md
+++ b/.github/workflows/daily-firewall-report.md
@@ -21,9 +21,6 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 3d
- category: "audits"
- max: 1
- close-older-discussions: true
tools:
agentic-workflows:
@@ -34,6 +31,7 @@ tools:
- "*"
edit:
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/trending-charts-simple.md
---
diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml
index 48a60b66fc6..6b67166c7e1 100644
--- a/.github/workflows/daily-issues-report.lock.yml
+++ b/.github/workflows/daily-issues-report.lock.yml
@@ -25,13 +25,14 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/issues-data-fetch.md
# - shared/jqschema.md
# - shared/python-dataviz.md
# - shared/reporting.md
# - shared/trends.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"667a196ac2033e3f747d5c0dd2d3391c9a05f01941879279691b28a1ccc5f68b","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"6818a76b8297b5268785c694a652df4dceff5ef850fe0b20c6ccc1e0317dbd96","strict":true}
name: "Daily Issues Report Generator"
"on":
@@ -184,6 +185,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/jqschema.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
diff --git a/.github/workflows/daily-issues-report.md b/.github/workflows/daily-issues-report.md
index c562df375f8..ccdaf9bb405 100644
--- a/.github/workflows/daily-issues-report.md
+++ b/.github/workflows/daily-issues-report.md
@@ -18,14 +18,10 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 3d
- category: "audits"
title-prefix: "[daily issues] "
- max: 1
- close-older-discussions: true
- close-discussion:
- max: 10
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/jqschema.md
- shared/issues-data-fetch.md
- shared/python-dataviz.md
diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml
index a3eafb8d47f..474faa41674 100644
--- a/.github/workflows/daily-observability-report.lock.yml
+++ b/.github/workflows/daily-observability-report.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"1b990129663822b2a2ec35c48272d37d9b5fd2588701da99710163ff9f98f551","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"c85c1403adef70acfcdb540e5f8430968291b947f10c40c9bf7dcbb2fbad55ba","strict":true}
name: "Daily Observability Report for AWF Firewall and MCP Gateway"
"on":
@@ -174,6 +175,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
diff --git a/.github/workflows/daily-observability-report.md b/.github/workflows/daily-observability-report.md
index f206a17ff89..c8fb6699eda 100644
--- a/.github/workflows/daily-observability-report.md
+++ b/.github/workflows/daily-observability-report.md
@@ -17,14 +17,10 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
title-prefix: "[observability] "
- max: 1
- close-older-discussions: true
- close-discussion:
- max: 10
timeout-minutes: 45
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml
index 70f12820a06..9fd30628fb7 100644
--- a/.github/workflows/daily-performance-summary.lock.yml
+++ b/.github/workflows/daily-performance-summary.lock.yml
@@ -25,11 +25,12 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/github-queries-mcp-script.md
# - shared/reporting.md
# - shared/trending-charts-simple.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"c93c3cce9fe58a74b02303d790120c6508d3d4d0bf95bb4fc24c36df3847efd0","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"c158f00b8cac75b3378e863689927a1c3bc41e1dba1317961562b6aa95f53894","strict":true}
name: "Daily Project Performance Summary Generator (Using MCP Scripts)"
"on":
@@ -176,6 +177,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/github-queries-mcp-script.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
diff --git a/.github/workflows/daily-performance-summary.md b/.github/workflows/daily-performance-summary.md
index 8041e5df7fc..350fbe9292a 100644
--- a/.github/workflows/daily-performance-summary.md
+++ b/.github/workflows/daily-performance-summary.md
@@ -19,14 +19,10 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 3d
- category: "audits"
title-prefix: "[daily performance] "
- max: 1
- close-older-discussions: true
- close-discussion:
- max: 10
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/github-queries-mcp-script.md
- shared/trending-charts-simple.md
- shared/reporting.md
diff --git a/.github/workflows/daily-regulatory.lock.yml b/.github/workflows/daily-regulatory.lock.yml
index ea88c62ada4..c8b7946fce1 100644
--- a/.github/workflows/daily-regulatory.lock.yml
+++ b/.github/workflows/daily-regulatory.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/github-queries-mcp-script.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"238c3282ef64bdb6800bd48877c082702a91b29214ffb81ce63903042421d706","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"9d36c8d42bd2a9ec079b1fd41b64467d1e6403a0314d7c2677e13d89b1770a31","strict":true}
name: "Daily Regulatory Report Generator"
"on":
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/github-queries-mcp-script.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
diff --git a/.github/workflows/daily-regulatory.md b/.github/workflows/daily-regulatory.md
index f1f3055de35..d22152f9b59 100644
--- a/.github/workflows/daily-regulatory.md
+++ b/.github/workflows/daily-regulatory.md
@@ -20,14 +20,10 @@ tools:
safe-outputs:
create-discussion:
expires: 3d
- category: "audits"
title-prefix: "[daily regulatory] "
- max: 1
- close-older-discussions: true
- close-discussion:
- max: 10
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/github-queries-mcp-script.md
- shared/reporting.md
---
diff --git a/.github/workflows/daily-secrets-analysis.lock.yml b/.github/workflows/daily-secrets-analysis.lock.yml
index f669f909879..dd8d7f8ef64 100644
--- a/.github/workflows/daily-secrets-analysis.lock.yml
+++ b/.github/workflows/daily-secrets-analysis.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"f2aa146eb6b0f4cbf136d67791c53ae36f856bb0e601f602bac114089b381231","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"36c9c58dd6119231334ec3acc8d46d7205e543be3b605ad0196d38bfa0931276","strict":true}
name: "Daily Secrets Analysis Agent"
"on":
@@ -165,6 +166,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
diff --git a/.github/workflows/daily-secrets-analysis.md b/.github/workflows/daily-secrets-analysis.md
index 81668166cc3..05615b1bc6c 100644
--- a/.github/workflows/daily-secrets-analysis.md
+++ b/.github/workflows/daily-secrets-analysis.md
@@ -18,14 +18,10 @@ tools:
safe-outputs:
create-discussion:
expires: 3d
- category: "audits"
title-prefix: "[daily secrets] "
- max: 1
- close-older-discussions: true
- close-discussion:
- max: 10
timeout-minutes: 20
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
features:
copilot-requests: true
diff --git a/.github/workflows/daily-team-evolution-insights.lock.yml b/.github/workflows/daily-team-evolution-insights.lock.yml
index 1036437fb23..13817ef1a18 100644
--- a/.github/workflows/daily-team-evolution-insights.lock.yml
+++ b/.github/workflows/daily-team-evolution-insights.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"5cd3e800be141c9f7d3c827c683abb13e8db1661f5b12e1d6af506e135cbe5a4"}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"4e0c9d08e56be835cf745bb499cd228b7716cf47e47032d72eaf29f334632174"}
name: "Daily Team Evolution Insights"
"on":
@@ -136,7 +137,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -171,6 +172,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -340,7 +344,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -380,6 +384,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -477,6 +523,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1176,7 +1249,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/daily-team-evolution-insights.md b/.github/workflows/daily-team-evolution-insights.md
index cc6073dc458..05cd51819ea 100644
--- a/.github/workflows/daily-team-evolution-insights.md
+++ b/.github/workflows/daily-team-evolution-insights.md
@@ -25,11 +25,9 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 90
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/delight.lock.yml b/.github/workflows/delight.lock.yml
index f536314e9f4..a4a62d95761 100644
--- a/.github/workflows/delight.lock.yml
+++ b/.github/workflows/delight.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"e01a758d3c758d82eabd4d9eb701b44134df6d64acef6cfda2bfc18ba603d73d","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"19833761cd321432d165c5dbf8044be7159f5bbbf829d2dd5c5b082974fefd7b","strict":true}
name: "Delight"
"on":
@@ -133,7 +134,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_issue, create_discussion, missing_tool, missing_data, noop
+ Tools: create_issue, create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -168,6 +169,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -363,7 +367,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":168,"max":1},"create_issue":{"expires":48,"group":true,"max":2},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":168,"max":1},"create_issue":{"expires":48,"group":true,"max":2},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -452,6 +456,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -564,6 +610,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1358,7 +1431,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"fallback_to_issue\":true,\"max\":1},\"create_issue\":{\"expires\":48,\"group\":true,\"labels\":[\"delight\",\"cookie\"],\"max\":2},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"fallback_to_issue\":true,\"max\":1},\"create_issue\":{\"expires\":48,\"group\":true,\"labels\":[\"delight\",\"cookie\"],\"max\":2},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/delight.md b/.github/workflows/delight.md
index 3066c35c73a..10d8186f35a 100644
--- a/.github/workflows/delight.md
+++ b/.github/workflows/delight.md
@@ -22,10 +22,6 @@ network:
- github
safe-outputs:
- create-discussion:
- category: "audits"
- max: 1
- close-older-discussions: true
create-issue:
expires: 2d
labels: [delight, cookie]
@@ -56,6 +52,7 @@ tools:
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/jqschema.md
diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml
index afd6ddbbe4d..0cb8a1a40a7 100644
--- a/.github/workflows/developer-docs-consolidator.lock.yml
+++ b/.github/workflows/developer-docs-consolidator.lock.yml
@@ -25,11 +25,12 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/qmd-docs.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"6062086459893e5e8da7159dd36519fd83efc186b31d4a17896352563213ccfc","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"651208a6ea832baa7dd433598465665d76876cb3e4a6f3e857823f36a32c543a","strict":true}
name: "Developer Documentation Consolidator"
"on":
@@ -140,7 +141,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, create_pull_request, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, create_pull_request, missing_tool, missing_data, noop
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/safe_outputs_create_pull_request.md"
cat << 'GH_AW_PROMPT_EOF'
@@ -178,6 +179,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -407,7 +411,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":168,"max":1},"create_pull_request":{"expires":48,"max":1,"title_prefix":"[docs] "},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":10240,"max_patch_size":10240}]}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":168,"max":1},"create_pull_request":{"expires":48,"max":1,"title_prefix":"[docs] "},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":10240,"max_patch_size":10240}]}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -447,6 +451,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Create a new GitHub pull request to propose code changes. Use this after making file edits to submit them for review and merging. The PR will be created from the current branch with your committed changes. For code review comments on an existing PR, use create_pull_request_review_comment instead. CONSTRAINTS: Maximum 1 pull request(s) can be created. Title will be prefixed with \"[docs] \". Labels [\"documentation\" \"automation\"] will be automatically added.",
"inputSchema": {
@@ -608,6 +654,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1646,7 +1719,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"fallback_to_issue\":true,\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":48,\"labels\":[\"documentation\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CLAUDE.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"title_prefix\":\"[docs] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"fallback_to_issue\":true,\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":48,\"labels\":[\"documentation\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CLAUDE.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"title_prefix\":\"[docs] \"},\"missing_data\":{},\"missing_tool\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/developer-docs-consolidator.md b/.github/workflows/developer-docs-consolidator.md
index 309ae6ac76b..4bef4453175 100644
--- a/.github/workflows/developer-docs-consolidator.md
+++ b/.github/workflows/developer-docs-consolidator.md
@@ -22,10 +22,6 @@ network:
- github
safe-outputs:
- create-discussion:
- category: "audits"
- max: 1
- close-older-discussions: true
create-pull-request:
expires: 2d
title-prefix: "[docs] "
@@ -52,6 +48,7 @@ tools:
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/mcp/serena-go.md
- shared/mcp/qmd-docs.md
diff --git a/.github/workflows/docs-noob-tester.lock.yml b/.github/workflows/docs-noob-tester.lock.yml
index b3cbc60c27a..b8d3ef87f27 100644
--- a/.github/workflows/docs-noob-tester.lock.yml
+++ b/.github/workflows/docs-noob-tester.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/docs-server-lifecycle.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"67d7121754cd87f039eff5782dd31356426aed9c72c09881a79957f3ab7b9580","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"a6cd6eb950ddf376ae429f913c30f3b7ceb1f829bbec3558a74452cf34531b08","strict":true}
name: "Documentation Noob Tester"
"on":
@@ -132,7 +133,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -169,6 +170,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/docs-server-lifecycle.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -338,7 +342,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -378,6 +382,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -500,6 +546,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1176,7 +1249,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/docs-noob-tester.md b/.github/workflows/docs-noob-tester.md
index ca9484595da..7350160254c 100644
--- a/.github/workflows/docs-noob-tester.md
+++ b/.github/workflows/docs-noob-tester.md
@@ -19,8 +19,6 @@ safe-outputs:
upload-asset:
create-discussion:
expires: 1d
- category: "audits"
- close-older-discussions: true
network:
allowed:
@@ -28,6 +26,7 @@ network:
- node
imports:
+ - shared/daily-audit-discussion.md
- shared/docs-server-lifecycle.md
- shared/reporting.md
features:
diff --git a/.github/workflows/example-workflow-analyzer.lock.yml b/.github/workflows/example-workflow-analyzer.lock.yml
index e4770ddae6e..0fcb8548934 100644
--- a/.github/workflows/example-workflow-analyzer.lock.yml
+++ b/.github/workflows/example-workflow-analyzer.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"b2b481f42784eb25bc36cfd587b8b96ac047f581e1d27b81d4f1563711bb420c","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"6e719f62ef8c7f3974467aa95b5893612d90f8a50eedbbd2268ee5f44c3b96bb","strict":true}
name: "Weekly Workflow Analysis"
"on":
@@ -136,7 +137,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -171,6 +172,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -391,7 +395,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -431,6 +435,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -528,6 +574,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1234,7 +1307,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[workflow-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[workflow-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/example-workflow-analyzer.md b/.github/workflows/example-workflow-analyzer.md
index d975ccccfd5..ccd85c4ca6e 100644
--- a/.github/workflows/example-workflow-analyzer.md
+++ b/.github/workflows/example-workflow-analyzer.md
@@ -17,10 +17,9 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[workflow-analysis] "
- category: "audits"
- close-older-discussions: true
timeout-minutes: 10
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/firewall-escape.lock.yml b/.github/workflows/firewall-escape.lock.yml
index 8bea34fba32..8b6bac3eaea 100644
--- a/.github/workflows/firewall-escape.lock.yml
+++ b/.github/workflows/firewall-escape.lock.yml
@@ -23,7 +23,11 @@
#
# Security testing to find escape paths in the AWF (Agent Workflow Firewall)
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"74e501e0d13e7e5a3b2d21418bc8460f5c0023998ac599caa303fec99234b69e","strict":true}
+# Resolved workflow manifest:
+# Imports:
+# - shared/daily-audit-discussion.md
+#
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"93dc6fdbeecb751253d74d734c95367e53805c9a60670ad8e58948331ee851a7","strict":true}
name: "The Great Escapi"
"on":
@@ -151,7 +155,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -186,6 +190,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/firewall-escape.md}}
GH_AW_PROMPT_EOF
} > "$GH_AW_PROMPT"
@@ -388,7 +395,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":50,"max_file_size":524288,"max_patch_size":10240}]}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":50,"max_file_size":524288,"max_patch_size":10240}]}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -428,6 +435,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -540,6 +589,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1344,7 +1420,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Firewall Escape] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Firewall Escape] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/firewall-escape.md b/.github/workflows/firewall-escape.md
index 44875827c69..39941b81017 100644
--- a/.github/workflows/firewall-escape.md
+++ b/.github/workflows/firewall-escape.md
@@ -35,9 +35,7 @@ sandbox:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
title-prefix: "[Firewall Escape] "
- max: 1
tools:
github:
@@ -84,6 +82,8 @@ jobs:
});
features:
copilot-requests: true
+imports:
+ - shared/daily-audit-discussion.md
---
# The Great Escapi
diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml
index a49758bcc40..04318de0971 100644
--- a/.github/workflows/github-mcp-structural-analysis.lock.yml
+++ b/.github/workflows/github-mcp-structural-analysis.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/python-dataviz.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"bae501e108ec9d6346e7e1686373396ef4828d5e532005db44bde88081d0ea79","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"a268a6981037d56b4b3fe8f9758e76aca05f4509443196021afa7811561248d5","strict":true}
name: "GitHub MCP Structural Analysis"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -174,6 +175,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/python-dataviz.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -386,7 +390,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -426,6 +430,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -548,6 +594,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1278,7 +1351,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,cdn.playwright.dev,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,static.crates.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[mcp-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[mcp-analysis] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/github-mcp-structural-analysis.md b/.github/workflows/github-mcp-structural-analysis.md
index 31328a90a87..778a40332de 100644
--- a/.github/workflows/github-mcp-structural-analysis.md
+++ b/.github/workflows/github-mcp-structural-analysis.md
@@ -24,11 +24,9 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
title-prefix: "[mcp-analysis] "
- max: 1
- close-older-discussions: true
imports:
+ - shared/daily-audit-discussion.md
- shared/python-dataviz.md
- shared/reporting.md
---
diff --git a/.github/workflows/github-mcp-tools-report.lock.yml b/.github/workflows/github-mcp-tools-report.lock.yml
index 1eba3bc8926..be6e9e1e3b0 100644
--- a/.github/workflows/github-mcp-tools-report.lock.yml
+++ b/.github/workflows/github-mcp-tools-report.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"4dfbb7c20c8c63aa5741b2465985b3e579cc02728ba2187d3a28a8f548d39d2c","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"191564471b96ff9b0aae2962a207b399f2a3cc626230de18bb914d3ae61887d4","strict":true}
name: "GitHub MCP Remote Server Tools Report Generator"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, create_pull_request, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, create_pull_request, missing_tool, missing_data, noop
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/safe_outputs_create_pull_request.md"
cat << 'GH_AW_PROMPT_EOF'
@@ -175,6 +176,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -360,7 +364,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":168,"max":1},"create_pull_request":{"expires":48,"max":1,"reviewers":["copilot"],"title_prefix":"[mcp-tools] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":168,"max":1},"create_pull_request":{"expires":48,"max":1,"reviewers":["copilot"],"title_prefix":"[mcp-tools] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -400,6 +404,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Create a new GitHub pull request to propose code changes. Use this after making file edits to submit them for review and merging. The PR will be created from the current branch with your committed changes. For code review comments on an existing PR, use create_pull_request_review_comment instead. CONSTRAINTS: Maximum 1 pull request(s) can be created. Title will be prefixed with \"[mcp-tools] \". Labels [\"documentation\" \"automation\"] will be automatically added. Reviewers [\"copilot\"] will be assigned.",
"inputSchema": {
@@ -546,6 +592,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1338,7 +1411,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"fallback_to_issue\":true,\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":48,\"labels\":[\"documentation\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CLAUDE.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"reviewers\":[\"copilot\"],\"title_prefix\":\"[mcp-tools] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":168,\"fallback_to_issue\":true,\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":48,\"labels\":[\"documentation\",\"automation\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CLAUDE.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\",\".claude/\"],\"reviewers\":[\"copilot\"],\"title_prefix\":\"[mcp-tools] \"},\"missing_data\":{},\"missing_tool\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/github-mcp-tools-report.md b/.github/workflows/github-mcp-tools-report.md
index 14510797b0b..2f141a10bea 100644
--- a/.github/workflows/github-mcp-tools-report.md
+++ b/.github/workflows/github-mcp-tools-report.md
@@ -18,10 +18,6 @@ tools:
cache-memory: true
edit:
safe-outputs:
- create-discussion:
- category: "audits"
- max: 1
- close-older-discussions: true
create-pull-request:
expires: 2d
title-prefix: "[mcp-tools] "
@@ -30,6 +26,7 @@ safe-outputs:
draft: false
timeout-minutes: 15
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml
index 05f761aa9ec..d3cda5ba886 100644
--- a/.github/workflows/github-remote-mcp-auth-test.lock.yml
+++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml
@@ -23,7 +23,11 @@
#
# Daily test of GitHub remote MCP authentication with GitHub Actions token
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"db9f3ebc997b550ea21426bffe49626f5370c470f814cac5e5846ac09231c0c4","strict":true}
+# Resolved workflow manifest:
+# Imports:
+# - shared/daily-audit-discussion.md
+#
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"f26eb872ab2016584fe4f0bb9d3b862c74e9c1c3ee88beed81de73f27ccc6316","strict":true}
name: "GitHub Remote MCP Authentication Test"
"on":
@@ -133,7 +137,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -168,6 +172,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/github-remote-mcp-auth-test.md}}
GH_AW_PROMPT_EOF
} > "$GH_AW_PROMPT"
@@ -333,7 +340,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -373,6 +380,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -470,6 +519,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1123,7 +1199,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[auth-test] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[auth-test] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/github-remote-mcp-auth-test.md b/.github/workflows/github-remote-mcp-auth-test.md
index 9d28b1eb7eb..98f0024b591 100644
--- a/.github/workflows/github-remote-mcp-auth-test.md
+++ b/.github/workflows/github-remote-mcp-auth-test.md
@@ -19,11 +19,10 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[auth-test] "
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 5
strict: true
+imports:
+ - shared/daily-audit-discussion.md
---
# GitHub Remote MCP Authentication Test
diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml
index 1a448b4ee18..3d4d9a3f1b8 100644
--- a/.github/workflows/go-fan.lock.yml
+++ b/.github/workflows/go-fan.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"3ca391548ba08c8a271413f4cf5a5ec319865e7da8f0a921a2d070743534688d","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"7d60d67a3747821c28c93fc1a4fc8727b264234b3759abb0b0daccc70997f5bf","strict":true}
name: "Go Fan"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -360,7 +364,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -400,6 +404,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -497,6 +543,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1241,7 +1314,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,go.dev,golang.org,goproxy.io,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkg.go.dev,playwright.download.prss.microsoft.com,ppa.launchpad.net,proxy.golang.org,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,storage.googleapis.com,sum.golang.org,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[go-fan] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[go-fan] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/go-fan.md b/.github/workflows/go-fan.md
index f8759cce00e..8c0fb4e0fff 100644
--- a/.github/workflows/go-fan.md
+++ b/.github/workflows/go-fan.md
@@ -23,6 +23,7 @@ network:
- go
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/mcp/serena-go.md
@@ -30,9 +31,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[go-fan] "
- category: "audits"
- max: 1
- close-older-discussions: true
tools:
cache-memory: true
diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml
index e72e4cbc79f..7eb4701b7a3 100644
--- a/.github/workflows/issue-arborist.lock.yml
+++ b/.github/workflows/issue-arborist.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"62b23a3c0dede758b81863caa7459cae020a40572108751686b33bc53ff6355f","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"b8714ef4ccc5d2c100f5ee19da9c2622944dcd088d8cabf9df2a7c57ebaf09ee","strict":true}
name: "Issue Arborist"
"on":
@@ -141,7 +142,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_issue, create_discussion, link_sub_issue, missing_tool, missing_data, noop
+ Tools: create_issue, create_discussion, close_discussion, link_sub_issue, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -176,6 +177,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/jqschema.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -342,7 +346,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"create_issue":{"expires":48,"group":true,"max":5},"link_sub_issue":{"max":50},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"create_issue":{"expires":48,"group":true,"max":5},"link_sub_issue":{"max":50},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -431,6 +435,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -564,6 +610,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1239,7 +1312,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,172.30.0.1,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Issue Arborist] \"},\"create_issue\":{\"expires\":48,\"group\":true,\"max\":5,\"title_prefix\":\"[Parent] \"},\"link_sub_issue\":{\"max\":50},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Issue Arborist] \"},\"create_issue\":{\"expires\":48,\"group\":true,\"max\":5,\"title_prefix\":\"[Parent] \"},\"link_sub_issue\":{\"max\":50},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/issue-arborist.md b/.github/workflows/issue-arborist.md
index 9729cce6254..ae32ab8dd23 100644
--- a/.github/workflows/issue-arborist.md
+++ b/.github/workflows/issue-arborist.md
@@ -14,6 +14,7 @@ network:
- defaults
- github
imports:
+ - shared/daily-audit-discussion.md
- shared/jqschema.md
- shared/reporting.md
tools:
@@ -65,8 +66,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[Issue Arborist] "
- category: "audits"
- close-older-discussions: true
timeout-minutes: 15
---
diff --git a/.github/workflows/lockfile-stats.lock.yml b/.github/workflows/lockfile-stats.lock.yml
index d1756a8ea80..c6a5fb3281c 100644
--- a/.github/workflows/lockfile-stats.lock.yml
+++ b/.github/workflows/lockfile-stats.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"8e7c90b156e9a9c5a415792db7e51dd31799eb95a17d36b2034ccb3ceb3d71d6","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"cb47c1df37524b9b2e754ff70942f13d6784704c82721ace21413e146324cd35","strict":true}
name: "Lockfile Statistics Analysis Agent"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -354,7 +358,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -394,6 +398,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -491,6 +537,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1196,7 +1269,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/lockfile-stats.md b/.github/workflows/lockfile-stats.md
index 9fd46dc99f6..8781e3e4db2 100644
--- a/.github/workflows/lockfile-stats.md
+++ b/.github/workflows/lockfile-stats.md
@@ -14,12 +14,10 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 15
strict: true
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml
index 7075c7aa195..6fef344f742 100644
--- a/.github/workflows/mcp-inspector.lock.yml
+++ b/.github/workflows/mcp-inspector.lock.yml
@@ -25,6 +25,7 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/arxiv.md
# - shared/mcp/ast-grep.md
# - shared/mcp/brave.md
@@ -42,7 +43,7 @@
# - shared/mcp/tavily.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"e92fc7f19a13329f2f521f2c3ade949e9a30c1bd31c9752c012a660be935c8a8"}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"607e02c37f9b8b343118aaf03e3d520f6d5a5f64a56a7f2bad64d3637dcea585"}
name: "MCP Inspector Agent"
"on":
@@ -152,7 +153,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -187,6 +188,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/mcp/arxiv.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -477,7 +481,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"notion-add-comment":{"description":"Add a comment to a Notion page","inputs":{"comment":{"default":null,"description":"The comment text to add","required":true,"type":"string"}},"output":"Comment added to Notion successfully!"},"post-to-slack-channel":{"description":"Post a message to a Slack channel. Message must be 200 characters or less. Supports basic Slack markdown: *bold*, _italic_, ~strike~, `code`, ```code block```, \u003equote, and links \u003curl|text\u003e. Requires GH_AW_SLACK_CHANNEL_ID environment variable to be set.","inputs":{"message":{"default":null,"description":"The message to post (max 200 characters, supports Slack markdown)","required":true,"type":"string"}},"output":"Message posted to Slack successfully!"}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"notion-add-comment":{"description":"Add a comment to a Notion page","inputs":{"comment":{"default":null,"description":"The comment text to add","required":true,"type":"string"}},"output":"Comment added to Notion successfully!"},"post-to-slack-channel":{"description":"Post a message to a Slack channel. Message must be 200 characters or less. Supports basic Slack markdown: *bold*, _italic_, ~strike~, `code`, ```code block```, \u003equote, and links \u003curl|text\u003e. Requires GH_AW_SLACK_CHANNEL_ID environment variable to be set.","inputs":{"message":{"default":null,"description":"The message to post (max 200 characters, supports Slack markdown)","required":true,"type":"string"}},"output":"Message posted to Slack successfully!"}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -517,6 +521,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -648,6 +694,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1800,7 +1873,7 @@ jobs:
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUT_JOBS: "{\"notion_add_comment\":\"\",\"post_to_slack_channel\":\"\"}"
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/mcp-inspector.md b/.github/workflows/mcp-inspector.md
index 2699481d118..dd2feef42fc 100644
--- a/.github/workflows/mcp-inspector.md
+++ b/.github/workflows/mcp-inspector.md
@@ -21,12 +21,10 @@ sandbox:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 20
strict: false
imports:
+ - shared/daily-audit-discussion.md
- shared/mcp/arxiv.md
- shared/mcp/ast-grep.md
# Note: azure.md excluded due to schema validation issue with entrypointArgs
diff --git a/.github/workflows/portfolio-analyst.lock.yml b/.github/workflows/portfolio-analyst.lock.yml
index 31cec5bea8f..5f857c6a92d 100644
--- a/.github/workflows/portfolio-analyst.lock.yml
+++ b/.github/workflows/portfolio-analyst.lock.yml
@@ -25,11 +25,12 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
# - shared/trending-charts-simple.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"e7935e168ae0e6f7257077dd33ddb274861679adccbf323280cef1efa3759fee","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"827c27451769f3cbc00cd84c01ca62bccb9d9010d0bb96fd121171b87195232b","strict":true}
name: "Automated Portfolio Analyst"
"on":
@@ -139,7 +140,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -176,6 +177,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -448,7 +452,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -488,6 +492,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -610,6 +656,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1303,7 +1376,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.pythonhosted.org,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,github.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,static.crates.io,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[portfolio] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[portfolio] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/portfolio-analyst.md b/.github/workflows/portfolio-analyst.md
index c107c7f50ef..6d7140c56f9 100644
--- a/.github/workflows/portfolio-analyst.md
+++ b/.github/workflows/portfolio-analyst.md
@@ -28,11 +28,10 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[portfolio] "
- category: "audits"
- close-older-discussions: true
upload-asset:
timeout-minutes: 20
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/jqschema.md
- shared/trending-charts-simple.md
diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml
index 4e694b100ff..6a2bc2dfc13 100644
--- a/.github/workflows/pr-nitpick-reviewer.lock.yml
+++ b/.github/workflows/pr-nitpick-reviewer.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"02499e8cdb83ed473b50353b2f91edd95d5c962027fc11a8aaf5b11e67096427","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"1955c6bb1f6ae42bf6948755db45182aa19879c0e54df176eb5d8e8186b4d3ef","strict":true}
name: "PR Nitpick Reviewer 🔍"
"on":
@@ -201,7 +202,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, create_pull_request_review_comment, submit_pull_request_review, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, create_pull_request_review_comment, submit_pull_request_review, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -239,6 +240,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -428,7 +432,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"create_pull_request_review_comment":{"max":10},"missing_data":{},"missing_tool":{},"noop":{"max":1},"submit_pull_request_review":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"create_pull_request_review_comment":{"max":10},"missing_data":{},"missing_tool":{},"noop":{"max":1},"submit_pull_request_review":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -468,6 +472,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Create a review comment on a specific line of code in a pull request. Use this for inline code review feedback, suggestions, or questions about specific code changes. For general PR comments not tied to specific lines, use add_comment instead. When the workflow is configured with `target: \"*\"`, you must specify `pull_request_number` to indicate which PR to target. CONSTRAINTS: Maximum 10 review comment(s) can be created. Comments will be on the RIGHT side of the diff.",
"inputSchema": {
@@ -660,6 +706,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1423,7 +1496,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[nitpick-report] \"},\"create_pull_request_review_comment\":{\"max\":10,\"side\":\"RIGHT\"},\"missing_data\":{},\"missing_tool\":{},\"submit_pull_request_review\":{\"max\":1}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[nitpick-report] \"},\"create_pull_request_review_comment\":{\"max\":10,\"side\":\"RIGHT\"},\"missing_data\":{},\"missing_tool\":{},\"submit_pull_request_review\":{\"max\":1}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/pr-nitpick-reviewer.md b/.github/workflows/pr-nitpick-reviewer.md
index b07eed1b353..babca002809 100644
--- a/.github/workflows/pr-nitpick-reviewer.md
+++ b/.github/workflows/pr-nitpick-reviewer.md
@@ -15,8 +15,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[nitpick-report] "
- category: "audits"
- max: 1
create-pull-request-review-comment:
max: 10
side: "RIGHT"
@@ -29,6 +27,7 @@ safe-outputs:
run-failure: "🔬 Lens cracked! [{workflow_name}]({run_url}) {status}. Some nitpicks remain undetected..."
timeout-minutes: 15
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml
index aa0092a8693..c493f1500c7 100644
--- a/.github/workflows/prompt-clustering-analysis.lock.yml
+++ b/.github/workflows/prompt-clustering-analysis.lock.yml
@@ -26,11 +26,12 @@
# Resolved workflow manifest:
# Imports:
# - shared/copilot-pr-data-fetch.md
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
# - shared/trending-charts-simple.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"711d989f13320ca6c9165974764c245b845badcef5a8e6cd3b6ec8ee0373b2db","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"135fecd1b65e5779d4426d1e44fffc5aae3cb44986dc28b3136a7e5634c7908e","strict":true}
name: "Copilot Agent Prompt Clustering Analysis"
"on":
@@ -142,7 +143,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -177,6 +178,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/jqschema.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -473,7 +477,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -513,6 +517,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -610,6 +656,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1327,7 +1400,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,cdn.playwright.dev,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.npmjs.org,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,static.crates.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[prompt-clustering] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[prompt-clustering] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/prompt-clustering-analysis.md b/.github/workflows/prompt-clustering-analysis.md
index e4cde4585eb..12dd609e01c 100644
--- a/.github/workflows/prompt-clustering-analysis.md
+++ b/.github/workflows/prompt-clustering-analysis.md
@@ -23,11 +23,9 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[prompt-clustering] "
- category: "audits"
- max: 1
- close-older-discussions: true
imports:
+ - shared/daily-audit-discussion.md
- shared/jqschema.md
- shared/reporting.md
- shared/copilot-pr-data-fetch.md
diff --git a/.github/workflows/repo-audit-analyzer.lock.yml b/.github/workflows/repo-audit-analyzer.lock.yml
index 91d929a6586..22fea13c5a1 100644
--- a/.github/workflows/repo-audit-analyzer.lock.yml
+++ b/.github/workflows/repo-audit-analyzer.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"83f67c7db0b6f9679570e272c311a7239fa2f9444319c2bf3b86710a3cdaa6ec","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"4ea98cb3b241347b3e435dbda3936aded051da67245ceda7a4c29920d09d8a9a","strict":true}
name: "Repository Audit & Agentic Workflow Opportunity Analyzer"
"on":
@@ -141,7 +142,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -176,6 +177,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -358,7 +362,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"create_missing_tool_issue":{"labels":["cookie"],"max":1,"title_prefix":"[missing tool]"},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"create_missing_tool_issue":{"labels":["cookie"],"max":1,"title_prefix":"[missing tool]"},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -398,6 +402,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -495,6 +541,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1148,7 +1221,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/repo-audit-analyzer.md b/.github/workflows/repo-audit-analyzer.md
index 62417693a9d..ed2594450ce 100644
--- a/.github/workflows/repo-audit-analyzer.md
+++ b/.github/workflows/repo-audit-analyzer.md
@@ -24,15 +24,13 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
missing-tool:
create-issue: true
labels: [cookie]
timeout-minutes: 45
strict: true
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml
index b531c2d0950..74da227d56c 100644
--- a/.github/workflows/repository-quality-improver.lock.yml
+++ b/.github/workflows/repository-quality-improver.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"6bb1a0d4a4a46eebdfbddfe915d6345a17575dd0489817be13e208c9921460da","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"c97b39f61bffe2d2d9f833d1b2c35bc0c7ba1587a697ebf14af904d398bd9e22","strict":true}
name: "Repository Quality Improvement Agent"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -357,7 +361,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -397,6 +401,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -494,6 +540,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1152,7 +1225,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/repository-quality-improver.md b/.github/workflows/repository-quality-improver.md
index 6bae0914ea4..4d8c6eb08e7 100644
--- a/.github/workflows/repository-quality-improver.md
+++ b/.github/workflows/repository-quality-improver.md
@@ -11,6 +11,7 @@ permissions:
pull-requests: read
engine: copilot
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/mcp/serena-go.md
tools:
@@ -25,9 +26,6 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 20
strict: true
diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml
index 35f9f527066..b095b9a89e5 100644
--- a/.github/workflows/safe-output-health.lock.yml
+++ b/.github/workflows/safe-output-health.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/jqschema.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"00020e00cf1cd2251ab99ac78f281500ee26b1c69695f71ec416769285c291a9","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"a65a1bce3159397fe4905898e02b4df8413befa79bc05b1dc3384d957132310d","strict":true}
name: "Safe Output Health Monitor"
"on":
@@ -138,7 +139,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -173,6 +174,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/jqschema.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -420,7 +424,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -460,6 +464,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -557,6 +603,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1289,7 +1362,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/safe-output-health.md b/.github/workflows/safe-output-health.md
index 6f663abde2c..38bc3ea2864 100644
--- a/.github/workflows/safe-output-health.md
+++ b/.github/workflows/safe-output-health.md
@@ -21,12 +21,10 @@ steps:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
timeout-minutes: 30
strict: true
imports:
+ - shared/daily-audit-discussion.md
- shared/jqschema.md
- shared/reporting.md
---
diff --git a/.github/workflows/schema-consistency-checker.lock.yml b/.github/workflows/schema-consistency-checker.lock.yml
index b5a9e11b9ee..1ffb237bb6a 100644
--- a/.github/workflows/schema-consistency-checker.lock.yml
+++ b/.github/workflows/schema-consistency-checker.lock.yml
@@ -25,9 +25,10 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"7cb844c9c9c32229b2755637af132ad41de3ddbda8eff01a2f5a5f753fb303a6","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"927d3f9868166e9bef338a1cb6610de8dff953ff5b911813f58cd731e674df3f","strict":true}
name: "Schema Consistency Checker"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -354,7 +358,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -394,6 +398,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -491,6 +537,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1196,7 +1269,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Schema Consistency] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Schema Consistency] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/schema-consistency-checker.md b/.github/workflows/schema-consistency-checker.md
index 80a5e80c2c1..9961288059e 100644
--- a/.github/workflows/schema-consistency-checker.md
+++ b/.github/workflows/schema-consistency-checker.md
@@ -20,12 +20,10 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
title-prefix: "[Schema Consistency] "
- max: 1
- close-older-discussions: true
timeout-minutes: 30
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
---
diff --git a/.github/workflows/sergo.lock.yml b/.github/workflows/sergo.lock.yml
index 24868a8e7ca..b4b7760e80a 100644
--- a/.github/workflows/sergo.lock.yml
+++ b/.github/workflows/sergo.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"02bf772df769e1b8dcee8170592780e7f1203860768210b7bf353632372b9d86","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"ffdf8880058e622435f10f1a41e0a416617d901e8e579cb2747ef567e63717d9","strict":true}
name: "Sergo - Serena Go Expert"
"on":
@@ -138,7 +139,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -173,6 +174,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -360,7 +364,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -400,6 +404,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -497,6 +543,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1240,7 +1313,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,github.githubassets.com,go.dev,golang.org,goproxy.io,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkg.go.dev,playwright.download.prss.microsoft.com,ppa.launchpad.net,proxy.golang.org,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,storage.googleapis.com,sum.golang.org,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[sergo] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[sergo] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/sergo.md b/.github/workflows/sergo.md
index edc3f9c09b4..eb79198ca5d 100644
--- a/.github/workflows/sergo.md
+++ b/.github/workflows/sergo.md
@@ -22,6 +22,7 @@ network:
- go
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/mcp/serena-go.md
@@ -29,9 +30,6 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[sergo] "
- category: "audits"
- max: 1
- close-older-discussions: true
tools:
cache-memory: true
diff --git a/.github/workflows/shared/daily-audit-discussion.md b/.github/workflows/shared/daily-audit-discussion.md
new file mode 100644
index 00000000000..881d9c672ff
--- /dev/null
+++ b/.github/workflows/shared/daily-audit-discussion.md
@@ -0,0 +1,45 @@
+---
+# Daily Audit Discussion — shared safe-output base configuration
+#
+# Usage:
+# imports:
+# - shared/daily-audit-discussion.md
+#
+# This component provides the standard safe-output configuration used by daily/weekly
+# audit and reporting workflows that publish a discussion in the "audits" category:
+# - create-discussion: category "audits", max 1, close-older-discussions
+# - close-discussion: max 10
+#
+# Each importing workflow keeps only its workflow-specific settings inline.
+# Because create-discussion uses field-level merging, any field that is NOT set
+# in the workflow's own safe-outputs block is automatically filled from this component.
+# Fields typically kept per-workflow: title-prefix and expires.
+#
+# Example — workflow-specific block after importing:
+# safe-outputs:
+# create-discussion:
+# title-prefix: "[my-workflow] "
+# expires: 3d
+
+safe-outputs:
+ create-discussion:
+ category: "audits"
+ max: 1
+ close-older-discussions: true
+ close-discussion:
+ max: 10
+---
+
+## Audit Discussion Output
+
+Create a new discussion in the `audits` category when the analysis is complete.
+Previous discussions for the same workflow are automatically closed.
+Charts and artifacts can be uploaded as assets and referenced in the discussion body.
+
+### Discussion Format
+
+Follow `shared/reporting.md` guidelines:
+- Use `###` (h3) for all section headers (never `#` or `##`)
+- Wrap verbose details in `` tags
+- Include a summary table at the top with key metrics
+- Reference the workflow run: `[${{ github.run_id }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`
diff --git a/.github/workflows/terminal-stylist.lock.yml b/.github/workflows/terminal-stylist.lock.yml
index bae77e1a0c3..e6d6042733c 100644
--- a/.github/workflows/terminal-stylist.lock.yml
+++ b/.github/workflows/terminal-stylist.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"da1780268adb86447e56695671e9c4099f9e4f3cfbba2ad1ea6299110b676880","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"0e4aae49bee0a021eeb1b73f4f536ff54121a465f241fa833bdd4c09e021ced1","strict":true}
name: "Terminal Stylist"
"on":
@@ -137,7 +138,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -172,6 +173,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/mcp/serena-go.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -338,7 +342,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -378,6 +382,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -475,6 +521,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1126,7 +1199,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/terminal-stylist.md b/.github/workflows/terminal-stylist.md
index e7bfc329a9d..8a1ae85469e 100644
--- a/.github/workflows/terminal-stylist.md
+++ b/.github/workflows/terminal-stylist.md
@@ -15,6 +15,7 @@ timeout-minutes: 10
strict: true
imports:
+ - shared/daily-audit-discussion.md
- shared/mcp/serena-go.md
- shared/reporting.md
@@ -28,9 +29,6 @@ tools:
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
---
# Terminal Stylist - Console Output Analysis
diff --git a/.github/workflows/typist.lock.yml b/.github/workflows/typist.lock.yml
index 226934c2aff..f99f68f9318 100644
--- a/.github/workflows/typist.lock.yml
+++ b/.github/workflows/typist.lock.yml
@@ -25,10 +25,11 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/mcp/serena-go.md
# - shared/reporting.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"a84f1d31ef089afc1ac4110815e97c8509584a617fb3384a318fe01d5e960c67","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"1a26a0ecb7db02014d0fe8ed4f23762446fc0b7da6c09fa521b87995592daa09","strict":true}
name: "Typist - Go Type Analysis"
"on":
@@ -136,7 +137,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -171,6 +172,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -341,7 +345,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -381,6 +385,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -478,6 +524,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1207,7 +1280,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,anthropic.com,api.anthropic.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,files.pythonhosted.org,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,pypi.org,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sentry.io,statsig.anthropic.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/typist.md b/.github/workflows/typist.md
index d1b0c9a4300..1108e7c0361 100644
--- a/.github/workflows/typist.md
+++ b/.github/workflows/typist.md
@@ -14,15 +14,13 @@ permissions:
engine: claude
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/mcp/serena-go.md
safe-outputs:
create-discussion:
expires: 1d
- category: "audits"
- max: 1
- close-older-discussions: true
tools:
github:
diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml
index e08038b5159..85271dacc34 100644
--- a/.github/workflows/weekly-issue-summary.lock.yml
+++ b/.github/workflows/weekly-issue-summary.lock.yml
@@ -25,11 +25,12 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/daily-audit-discussion.md
# - shared/python-dataviz.md
# - shared/reporting.md
# - shared/trends.md
#
-# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"ccb4a4b9b79c5fda99bccf6c37c613c84d09d13bd2d0b60ed372613aa03e78d1","strict":true}
+# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"7c27cb82ddd31ec653f571f5a98f8fc983416abf091fa858819f78732dbeea21","strict":true}
name: "Weekly Issue Summary"
"on":
@@ -141,7 +142,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_discussion, upload_asset, missing_tool, missing_data, noop
+ Tools: create_discussion, close_discussion, upload_asset, missing_tool, missing_data, noop
upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs).
@@ -178,6 +179,9 @@ jobs:
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
+ {{#runtime-import .github/workflows/shared/daily-audit-discussion.md}}
+ GH_AW_PROMPT_EOF
+ cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF'
@@ -361,7 +365,7 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
+ {"close_discussion":{"max":10},"create_discussion":{"expires":24,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"upload_asset":{"max":0}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
@@ -401,6 +405,48 @@ jobs:
},
"name": "create_discussion"
},
+ {
+ "description": "Close a GitHub discussion with a resolution comment and optional reason. You can and should always add a comment when closing a discussion to explain the action or provide context. Use this to mark discussions as resolved, answered, or no longer needed. The closing comment should explain why the discussion is being closed. If the discussion is already closed, a comment will still be posted. CONSTRAINTS: Maximum 10 discussion(s) can be closed.",
+ "inputSchema": {
+ "additionalProperties": false,
+ "properties": {
+ "body": {
+ "description": "Closing comment explaining why the discussion is being closed and summarizing any resolution or conclusion.",
+ "type": "string"
+ },
+ "discussion_number": {
+ "description": "Discussion number to close. This is the numeric ID from the GitHub URL (e.g., 678 in github.com/owner/repo/discussions/678). If omitted, closes the discussion that triggered this workflow (requires a discussion event trigger).",
+ "type": [
+ "number",
+ "string"
+ ]
+ },
+ "integrity": {
+ "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Resolution reason: RESOLVED (issue addressed), DUPLICATE (discussed elsewhere), OUTDATED (no longer relevant), or ANSWERED (question answered).",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ],
+ "type": "string"
+ },
+ "secrecy": {
+ "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
+ "type": "string"
+ }
+ },
+ "required": [
+ "body"
+ ],
+ "type": "object"
+ },
+ "name": "close_discussion"
+ },
{
"description": "Upload a file as a URL-addressable asset that can be referenced in issues, PRs, or comments. The file is stored on an orphaned git branch and returns a permanent URL. Use this for images, diagrams, or other files that need to be embedded in GitHub content. CONSTRAINTS: Maximum file size: 10240KB. Allowed file extensions: [.png .jpg .jpeg].",
"inputSchema": {
@@ -523,6 +569,33 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
+ "close_discussion": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "discussion_number": {
+ "optionalPositiveInteger": true
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "RESOLVED",
+ "DUPLICATE",
+ "OUTDATED",
+ "ANSWERED"
+ ]
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
"create_discussion": {
"defaultMax": 1,
"fields": {
@@ -1201,7 +1274,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.jsr.io,*.pythonhosted.org,anaconda.org,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,binstar.org,bootstrap.pypa.io,bun.sh,cdn.jsdelivr.net,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,esm.sh,files.pythonhosted.org,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,host.docker.internal,index.crates.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.anaconda.com,repo.continuum.io,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,static.crates.io,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Weekly Summary] \"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"close_discussion\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Weekly Summary] \"},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/weekly-issue-summary.md b/.github/workflows/weekly-issue-summary.md
index aade7184a65..571681127ab 100644
--- a/.github/workflows/weekly-issue-summary.md
+++ b/.github/workflows/weekly-issue-summary.md
@@ -30,9 +30,8 @@ safe-outputs:
create-discussion:
expires: 1d
title-prefix: "[Weekly Summary] "
- category: "audits"
- close-older-discussions: true
imports:
+ - shared/daily-audit-discussion.md
- shared/reporting.md
- shared/trends.md
---
diff --git a/pkg/workflow/imports.go b/pkg/workflow/imports.go
index 3a2a7c81c15..1d1904d7a1e 100644
--- a/pkg/workflow/imports.go
+++ b/pkg/workflow/imports.go
@@ -216,14 +216,24 @@ func (c *Compiler) MergeSafeOutputs(topSafeOutputs *SafeOutputsConfig, importedS
}
// Check for conflicts and remove types already defined in top-level config
- // Main workflow definitions take precedence over imports (override behavior)
+ // Main workflow definitions take precedence over imports (override behavior).
+ // Exception: create-discussion supports field-level merging so shared components
+ // can provide base fields (category, max, close-older-discussions) while individual
+ // workflows override only their specific settings (title-prefix, expires).
for _, key := range typeKeys {
if _, exists := config[key]; exists {
if topDefinedTypes[key] {
- // Main workflow overrides imported definition - remove from imported config
- importsLog.Printf("Main workflow overrides imported safe-output: %s", key)
- delete(config, key)
- continue
+ if key == "create-discussion" {
+ // Allow field-level merge: keep imported create-discussion so
+ // mergeSafeOutputConfig can fill in base fields that the main
+ // workflow has not set (e.g. category, close-older-discussions).
+ importsLog.Printf("Allowing field-level merge for create-discussion from import")
+ } else {
+ // Main workflow overrides imported definition - remove from imported config
+ importsLog.Printf("Main workflow overrides imported safe-output: %s", key)
+ delete(config, key)
+ continue
+ }
}
if importedDefinedTypes[key] {
return nil, fmt.Errorf("safe-outputs conflict: '%s' is defined in multiple imported workflows. Each safe-output type can only be defined once", key)
@@ -372,8 +382,14 @@ func mergeSafeOutputConfig(result *SafeOutputsConfig, config map[string]any, c *
if result.CreateIssues == nil && importedConfig.CreateIssues != nil {
result.CreateIssues = importedConfig.CreateIssues
}
- if result.CreateDiscussions == nil && importedConfig.CreateDiscussions != nil {
- result.CreateDiscussions = importedConfig.CreateDiscussions
+ if importedConfig.CreateDiscussions != nil {
+ if result.CreateDiscussions == nil {
+ result.CreateDiscussions = importedConfig.CreateDiscussions
+ } else {
+ // Field-level merge: fill in base fields from shared component that the
+ // main workflow has not explicitly set (e.g. category, close-older-discussions).
+ mergeCreateDiscussionsFields(result.CreateDiscussions, importedConfig.CreateDiscussions)
+ }
}
if result.UpdateDiscussions == nil && importedConfig.UpdateDiscussions != nil {
result.UpdateDiscussions = importedConfig.UpdateDiscussions
@@ -615,6 +631,35 @@ func mergeMessagesConfig(result, imported *SafeOutputMessagesConfig) *SafeOutput
return result
}
+// mergeCreateDiscussionsFields fills in base configuration fields from the imported (shared)
+// component into the result (main workflow) config. This enables shared components to provide
+// base fields such as category and close-older-discussions while individual workflows override
+// only their specific settings (title-prefix, expires).
+// The main workflow's non-zero/non-nil values always take precedence.
+func mergeCreateDiscussionsFields(result, imported *CreateDiscussionsConfig) {
+ if result.Category == "" && imported.Category != "" {
+ result.Category = imported.Category
+ }
+ if result.CloseOlderDiscussions == nil && imported.CloseOlderDiscussions != nil {
+ result.CloseOlderDiscussions = imported.CloseOlderDiscussions
+ }
+ if result.RequiredCategory == "" && imported.RequiredCategory != "" {
+ result.RequiredCategory = imported.RequiredCategory
+ }
+ if len(result.Labels) == 0 && len(imported.Labels) > 0 {
+ result.Labels = imported.Labels
+ }
+ if len(result.AllowedLabels) == 0 && len(imported.AllowedLabels) > 0 {
+ result.AllowedLabels = imported.AllowedLabels
+ }
+ if result.Footer == nil && imported.Footer != nil {
+ result.Footer = imported.Footer
+ }
+ // Note: TitlePrefix, Expires, TargetRepoSlug, AllowedRepos, CloseOlderKey, Max, and
+ // BaseSafeOutputConfig fields are NOT merged – they either default in parseDiscussionsConfig
+ // or are intentionally workflow-specific.
+}
+
// MergeFeatures merges features configurations from imports with top-level features
// Features from top-level take precedence over imported features
func (c *Compiler) MergeFeatures(topFeatures map[string]any, importedFeatures []map[string]any) (map[string]any, error) {
diff --git a/pkg/workflow/safe_outputs_import_test.go b/pkg/workflow/safe_outputs_import_test.go
index a8e0b00283a..abfe1ca775b 100644
--- a/pkg/workflow/safe_outputs_import_test.go
+++ b/pkg/workflow/safe_outputs_import_test.go
@@ -412,6 +412,216 @@ imports:
assert.Equal(t, strPtr("5"), workflowData.SafeOutputs.AddComments.Max)
}
+// TestCreateDiscussionFieldLevelMerge tests that when the same create-discussion type is defined
+// in both main and imported workflow, base fields from the imported config fill in any unset fields
+// in the main workflow's create-discussion config (field-level merge).
+func TestCreateDiscussionFieldLevelMerge(t *testing.T) {
+ compiler := NewCompilerWithVersion("1.0.0")
+
+ // Create a temporary directory for test files
+ tmpDir := t.TempDir()
+ workflowsDir := filepath.Join(tmpDir, ".github", "workflows")
+ err := os.MkdirAll(workflowsDir, 0755)
+ require.NoError(t, err, "Failed to create workflows directory")
+
+ // Create a shared workflow that provides the base create-discussion config
+ sharedWorkflow := `---
+safe-outputs:
+ create-discussion:
+ category: "audits"
+ close-older-discussions: true
+---
+
+# Shared Audit Discussion Base Config
+`
+
+ sharedFile := filepath.Join(workflowsDir, "shared-audit-discussion.md")
+ err = os.WriteFile(sharedFile, []byte(sharedWorkflow), 0644)
+ require.NoError(t, err, "Failed to write shared file")
+
+ // Create main workflow that only specifies workflow-specific fields
+ mainWorkflow := `---
+on: schedule
+permissions:
+ contents: read
+ discussions: write
+imports:
+ - ./shared-audit-discussion.md
+safe-outputs:
+ create-discussion:
+ title-prefix: "[my-workflow] "
+ expires: 1d
+---
+
+# Main Workflow
+`
+
+ mainFile := filepath.Join(workflowsDir, "main.md")
+ err = os.WriteFile(mainFile, []byte(mainWorkflow), 0644)
+ require.NoError(t, err, "Failed to write main file")
+
+ // Change to the workflows directory for relative path resolution
+ oldDir, err := os.Getwd()
+ require.NoError(t, err, "Failed to get current directory")
+ err = os.Chdir(workflowsDir)
+ require.NoError(t, err, "Failed to change directory")
+ defer func() { _ = os.Chdir(oldDir) }()
+
+ // Parse the main workflow
+ workflowData, err := compiler.ParseWorkflowFile("main.md")
+ require.NoError(t, err, "Should parse workflow successfully")
+ require.NotNil(t, workflowData.SafeOutputs, "SafeOutputs should not be nil")
+ require.NotNil(t, workflowData.SafeOutputs.CreateDiscussions, "CreateDiscussions should be present")
+
+ // Verify workflow-specific fields from main workflow are present
+ assert.Equal(t, "[my-workflow] ", workflowData.SafeOutputs.CreateDiscussions.TitlePrefix, "TitlePrefix should come from main workflow")
+ assert.Equal(t, 24, workflowData.SafeOutputs.CreateDiscussions.Expires, "Expires should come from main workflow (1d = 24 hours)")
+
+ // Verify base fields from shared component are filled in via field-level merge
+ assert.Equal(t, "audits", workflowData.SafeOutputs.CreateDiscussions.Category, "Category should come from shared component")
+ require.NotNil(t, workflowData.SafeOutputs.CreateDiscussions.CloseOlderDiscussions, "CloseOlderDiscussions should come from shared component")
+ assert.Equal(t, "true", *workflowData.SafeOutputs.CreateDiscussions.CloseOlderDiscussions, "CloseOlderDiscussions should be true from shared component")
+}
+
+// TestCreateDiscussionFieldLevelMergeMainTakesPrecedence tests that when both main and imported
+// workflow define the same create-discussion field, the main workflow's value wins.
+func TestCreateDiscussionFieldLevelMergeMainTakesPrecedence(t *testing.T) {
+ compiler := NewCompilerWithVersion("1.0.0")
+
+ // Create a temporary directory for test files
+ tmpDir := t.TempDir()
+ workflowsDir := filepath.Join(tmpDir, ".github", "workflows")
+ err := os.MkdirAll(workflowsDir, 0755)
+ require.NoError(t, err, "Failed to create workflows directory")
+
+ // Create a shared workflow with base config
+ sharedWorkflow := `---
+safe-outputs:
+ create-discussion:
+ category: "audits"
+ close-older-discussions: true
+---
+
+# Shared Config
+`
+
+ sharedFile := filepath.Join(workflowsDir, "shared.md")
+ err = os.WriteFile(sharedFile, []byte(sharedWorkflow), 0644)
+ require.NoError(t, err, "Failed to write shared file")
+
+ // Create main workflow that explicitly sets category (overrides shared's category)
+ mainWorkflow := `---
+on: schedule
+permissions:
+ contents: read
+ discussions: write
+imports:
+ - ./shared.md
+safe-outputs:
+ create-discussion:
+ category: "reports"
+ title-prefix: "[report] "
+ expires: 3d
+---
+
+# Main Workflow
+`
+
+ mainFile := filepath.Join(workflowsDir, "main.md")
+ err = os.WriteFile(mainFile, []byte(mainWorkflow), 0644)
+ require.NoError(t, err, "Failed to write main file")
+
+ // Change to the workflows directory for relative path resolution
+ oldDir, err := os.Getwd()
+ require.NoError(t, err, "Failed to get current directory")
+ err = os.Chdir(workflowsDir)
+ require.NoError(t, err, "Failed to change directory")
+ defer func() { _ = os.Chdir(oldDir) }()
+
+ // Parse the main workflow
+ workflowData, err := compiler.ParseWorkflowFile("main.md")
+ require.NoError(t, err, "Should parse workflow successfully")
+ require.NotNil(t, workflowData.SafeOutputs, "SafeOutputs should not be nil")
+ require.NotNil(t, workflowData.SafeOutputs.CreateDiscussions, "CreateDiscussions should be present")
+
+ // Verify main workflow's explicit category overrides shared's category
+ assert.Equal(t, "reports", workflowData.SafeOutputs.CreateDiscussions.Category, "Category from main workflow should take precedence over shared")
+
+ // Verify close-older-discussions from shared fills in (not set in main)
+ require.NotNil(t, workflowData.SafeOutputs.CreateDiscussions.CloseOlderDiscussions, "CloseOlderDiscussions should come from shared component")
+ assert.Equal(t, "true", *workflowData.SafeOutputs.CreateDiscussions.CloseOlderDiscussions, "CloseOlderDiscussions should be true from shared")
+
+ // Verify workflow-specific fields
+ assert.Equal(t, "[report] ", workflowData.SafeOutputs.CreateDiscussions.TitlePrefix, "TitlePrefix should come from main workflow")
+ assert.Equal(t, 72, workflowData.SafeOutputs.CreateDiscussions.Expires, "Expires should come from main workflow (3d = 72 hours)")
+}
+
+// TestCreateDiscussionImportConflictBetweenSharedComponents tests that a conflict error is
+// returned when create-discussion is defined in multiple imported shared workflows.
+func TestCreateDiscussionImportConflictBetweenSharedComponents(t *testing.T) {
+ compiler := NewCompilerWithVersion("1.0.0")
+
+ // Create a temporary directory for test files
+ tmpDir := t.TempDir()
+ workflowsDir := filepath.Join(tmpDir, ".github", "workflows")
+ err := os.MkdirAll(workflowsDir, 0755)
+ require.NoError(t, err, "Failed to create workflows directory")
+
+ // Create two shared workflows both defining create-discussion
+ shared1 := `---
+safe-outputs:
+ create-discussion:
+ category: "audits"
+---
+
+# Shared 1
+`
+ shared2 := `---
+safe-outputs:
+ create-discussion:
+ category: "reports"
+---
+
+# Shared 2
+`
+
+ err = os.WriteFile(filepath.Join(workflowsDir, "shared1.md"), []byte(shared1), 0644)
+ require.NoError(t, err, "Failed to write shared1 file")
+ err = os.WriteFile(filepath.Join(workflowsDir, "shared2.md"), []byte(shared2), 0644)
+ require.NoError(t, err, "Failed to write shared2 file")
+
+ // Create main workflow that imports both (conflict between imports)
+ mainWorkflow := `---
+on: schedule
+permissions:
+ contents: read
+ discussions: write
+imports:
+ - ./shared1.md
+ - ./shared2.md
+---
+
+# Main Workflow
+`
+
+ mainFile := filepath.Join(workflowsDir, "main.md")
+ err = os.WriteFile(mainFile, []byte(mainWorkflow), 0644)
+ require.NoError(t, err, "Failed to write main file")
+
+ // Change to the workflows directory for relative path resolution
+ oldDir, err := os.Getwd()
+ require.NoError(t, err, "Failed to get current directory")
+ err = os.Chdir(workflowsDir)
+ require.NoError(t, err, "Failed to change directory")
+ defer func() { _ = os.Chdir(oldDir) }()
+
+ // Parse should fail with a conflict error
+ _, err = compiler.ParseWorkflowFile("main.md")
+ require.Error(t, err, "Should return error for create-discussion defined in multiple imports")
+ assert.Contains(t, err.Error(), "safe-outputs conflict", "Error should mention safe-outputs conflict")
+ assert.Contains(t, err.Error(), "create-discussion", "Error should mention create-discussion")
+}
+
// TestMergeSafeOutputsUnit tests the MergeSafeOutputs function directly
func TestMergeSafeOutputsUnit(t *testing.T) {
compiler := NewCompilerWithVersion("1.0.0")
From 773448e66d8b7334ef22bf2030ea9f715eabcda8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 15 Mar 2026 19:45:30 +0000
Subject: [PATCH 3/3] refactor: address code review - improve godoc and
comments in imports.go
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
pkg/workflow/imports.go | 22 +++++++++++++++++++---
pkg/workflow/safe_outputs_import_test.go | 3 ++-
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/pkg/workflow/imports.go b/pkg/workflow/imports.go
index 1d1904d7a1e..f01aed3a0f3 100644
--- a/pkg/workflow/imports.go
+++ b/pkg/workflow/imports.go
@@ -172,6 +172,19 @@ func getSafeOutputTypeKeys() ([]string, error) {
// MergeSafeOutputs merges safe-outputs configurations from imports into the top-level safe-outputs
// Returns an error if a conflict is detected (same safe-output type defined in both main and imported)
+// MergeSafeOutputs merges safe-output configurations from imported workflows into the
+// top-level (main workflow) configuration. For most safe-output types the main workflow
+// definition takes complete precedence over any imported definition (override semantics).
+//
+// Exception — create-discussion: uses field-level merge semantics so that a shared
+// component (e.g. shared/daily-audit-discussion.md) can provide base fields such as
+// category and close-older-discussions while individual workflows override only their
+// specific settings (title-prefix, expires). See mergeCreateDiscussionsFields for the
+// exact fields that participate in field-level merge.
+//
+// Conflict detection still applies between multiple imported files: if two imported
+// workflows both define the same safe-output type (including create-discussion), an
+// error is returned.
func (c *Compiler) MergeSafeOutputs(topSafeOutputs *SafeOutputsConfig, importedSafeOutputsJSON []string) (*SafeOutputsConfig, error) {
importsLog.Print("Merging safe-outputs from imports")
@@ -655,9 +668,12 @@ func mergeCreateDiscussionsFields(result, imported *CreateDiscussionsConfig) {
if result.Footer == nil && imported.Footer != nil {
result.Footer = imported.Footer
}
- // Note: TitlePrefix, Expires, TargetRepoSlug, AllowedRepos, CloseOlderKey, Max, and
- // BaseSafeOutputConfig fields are NOT merged – they either default in parseDiscussionsConfig
- // or are intentionally workflow-specific.
+ // Note: TitlePrefix, Expires, TargetRepoSlug, AllowedRepos, and CloseOlderKey are
+ // intentionally workflow-specific and are NOT merged from shared components.
+ // Max is excluded because it can be set to a non-default value per workflow (e.g. max: 2
+ // for poem-bot.md) and is already defaulted to 1 by parseDiscussionsConfig, so merging
+ // would silently overwrite a deliberate workflow choice.
+ // BaseSafeOutputConfig fields (GitHubToken, Staged) are similarly excluded.
}
// MergeFeatures merges features configurations from imports with top-level features
diff --git a/pkg/workflow/safe_outputs_import_test.go b/pkg/workflow/safe_outputs_import_test.go
index abfe1ca775b..829d4f0e02f 100644
--- a/pkg/workflow/safe_outputs_import_test.go
+++ b/pkg/workflow/safe_outputs_import_test.go
@@ -475,7 +475,8 @@ safe-outputs:
// Verify workflow-specific fields from main workflow are present
assert.Equal(t, "[my-workflow] ", workflowData.SafeOutputs.CreateDiscussions.TitlePrefix, "TitlePrefix should come from main workflow")
- assert.Equal(t, 24, workflowData.SafeOutputs.CreateDiscussions.Expires, "Expires should come from main workflow (1d = 24 hours)")
+ // expires: 1d is parsed as 24 hours by parseDiscussionsConfig duration parsing
+ assert.Equal(t, 24, workflowData.SafeOutputs.CreateDiscussions.Expires, "Expires should come from main workflow: 1d parses to 24 hours")
// Verify base fields from shared component are filled in via field-level merge
assert.Equal(t, "audits", workflowData.SafeOutputs.CreateDiscussions.Category, "Category should come from shared component")