Skip to content

Consolidate 13 hand-rolled sync.Once+error caches onto syncutil.OnceLoader - #50934

Merged
pelikhan merged 4 commits into
mainfrom
copilot/refactor-consolidate-sync-once-caches
Aug 7, 2026
Merged

Consolidate 13 hand-rolled sync.Once+error caches onto syncutil.OnceLoader#50934
pelikhan merged 4 commits into
mainfrom
copilot/refactor-consolidate-sync-once-caches

Conversation

Copilot AI commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

pkg/syncutil.OnceLoader[T] already implements the sync.Once + cached-value + cached-error contract, but 13 call sites across pkg/parser and pkg/workflow hand-rolled the same pattern independently — each a separate chance to get the mutex/visibility semantics wrong, and none with OnceLoader's test-friendly Reset()/Override() escape hatches.

Changes

  • pkg/parser/schema_compiler.go: main workflow, MCP config, repo config, and AW manifest schema loaders, plus the two parsed-schema-doc caches (6 sites → 6 OnceLoader fields)
  • pkg/parser/schema_deprecation.go: shallow and deep deprecated-fields caches
  • pkg/workflow/schema_validation.go / awf_config.go: GitHub Actions schema and AWF config schema loaders
  • pkg/workflow/samples_validation.go: compiled tool schemas + sorted safe-output field names
  • pkg/workflow/imports.go: safe output type keys
  • pkg/workflow/model_aliases.go: builtin model aliases, plus the builtin-only alias map identity cache (retains its unsafe-derived pointer for map identity comparison, now hardened to reset on load failure so a panic-recover retry can't be stuck with a stale/zeroed pointer)

No functional or behavioral change — each site preserves its original cache-the-error semantics.

Every site collapses from 3 package-level vars (*Once, cached value, cached error) to one:

// before
var (
	compiledSchemaOnce sync.Once
	compiledSchema     *jsonschema.Schema
	schemaCompileError error
)

func getCompiledSchema() (*jsonschema.Schema, error) {
	compiledSchemaOnce.Do(func() {
		compiledSchema, schemaCompileError = compileSchema(...)
	})
	return compiledSchema, schemaCompileError
}

// after
var compiledSchemaLoader syncutil.OnceLoader[*jsonschema.Schema]

func getCompiledSchema() (*jsonschema.Schema, error) {
	return compiledSchemaLoader.Get(func() (*jsonschema.Schema, error) {
		return compileSchema(...)
	})
}

Copilot AI and others added 2 commits August 6, 2026 23:38
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor to consolidate sync.Once+error caches onto syncutil.OnceLoader Consolidate 13 hand-rolled sync.Once+error caches onto syncutil.OnceLoader Aug 6, 2026
Copilot AI requested a review from pelikhan August 6, 2026 23:45
@pelikhan
pelikhan marked this pull request as ready for review August 6, 2026 23:53
Copilot AI balanced review requested due to automatic review settings August 6, 2026 23:53

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

Consolidates schema and metadata caches onto syncutil.OnceLoader, reducing duplicated synchronization logic.

Changes:

  • Migrates parser schema and deprecation caches.
  • Migrates workflow schema, tool, output, and alias caches.
  • Adds retry handling for the builtin-only alias map.
Show a summary per file
File Description
pkg/parser/schema_compiler.go Migrates six schema caches.
pkg/parser/schema_deprecation.go Migrates deprecated-field caches.
pkg/workflow/schema_validation.go Migrates GitHub Actions schema caching.
pkg/workflow/awf_config.go Migrates AWF schema caching.
pkg/workflow/samples_validation.go Migrates tool and sorted-name caches.
pkg/workflow/imports.go Migrates safe-output key caching.
pkg/workflow/model_aliases.go Migrates model-alias caches and recovery handling.

Review details

Tip

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

  • Files reviewed: 7/7 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread pkg/workflow/model_aliases.go Outdated
Comment on lines +94 to +98
if err != nil {
// Don't permanently cache the failure: leave the loader ready to retry
// (and builtinOnlyAliasMapID at its zero value) so a caller that recovers
// from this panic doesn't get stuck with a stale, un-set identity pointer.
builtinOnlyAliasMapLoader.Reset()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 716c1b2: restored getBuiltinOnlyAliasMap to the infallible sync.Once cache pattern (builtinOnlyAliasMapOnce + shared map/id), removing the OnceLoader retry/reset behavior from this excluded site.

Comment thread pkg/workflow/samples_validation.go Outdated
Comment on lines 169 to 171
names, _ := sortedSafeOutputFieldNamesLoader.Get(func() ([]string, error) {
return sliceutil.SortedKeys(safeOutputFieldMapping), nil
})

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 716c1b2: restored the sorted safe-output field-name cache to infallible sync.Once (sortedSafeOutputFieldNamesOnce) so this site is no longer using OnceLoader and stays out of the 13 error-caching scope.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Test Quality Sentinel. Review the logs for details.

No test files were added or modified in this PR. PR #50934 only modifies production code files (7 Go source files in pkg/parser/ and pkg/workflow/). Test Quality Sentinel found no behavioral tests to analyze.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Design Decision Gate 🏗️. Review the logs for details.

No ADR enforcement needed: PR does not have the implementation label and has 82 new lines of code in business logic directories (threshold is 100).

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Matt Pocock Skills Reviewer. Review the logs for details.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during 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.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

PR #50934: "Consolidate 13 hand-rolled sync.Once+error caches onto syncutil.OnceLoader"

Analysis Result

No test files were added or modified in this PR.

This refactoring consolidates 13 hand-rolled sync.Once + error cache patterns across multiple files in pkg/parser/ and pkg/workflow/ into a centralized syncutil.OnceLoader utility.

Files changed (production code only):

  • pkg/parser/schema_compiler.go (23 +, 40 −)
  • pkg/parser/schema_deprecation.go (10 +, 23 −)
  • pkg/workflow/awf_config.go (6 +, 10 −)
  • pkg/workflow/imports.go (4 +, 9 −)
  • pkg/workflow/model_aliases.go (20 +, 20 −)
  • pkg/workflow/samples_validation.go (12 +, 21 −)
  • pkg/workflow/schema_validation.go (7 +, 12 −)

Test files changed: 0

Test Coverage Assessment

Since no behavioral tests were added or modified, existing test suites will validate this refactoring through integration and regression coverage. The consolidation maintains API compatibility and behavioral equivalence with the original scattered caches.

Score: N/A — No behavioral tests to analyze

Recommendation: ✅ No test quality issues identified. Proceed with existing test coverage validation during CI.

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 13 AIC · ⊞ 7.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: No test files added or modified. This refactoring PR modifies only production code files (7 Go files consolidating cache patterns). Existing test suites will validate behavioral equivalence during CI.

@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: Consolidate 13 hand-rolled sync.Once+error caches onto syncutil.OnceLoader

Clean, mechanical refactoring with consistent application across 7 files.

Observations

Correctness
All converted sites faithfully preserve cache-the-error semantics. OnceLoader.Get holds the mutex for the full loader execution, maintaining the single-invocation guarantee.

builtinOnlyAliasMapID visibility ⚠️
Line 91 in model_aliases.go sets builtinOnlyAliasMapID = mapHeaderPointer(data) inside the loader closure (under OnceLoader's mutex), but isBuiltinOnlyAliasMap reads it without any lock. The same exposure existed with sync.Once — worth verifying with go test -race that no new race is introduced by the reset-on-panic path.

Infallible sites wrapped in OnceLoader (existing review comment at samples_validation.go:171)
Minor: the sorted-field-names cache discards a synthesized nil error. Not blocking.

No security concerns introduced.

Verdict

No blocking issues. The PR achieves its stated goal cleanly and reduces the error-prone boilerplate surface area significantly.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 43.6 AIC · ⊞ 5.4K

@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 — requesting one change for a data-safety issue surfaced by the new Reset() path.

📋 Key Themes & Highlights

Key Themes

  • Data race introduced by Reset(): builtinOnlyAliasMapID is a plain uintptr written under builtinOnlyAliasMapLoader’s internal mutex but read bare in isBuiltinOnlyAliasMap. The original sync.Once guaranteed a single write, so unsynchronized readers were safe. OnceLoader.Reset() breaks that guarantee — a concurrent Reset + retry cycle races against readers of the ID. Fix: atomic.Uintptr.

Positive Highlights

  • ✅ Clean, consistent mechanical substitution across 7 files — the pattern is easy to audit
  • OnceLoader.Get is simpler and harder to misuse than the three-variable hand-roll
  • ✅ Error-caching semantics are preserved identically at all 13 sites
  • awf_config.go and schema_validation.go refactors are textbook-clean
  • ✅ The sortedSafeOutputFieldNamesLoader infallible closure is a pragmatic choice given SortedKeys cannot fail

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

Comments that could not be inline-anchored

pkg/workflow/model_aliases.go:112

[/codebase-design] Data race: builtinOnlyAliasMapID is written inside builtinOnlyAliasMapLoader.Get’s mutex (line 91) but read in isBuiltinOnlyAliasMap without any synchronization — and Reset() makes re-runs of the loader possible, turning this into an observable race under the Go memory model.

<details>
<summary>💡 Suggested fix</summary>

Replace the bare uintptr field with atomic.Uintptr:

builtinOnlyAliasMapID atomic.Uintptr // replaces plain uintptr

Then use `at…

@pelikhan

pelikhan commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

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

Copilot AI commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Done. I ran the PR finisher pass and pushed 716c1b2, restoring the two infallible caches to sync.Once while keeping the 13 sync.Once+error cache migrations on OnceLoader.

@pelikhan
pelikhan merged commit b09ccf4 into main Aug 7, 2026
27 checks passed
@pelikhan
pelikhan deleted the copilot/refactor-consolidate-sync-once-caches branch August 7, 2026 01:20
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.86.0

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.

[refactor] Consolidate 13 hand-rolled sync.Once+error caches onto syncutil.OnceLoader

3 participants