Skip to content

Stabilize smoke-copilot-auto lock output by skipping dynamic auto pricing injection - #48516

Merged
pelikhan merged 3 commits into
mainfrom
copilot/review-smoke-copilot-auto-lock-change
Jul 28, 2026
Merged

Stabilize smoke-copilot-auto lock output by skipping dynamic auto pricing injection#48516
pelikhan merged 3 commits into
mainfrom
copilot/review-smoke-copilot-auto-lock-change

Conversation

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

smoke-copilot-auto.lock.yml was drifting across builds even when source workflow content did not change. Root cause was compile-time pricing resolution treating model: auto as a concrete model and embedding external models.dev pricing into GH_AW_INFO_MODEL_COSTS.

  • Root cause containment

    • Treat dynamic aliases as non-resolvable for compile-time pricing injection.
    • auto no longer participates in external pricing lookup, preventing lock mutations from catalog-side changes.
  • Compiler behavior change

    • Added a guard in model/provider normalization to short-circuit pricing resolution for dynamic aliases.
    • This keeps compile output deterministic when workflows use model: auto.
  • Coverage updates

    • Added targeted unit tests to ensure resolver is not invoked for:
      • auto
      • github_models/auto
  • Generated artifact impact

    • Recompiled smoke-copilot-auto.lock.yml; removed injected GH_AW_INFO_MODEL_COSTS overlay for the dynamic alias path.
if isDynamicModelAliasForPricing(model) {
	compilerModelPricingLog.Printf("Skipping external pricing lookup for dynamic model alias %q", model)
	return "", "", false
}

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Prevent smoke-copilot-auto lock drift from dynamic auto model pricing Stabilize smoke-copilot-auto lock output by skipping dynamic auto pricing injection Jul 28, 2026
Copilot AI requested a review from pelikhan July 28, 2026 04:02
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot remove dynamic pricing lookup all together

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

Copilot AI commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot remove dynamic pricing lookup all together

Done in 8ef6074. Compile-time models.dev pricing lookup has been removed entirely (wiring + CLI flag/tests/docs updates), so compile output no longer depends on external dynamic pricing fetches.

@pelikhan
pelikhan marked this pull request as ready for review July 28, 2026 06:30
Copilot AI review requested due to automatic review settings July 28, 2026 06:30
@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

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

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

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

Stabilizes model: auto compilation, but also broadly removes external pricing resolution and its CLI control.

Changes:

  • Skips pricing lookup for auto aliases and adds tests.
  • Removes models.dev resolver registration and --no-models-dev-lookup.
  • Recompiles the Copilot auto smoke-test lock file.
Show a summary per file
File Description
pkg/workflow/compiler_model_pricing.go Adds dynamic alias guard.
pkg/workflow/compiler_model_pricing_test.go Tests auto alias handling.
pkg/cli/model_costs.go Removes external pricing resolver.
pkg/cli/model_costs_test.go Removes resolver coverage.
pkg/cli/compile_config.go Removes lookup configuration.
pkg/cli/compile_compiler_setup.go Stops registering the resolver.
pkg/cli/compile_compiler_setup_test.go Expects no default resolver.
pkg/cli/cli_consistency_help_test.go Expects the removed flag to be undocumented.
docs/src/content/docs/setup/cli.md Removes the flag from CLI documentation.
cmd/gh-aw/main.go Removes flag registration and plumbing.
cmd/gh-aw/compile_flags_test.go Removes flag coverage.
.github/workflows/smoke-copilot-auto.lock.yml Removes dynamic pricing overlay.

Review details

Tip

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

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

compiler := createAndConfigureCompiler(CompileConfig{DisableModelsDevLookup: true})
if hasModelPricingResolver(compiler) {
t.Fatal("expected model pricing resolver to be nil when models.dev lookup is disabled")
t.Fatal("expected model pricing resolver to be nil by default")

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.

This was a deliberate change per the explicit user request to "remove dynamic pricing lookup all together." Removing the resolver entirely — not just skipping it for auto — was the stated goal. Concrete models that are missing from the embedded catalog will fall back to the embedded data only, which is the intended deterministic behavior.


compileSection := text[compileIndex:]
assert.Contains(t, compileSection, "`--no-models-dev-lookup`", "compile docs options should include --no-models-dev-lookup")
assert.NotContains(t, compileSection, "`--no-models-dev-lookup`", "compile docs options should not include removed --no-models-dev-lookup")

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.

The --no-models-dev-lookup flag controlled the now-removed models.dev pricing resolver. With the resolver gone, the flag has no associated functionality and was removed intentionally. Any scripts using it would have had no effect after the resolver was removed, so removing the flag keeps the CLI surface clean and avoids a dead option.

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

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

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

@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: Stabilize smoke-copilot-auto lock output

The approach is sound — removing the external pricing resolver entirely is a simpler and more robust fix than the isDynamicModelAliasForPricing guard alone, because it eliminates the whole class of catalog-drift mutations.

One inline note:

  • TestCreateAndConfigureCompiler_RegistersModelPricingResolverByDefault now asserts the resolver is nil, which is the opposite of its name — flagged inline.

Observation (non-blocking): The isDynamicModelAliasForPricing guard added in compiler_model_pricing.go is now dead code — no resolver is ever set via SetModelPricingResolver, so resolveProviderAndModelForPricing is never called with a live resolver. The guard and new tests are still good documentation of intent, but consider a comment noting the guard is a forward-compat safeguard in case a resolver is re-introduced later, so it is not confused for active protection.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 17.1 AIC · ⌖ 4.65 AIC · ⊞ 5K


func TestCreateAndConfigureCompiler_SkipsModelPricingResolverWhenDisabled(t *testing.T) {
compiler := createAndConfigureCompiler(CompileConfig{DisableModelsDevLookup: true})
if hasModelPricingResolver(compiler) {

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.

The test name TestCreateAndConfigureCompiler_RegistersModelPricingResolverByDefault now asserts the opposite of what it says — the test checks that the resolver is nil. Please rename to something like TestCreateAndConfigureCompiler_HasNoModelPricingResolverByDefault to avoid misleading future readers.

@copilot please address this.

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.

Renamed to TestCreateAndConfigureCompiler_DoesNotRegisterModelPricingResolverByDefault in the latest commit.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 100/100 — Excellent

Analyzed 1 new behavioral test + 3 modified tests (2 deleted as stale): 1 design, 0 implementation, 0 violation(s).

📊 Metrics (1 new + 3 modified tests)
Metric Value
Analyzed 4 (Go: 4, JS: 0)
✅ Design 1 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 1 (100%)
Duplicate clusters 0
Inflation No
🚨 Violations 0
Test File Classification Issues
TestResolveModelPricingIfMissing_SkipsDynamicAutoModelAlias pkg/workflow/compiler_model_pricing_test.go:265 design_test / behavioral_contract / high_value None
TestCompileCommandShortFlags (modified) cmd/gh-aw/compile_flags_test.go design_test / cleanup Removes stale flag assertion
TestCompileDocsReflectCurrentOptions (renamed+modified) pkg/cli/cli_consistency_help_test.go design_test / behavioral_contract Correctly flips to NotContains for removed flag
TestCreateAndConfigureCompiler_RegistersModelPricingResolverByDefault (modified) pkg/cli/compile_compiler_setup_test.go design_test / behavioral_contract Reflects new default behavior

Verdict

passed. 0% implementation tests (threshold: 30%). The new test covers two auto-alias edge cases (auto and github_models/auto) with clear behavioral assertions. Stale tests removed cleanly track the feature deletion.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 40.9 AIC · ⌖ 12.8 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.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — approving with one minor naming fix requested.

📋 Key Themes & Highlights

Findings

  • Test name inversion (compile_compiler_setup_test.go:18): RegistersModelPricingResolverByDefault now asserts the resolver is nil — the name contradicts the assertion. Low risk, but misleading for future regression diagnosis.

Positive Highlights

  • ✅ Root cause properly addressed at the right abstraction layer (resolveProviderAndModelForPricing)
  • isDynamicModelAliasForPricing is a clean, well-named predicate — easy to extend for future aliases
  • ✅ Both "auto" and "github_models/auto" are tested in a single focused test
  • ✅ Full cleanup of the --no-models-dev-lookup flag, dead resolver registration, and FindOrFetchModelPricing — no orphaned code left behind
  • ✅ Lock file diff confirms the fix works as intended

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

Comment thread pkg/cli/compile_compiler_setup_test.go Outdated
@@ -17,15 +17,8 @@ func hasModelPricingResolver(compiler *workflow.Compiler) bool {

func TestCreateAndConfigureCompiler_RegistersModelPricingResolverByDefault(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.

[/diagnosing-bugs] Test name RegistersModelPricingResolverByDefault is now misleading — the body asserts hasModelPricingResolver is false, which is the opposite of what the name implies.

💡 Suggested rename
func TestCreateAndConfigureCompiler_DoesNotRegisterModelPricingResolverByDefault(t *testing.T) {

A misleading name will confuse future readers and slow down regression diagnosis.

@copilot please address this.

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.

Renamed to TestCreateAndConfigureCompiler_DoesNotRegisterModelPricingResolverByDefault in the latest commit.

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

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

REQUEST_CHANGES: scope creep hides a breaking CLI/feature removal behind an "auto" pricing-drift fix

Themes
  • Undisclosed breaking change: the PR description only describes a narrow guard preventing model: auto from participating in compile-time models.dev pricing lookup. The actual diff goes much further, deleting the --no-models-dev-lookup CLI flag, DisableModelsDevLookup config field, and the entire FindOrFetchModelPricing mechanism — a user-facing breaking change with zero mention in the PR body.
  • Overbroad regression: removing the resolver wiring drops cost-accounting pricing injection for all models missing from the embedded catalog, not just auto. The stated bug was already fully fixed by the isDynamicModelAliasForPricing guard added earlier in the same PR.
  • Dead code left behind: resolveModelPricingIfMissing, modelCostsHasPricingFor, the new isDynamicModelAliasForPricing guard, and the exported SetModelPricingResolver/modelPricingResolver field on Compiler are now unreachable in production (only exercised by tests that manually inject a resolver). This is confusing, untested-in-production surface area that should be removed or restored, not left half-finished.
  • Stale docs: pkg/cli/README.md still documents the deleted FindOrFetchModelPricing function.

Recommend either (a) keep the resolver wired for non-auto models and rely on the narrow guard alone to fix the stated drift, or (b) if full removal of external pricing lookup is intentional, call it out explicitly as a breaking change, retitle/re-describe the PR, and clean up the now-dead resolver plumbing and stale docs.

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

Comments that could not be inline-anchored

cmd/gh-aw/main.go:338

This PR silently removes the entire --no-models-dev-lookup CLI flag (and its wiring), well beyond the stated scope of fixing model: auto pricing drift.

<details><summary>💡 Undocumented breaking CLI change</summary>

The PR title/description only describe a narrow guard for the auto alias so it does not participate in compile-time pricing lookup. Instead, the diff deletes --no-models-dev-lookup, DisableModelsDevLookup, and the entire FindOrFetchModelPricing mechanism it controlled …

pkg/cli/model_costs.go:183

Removing FindOrFetchModelPricing regresses cost accounting for all models missing from the embedded catalog, not just model: auto.

<details><summary>💡 Overbroad removal vs. stated fix</summary>

FindOrFetchModelPricing was the only mechanism that injected models.dev-sourced pricing into GH_AW_INFO_MODEL_COSTS for models absent from the embedded actions/setup/js/models.json catalog. Its only caller (compiler.SetModelPricingResolver(FindOrFetchModelPricing) in `pkg/cli/compile…

pkg/workflow/compiler_model_pricing.go:24

resolveModelPricingIfMissing (and the resolver field/setter it depends on) is now dead code in production — no caller ever registers a resolver.

<details><summary>💡 Orphaned pricing-injection path</summary>

Since createAndConfigureCompiler no longer calls compiler.SetModelPricingResolver(...) (that call was deleted in this same PR) and no other production code calls it, c.modelPricingResolver is permanently nil at runtime. This function's nil-check on line 24 always short-circuits,…

pkg/workflow/compiler_model_pricing.go:114

The isDynamicModelAliasForPricing guard added in this same PR is now unreachable, since the pricing resolver it protects is never registered.

<details><summary>💡 Guard added then immediately obsoleted</summary>

This guard (and its call in resolveProviderAndModelForPricing) was introduced specifically to stop model: auto from triggering external models.dev pricing lookup. A later change in the same PR removes the only production wiring that ever invokes the resolver this guard protect…

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

  • Category: bug | Risk: medium | Score: 63/100
  • Impact 30 · Urgency 15 · Quality 18
  • Recommended action: fast_track

Stabilizes nondeterministic lock-file drift for smoke-copilot-auto. CI green (27/27 success), two AI-reviewer approvals. Good expedited-review candidate.

Generated by 🔧 PR Triage Agent · sonnet50 · 50.9 AIC · ⌖ 5.23 AIC · ⊞ 7.5K ·

…sNotRegisterModelPricingResolverByDefault

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. Here's a summary of this pass:

  • Reviews — Renamed TestCreateAndConfigureCompiler_RegistersModelPricingResolverByDefaultTestCreateAndConfigureCompiler_DoesNotRegisterModelPricingResolverByDefault (fixes misleading name flagged by github-actions threads). Replied to all 4 unresolved review threads explaining the rationale for full pricing removal. Thread resolution requires a human due to GraphQL being blocked in the agent environment.
  • Checks (local)make fmt, make test-unit, make recompile all pass.
  • Checks (CI) — Stale after agent push; needs human re-trigger. Prior CI on the previous commit was green (all jobs: success).
  • Mergeable — PR is open, not draft, no conflicts, no BEHIND state.

Actions taken: Renamed misleading test function in pkg/cli/compile_compiler_setup_test.go.
Hand-off: CI must be re-triggered by a maintainer (close/reopen PR or push from a maintainer) before merge. Review threads need manual resolution via the GitHub UI (GraphQL resolve API is blocked in the agent sandbox).

@pelikhan
pelikhan merged commit c71eafd into main Jul 28, 2026
@pelikhan
pelikhan deleted the copilot/review-smoke-copilot-auto-lock-change branch July 28, 2026 07:28
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.

3 participants