Overview
The file pkg/workflow/compiler_yaml.go has grown to 1262 lines, significantly exceeding the healthy threshold of 800 lines. It contains distinct functional domains tightly packed into a single file, making it harder to navigate, maintain, and test.
Current State
- File:
pkg/workflow/compiler_yaml.go
- Size: 1262 lines
- Test file:
pkg/workflow/compiler_yaml_test.go (1860 lines)
- Test-to-source ratio: 1.47× (good coverage exists)
- Complexity: High — the file covers YAML generation, prompt assembly, output collection, header construction, and text-normalization utilities
Full File Analysis
Function Distribution
| Function |
Lines |
Domain |
generateWorkflowHeader |
~177 |
Header/metadata generation |
generatePrompt |
~290 |
Prompt assembly |
generateYAML |
~131 |
Top-level YAML orchestration |
normalizeBlankLines |
~105 |
YAML text normalization |
generateCreateAwInfo |
~181 |
AW info step generation |
generateOutputCollectionStep |
~88 |
Output collection |
blockScalarHeaderIndentForLine |
~32 |
YAML indent utility |
splitContentIntoChunks |
~30 |
Prompt chunking |
| Small helpers |
~80 |
Various |
Complexity Hotspots
generatePrompt (lines 633–922, ~290 lines): Largest function — handles ordered/legacy imports, runtime-import macros, expression mappings, chunking, and YAML emission. High cyclomatic complexity.
generateWorkflowHeader (lines 84–260, ~177 lines): Embeds metadata, permissions, secrets, on-triggers, and concurrency config.
generateCreateAwInfo (lines 965–1145, ~181 lines): Serialises engine info, environment variables, and run metadata into YAML steps.
Refactoring Strategy
Proposed File Splits
-
compiler_yaml_header.go
- Functions:
generateWorkflowHeader, effectiveStrictMode, effectiveSafeUpdate
- Responsibility: YAML header/metadata/frontmatter emission
- Estimated LOC: ~230
-
compiler_yaml_prompt.go
- Functions:
generatePrompt, splitContentIntoChunks, extractPromptChunksFromMarkdown, writePromptBashStep
- Responsibility: Prompt assembly, chunking, import resolution, expression mapping
- Estimated LOC: ~340
-
compiler_yaml_steps.go
- Functions:
generatePreSteps, generatePostSteps, generatePreAgentSteps, writeStepsSection, generateCreateAwInfo, generateOutputCollectionStep
- Responsibility: Individual step generation (pre/post steps, aw-info, output collection)
- Estimated LOC: ~320
-
compiler_yaml_normalize.go
- Functions:
normalizeBlankLines, countLeadingSpaces, blockScalarHeaderIndentForLine
- Responsibility: YAML text normalization and indentation utilities
- Estimated LOC: ~110
-
compiler_yaml.go (trimmed)
- Functions:
buildJobsAndValidate, generateYAML, generateWorkflowBody, resolveWorkspaceRoot
- Responsibility: Top-level orchestration — entry point for YAML generation
- Estimated LOC: ~280
Shared Utilities
normalizeBlankLines, countLeadingSpaces, and blockScalarHeaderIndentForLine are pure text utilities with no Compiler receiver — natural candidates for compiler_yaml_normalize.go with zero coupling change.
Interface Abstractions
No new interfaces required for this split; all functions share the same *Compiler receiver. The split is purely by domain/file boundary.
Test Coverage Plan
Existing tests in compiler_yaml_test.go cover the public surface well (ratio 1.47×). After the split:
compiler_yaml_header_test.go: TestEffectiveStrictMode, TestGenerateWorkflowHeader
compiler_yaml_prompt_test.go: TestSplitContentIntoChunks, TestGeneratePrompt, TestExtractPromptChunksFromMarkdown
compiler_yaml_steps_test.go: TestWriteStepsSection, TestGenerateCreateAwInfo, TestGenerateOutputCollectionStep
compiler_yaml_normalize_test.go: TestNormalizeBlankLines, TestBlockScalarHeaderIndentForLine
Existing tests can be redistributed to match the new file structure or kept in the single test file — both are valid per existing repository patterns.
Implementation Guidelines
- Preserve Behavior: Ensure all existing functionality works identically
- Maintain Exports: Keep public API unchanged (exported functions/types)
- Incremental Changes: Split one module at a time, verify
make test-unit after each
- Update Imports: Ensure all import paths are correct after each split
- Document Changes: Add comments explaining module boundaries
Acceptance Criteria
Additional Context
- Repository Guidelines: Follow patterns in
.github/agents/developer.instructions.agent.md
- Code Organization: Prefer many small files grouped by functionality (see
create_*.go pattern)
- Testing: Match existing test patterns in
pkg/workflow/*_test.go
Priority: Medium
Effort: Medium (well-tested file, clear domain boundaries, no interface changes needed)
Expected Impact: Improved maintainability, easier navigation, reduced per-file complexity
Generated by 🧹 Daily File Diet · 43.6 AIC · ⌖ 8.41 AIC · ⊞ 6.8K · ◷
Overview
The file
pkg/workflow/compiler_yaml.gohas grown to 1262 lines, significantly exceeding the healthy threshold of 800 lines. It contains distinct functional domains tightly packed into a single file, making it harder to navigate, maintain, and test.Current State
pkg/workflow/compiler_yaml.gopkg/workflow/compiler_yaml_test.go(1860 lines)Full File Analysis
Function Distribution
generateWorkflowHeadergeneratePromptgenerateYAMLnormalizeBlankLinesgenerateCreateAwInfogenerateOutputCollectionStepblockScalarHeaderIndentForLinesplitContentIntoChunksComplexity Hotspots
generatePrompt(lines 633–922, ~290 lines): Largest function — handles ordered/legacy imports, runtime-import macros, expression mappings, chunking, and YAML emission. High cyclomatic complexity.generateWorkflowHeader(lines 84–260, ~177 lines): Embeds metadata, permissions, secrets, on-triggers, and concurrency config.generateCreateAwInfo(lines 965–1145, ~181 lines): Serialises engine info, environment variables, and run metadata into YAML steps.Refactoring Strategy
Proposed File Splits
compiler_yaml_header.gogenerateWorkflowHeader,effectiveStrictMode,effectiveSafeUpdatecompiler_yaml_prompt.gogeneratePrompt,splitContentIntoChunks,extractPromptChunksFromMarkdown,writePromptBashStepcompiler_yaml_steps.gogeneratePreSteps,generatePostSteps,generatePreAgentSteps,writeStepsSection,generateCreateAwInfo,generateOutputCollectionStepcompiler_yaml_normalize.gonormalizeBlankLines,countLeadingSpaces,blockScalarHeaderIndentForLinecompiler_yaml.go(trimmed)buildJobsAndValidate,generateYAML,generateWorkflowBody,resolveWorkspaceRootShared Utilities
normalizeBlankLines,countLeadingSpaces, andblockScalarHeaderIndentForLineare pure text utilities with noCompilerreceiver — natural candidates forcompiler_yaml_normalize.gowith zero coupling change.Interface Abstractions
No new interfaces required for this split; all functions share the same
*Compilerreceiver. The split is purely by domain/file boundary.Test Coverage Plan
Existing tests in
compiler_yaml_test.gocover the public surface well (ratio 1.47×). After the split:compiler_yaml_header_test.go:TestEffectiveStrictMode,TestGenerateWorkflowHeadercompiler_yaml_prompt_test.go:TestSplitContentIntoChunks,TestGeneratePrompt,TestExtractPromptChunksFromMarkdowncompiler_yaml_steps_test.go:TestWriteStepsSection,TestGenerateCreateAwInfo,TestGenerateOutputCollectionStepcompiler_yaml_normalize_test.go:TestNormalizeBlankLines,TestBlockScalarHeaderIndentForLineExisting tests can be redistributed to match the new file structure or kept in the single test file — both are valid per existing repository patterns.
Implementation Guidelines
make test-unitafter eachAcceptance Criteria
compiler_yaml.gois split into 5 focused filesmake test-unit)make lint)make build)Additional Context
.github/agents/developer.instructions.agent.mdcreate_*.gopattern)pkg/workflow/*_test.goPriority: Medium
Effort: Medium (well-tested file, clear domain boundaries, no interface changes needed)
Expected Impact: Improved maintainability, easier navigation, reduced per-file complexity