Skip to content

Split pkg/workflow/compiler_types.go by lifecycle: options, mutators, types - #52109

Merged
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-split-compiler-types
Aug 11, 2026
Merged

Split pkg/workflow/compiler_types.go by lifecycle: options, mutators, types#52109
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-split-compiler-types

Conversation

Copilot AI commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

compiler_types.go mixed three lifecycles in one file: build-time functional options, post-construction runtime mutators/accessors, and plain type declarations. Mechanical split, no behavior change.

File split

  • compiler_options.goCompilerOption type, With* builders, and NewCompiler.
  • compiler_mutators.go — all *Compiler setters/getters (SetContext, SetStrictMode, Get*, warning counters, repository-slug locking) plus the lazily-initialized shared cache helpers (getSharedActionResolver, getSharedImportCache).
  • compiler_types.go — now only logTypes, FileCreationTracker, the Compiler struct, and allowedDomain. Also drops an orphaned doc comment for SkipIfMatchConfig, whose type actually lives in workflow_data.go.

Tests

The existing compiler_types_test.go only covers WorkflowData pin context, so there was nothing to relocate. Added direct coverage alongside the new files instead:

  • compiler_options_test.go — every option is applied by NewCompiler; defaults are unchanged.
  • compiler_mutators_test.go — mutators, repository-slug lock semantics (SetRepositorySlugIfUnlocked is a no-op once locked), shared cache/resolver instance reuse, and SetPriorManifests(nil) resetting to an empty map.

Docs

pkg/workflow/README.md symbol table: the 38 relocated symbols now point at compiler_mutators.go, kept in the table's existing file-name ordering.


pr-sous-chef branch refresh requested.> Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.67 AIC · ⌖ 6.25 AIC · ⊞ 8.5K ·

Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Split compiler types into separate builders and mutators Split pkg/workflow/compiler_types.go by lifecycle: options, mutators, types Aug 11, 2026
Copilot AI requested a review from pelikhan August 11, 2026 16:21
@pelikhan
pelikhan marked this pull request as ready for review August 11, 2026 16:57
Copilot AI balanced review requested due to automatic review settings August 11, 2026 16:57

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

Splits compiler construction, runtime mutation, and type declarations by lifecycle without intended behavior changes.

Changes:

  • Moves functional options and construction into compiler_options.go.
  • Moves compiler mutators, accessors, and shared caches into compiler_mutators.go.
  • Adds focused tests and updates symbol documentation.
Show a summary per file
File Description
pkg/workflow/README.md Updates relocated symbol paths.
pkg/workflow/compiler_types.go Retains compiler types and state declarations.
pkg/workflow/compiler_options.go Houses options and compiler construction.
pkg/workflow/compiler_options_test.go Tests options and defaults.
pkg/workflow/compiler_mutators.go Houses runtime methods and cache helpers.
pkg/workflow/compiler_mutators_test.go Tests representative mutator and cache behavior.

Review details

Tip

Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread pkg/workflow/compiler_options.go Outdated

// Create compiler with defaults
c := &Compiler{
ctx: context.Background(), // Default context; override with WithContext
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Lean already. Ship. This PR is a pure mechanical file split (compiler_types.go into compiler_options.go, compiler_mutators.go, compiler_types.go) with no new abstractions, wrappers, or behavior changes introduced. The only duplicate-looking pair (effectiveActionsRepo/EffectiveActionsRepo) predates this PR and was just relocated. Nothing new to cut under ponytail-review scope.

Generated by Ponytail Reviewer for #52109

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

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

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

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Warning

Firewall blocked 1 domain

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

  • api.individual.githubcopilot.com

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

network:
  allowed:
    - defaults
    - "api.individual.githubcopilot.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

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

🏗️ 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.

This is a clean, mechanical file split with no logic changes. compiler_types.go now contains only types, compiler_mutators.go contains setter/getter methods, and compiler_options.go contains functional options and NewCompiler. Test coverage for the moved code is added in compiler_mutators_test.go and compiler_options_test.go. No issues found in the changed lines.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 42.6 AIC · ⌖ 6.21 AIC · ⊞ 5.4K

@github-actions

Copy link
Copy Markdown
Contributor

Great work on this refactoring! 🎯 This PR successfully splits a monolithic 900+ line file into three focused modules by lifecycle concern — a textbook example of separation of concerns. The diff is clean, mechanical, and includes comprehensive test coverage for both new files.

Aligned with guidelines — The PR follows the project's core contribution model: this work was scoped in issue #52092 (generated by Deep Report), and the Copilot coding agent has delivered a focused, well-structured refactor that improves navigability and reduces merge-conflict surface in a high-churn file.

Well-organized split — Three new/modified files with clear responsibilities:

  • compiler_options.go — build-time configuration (CompilerOption, With* builders, NewCompiler)
  • compiler_mutators.go — runtime state mutations and shared cache helpers
  • compiler_types.go — now only core type definitions and utilities

Full test coverage — Two new test files with meaningful coverage.

Documentation updated — pkg/workflow/README.md symbol table correctly reflects the relocated 38 symbols with proper file assignments.

No actionable changes needed — this is ready for review and merge.

Generated by ✅ Contribution Check · auto · 56.8 AIC · ⌖ 5.01 AIC · ⊞ 8.8K ·

@github-actions

Copy link
Copy Markdown
Contributor

Test Quality Sentinel 🧪

Summary

Score: 90/100 ✅ Excellent

PR adds 2 new test files (6 test functions, 119 lines) for the refactored compiler_types.go split into compiler_options.go and compiler_mutators.go.

Test Coverage Analysis

New Test Functions Analyzed: 6

Test Name File Classification Value Notes
TestCompilerMutators compiler_mutators_test.go design_test high_value Verifies 7 mutator methods correctly set internal state. All assertions explicit.
TestCompilerRepositorySlugLocking compiler_mutators_test.go design_test high_value Tests locking invariant: locked slug cannot be overridden. Edge case coverage with state transitions.
TestCompilerSharedActionCacheAndResolver compiler_mutators_test.go design_test high_value Verifies lazy initialization + singleton pattern. Uses assert.Same() for identity guarantee.
TestCompilerSetPriorManifestsNilResetsMap compiler_mutators_test.go design_test high_value Edge case: nil input resets to empty map (not nil). Important state initialization contract.
TestCompilerOptionsAppliedByNewCompiler compiler_options_test.go design_test high_value Verifies functional options pattern correctness: 7 options properly applied via NewCompiler(opts...).
TestNewCompilerDefaults compiler_options_test.go design_test high_value Tests baseline defaults when no options provided. Good control test for option application.

Quality Signals

  • 100% design contracts: All tests verify behavioral guarantees (options, state mutation, locking, defaults, edge cases)
  • 66% edge-case coverage: Nil handling, locking/unlock state, singleton reuse, defaults
  • No duplicates: Each test exercises distinct behavior
  • Proper build tags: Both _test.go files have (go/redacted):build !integration on line 1
  • Appropriate libraries: Uses testify/assert and testify/require (not mock libraries); focus is on behavior
  • Test inflation: compiler_mutators_test.go ratio 0.24:1, compiler_options_test.go ratio 0.43:1 (both well under 2:1 threshold)
  • No forbidden patterns: No gomock, testify/mock, or mock-heavy assertions

Implementation vs. Design

Implementation tests / total: 0/6 = 0% (threshold: ≤30%) ✅

All tests verify design contracts (functional option correctness, state invariants, locking mechanism, singleton pattern, edge cases). No tests verify implementation details only.

Recommendations

None — test coverage is strong for the refactored code. Setter/getter pairs and functional options are well-exercised.

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 20.3 AIC · ⌖ 4.02 AIC · ⊞ 7.6K ·
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: 90/100. 0% implementation tests (threshold: 30%). All 6 tests verify design contracts with strong edge-case coverage.

@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 — no blocking issues, but four actionable improvements flagged as inline comments.

📋 Key Themes & Highlights

Key Themes

  • Test structure: TestCompilerMutators bundles too many behaviours — t.Run sub-tests would make specs readable and failures pinpointable.
  • Dead code: actionMode is set twice in NewCompiler; the struct-literal assignment is always overwritten after the options loop.
  • Naming: getSharedActionResolver() returns two values but its name only describes one — callers need to read the implementation to understand the full contract.
  • Doc gap: NewCompiler's doc comment lists only 4 of 7 With* options and doesn't articulate the With* vs Set* lifecycle distinction.

Positive Highlights

  • ✅ Clean lifecycle split — options / mutators / types is a meaningful and navigable boundary.
  • ✅ Good test coverage for non-obvious semantics: slug-locking no-op, shared-cache instance reuse, nil-manifest reset.
  • ✅ Orphaned SkipIfMatchConfig doc comment correctly removed.
  • ✅ README symbol table kept consistent with the new file names.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 43.3 AIC · ⌖ 6.88 AIC · ⊞ 7.1K
Comment /matt to run again

Comments that could not be inline-anchored

pkg/workflow/compiler_mutators_test.go:474

[/tdd] TestCompilerMutators bundles ~10 independent behaviours into a single function — one failure masks the rest and the test name doesn't read as a specification.

<details>
<summary>💡 Suggested structure</summary>

Split into focused sub-tests:

func TestCompilerMutators(t *testing.T) {
    t.Run(&quot;SetNoEmit toggles flag&quot;, func(t *testing.T) {
        c := NewCompiler()
        c.SetNoEmit(true)
        assert.True(t, c.noEmit)
    })
    t.Run(&quot;WarningCounter increments and res</details>

<details><summary>pkg/workflow/compiler_options.go:603</summary>

**[/codebase-design]** `actionMode` is assigned twice in `NewCompiler`: once in the struct literal (line 582) and again unconditionally at line 603. The first assignment is dead code.

&lt;details&gt;
&lt;summary&gt;💡 Fix&lt;/summary&gt;

Remove the `actionMode` field from the struct literal:

```go
// Before (struct literal):
actionMode: DetectActionMode(version), // redundant — overwritten below

// After applying options, the single assignment suffices:
c.actionMode = DetectActionMode(c.version)

The cur…

pkg/workflow/compiler_mutators.go:395

[/codebase-design] getSharedActionResolver() returns both the cache and the resolver, but its name only mentions the resolver — a caller reading the signature has to look inside the function to discover it also initialises the cache.

<details>
<summary>💡 Suggestion</summary>

Rename to initSharedActionCacheAndResolver() or introduce separate lazy-init helpers so each accessor (GetSharedActionCache, GetSharedActionResolver) is independently readable. The current dual-return private…

pkg/workflow/compiler_options.go:565

[/codebase-design] The NewCompiler doc comment says "Common options: WithVerbose, WithEngineOverride, WithNoEmit, WithSkipValidation" but the file defines 7 With* options — WithFailFast, WithWorkflowIdentifier, and WithVersion are omitted from the example list. There's also no guidance on when callers should prefer With* (construction time) vs Set* (post-construction), leaving the dual-API surface undocumented.

<details>
<summary>💡 Suggestion</summary>

Update the doc commen…

…ecycle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (+579 new lines in pkg/workflow/) but did not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/52109-split-compiler-types-by-lifecycle.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch at docs/adr/52109-split-compiler-types-by-lifecycle.md
  2. Complete the missing sections — add context the AI could not infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-52109: Split compiler_types.go by Lifecycle Responsibility

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

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 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)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 0042-use-postgresql.md for PR #42).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 · 81.1 AIC · ⌖ 20.7 AIC · ⊞ 8.7K ·
Comment /review to run again

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please address the remaining PR follow-ups in one pass, then refresh the branch and use the pr-finisher skill before handing back.

Open review feedback to consider:

  • pkg/workflow/compiler_mutators_test.go:474 — split TestCompilerMutators into focused subtests for clearer failure isolation.
  • pkg/workflow/compiler_options.go:603 — remove the redundant actionMode struct-literal assignment since NewCompiler recomputes it after applying options.
  • pkg/workflow/compiler_mutators.go:395 — rename or clarify the dual-return shared-action helper so the cache+resolver contract is obvious.
  • pkg/workflow/compiler_options.go:565 — expand the NewCompiler docs to cover all With* options and when to use constructor options vs mutators.

Please also link the ADR already committed at docs/adr/52109-split-compiler-types-by-lifecycle.md in the PR body so the ADR gate can clear.
No failed checks were reported in the compact candidate set for this run.
Please update the branch if needed and use the pr-finisher skill before handing back.

Generated by 👨🍳 PR Sous Chef

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.67 AIC · ⌖ 6.25 AIC · ⊞ 8.5K ·
Comment /souschef to run again

…ed helper

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

Copilot AI commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please address the remaining PR follow-ups in one pass, then refresh the branch and use the pr-finisher skill before handing back.

Open review feedback to consider:...

Addressed in 6be1a63 (pushed via report_progress):

  • Split TestCompilerMutators into focused per-behavior subtests.
  • Removed the redundant actionMode struct-literal assignment (still recomputed unconditionally after applying options, so no behavior change).
  • Renamed getSharedActionResolver to ensureSharedActionCacheAndResolver and clarified its doc comment; updated all call sites and the ADR.
  • Expanded NewCompiler docs to cover all With* options and clarify constructor options vs. mutators.
  • Fixed the stale WithContext comment to point to SetContext.
  • ADR-52109 is already present at docs/adr/52109-split-compiler-types-by-lifecycle.md and linked in the PR description.

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage: #52109

  • Category: refactor
  • Risk: medium
  • Priority score: 53/100 (impact 20/50, urgency 15/30, quality 18/20) → medium
  • Recommended action: batch_review
  • Batch: deep-report-refactor-cluster (mechanical structural-split/consolidation PRs from the deep-report agent)

Automated triage — see labels for machine-readable classification.

Generated by 🔧 PR Triage Agent · auto · 45 AIC · ⌖ 2.09 AIC · ⊞ 7.8K ·

@pelikhan
pelikhan merged commit a583d83 into main Aug 11, 2026
29 checks passed
@pelikhan
pelikhan deleted the copilot/deep-report-split-compiler-types branch August 11, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[deep-report] Split pkg/workflow/compiler_types.go: separate CompilerOption builders from Compiler mutators

4 participants