Skip to content

Consolidate near-duplicate WorkflowListItem ⊂ WorkflowStatus structs in pkg/cli#39637

Merged
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-consolidate-structs
Jun 16, 2026
Merged

Consolidate near-duplicate WorkflowListItem ⊂ WorkflowStatus structs in pkg/cli#39637
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-consolidate-structs

Conversation

Copilot AI commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

WorkflowListItem and WorkflowStatus in pkg/cli duplicated 5 fields with identical tags (Workflow, EngineID, Compiled, Labels, On). WorkflowStatus now embeds WorkflowListItem as the single source of truth for shared workflow metadata.

Struct change

// Before: 5 fields copy-pasted from WorkflowListItem
type WorkflowStatus struct {
    Workflow      string   `json:"workflow" console:"header:Workflow"`
    EngineID      string   `json:"engine_id" console:"header:Engine"`
    // ... 3 more duplicated fields ...
    Status        string   `json:"status" console:"header:Status"`
    // ...
}

// After: embed the smaller struct
type WorkflowStatus struct {
    WorkflowListItem                                        // shared fields live here once
    Status        string `json:"status" console:"header:Status"`
    TimeRemaining string `json:"time_remaining" console:"header:Time Remaining"`
    Dependencies  []string `json:"dependencies,omitempty" console:"-"`
    RunStatus     string `json:"run_status,omitempty" console:"header:Run Status,omitempty"`
    RunConclusion string `json:"run_conclusion,omitempty" console:"header:Run Conclusion,omitempty"`
}

JSON serialisation is unchanged — Go promotes embedded fields in encoding/json by default.

Console rendering (pkg/console/render.go)

The existing table renderer used flat []int field indices and had no concept of embedded structs, so a naïve embed would have produced a broken table with a raw WorkflowListItem column. Two rendering paths updated:

  • Table rendering (buildTableHeaders / buildTableRows): switched from []int to [][]int field index paths; collectTableFields now flattens anonymous embedded structs, including pointer embeds, so their fields surface as top-level columns.
  • Single-struct rendering (renderStruct / computeMaxFieldLen): shared inline field traversal now flattens anonymous embedded structs at the parent level instead of opening a nested section, including nested and pointer embeds.

Tests

  • pkg/console/render_test.go: added coverage for embedded-struct flattening in struct and slice rendering, including omitempty, nested embeds, pointer embeds, header ordering, and nil embedded-pointer rows.
  • All WorkflowStatus{...} composite literals in production code and tests updated to the embedded-struct initialisation form (WorkflowStatus{WorkflowListItem: WorkflowListItem{...}, ...}).

Documentation

  • pkg/cli/README.md: clarified that WorkflowListItem is the gh aw list item type and that its shared workflow metadata is also embedded in WorkflowStatus.
  • pkg/cli/status_command.go: added a clarifying comment that remote workflow status entries only populate the workflow name because the GitHub Actions API does not provide the list metadata fields at that point.

…latten in console rendering

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Consolidate near-duplicate WorkflowListItem and WorkflowStatus structs Consolidate near-duplicate WorkflowListItem ⊂ WorkflowStatus structs in pkg/cli Jun 16, 2026
Copilot AI requested a review from pelikhan June 16, 2026 18:39
@pelikhan pelikhan marked this pull request as ready for review June 16, 2026 18:50
Copilot AI review requested due to automatic review settings June 16, 2026 18:50

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR adds 222 new lines to core business logic (pkg/cli, pkg/console), crossing the 100-line threshold, but has no linked Architecture Decision Record (ADR).

🔒 This PR cannot merge until an ADR for the embedding decision is added to docs/adr/ and linked in the PR body.

⚠️ Note: I generated a draft ADR but could not auto-commit it to your branch (the push step hit a detached-HEAD condition in this run). The full draft is included below — please save it to docs/adr/39637-embed-workflowlistitem-in-workflowstatus.md on your branch.

📄 Draft ADR-39637 (copy into docs/adr/39637-embed-workflowlistitem-in-workflowstatus.md)
# ADR-39637: Embed WorkflowListItem in WorkflowStatus to Share Workflow Metadata

**Date**: 2026-06-16
**Status**: Draft

## Context

The `pkg/cli` package exposes two structs that describe workflows for JSON and console output: `WorkflowListItem` (backing `gh aw list`) and `WorkflowStatus` (backing `gh aw status`). Five fields — `Workflow`, `EngineID`, `Compiled`, `Labels`, and `On` — were copy-pasted into both structs with identical `json` and `console` struct tags, so any change to the shared metadata had to be made in two places and could silently drift. The console table renderer in `pkg/console/render.go` modeled struct fields as a flat `[]int` of top-level indices and had no notion of anonymous embedded structs, which is why the duplication had not previously been collapsed.

## Decision

We will make `WorkflowListItem` the single source of truth for shared workflow metadata and embed it anonymously in `WorkflowStatus`, removing the five duplicated field declarations. To keep console output correct, we will extend the `pkg/console` renderer to flatten anonymous embedded structs: the table path switches from `[]int` field indices to `[][]int` index paths (via a new `collectTableFields` helper using `reflect.Value.FieldByIndex`), and the single-struct path gains a `renderInlineEmbeddedFields` helper that inlines promoted fields at the parent level. JSON serialization is intentionally left unchanged, relying on Go's default promotion of embedded fields in `encoding/json`.

## Alternatives Considered

### Alternative 1: Keep the duplicated fields
Leave both structs with their own copies of the five fields. Rejected because it preserves the maintenance hazard — the tags must be kept byte-for-byte identical by hand, and divergence would surface as inconsistent JSON keys or console headers between the `list` and `status` commands.

### Alternative 2: Extract a named (non-embedded) shared field
Introduce a `WorkflowListItem`-typed field with an explicit name (e.g. `Meta WorkflowListItem`) instead of anonymous embedding. Rejected because it changes the JSON shape (the shared fields would nest under a `meta` object) and would require custom marshaling or `json:",inline"`-style handling, breaking existing consumers of the flat JSON output and the console column layout.

## Consequences

### Positive
- Shared workflow metadata is defined once; tag or field changes propagate to both commands automatically.
- JSON output is byte-compatible with the previous flat shape because Go promotes embedded fields during marshaling.
- The console renderer now generically supports embedded structs, reusable by other report types in `pkg/cli`.

### Negative
- The console renderer gained real complexity: recursive field collection, `[][]int` index paths, and a separate inline-embedded rendering path that must stay in sync with the non-embedded path.
- All `WorkflowStatus{...}` composite literals in production and test code became more verbose, requiring the nested `WorkflowListItem: WorkflowListItem{...}` initialization form.

### Neutral
- Correctness of console rendering now depends on `reflect`'s `FieldByIndex` traversal rather than direct top-level indexing.
- New tests (`TestRenderStruct_EmbeddedStruct`, `TestRenderSlice_EmbeddedStruct`) pin the flattening behavior, and `pkg/cli/README.md` was updated to document the embedding relationship.
📋 What to do next
  1. Save the draft ADR above to docs/adr/39637-embed-workflowlistitem-in-workflowstatus.md on your branch.
  2. Review and complete it — confirm the inferred context, decision, and alternatives match your intent.
  3. Commit the ADR to your branch.
  4. Reference it in this PR body, e.g.:

    ADR: ADR-39637: Embed WorkflowListItem in WorkflowStatus

Once the ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

ADRs create a searchable, permanent record of why the codebase looks the way it does. This consolidation is exactly the kind of structural decision (single source of truth via embedding, plus a renderer capability change) that a future contributor will want explained. Capturing it now — including the rejected "named field" alternative and its JSON-shape trade-off — preserves that reasoning.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

ADRs live in docs/adr/ numbered by PR number (e.g., 39637-...md).

🔒 Blocking: add and link the ADR before merging.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ ·

@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 /zoom-out, /improve-codebase-architecture, /tdd, and /grill-with-docs.

The DRY-up goal is well-executed — embedding eliminates the 5-field duplication cleanly and the JSON wire format is preserved. The main themes are architectural friction introduced by the renderer extension (three independent recursive walks, one duplicated function body) and test coverage gaps on the new recursive paths.

No blocking correctness bugs in changed code. All issues are maintainability/coverage concerns.

📋 Key Themes & Highlights

Key Themes

  1. Renderer duplicationrenderInlineEmbeddedFields body is nearly identical to the inner loop of renderStruct. Making renderStruct delegate to it would give a single source of truth (/improve-codebase-architecture, render.go:109).

  2. Three independent recursive walkscomputeMaxFieldLen, renderInlineEmbeddedFields, and collectTableFields all traverse the same anonymous-embed tree with slightly different logic. A shared walkFields visitor would collapse this and make future changes (e.g. pointer-embed support) a one-liner (/improve-codebase-architecture, render.go:140).

  3. Pointer-embedded struct not handledfield.Kind() == reflect.Struct silently skips *EmbeddedType anonymous embeds in all three traversal sites. Fix or document the value-only restriction (/zoom-out, render.go:79, 116, 305).

  4. Test coverage gaps — New flattening paths miss: omitempty on embedded fields, 3-level nested embeds, and column ordering in slice output (/tdd, render_test.go).

Positive Highlights

  • ✅ Clean separation between struct-rendering and table-rendering paths — both updated symmetrically
  • FieldByIndex correctly used for multi-level path traversal in buildTableRows
  • ✅ New renderer tests use isolated local types (no cli coupling) — clean unit test design
  • ✅ All composite literals mechanically updated; no missed call sites
  • ✅ PR description accurately documents the JSON promotion behaviour

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

Comment thread pkg/console/render.go
// computeMaxFieldLen computes the longest visible field name for alignment.
// renderInlineEmbeddedFields renders the fields of an anonymous embedded struct
// directly into the parent struct output, flattening the hierarchy.
func renderInlineEmbeddedFields(val reflect.Value, maxFieldLen int, output *strings.Builder, depth int) {

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.

[/improve-codebase-architecture] renderInlineEmbeddedFields body is nearly identical to the inner loop of renderStruct — the module is shallow and the duplication will drift.

💡 Suggestion: make `renderStruct` delegate its field loop to `renderInlineEmbeddedFields`

The only things renderStruct adds around the loop are: (a) the title block and (b) the trailing output.WriteString("\n"). If renderInlineEmbeddedFields accepted the top-level reflect.Value, it could replace the loop entirely:

func renderStruct(val reflect.Value, title string, output *strings.Builder, depth int) {
    // ... title block ...
    maxFieldLen := computeMaxFieldLen(val, val.Type())
    renderInlineEmbeddedFields(val, maxFieldLen, output, depth) // replaces the loop
    output.WriteString("\n")
}

This makes renderInlineEmbeddedFields the single source of truth for field iteration and eliminates the copy-paste.

Comment thread pkg/console/render.go Outdated
fieldType := typ.Field(i)

// Flatten anonymous embedded structs by inlining their fields.
if fieldType.Anonymous && field.Kind() == reflect.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.

[/zoom-out] field.Kind() == reflect.Struct silently misses anonymous pointer embeds (type Foo struct { *Bar }), which Go allows. Those fields would fall through to normal rendering (producing a Bar: {...} row) rather than being flattened.

💡 Suggestion: handle the pointer case, or document the value-only assumption

Either dereference the pointer and recurse:

if fieldType.Anonymous {
    f := field
    if f.Kind() == reflect.Ptr {
        if f.IsNil() { continue }
        f = f.Elem()
    }
    if f.Kind() == reflect.Struct {
        renderInlineEmbeddedFields(f, maxFieldLen, output, depth)
        continue
    }
}

Or add a short comment: // Only value-type anonymous embeds are flattened; pointer embeds are treated as normal fields.

The same gap exists at line 116 (the recursive call in renderInlineEmbeddedFields) and line 305 in collectTableFields.

Comment thread pkg/console/render.go Outdated

// computeMaxFieldLen computes the longest visible field name for alignment,
// recursing into anonymous embedded structs to include their fields.
func computeMaxFieldLen(val reflect.Value, typ reflect.Type) int {

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.

[/improve-codebase-architecture] Three separate recursive traversals of the same anonymous-embed field tree now exist: computeMaxFieldLen, renderStructrenderInlineEmbeddedFields, and collectTableFields. Each is slightly different, so future changes (e.g. adding pointer-embed support) need to be made in three places.

💡 Suggestion: a shared field visitor

A single walkFields(v reflect.Value, fn func(val reflect.Value, sf reflect.StructField)) helper that recurses into anonymous value-type embeds would reduce this to one traversal. All three current functions could be expressed as walkFields callbacks. This would also make the pointer-embed fix a one-liner.

This is the deepening opportunity from /improve-codebase-architecture: replace three shallow helpers with one deep one.

Comment thread pkg/console/render.go Outdated

// collectTableFields recursively walks a struct type, inlining the fields of any
// anonymous embedded structs so they appear as top-level table columns.
func collectTableFields(t reflect.Type, prefix []int, headers *[]string, fieldPaths *[][]int, fieldTags *[]consoleTag) {

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.

[/improve-codebase-architecture] Triple pointer-to-slice parameters (headers *[]string, fieldPaths *[][]int, fieldTags *[]consoleTag) make the signature harder to read than necessary, given the only call site is buildTableHeaders.

💡 Suggestion: a collector struct
type tableFieldCollector struct {
    headers    []string
    fieldPaths [][]int
    fieldTags  []consoleTag
}

func (c *tableFieldCollector) collect(t reflect.Type, prefix []int) { ... }

Or simply return a []tableFieldEntry slice from collectTableFields and have buildTableHeaders unzip it. Either approach reduces pointer indirection and makes recursive calls self-documenting.


// TestRenderStruct_EmbeddedStruct tests that anonymous embedded struct fields are
// inlined into the parent struct output rather than rendered as a nested section.
func TestRenderStruct_EmbeddedStruct(t *testing.T) {

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] The test uses plain fields with no omitempty tag, leaving the omitempty branch of renderInlineEmbeddedFields (line 125–127 in render.go) untested. A zero-valued embedded field with omitempty would silently fall through to output — there is no regression guard.

💡 Suggested addition to this test
type BaseWithOmit struct {
    Name   string `console:"header:Name"`
    Engine string `console:"header:Engine,omitempty"`
}
type ExtendedWithOmit struct {
    BaseWithOmit
    Status string `console:"header:Status"`
}
data := ExtendedWithOmit{BaseWithOmit: BaseWithOmit{Name: "wf"}, Status: "active"}
out := RenderStruct(data)
assert.NotContains(t, out, "Engine", "zero omitempty field in embed should be suppressed")


// TestRenderSlice_EmbeddedStruct tests that a slice of structs with anonymous embedded
// fields is rendered as a flat table with all promoted fields as columns.
func TestRenderSlice_EmbeddedStruct(t *testing.T) {

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] renderInlineEmbeddedFields recurses for nested anonymous embedded structs (render.go line 116–118), but no test exercises that path. A 3-level embed (type C struct { Base }; type D struct { C }) would hit the recursive case.

💡 Suggested test skeleton
func TestRenderStruct_NestedEmbeddedStruct(t *testing.T) {
    type Inner struct {
        Name string `console:"header:Name"`
    }
    type Middle struct {
        Inner
        Engine string `console:"header:Engine"`
    }
    type Outer struct {
        Middle
        Status string `console:"header:Status"`
    }
    out := RenderStruct(Outer{Middle: Middle{Inner: Inner{Name: "wf"}, Engine: "copilot"}, Status: "ok"})
    assert.Contains(t, out, "wf")
    assert.Contains(t, out, "copilot")
    assert.Contains(t, out, "ok")
    assert.NotContains(t, out, "Middle")
    assert.NotContains(t, out, "Inner")
}

}

output := RenderStruct(items)

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] assert.Contains checks that column values exist anywhere in the output, but not their order. Since embedded fields are promoted to the left of outer fields, a column reorder would pass this test silently. Pinning the expected header line would make this test a true specification.

💡 Suggested assertion
// Column order: embedded fields first, then outer fields.
assert.Contains(t, output, "Name"+"  "+"Engine")
// or use a regex / index comparison:
nameIdx := strings.Index(output, "Name")
statusIdx := strings.Index(output, "Status")
assert.Less(t, nameIdx, statusIdx, "embedded Name column must appear before outer Status column")

Comment thread pkg/cli/status_command.go

statuses = append(statuses, WorkflowStatus{
Workflow: name,
WorkflowListItem: WorkflowListItem{

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.

[/zoom-out] The WorkflowListItem inside buildRemoteWorkflowStatuses is partially initialised — only Workflow is set; EngineID, Compiled, Labels, and On stay at zero values. This was the same behaviour before the refactor, but the embedding makes the partial init more visible now.

💡 Suggestion: add a comment clarifying intent

A short comment prevents a future contributor from treating the missing fields as an oversight:

statuses = append(statuses, WorkflowStatus{
    // Remote-status entries only carry the workflow name; engine/compiled
    // metadata is not available from the GitHub Actions API at this point.
    WorkflowListItem: WorkflowListItem{Workflow: name},
    ...
})

Comment thread pkg/cli/README.md Outdated
| `WorkflowFileStatus` | struct | Status of a workflow file (exists, outdated, etc.) |
| `WorkflowJob` | struct | A GitHub Actions job within a workflow run |
| `WorkflowListItem` | struct | A single item in the `gh aw list` output |
| `WorkflowListItem` | struct | Shared workflow metadata (name, engine, compiled status, labels, triggers); embedded in `WorkflowStatus` |

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.

[/grill-with-docs] The new description focuses on the embedding relationship and de-emphasises that WorkflowListItem is the primary output type for gh aw list. A reader scanning the table might assume it exists only for WorkflowStatus.

💡 Suggested wording
| `WorkflowListItem` | struct | A single item in the `gh aw list` output; shared workflow metadata fields (name, engine, compiled status, labels, triggers) also embedded in `WorkflowStatus` |

This preserves the original intent while documenting the new relationship.

Comment thread pkg/console/render.go Outdated
field := t.Field(i)

// Flatten anonymous embedded structs.
if field.Anonymous && field.Type.Kind() == reflect.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.

[/zoom-out] Same anonymous pointer-embed gap as in renderStruct/renderInlineEmbeddedFields: field.Type.Kind() == reflect.Struct will not match *EmbeddedType, so pointer-embedded struct fields would not be promoted to table columns. Consistent with the other two call sites but worth fixing or documenting in one place (ideally a shared walkFields helper) so future readers know this is a deliberate scope restriction.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 80/100 — Excellent

Analyzed 12 test(s): 12 design, 0 implementation, 0 guideline violation(s). All changes are either mechanical struct-embedding refactors or new behavioral tests for the embedded-struct rendering contract.

📊 Metrics & Test Classification (12 tests analyzed)
Metric Value
New/modified tests analyzed 12
✅ Design tests (behavioral contracts) 12 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 8 (67%)
Duplicate test clusters 0
Test inflation detected YES — status_command_test.go (+50) vs status_command.go (+14) = 3.6×, but due to struct literal syntax expansion, not hollow tests
🚨 Coding-guideline violations 0
Test File Classification Issues Detected
TestGeneratedSchemasValidateRealOutput pkg/cli/mcp_schema_test.go ✅ Design
TestWorkflowStatus_JSONMarshaling pkg/cli/status_command_test.go ✅ Design
TestWorkflowStatus_ConsoleRendering pkg/cli/status_command_test.go ✅ Design
TestWorkflowStatus_JSONMarshalingWithRunStatus pkg/cli/status_command_test.go ✅ Design
TestWorkflowStatus_JSONMarshalingWithEmptyRunStatus pkg/cli/status_command_test.go ✅ Design
TestWorkflowStatus_JSONMarshalingWithLabels pkg/cli/status_command_test.go ✅ Design
TestWorkflowStatus_JSONMarshalingWithEmptyLabels pkg/cli/status_command_test.go ✅ Design
TestWorkflowStatus_ConsoleRenderingWithRunStatus pkg/cli/status_command_test.go ✅ Design
TestRenderWorkflowDependencyTree pkg/cli/status_dependency_tree_test.go ✅ Design
TestRenderWorkflowDependencyTree_Empty pkg/cli/status_dependency_tree_test.go ✅ Design
TestRenderStruct_EmbeddedStruct (new) pkg/console/render_test.go ✅ Design
TestRenderSlice_EmbeddedStruct (new) pkg/console/render_test.go ✅ Design

Go: 12 (*_test.go); JavaScript: 0. No other languages detected.

Verdict

Check passed. 0% implementation tests (threshold: 30%). The two new tests in render_test.go directly enforce the embedded-struct flattening behavioral contract introduced by this PR. The 10-point inflation deduction is a scoring artefact: the line-count expansion in status_command_test.go is entirely due to Go struct-literal syntax (each 3-field group expands from 3 → 5 lines when wrapped in the embedded type), not hollow or duplicated tests.

🧪 Test quality analysis by Test Quality Sentinel ·

@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. Test quality is acceptable — 0% of new tests are implementation tests (threshold: 30%). All 12 tests classified as design/behavioral contracts, with 2 new tests directly verifying the embedded-struct flattening contract introduced by this PR.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

Copilot AI and others added 3 commits June 16, 2026 20:33
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Completed in 8b8fb77.

Local make fmt, make lint, make test-unit, make test, and make recompile passed. I also reviewed the prior CI failures: the code-review run failed with an auth error, the PR code quality reviewer failure was a stale lock-file check, and the earlier CGO test failure is not reproducing locally on the current branch.

CI on the latest agent-pushed HEAD is still unverified until a maintainer re-triggers it.

@pelikhan pelikhan merged commit 1694b45 into main Jun 16, 2026
36 checks passed
@pelikhan pelikhan deleted the copilot/deep-report-consolidate-structs branch June 16, 2026 21:04
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