Skip to content

Split oversized engine_validation.go (521 lines) into domain-focused files - #48568

Merged
pelikhan merged 5 commits into
mainfrom
copilot/hippo-split-oversized-validator
Jul 28, 2026
Merged

Split oversized engine_validation.go (521 lines) into domain-focused files#48568
pelikhan merged 5 commits into
mainfrom
copilot/hippo-split-oversized-validator

Conversation

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

engine_validation.go at 521 lines exceeded the 300-line refactor threshold and mixed three unrelated validation domains in a single file, making it difficult to maintain and test independently.

Changes

  • engine_driver_validation.go (171 lines) — extracted validateEngineScriptFilename, validateEngineHarnessScript, validateEngineDriver, validateInlineEngineDriver, and the associated safeHarnessScriptPattern/safeSDKDriverSegmentPattern regexes

  • engine_inline_definition_validation.go (177 lines) — extracted validateEngineInlineDefinition, registerInlineEngineDefinition, validateEngineAuthDefinition; uses a new engineInlineDefinitionLog logger with a domain-specific prefix

  • engine_validation.go (255 lines, trimmed from 521) — retains engine version warning, MCP timeout validation, multi-file engine specification consistency, and EngineHasValidateSecretStep

  • engine_driver_validation_test.go — adds direct unit tests for validateEngineScriptFilename (valid basenames, whitespace, path traversal, metacharacters, unsupported extensions); previously only had indirect coverage through harness script tests

  • scratchpad/validation-architecture.md — updated to document the three-file structure with per-file function inventories and guidance on where to add new validation

No behavioral changes — pure structural refactoring with all function signatures preserved.


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.36 AIC · ⌖ 5.35 AIC · ⊞ 7.2K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor oversized validator in pkg/workflow or pkg/cli Split oversized engine_validation.go (521 lines) into domain-focused files Jul 28, 2026
Copilot AI requested a review from pelikhan July 28, 2026 09:27
@github-actions

Copy link
Copy Markdown
Contributor

Excellent refactoring! 🎯 This PR cleanly decomposes engine_validation.go (521 lines) into three domain-focused files.

What looks great:

  • Clear scope — splits one monolithic file into focused concerns: driver validation, inline definition validation, and general engine validation.
  • Preserved behavior — no functional changes, all function signatures maintained.
  • Added tests — new direct unit tests for validateEngineScriptFilename cover valid, edge-case, and invalid scenarios (whitespace, path traversal, metacharacters).
  • Documentationscratchpad/validation-architecture.md updated to guide future maintenance.
  • Size reduction — trimmed engine_validation.go from 521 to 255 lines, making it much easier to reason about.

This aligns perfectly with the project's refactoring thresholds and code quality standards. Ready for review! 🚀

Generated by ✅ Contribution Check · sonnet50 · 53.9 AIC · ⌖ 11.5 AIC · ⊞ 8.3K ·

@pelikhan
pelikhan marked this pull request as ready for review July 28, 2026 10:11
Copilot AI review requested due to automatic review settings July 28, 2026 10:11

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 engine validation into focused modules while preserving validation behavior.

Changes:

  • Separates driver and inline-definition validation.
  • Adds direct script-filename tests.
  • Updates validation architecture documentation.
Show a summary per file
File Description
pkg/workflow/engine_validation.go Retains top-level engine validation.
pkg/workflow/engine_driver_validation.go Houses driver and harness validation.
pkg/workflow/engine_inline_definition_validation.go Houses inline definition and auth validation.
pkg/workflow/engine_driver_validation_test.go Adds script-filename tests.
scratchpad/validation-architecture.md Documents the split architecture.

Review details

Tip

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

  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment thread scratchpad/validation-architecture.md Outdated
Comment on lines +12 to +15
// TestValidateEngineScriptFilename tests the validateEngineScriptFilename helper directly.
// The function validates that a script name is a safe Node.js basename (no paths, safe chars,
// correct extension). It is also exercised indirectly by TestValidateEngineHarnessScript.
func TestValidateEngineScriptFilename_ValidInputs(t *testing.T) {
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 100/100 — Excellent

Analyzed 2 test(s): 2 design, 0 implementation, 0 violation(s).

📊 Metrics (2 tests)
Metric Value
Analyzed 2 (Go: 2, JS: 0)
✅ Design 2 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 2 (100%)
Duplicate clusters 0
Inflation No (0.6:1 ratio)
🚨 Violations 0
Test File Classification Issues
TestValidateEngineScriptFilename_ValidInputs engine_driver_validation_test.go design_test / behavioral_contract / high_value None
TestValidateEngineScriptFilename_InvalidInputs engine_driver_validation_test.go design_test / behavioral_contract / high_value None

Verdict

passed. 0% implementation tests (threshold: 30%). Both tests cover the security-sensitive validateEngineScriptFilename function with thorough table-driven cases including path traversal, unsafe characters, and bad extensions.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 30.7 AIC · ⌖ 8.64 AIC · ⊞ 8.1K ·
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: 100/100. 0% implementation tests (threshold: 30%).

@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: Split oversized engine_validation.go

Clean structural refactoring with no behavioral changes. Domain boundaries are clear and well-documented.

Two existing review comments already cover the actionable issues:

  1. Stale line counts in scratchpad/validation-architecture.md (~155 documented vs 171 actual)
  2. Test coverage gap — validateEngineHarnessScript and validateEngineDriver retain only indirect coverage; direct tests should be added to engine_driver_validation_test.go

No additional blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 21.8 AIC · ⌖ 4.54 AIC · ⊞ 5K

@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 /tdd and /codebase-design — commenting on test coverage gaps and a minor logging ordering issue. The structural refactor itself is clean and well-motivated.

📋 Key Themes & Highlights

Key Themes

  • Test coverage gap: validateEngineDriver (the most security-relevant function — it enforces path-traversal and metacharacter rejection) has no direct unit tests in the new engine_driver_validation_test.go. The added tests cover only validateEngineScriptFilename. The extension-dispatch branching for copilot vs. other engines is untested directly.
  • Inline-driver functions also untested directly: validateInlineEngineDriver, validateEngineHarnessScript moved here but their tests remain in engine_validation_test.go, splitting related tests across files.
  • Minor log ordering bug in validateEngineInlineDefinition: the log fires before the empty-string guard.

Positive Highlights

  • ✅ Excellent file-level doc comments with clear "When to Add Validation Here" guidance — this is exactly the kind of deep-module documentation that makes a codebase navigable.
  • engineInlineDefinitionLog uses a domain-specific prefix (workflow:engine_inline_definition_validation) — consistent with the existing logger pattern.
  • ✅ No behavioral changes; the refactor is purely mechanical — verified by identical function bodies in the diff.
  • scratchpad/validation-architecture.md updated to reflect the new three-file structure.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 32.4 AIC · ⌖ 4.91 AIC · ⊞ 6.7K
Comment /matt to run again

// TestValidateEngineScriptFilename tests the validateEngineScriptFilename helper directly.
// The function validates that a script name is a safe Node.js basename (no paths, safe chars,
// correct extension). It is also exercised indirectly by TestValidateEngineHarnessScript.
func TestValidateEngineScriptFilename_ValidInputs(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] validateEngineDriver — the most complex function in this new file — has no direct unit tests covering its copilot-vs-other-engine extension branching (.py, .ts, .mts, .rb pass for copilot, fail for others) or segment-safety checks.

💡 Suggested test skeleton
func TestValidateEngineDriver_ExtensionsByEngine(t *testing.T) {
    tests := []struct{
        name     string
        engineID string
        driver   string
        wantErr  bool
    }{
        {"py allowed for copilot",  "copilot", "driver.py",  false},
        {"py rejected for pi",      "pi",      "driver.py",  true},
        {"ts allowed for copilot",  "copilot", "driver.ts",  false},
        {"bare name ok",            "pi",      "mydriver",   false},
        {"traversal rejected",      "copilot", "../bad.js",  true},
        {"empty segment rejected",  "copilot", "a//b.js",    true},
    }
    // build a minimal *Compiler and call c.validateEngineDriver for each case
}

@copilot please address this.

// TestValidateEngineScriptFilename tests the validateEngineScriptFilename helper directly.
// The function validates that a script name is a safe Node.js basename (no paths, safe chars,
// correct extension). It is also exercised indirectly by TestValidateEngineHarnessScript.
func TestValidateEngineScriptFilename_ValidInputs(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] validateInlineEngineDriver and validateEngineHarnessScript also moved to this file but remain untested directly — only the harness script test was previously in engine_validation_test.go indirectly. The split is a good opportunity to add direct tests for inline-driver edge cases (empty source, unsupported runtime, wrong engine ID).

@copilot please address this.

func (c *Compiler) validateEngineInlineDefinition(config *EngineConfig) error {
if !config.IsInlineDefinition {
return nil
}

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] validateEngineInlineDefinition logs runtimeID=%s using config.ID, but config.ID is checked for emptiness two lines later — the log line will print an empty string if config.ID == "". Swap the guard and the log, or defer the log until after the empty check.

@copilot please address this.

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (463 new lines across pkg/workflow/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/48568-split-engine-validation-into-domain-focused-files.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 — it was generated from the PR diff
  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-48568: Split engine_validation.go Into Domain-Focused Files

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., 48568-split-engine-validation-into-domain-focused-files.md for PR #48568).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 · 68.2 AIC · ⌖ 12.8 AIC · ⊞ 8.5K ·
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.

APPROVE — clean, verified refactor

Build passes (go build ./...), the extraction is behavior-preserving (function bodies moved verbatim, imports correctly split, no leftover/duplicate declarations), and no new blocking issues were found beyond what existing bot review comments already flag.

💡 Review notes
  • Verified validateEngineScriptFilename, validateEngineHarnessScript, validateEngineDriver, validateInlineEngineDriver moved byte-for-byte into engine_driver_validation.go with correct import adjustments (added path/filepath, regexp; removed from engine_validation.go).
  • Verified validateEngineInlineDefinition, registerInlineEngineDefinition, validateEngineAuthDefinition moved into engine_inline_definition_validation.go; the new engineInlineDefinitionLog logger (workflow:engine_inline_definition_validation) replaces engineValidationLog consistently in all six call sites, and no test asserts the old prefix string, so this rename is safe.
  • go build ./... succeeds with no compile errors from the split (no duplicate declarations, no import cycles).
  • Two pre-existing bot review comments already cover the two real (non-blocking) issues found independently by my own pass and by a grumpy sub-agent review: (1) stale ~155 lines doc count for engine_driver_validation.go (actual: 171 lines) in scratchpad/validation-architecture.md, and (2) TestValidateEngineHarnessScript / TestValidateEngineCopilotSDKDriver_Copilot still live in engine_validation_test.go instead of being colocated with the new engine_driver_validation_test.go. Both are minor maintainability nits, not correctness bugs — no new comments added to avoid duplicating existing feedback.

🔎 Code quality review by PR Code Quality Reviewer · sonnet50 · 67 AIC · ⌖ 4.35 AIC · ⊞ 7.4K
Comment /review to run again

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

…n_test.go; fix doc line count

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Done in 2a556ff. Both review threads addressed:

  1. Updated engine_driver_validation.go size in validation-architecture.md from ~155 to ~171 lines.
  2. Moved TestValidateEngineHarnessScript and TestValidateEngineCopilotSDKDriver_Copilot from engine_validation_test.go into engine_driver_validation_test.go, colocating all driver-domain tests with their implementation file. All unit tests pass locally.

@pelikhan
pelikhan merged commit d1f49ec into main Jul 28, 2026
28 checks passed
@pelikhan
pelikhan deleted the copilot/hippo-split-oversized-validator branch July 28, 2026 12:03
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.

[hippo] [Code Quality] Split an oversized validator in pkg/workflow or pkg/cli

3 participants