Skip to content

feat: merge gh aw audit report into gh aw logs --format#24396

Merged
pelikhan merged 2 commits intomainfrom
copilot/integrate-report-features-into-logs
Apr 3, 2026
Merged

feat: merge gh aw audit report into gh aw logs --format#24396
pelikhan merged 2 commits intomainfrom
copilot/integrate-report-features-into-logs

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

gh aw audit report was a separate subcommand that duplicated the run-fetching and artifact-download pipeline already in gh aw logs. This PR consolidates the cross-run security report output into logs via a --format flag, then removes the audit report subcommand.

Changes

gh aw logs (logs_command.go, logs_orchestrator.go)

  • Added --format markdown|pretty — when set, builds crossRunInput entries from the already-collected processedRuns and renders via the existing renderCrossRunReport{Markdown,Pretty,JSON} functions instead of the default metrics table
  • Added --last as an alias for --count (drop-in compat for former audit report --last users)
  • --json continues to work in format mode, producing cross-run report JSON

Removed

  • audit_report_cross_run_command.goNewAuditReportSubcommand, RunAuditReport, RunAuditReportConfig all deleted
  • cmd.AddCommand(NewAuditReportSubcommand()) removed from audit.go
  • Unused maxAuditReportRuns constant removed from audit_cross_run.go

Tests (audit_cross_run_test.go, context_cancellation_test.go, logs_*_test.go)

  • Replaced TestNewAuditReportSubcommand* / TestRunAuditReportConfig* with TestNewLogsCommand_HasFormatFlag, TestLogsCommand_FormatPrecedence, TestLogsCommand_RepoParsingWithHost
  • Updated all direct DownloadWorkflowLogs call sites to pass the new format parameter

Docsaudit.md, glossary.md, cost-management.md, blog post updated to reference gh aw logs --format instead of gh aw audit report

Migration

# Before
gh aw audit report --workflow "agent-task" --last 10
gh aw audit report --format pretty
gh aw audit report --last 5 --json

# After
gh aw logs agent-task --format markdown --count 10
gh aw logs --format pretty
gh aw logs --format markdown --last 5 --json

Copilot AI and others added 2 commits April 3, 2026 23:07
… report subcommand

- Add --format flag to `gh aw logs` with markdown/pretty values to generate
  cross-run security audit reports (executive summary, domain inventory,
  metrics trends, MCP server health, per-run breakdown)
- Add --last flag as an alias for --count for compatibility
- Remove `gh aw audit report` subcommand (audit_report_cross_run_command.go)
- Remove unused maxAuditReportRuns constant from audit_cross_run.go
- Update all tests that called DownloadWorkflowLogs directly to pass new format param
- Replace TestNewAuditReportSubcommand* tests with TestNewLogsCommand_HasFormatFlag,
  TestLogsCommand_FormatPrecedence, TestLogsCommand_RepoParsingWithHost
- Update docs: audit.md, glossary.md, cost-management.md, blog post

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/33720f43-ca5a-402b-a2de-032ffa8269fd

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan pelikhan marked this pull request as ready for review April 3, 2026 23:11
Copilot AI review requested due to automatic review settings April 3, 2026 23:11
@pelikhan pelikhan merged commit 5a19c28 into main Apr 3, 2026
106 of 151 checks passed
@pelikhan pelikhan deleted the copilot/integrate-report-features-into-logs branch April 3, 2026 23:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR consolidates the cross-run security audit report into gh aw logs via a new --format flag, and removes the now-redundant gh aw audit report subcommand.

Changes:

  • Added --format markdown|pretty (and --last alias for --count) to gh aw logs to render cross-run reports from already-processed runs.
  • Removed the audit report subcommand and related constants/wiring.
  • Updated unit tests and documentation to reference gh aw logs --format as the new entry point.
Show a summary per file
File Description
pkg/cli/logs_orchestrator.go Adds format parameter and renders cross-run report output modes.
pkg/cli/logs_command.go Adds --format and --last flags and passes format through to orchestrator.
pkg/cli/logs_json_stderr_order_test.go Updates orchestrator callsites for new format parameter.
pkg/cli/logs_download_test.go Updates orchestrator callsites for new format parameter.
pkg/cli/logs_ci_scenario_test.go Updates orchestrator callsites for new format parameter.
pkg/cli/context_cancellation_test.go Updates orchestrator callsites for new format parameter.
pkg/cli/audit.go Removes registration of the deleted audit report subcommand.
pkg/cli/audit_report_cross_run_command.go Removes the legacy cross-run report subcommand implementation.
pkg/cli/audit_cross_run.go Removes the legacy maxAuditReportRuns constant (report generation remains).
pkg/cli/audit_cross_run_test.go Replaces audit report command tests with logs --format flag/precedence tests.
docs/src/content/docs/reference/glossary.md Updates glossary entry to point to gh aw logs --format.
docs/src/content/docs/reference/cost-management.md Updates guidance to use gh aw logs --format ... for cross-run trends.
docs/src/content/docs/reference/audit.md Updates reference docs from audit report to logs --format.
docs/src/content/docs/blog/2026-03-30-weekly-update.md Updates blog content to reference gh aw logs --format.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (1)

pkg/cli/audit_cross_run_test.go:447

  • This test asserts repo parsing for [HOST/]owner/repo by splitting and taking the last two path segments, but the production logs path (downloadRunArtifactsConcurrent) currently uses strings.SplitN(repoOverride, "/", 2), which will mis-parse host/owner/repo as owner=host, repo=owner/repo. Consider extracting a shared repo parser used by logs/audit (including optional host) and updating the test to exercise that implementation.
			// Apply the same repo parsing logic used in audit commands
			parts := strings.Split(tt.repoFlag, "/")
			if len(parts) < 2 {
				assert.True(t, tt.wantErr, "Should expect error for: %s", tt.repoFlag)
				return
			}
			ownerPart := parts[len(parts)-2]
			repoPart := parts[len(parts)-1]
  • Files reviewed: 14/14 changed files
  • Comments generated: 4

Comment on lines +559 to +562
report := buildCrossRunAuditReport(inputs)
if jsonOutput {
return renderCrossRunReportJSON(report)
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

When --format is set and --json is also requested, the cross-run JSON path is only reached if at least one run is processed. If no runs match (or all are filtered out), the earlier len(processedRuns)==0 fast-return renders the metrics JSON instead, which contradicts the documented behavior that --json in format mode produces the cross-run report JSON. Consider handling the no-runs case for format mode explicitly (e.g., emit an empty CrossRunAuditReport JSON/markdown/pretty as appropriate).

Copilot uses AI. Check for mistakes.
Comment on lines +541 to +558
inputs := make([]crossRunInput, 0, len(processedRuns))
for _, pr := range processedRuns {
inputs = append(inputs, crossRunInput{
RunID: pr.Run.DatabaseID,
WorkflowName: pr.Run.WorkflowName,
Conclusion: pr.Run.Conclusion,
Duration: pr.Run.Duration,
FirewallAnalysis: pr.FirewallAnalysis,
Metrics: LogMetrics{
TokenUsage: pr.Run.TokenUsage,
EstimatedCost: pr.Run.EstimatedCost,
Turns: pr.Run.Turns,
},
MCPToolUsage: pr.MCPToolUsage,
MCPFailures: pr.MCPFailures,
ErrorCount: pr.Run.ErrorCount,
})
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The cross-run report inputs are built only from processedRuns, which excludes runs that were skipped due to missing/expired artifacts (ErrNoArtifacts) or other skip conditions. This means the cross-run report will silently omit those runs and undercount RunsWithoutData, unlike the previous audit report behavior that intentionally included skipped runs as HasData=false. To preserve report accuracy, consider including skipped runs in the aggregation inputs (with FirewallAnalysis=nil), or altering skip behavior when --format is active.

Suggested change
inputs := make([]crossRunInput, 0, len(processedRuns))
for _, pr := range processedRuns {
inputs = append(inputs, crossRunInput{
RunID: pr.Run.DatabaseID,
WorkflowName: pr.Run.WorkflowName,
Conclusion: pr.Run.Conclusion,
Duration: pr.Run.Duration,
FirewallAnalysis: pr.FirewallAnalysis,
Metrics: LogMetrics{
TokenUsage: pr.Run.TokenUsage,
EstimatedCost: pr.Run.EstimatedCost,
Turns: pr.Run.Turns,
},
MCPToolUsage: pr.MCPToolUsage,
MCPFailures: pr.MCPFailures,
ErrorCount: pr.Run.ErrorCount,
})
}
processedByRunID := make(map[int64]processedRun, len(processedRuns))
for _, pr := range processedRuns {
processedByRunID[pr.Run.DatabaseID] = pr
}
// Build report inputs from the full set of runs, not only successfully processed ones,
// so skipped runs are still counted as runs without data.
inputs := make([]crossRunInput, 0, len(runs))
for _, run := range runs {
input := crossRunInput{
RunID: run.DatabaseID,
WorkflowName: run.WorkflowName,
Conclusion: run.Conclusion,
Duration: run.Duration,
Metrics: LogMetrics{
TokenUsage: run.TokenUsage,
EstimatedCost: run.EstimatedCost,
Turns: run.Turns,
},
ErrorCount: run.ErrorCount,
}
if pr, ok := processedByRunID[run.DatabaseID]; ok {
input.FirewallAnalysis = pr.FirewallAnalysis
input.MCPToolUsage = pr.MCPToolUsage
input.MCPFailures = pr.MCPFailures
}
inputs = append(inputs, input)
}

Copilot uses AI. Check for mistakes.
Comment on lines +211 to +212
logsCmd.Flags().String("format", "", "Output format for cross-run audit report: markdown, pretty (generates security audit report instead of default metrics table)")
logsCmd.Flags().Int("last", 0, "Alias for --count: number of recent runs to analyze when generating a cross-run report")
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

--format accepts arbitrary strings; any unexpected value currently falls back to the default metrics output with no error, which can look like the flag was ignored. Consider validating --format (allowing only "", "markdown", "pretty") and returning a clear error for invalid values.

Copilot uses AI. Check for mistakes.
### Cross-Run Audit Report (`gh aw logs --format`)

A `gh aw audit` subcommand that aggregates firewall data across multiple workflow runs to produce a cross-run security report. The report includes an executive summary, domain inventory, and per-run breakdown. Designed for security reviews, compliance checks, and feeding debugging or optimization agents. Outputs markdown by default (suitable for `$GITHUB_STEP_SUMMARY`), or pretty/JSON format. See [CLI Reference](/gh-aw/setup/cli/#audit-report).
A feature of `gh aw logs` that aggregates firewall data across multiple workflow runs to produce a cross-run security report. The report includes an executive summary, domain inventory, and per-run breakdown. Designed for security reviews, compliance checks, and feeding debugging or optimization agents. Outputs markdown by default (suitable for `$GITHUB_STEP_SUMMARY`), or pretty/JSON format. See [CLI Reference](/gh-aw/setup/cli/#logs).
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The glossary entry says the cross-run report "Outputs markdown by default", but gh aw logs only generates the cross-run report when --format is explicitly set (and the default --format is empty). Consider rewording to clarify that the report output is selected via --format markdown|pretty (and --json for JSON).

Suggested change
A feature of `gh aw logs` that aggregates firewall data across multiple workflow runs to produce a cross-run security report. The report includes an executive summary, domain inventory, and per-run breakdown. Designed for security reviews, compliance checks, and feeding debugging or optimization agents. Outputs markdown by default (suitable for `$GITHUB_STEP_SUMMARY`), or pretty/JSON format. See [CLI Reference](/gh-aw/setup/cli/#logs).
A feature of `gh aw logs` that aggregates firewall data across multiple workflow runs to produce a cross-run security report. The report includes an executive summary, domain inventory, and per-run breakdown. Designed for security reviews, compliance checks, and feeding debugging or optimization agents. Select report output with `--format markdown` (suitable for `$GITHUB_STEP_SUMMARY`) or `--format pretty`, and use `--json` for JSON output. See [CLI Reference](/gh-aw/setup/cli/#logs).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants