Skip to content

Refactor schema compilation to use a single shared helper#42614

Merged
pelikhan merged 2 commits into
mainfrom
copilot/refactor-semantic-function-clustering
Jul 1, 2026
Merged

Refactor schema compilation to use a single shared helper#42614
pelikhan merged 2 commits into
mainfrom
copilot/refactor-semantic-function-clustering

Conversation

Copilot AI commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

This change removes the only real duplicate found by the semantic function clustering sweep: two package-local compileSchema implementations that performed the same JSON Schema compiler setup. The workflow package now reuses the parser package’s shared implementation instead of maintaining a second copy.

  • What changed

    • Exported parser.CompileSchema as the shared JSON Schema compilation helper.
    • Updated pkg/workflow/schema_utils.go to delegate to parser.CompileSchema.
    • Kept the existing parser-local wrapper so current internal call sites remain unchanged.
  • Why this is scoped narrowly

    • No schema behavior changes are introduced.
    • Callers in pkg/workflow continue to use the same local helper shape; only the implementation source changed.
  • Coverage

    • Added a focused parser unit test for the shared compiler helper to validate compile + validate behavior directly.
func compileSchema(schemaJSON, schemaURL string) (*jsonschema.Schema, error) {
	return parser.CompileSchema(schemaJSON, schemaURL)
}

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor semantic function clustering to consolidate duplicate compileSchema Refactor schema compilation to use a single shared helper Jul 1, 2026
Copilot AI requested a review from pelikhan July 1, 2026 02:45
@pelikhan pelikhan marked this pull request as ready for review July 1, 2026 02:52
Copilot AI review requested due to automatic review settings July 1, 2026 02:52

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

This PR refactors JSON Schema compilation to eliminate duplicate compiler setup logic by centralizing it in pkg/parser and reusing it from pkg/workflow, while adding a focused unit test for the shared helper.

Changes:

  • Exported parser.CompileSchema as the shared JSON Schema compilation helper (retaining a package-local wrapper for existing internal call sites).
  • Updated pkg/workflow’s schema helper to delegate compilation to parser.CompileSchema.
  • Added a unit test covering compile + validate behavior for the shared helper.
Show a summary per file
File Description
pkg/workflow/schema_utils.go Replaces the local schema compiler implementation with a delegation to parser.CompileSchema.
pkg/parser/schema_compiler.go Exports CompileSchema and keeps the original compileSchema wrapper for internal callers.
pkg/parser/schema_compiler_test.go Adds a unit test to validate successful compilation and basic validation behavior.

Review details

Tip

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

  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment on lines +147 to +150
// compileSchema preserves existing package-local call sites.
func compileSchema(schemaJSON, schemaURL string) (*jsonschema.Schema, error) {
return CompileSchema(schemaJSON, schemaURL)
}
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

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

No ADR enforcement needed: PR #42614 does not have the 'implementation' label and has only 38 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions github-actions Bot mentioned this pull request Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100 — Excellent

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

📊 Metrics & Test Classification (1 test analyzed)
Metric Value
New/modified tests analyzed 1
✅ Design tests (behavioral contracts) 1 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 1 (100%)
Duplicate test clusters 0
Test inflation detected YES (4.14:1)
🚨 Coding-guideline violations 0
Test File Classification Issues Detected
TestCompileSchema pkg/parser/schema_compiler_test.go:7 ✅ Design Inflation 4.14:1

Go: 1 (*_test.go); JavaScript: 0.

Score breakdown:

  • Design tests component: 40/40 (100%)
  • Edge-case coverage component: 30/30 (100%)
  • Duplicate penalty: 0 deducted (0 clusters)
  • Inflation penalty: −10 (test +29 lines vs prod +7 lines = 4.14:1 > 2:1 threshold)
⚠️ Flagged Tests (1 issue)

TestCompileSchema (pkg/parser/schema_compiler_test.go:7) — Test inflation (4.14:1). The test file adds 29 lines while the corresponding production change is only 7 new lines (exporting an existing function + a thin wrapper). This ratio exceeds the 2:1 threshold. Contextually this is acceptable: the function was previously unexported and untested, so the new coverage is genuinely valuable. No structural changes needed, but be aware of the ratio if the test file grows further.

Verdict

Check passed. 0% implementation tests (threshold: 30%). No coding-guideline violations. The single test TestCompileSchema is a solid behavioral-contract test: it verifies that CompileSchema compiles a valid JSON Schema, accepts conforming data, and rejects non-conforming data (type mismatch). Build tag //go:build !integration is present on line 1, t.Parallel() is used, and all three assertions carry descriptive failure messages. The only flag is test inflation (4.14:1), which is contextually benign since this is a net-new test for a previously untested exported function.

References: §28490188843

Warning

Firewall blocked 1 domain

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

  • awmgmcpg

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

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 51.7 AIC · ⌖ 12.1 AIC · ⊞ 7K ·
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%). No coding-guideline violations. See the detailed report in the comment above.

@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: Refactor schema compilation to use a single shared helper

The refactoring is correct and well-scoped — no import cycles, no logic changes, and the workflow package correctly delegates to the shared parser.CompileSchema. Three non-blocking observations:

Summary of comments
  1. Error message regression (schema_compiler.go line 141): The old workflow.compileSchema included schemaURL in all three error messages, but the new CompileSchema drops it (URL is only logged). This subtly degrades debuggability when a schema fails to compile at runtime.

  2. Unnecessary private wrapper (schema_compiler.go line 149): The new private compileSchema is a one-liner that exists only to avoid updating 4 internal call sites. Updating those call sites to use CompileSchema directly would remove this layer of indirection.

  3. Missing error-path test (schema_compiler_test.go line 29): The test covers the happy path and type validation but not the malformed-JSON error path through CompileSchema.

None of these block merging.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 36.6 AIC · ⌖ 9.92 AIC · ⊞ 4.8K

Comments that could not be inline-anchored

pkg/parser/schema_compiler.go:141

The old workflow.compileSchema included schemaURL in all three error messages (e.g. &quot;failed to parse schema JSON for %s: %w&quot;, schemaURL, err), but CompileSchema drops it from returned errors — the URL is only logged. When multiple schemas are compiled and one fails at runtime, callers lose the URL context in the error chain.

Consider including schemaURL in each error string for easier diagnosis:

return nil, fmt.Errorf(&quot;failed to parse schema JSON for %s: %w&quot;, schemaURL, err)
re</details>

<details><summary>pkg/parser/schema_compiler.go:149</summary>

The private `compileSchema` wrapper is now a one-liner with no extra logicit exists only to avoid updating the 4 internal call sites in this file. The cleaner long-term approach is to replace those call sites with `CompileSchema` directly and remove this wrapper, reducing indirection:

```go
// Before:
compileSchema(mainWorkflowSchema, &quot;(contoso.com/redacted)
// After:
CompileSchema(mainWorkflowSchema, &quot;(contoso.com/redacted)

This is a non-blocking suggestion — the wrapper is not wrong,…

pkg/parser/schema_compiler_test.go:29

The happy path and type-mismatch validation are well covered. Consider adding an error-path case for malformed JSON input to verify the first Unmarshal error is correctly propagated:

_, err = CompileSchema(`{not valid json}`, &quot;(example.com/redacted)
if err == nil {
    t.Fatal(&quot;CompileSchema(bad JSON) returned nil error, want parse failure&quot;)
}

This would ensure the error wrapping in CompileSchema works end-to-end.

@copilot please address this.

@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 — leaving as COMMENT since no blocking issues were found. Three targeted improvements worth addressing.

📋 Key Themes & Highlights

Key Themes

  • Stale doc comment (pkg/workflow/schema_utils.go): The compileSchema wrapper still advertises NewCompiler → AddResource → Compile boilerplate that no longer lives here — misleads readers navigating the codebase.
  • Unnecessary private shim (pkg/parser/schema_compiler.go): The private compileSchema wrapper is a trivial one-liner kept only to avoid touching internal call sites. Updating those call sites directly would make the package cleaner.
  • Missing error-path test (pkg/parser/schema_compiler_test.go): The new test validates happy-path compile and both valid/invalid data inputs, but does not specify what happens when schemaJSON is itself not valid JSON — the error contract is untested.

Positive Highlights

  • ✅ Clean, well-scoped refactor — no behaviour changes, exactly as described
  • ✅ New cross-package dependency direction (workflowparser) is natural and correct
  • ✅ Test uses t.Parallel() and covers both the valid and invalid validation branches
  • ✅ Good use of //go:build !integration to keep the test in the fast suite

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 38.8 AIC · ⌖ 7.82 AIC · ⊞ 6.6K
Comment /matt to run again

}

// compileSchema preserves existing package-local call sites.
func compileSchema(schemaJSON, schemaURL string) (*jsonschema.Schema, error) {

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] The private compileSchema wrapper is a trivial one-liner that adds indirection without benefit — internal callers could call CompileSchema directly.

💡 Suggested alternative

Instead of keeping this private shim, update the existing internal call sites in pkg/parser to call CompileSchema directly and remove the wrapper:

// Before (internal callers)
schema, err := compileSchema(json, url)

// After
schema, err := CompileSchema(json, url)

The shim exists "to preserve existing call sites" per the PR description, but the cost is a dead-end indirection that makes the package harder to navigate. If the goal is to keep the diff small, that is reasonable — but a follow-up to remove it would clean the API surface.

@copilot please address this.

@@ -12,20 +11,5 @@ import (
// It is a shared helper used by all schema-compilation sites in this package to avoid
// repeating the NewCompiler → AddResource → Compile boilerplate.

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] The doc comment still references the concrete boilerplate (NewCompiler → AddResource → Compile) that no longer lives here — it now lives in parser.CompileSchema. A reader of this file will look for that boilerplate and not find it, which creates confusion.

💡 Suggested wording
// compileSchema is a package-local alias that delegates to parser.CompileSchema,
// the shared JSON Schema compilation helper for the entire project.
func compileSchema(schemaJSON, schemaURL string) (*jsonschema.Schema, error) {

Or simply drop the boilerplate description entirely since the body is now self-explanatory.

@copilot please address this.


import "testing"

func TestCompileSchema(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] TestCompileSchema does not exercise the error path when schemaJSON is not valid JSON. The error contract of CompileSchema is unspecified by the test suite — a future refactor could silently change error behaviour.

💡 Suggested addition using subtests

Consider restructuring as table-driven subtests so each scenario is independently reported, and add an error-path case:

func TestCompileSchema(t *testing.T) {
    t.Parallel()

    t.Run("valid schema", func(t *testing.T) {
        t.Parallel()
        schema, err := CompileSchema(`{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"additionalProperties":false}`, "(example.com/redacted)
        if err != nil {
            t.Fatalf("CompileSchema returned error: %v", err)
        }
        if err := schema.Validate(map[string]any{"name": "gh-aw"}); err != nil {
            t.Fatalf("Validate(valid) returned error: %v", err)
        }
        if err := schema.Validate(map[string]any{"name": 1}); err == nil {
            t.Fatal("Validate(invalid) returned nil error, want validation failure")
        }
    })

    t.Run("invalid JSON input", func(t *testing.T) {
        t.Parallel()
        _, err := CompileSchema("not-valid-json", "(example.com/redacted)
        if err == nil {
            t.Fatal("CompileSchema returned nil error for invalid JSON, want error")
        }
    })
}

@copilot please address this.

@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.

🔎 Code quality review by PR Code Quality Reviewer · 57.7 AIC · ⌖ 7.14 AIC · ⊞ 1.6K
Comment /review to run again

}

// compileSchema preserves existing package-local call sites.
func compileSchema(schemaJSON, schemaURL string) (*jsonschema.Schema, error) {

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.

Unnecessary shim creates a two-name problem in the same package — the 5 internal callers (lines 68, 76, 84, 92, 305) could be trivially updated to CompileSchema directly, eliminating this wrapper entirely.

💡 Why this matters

With both compileSchema and CompileSchema in the package, any new internal code must decide which to call — and the unexported name silently 'wins' for internal use since it is the familiar name. This creates ongoing confusion about intent: is there a reason to call the wrapper vs. the real function?

The fix is a 5-line search-replace across this file — replacing compileSchema( with CompileSchema( at the 5 call sites — which is lower-risk and leaves no residual ambiguity. The wrapper can then be deleted entirely.

if err := schema.Validate(map[string]any{"name": 1}); err == nil {
t.Fatal("Validate(invalid) returned nil error, want validation failure")
}
}

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 has zero coverage of CompileSchema's error paths — only the happy path and schema-validation failure are exercised; the JSON unmarshal, AddResource, and Compile error branches are completely untested.

💡 Suggested addition
func TestCompileSchema_InvalidJSON(t *testing.T) {
    t.Parallel()
    _, err := CompileSchema(`{not valid json}`, "(example.com/redacted)
    if err == nil {
        t.Fatal("CompileSchema with malformed JSON should return an error")
    }
}

func TestCompileSchema_InvalidSchema(t *testing.T) {
    t.Parallel()
    // references an undefined  — compile step should fail
    _, err := CompileSchema(`{"": "#/definitions/missing"}`, "(example.com/redacted)
    if err == nil {
        t.Fatal("CompileSchema with unresolvable $ref should return an error")
    }
}

The PR description specifically claims "validate compile + validate behavior directly"; testing only the sunny-day path does not validate the compile error branch, which is exactly the code that just moved between packages and is most likely to have a subtle behavioural gap.

@pelikhan pelikhan merged commit d0c3327 into main Jul 1, 2026
95 checks passed
@pelikhan pelikhan deleted the copilot/refactor-semantic-function-clustering branch July 1, 2026 03:31
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.

[refactor] Semantic function clustering: consolidate duplicate compileSchema; codebase otherwise well-organized

3 participants