-
Notifications
You must be signed in to change notification settings - Fork 34
Description
Objective
Add comprehensive documentation explaining the intentional use of map[string]any and any types for YAML/JSON parsing throughout the codebase, helping maintainers understand these design decisions.
Context
The codebase makes extensive use of any type (1,076 occurrences), which is intentional and appropriate for parsing dynamic YAML/JSON structures. However, this design decision is not explicitly documented, which could lead to confusion or unnecessary refactoring attempts.
Key patterns that need documentation:
- YAML frontmatter parsing (~400 occurrences)
- GitHub Actions step processing (~300 occurrences)
- Dynamic configuration fields (~200 occurrences)
- Runtime type assertions and conversions (~176 occurrences)
Implementation Approach
Step 1: Create package-level documentation
Create pkg/workflow/doc.go:
// Package workflow implements the agentic workflow compiler that transforms
// markdown-based workflow definitions into GitHub Actions YAML files.
//
// # Type Safety and Dynamic Configuration
//
// This package makes extensive use of map[string]any for parsing YAML/JSON
// frontmatter and GitHub Actions configurations. This is intentional and
// follows Go best practices for handling dynamic data structures:
//
// 1. YAML unmarshaling produces map[string]any for structures unknown at compile time
// 2. Code validates types at runtime using type assertions with error handling
// 3. Validated data is converted to strongly-typed domain objects where possible
// 4. Type safety is maintained through typed constants and domain models
//
// # Common Patterns
//
// Dynamic Frontmatter Parsing:
// var frontmatter map[string]any
// yaml.Unmarshal(data, &frontmatter)
// // Then extract and validate specific fields
//
// Runtime Type Checking:
// if stepsList, ok := steps.([]any); ok {
// // Process as list
// } else if stepMap, ok := steps.(map[string]any); ok {
// // Process as map
// }
//
// Extensible Configuration:
// type Config struct {
// KnownField string
// CustomFields map[string]any `yaml:",inline"`
// }
//
// Do not attempt to eliminate all uses of 'any' - it is required for
// dynamic configuration parsing and provides necessary flexibility for
// extensible configurations like MCP server settings.
//
// # Type Hierarchies
//
// The package uses base types with embedded fields to share common
// configuration while allowing domain-specific extensions:
//
// types.BaseMCPServerConfig (shared fields)
// ├─ parser.MCPServerConfig (parser-specific)
// └─ workflow.MCPServerConfig (workflow-specific)
//
// This pattern prevents duplication while maintaining domain boundaries.
package workflowStep 2: Add inline comments to key functions
Add explanatory comments to representative functions that use any:
File: pkg/workflow/compiler_jobs.go
// extractFeatures extracts feature flags from frontmatter.
// Uses map[string]any because feature flags are extensible and
// new flags can be added without code changes.
func (c *Compiler) extractFeatures(frontmatter map[string]any) map[string]any {
// ...
}File: pkg/workflow/action_pins.go
// ApplyActionPinsToSteps processes workflow steps to pin action versions.
// Steps use []any because GitHub Actions allows heterogeneous step types:
// - String references: "actions/checkout@v4"
// - Map objects: {uses: "actions/checkout@v4", with: {...}}
func ApplyActionPinsToSteps(steps []any, data *WorkflowData) []any {
// ...
}Step 3: Add code review guideline
Update CONTRIBUTING.md or AGENTS.md with a guideline:
### Dynamic Type Usage Guidelines
**When to use `any` or `map[string]any`:**
- ✅ Parsing YAML/JSON with unknown structure
- ✅ Extensible configuration fields (e.g., MCP server custom fields)
- ✅ GitHub Actions heterogeneous structures (steps, jobs)
- ✅ Runtime type checking after unmarshaling
**When to avoid `any`:**
- ❌ Internal function parameters with known types
- ❌ Return values where type is deterministic
- ❌ Struct fields that should be strongly typed
**Code Review Checklist:**
- New uses of `any` should be for YAML/JSON parsing or documented
- Type assertions should include error handling
- Consider if a typed constant or struct would be more appropriateFiles to Modify
- Create:
pkg/workflow/doc.go(package documentation) - Update:
pkg/workflow/compiler_jobs.go(add explanatory comments) - Update:
pkg/workflow/action_pins.go(add explanatory comments) - Update:
AGENTS.mdorCONTRIBUTING.md(add code review guidelines)
Acceptance Criteria
- Package-level documentation explains dynamic typing rationale
- Key functions have inline comments explaining
anyusage - Code review guidelines added for future development
- Documentation explains common patterns with examples
- Documentation clarifies when to use and avoid
any
Priority
⭐⭐ Medium Priority - Helps maintainers understand design decisions and prevents unnecessary refactoring attempts.
Estimated Effort
1-2 hours
Benefits
- Prevents confusion about intentional
anyusage - Guides future contributors on appropriate patterns
- Documents architectural decisions
- Reduces likelihood of inappropriate refactoring
Related to [plan] Implement type safety improvements from Typist analysis #8604
AI generated by Plan Command for discussion #8598