Skip to content

refactor(logs): extract AggregatedSummaryBase from near-duplicate summary structs - #42552

Merged
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-extract-shared-base
Jun 30, 2026
Merged

refactor(logs): extract AggregatedSummaryBase from near-duplicate summary structs#42552
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-extract-shared-base

Conversation

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

MissingToolSummary and MissingDataSummary in logs_models.go had six byte-identical trailing fields, creating silent copy-paste drift risk across the aggregated-report types.

Changes

  • logs_models.go — introduces AggregatedSummaryBase embedding Count, Workflows, WorkflowsDisplay, FirstReason, FirstReasonDisplay, RunIDs; both MissingToolSummary and MissingDataSummary now embed it, retaining only their identity field inline
  • logs_report_errors.go — updates composite literals in buildMissingToolsSummary / buildMissingDataSummary to use embedded-struct syntax
  • logs_display_fields_test.go, logs_report_test.go — corresponding literal updates

MCPFailureSummary is intentionally left flat: its Count (header:Failures) and WorkflowsDisplay (maxlen:60) carry different console: tags, so it cannot share the same base without overriding behaviour.

// Before — duplicated verbatim in both structs
type MissingToolSummary struct {
    Tool               string   `json:"tool" console:"header:Tool"`
    Count              int      `json:"count" console:"header:Occurrences"`
    Workflows          []string `json:"workflows" console:"-"`
    WorkflowsDisplay   string   `json:"-" console:"header:Workflows,maxlen:40"`
    FirstReason        string   `json:"first_reason" console:"-"`
    FirstReasonDisplay string   `json:"-" console:"header:First Reason,maxlen:50"`
    RunIDs             []int64  `json:"run_ids" console:"-"`
}

// After — single source of truth
type AggregatedSummaryBase struct {
    Count              int      `json:"count" console:"header:Occurrences"`
    Workflows          []string `json:"workflows" console:"-"`
    WorkflowsDisplay   string   `json:"-" console:"header:Workflows,maxlen:40"`
    FirstReason        string   `json:"first_reason" console:"-"`
    FirstReasonDisplay string   `json:"-" console:"header:First Reason,maxlen:50"`
    RunIDs             []int64  `json:"run_ids" console:"-"`
}

type MissingToolSummary struct {
    Tool string `json:"tool" console:"header:Tool"`
    AggregatedSummaryBase
}

Generated by 👨‍🍳 PR Sous Chef · 146.2 AIC · ⌖ 9.97 AIC · ⊞ 1.7K ·


Generated by 👨‍🍳 PR Sous Chef · 153.3 AIC · ⌖ 10.3 AIC · ⊞ 1.7K ·

…tructs

MissingToolSummary and MissingDataSummary had byte-identical trailing
fields (Count, Workflows, WorkflowsDisplay, FirstReason,
FirstReasonDisplay, RunIDs). Extract them into an embedded
AggregatedSummaryBase to eliminate copy-paste drift risk.

MCPFailureSummary is intentionally left inline — its Count and
WorkflowsDisplay carry different console tags (header:Failures,
maxlen:60) that make a shared base impractical.

Closes #42504

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Extract shared base for near-duplicate logs summary structs refactor(logs): extract AggregatedSummaryBase from near-duplicate summary structs Jun 30, 2026
Copilot AI requested a review from pelikhan June 30, 2026 20:12
@pelikhan
pelikhan marked this pull request as ready for review June 30, 2026 20:12
Copilot AI review requested due to automatic review settings June 30, 2026 20:12
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #42552 does not have the 'implementation' label and has ≤100 new lines of code in business logic directories (60 additions detected, threshold is 100).

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Refactors the aggregated logs-report summary models to remove duplicated trailing fields by extracting a shared embedded struct, updating the report builders and tests to construct the embedded portion explicitly.

Changes:

  • Introduces AggregatedSummaryBase to centralize shared aggregated-summary fields used by missing-tool and missing-data summaries.
  • Updates buildMissingToolsSummary / buildMissingDataSummary to initialize the embedded struct in composite literals.
  • Updates tests to reflect the new composite literal shape.
Show a summary per file
File Description
pkg/cli/logs_models.go Adds AggregatedSummaryBase and embeds it into MissingToolSummary / MissingDataSummary to eliminate duplicated fields.
pkg/cli/logs_report_errors.go Updates summary construction to populate the embedded base struct fields.
pkg/cli/logs_report_test.go Updates test data and helper literals to use the embedded base struct syntax.
pkg/cli/logs_display_fields_test.go Updates display-field rendering test to populate fields via AggregatedSummaryBase.

Review details

Tip

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

  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread pkg/cli/logs_models.go
Comment on lines +164 to 168
// MissingToolSummary aggregates missing tool reports across runs
type MissingToolSummary struct {
Tool string `json:"tool" console:"header:Tool"`
AggregatedSummaryBase
}
Comment thread pkg/cli/logs_models.go
Comment on lines 179 to 183
// MissingDataSummary aggregates missing data reports across runs
type MissingDataSummary struct {
DataType string `json:"data_type" console:"header:Data Type"`
Count int `json:"count" console:"header:Occurrences"`
Workflows []string `json:"workflows" console:"-"` // List of workflow names that reported this data
WorkflowsDisplay string `json:"-" console:"header:Workflows,maxlen:40"` // Formatted display of workflows
FirstReason string `json:"first_reason" console:"-"` // Reason from the first occurrence
FirstReasonDisplay string `json:"-" console:"header:First Reason,maxlen:50"` // Formatted display of first reason
RunIDs []int64 `json:"run_ids" console:"-"` // List of run IDs where this data was reported
DataType string `json:"data_type" console:"header:Data Type"`
AggregatedSummaryBase
}
@github-actions github-actions Bot mentioned this pull request Jun 30, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review: refactor(logs): extract AggregatedSummaryBase

Clean, well-scoped refactoring with no correctness or security issues.

What works well:

  • JSON field order is preserved — Go promotes embedded struct fields exactly as if they were declared inline, so no serialization behaviour changes.
  • console: struct tags are unaffected; the rendering pipeline will see the same promoted fields and tags.
  • updateSummary functions in logs_report_errors.go correctly access promoted fields (summary.Count, summary.Workflows, etc.) without changes — field promotion handles this transparently.
  • MCPFailureSummary is correctly excluded with the rationale documented in the PR body.
  • All composite literals (production + tests) are consistently updated.

One non-blocking suggestion — the AggregatedSummaryBase doc comment's parenthetical mentioning MCPFailureSummary is slightly misleading (see inline comment).

Otherwise LGTM. ✅

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 28.5 AIC · ⌖ 6.57 AIC · ⊞ 4.9K

Comment thread pkg/cli/logs_models.go
type MissingToolSummary struct {
Tool string `json:"tool" console:"header:Tool"`
// AggregatedSummaryBase holds the shared tail fields that appear byte-for-byte identically
// in MissingToolSummary and MissingDataSummary (and as a subset in MCPFailureSummary).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The parenthetical (and as a subset in MCPFailureSummary) is misleading — MCPFailureSummary does not embed AggregatedSummaryBase; it keeps its own flat fields with intentionally different console: tags (header:Failures, maxlen:60). A reader who hasn't seen the PR description may assume MCPFailureSummary shares the base, or be confused why it's mentioned here.

Suggested wording:

// AggregatedSummaryBase holds the shared tail fields that appear byte-for-byte identically
// in MissingToolSummary and MissingDataSummary. MCPFailureSummary is intentionally excluded:
// its Count (header:Failures) and WorkflowsDisplay (maxlen:60) carry different console: tags.
// Embedding this struct removes copy-paste drift risk across the aggregated-report types.

@copilot please address this.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 80/100 — Excellent

Analyzed 3 modified test(s): 3 design, 0 implementation, 0 guideline violation(s). All changes are structural refactoring — updating struct initialization to use the new AggregatedSummaryBase embedded type.

📊 Metrics & Test Classification (3 tests analyzed)
Metric Value
New/modified tests analyzed 3
✅ Design tests (behavioral contracts) 3 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 1 (33%)
Duplicate test clusters 0
Test inflation detected No
🚨 Coding-guideline violations 0
Test File Classification Issues Detected
TestMissingToolSummaryDisplayFields pkg/cli/logs_display_fields_test.go:14 ✅ Design
TestRenderLogsConsoleUnified pkg/cli/logs_report_test.go:16 ✅ Design
TestAggregateSummaryItems pkg/cli/logs_report_test.go:404 ✅ Design

Go: 3 (*_test.go); JavaScript: 0.

Test inflation check:

  • logs_display_fields_test.go (+9 lines) vs logs_models.go (+14 lines) → ratio 0.64 ✅
  • logs_report_test.go (+23 lines) vs logs_report_errors.go (+14 lines) → ratio 1.64 ✅

Build tag compliance: both test files carry //go:build !integration on line 1 ✅

Verdict

Check passed. 0% implementation tests (threshold: 30%). No guideline violations. The test modifications faithfully track the production refactoring — the new embedded AggregatedSummaryBase struct is correctly reflected in all test fixtures, preserving the original behavioral guarantees.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 47.9 AIC · ⌖ 13.9 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 80/100. 0% implementation tests (threshold: 30%). No guideline violations. All 3 modified tests are behavioral design tests that correctly track the AggregatedSummaryBase refactoring.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔎 Code quality review by PR Code Quality Reviewer · 72.7 AIC · ⌖ 7.44 AIC · ⊞ 1.6K
Comment /review to run again

Comments that could not be inline-anchored

pkg/cli/logs_models.go:153

Misleading doc comment: the parenthetical "(and as a subset in MCPFailureSummary)" implies MCPFailureSummary uses this type, but it does not — and it was explicitly left out of this refactor.

<details>
<summary>💡 Suggested fix</summary>

The PR description is clear that MCPFailureSummary was intentionally left flat. The comment should reflect that rather than imply a structural relationship that does not exist in code:

// AggregatedSummaryBase holds the shared tail fields that …

</details>

<details><summary>pkg/cli/logs_report_errors.go:97</summary>

**Incomplete refactor**: the `updateSummary` and `finalizeSummary` closures in `buildMissingToolsSummary` and `buildMissingDataSummary` are still byte-identicalthe copy-paste drift risk this PR targets is only half-fixed.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Since both types now embed `AggregatedSummaryBase`, the shared mutation logic belongs there as methods. This eliminates the remaining duplication and makes future types that embed the base automatically correct:

```go
// on A…

</details>

<details><summary>pkg/cli/logs_models.go:155</summary>

**Unnecessary export**: `AggregatedSummaryBase` is an intra-package implementation detail with no intended external callers — exporting it widens the public API surface for free.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Rename to `aggregatedSummaryBase` (unexported). External callers of `MissingToolSummary` and `MissingDataSummary` still access all promoted fields (`Count`, `Workflows`, `RunIDs`, etc.) normally — Go promotes them regardless of the embedding type&#39;s visibility.

The only c…

</details>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /codebase-design and /tdd — leaving 3 comments, no blocking issues.

📋 Key Themes & Highlights

Key Themes

  • Doc comment accuracy: The AggregatedSummaryBase comment mentions MCPFailureSummary in a way that implies an embedding relationship that does not exist — see inline comment on line 153.
  • Naming convention: Base is an OOP inheritance idiom; Go prefers names that describe what the type is, not its hierarchy role.
  • Test symmetry: MissingDataSummary gained embedding but lacks its own TestMissingDataSummaryDisplayFields to mirror the existing MissingToolSummary and MCPFailureSummary tests.

Positive Highlights

  • Clear motivation: The PR description and comment both explain why the duplication existed and precisely why MCPFailureSummary is excluded (different console: tag values). That level of rationale in the code is rare and valuable.
  • Tight scope: Only the two structs that are genuinely byte-identical get the base type; the third is consciously left flat. Good restraint.
  • Test coverage maintained: All four changed files include updated test literals — the refactor does not reduce test confidence.
  • Field promotion works correctly: The updateSummary callbacks access promoted fields (summary.Count++, summary.Workflows, etc.) idiomatically without needing to route through summary.AggregatedSummaryBase.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 63.8 AIC · ⌖ 7.83 AIC · ⊞ 6.6K
Comment /matt to run again

Comment thread pkg/cli/logs_models.go
type MissingToolSummary struct {
Tool string `json:"tool" console:"header:Tool"`
// AggregatedSummaryBase holds the shared tail fields that appear byte-for-byte identically
// in MissingToolSummary and MissingDataSummary (and as a subset in MCPFailureSummary).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/codebase-design] The doc comment says (and as a subset in MCPFailureSummary), but MCPFailureSummary does not embed AggregatedSummaryBase. A reader unfamiliar with the PR description may infer an embedding relationship that does not exist.

💡 Suggested rewording
// AggregatedSummaryBase holds the shared tail fields that appear byte-for-byte identically
// in MissingToolSummary and MissingDataSummary. MCPFailureSummary carries overlapping fields
// but with different console: tag values (header:Failures, maxlen:60), so it does not embed
// this type.

Being explicit about why MCPFailureSummary is excluded makes the design rationale self-documenting, rather than relying on the PR description.

@copilot please address this.

Comment thread pkg/cli/logs_models.go
// AggregatedSummaryBase holds the shared tail fields that appear byte-for-byte identically
// in MissingToolSummary and MissingDataSummary (and as a subset in MCPFailureSummary).
// Embedding this struct removes copy-paste drift risk across the aggregated-report types.
type AggregatedSummaryBase struct {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/codebase-design] The Base suffix implies OOP-style inheritance, which is not idiomatic in Go. Go composition is best named by what the type is, not its role in a hierarchy.

💡 Naming alternatives

Consider a name that describes the data these fields represent:

  • OccurrenceSummary — the thing being counted across workflow occurrences
  • WorkflowOccurrence — what each aggregated item tracks
  • AggregatedOccurrence — keeps "aggregated" from the original, drops "Base"

Base will lead future readers to ask "base of what?" whereas a descriptive noun answers the domain question immediately.

@copilot please address this.

FirstReasonDisplay: "Tool not found in MCP server", // This should be rendered
RunIDs: []int64{1, 2, 3},
},
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] TestMissingToolSummaryDisplayFields exists, and there is a symmetric TestMCPFailureSummaryDisplayFields, but no TestMissingDataSummaryDisplayFields. Since MissingDataSummary now embeds AggregatedSummaryBase, a parallel test would confirm that console.RenderStruct promotes the embedded headers (Occurrences, Workflows, First Reason) correctly for MissingDataSummary too.

💡 Suggested test skeleton
func TestMissingDataSummaryDisplayFields(t *testing.T) {
    summaries := []MissingDataSummary{
        {
            DataType: "context",
            AggregatedSummaryBase: AggregatedSummaryBase{
                Count:              3,
                WorkflowsDisplay:   "workflow1, workflow2",
                FirstReasonDisplay: "context data missing",
            },
        },
    }
    output := console.RenderStruct(summaries)
    if !strings.Contains(output, "workflow1, workflow2") {
        t.Errorf("WorkflowsDisplay not found in output:\n%s", output)
    }
    if !strings.Contains(output, "context data missing") {
        t.Errorf("FirstReasonDisplay not found in output:\n%s", output)
    }
}

@copilot please address this.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill to finalize this PR.

Generated by 👨‍🍳 PR Sous Chef · 146.2 AIC · ⌖ 9.97 AIC · ⊞ 1.7K ·

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill to finalize this PR.

...

Completed. I ran the PR-finisher pass and validated locally on commit 36663d8 (make fmt, make lint, make test-unit, make test, make recompile all passed). CI on this head is still unverified until a maintainer re-triggers workflows.

Copilot AI requested a review from gh-aw-bot June 30, 2026 21:04
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill to help finalize this PR.

Feel free to edit this comment to add additional instructions or context for the pr-finisher skill.

Generated by 👨‍🍳 PR Sous Chef · 153.3 AIC · ⌖ 10.3 AIC · ⊞ 1.7K ·

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill to help finalize this PR.

Feel free to edit this comment to add additional instructions or context for the pr-finisher skill....

Ran pr-finisher again on commit 36663d8. Local validation passed (make fmt, make lint, make test-unit, make test, make recompile), and there are no local changes to push. I could not fetch PR/CI state from GitHub APIs in this environment due 403 responses, so CI status on this head remains unverified and needs maintainer re-trigger.

@pelikhan
pelikhan merged commit 2dd829a into main Jun 30, 2026
19 of 20 checks passed
@pelikhan
pelikhan deleted the copilot/deep-report-extract-shared-base branch June 30, 2026 22:16
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.82.1

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.

[deep-report] Extract shared base for near-duplicate logs summary structs

4 participants