Skip to content

Add codemods to auto-remove deprecated sandbox.mcp.* and sandbox.agent: false keys#29483

Merged
pelikhan merged 4 commits intomainfrom
copilot/aw-compat-remove-deprecated-keys
May 1, 2026
Merged

Add codemods to auto-remove deprecated sandbox.mcp.* and sandbox.agent: false keys#29483
pelikhan merged 4 commits intomainfrom
copilot/aw-compat-remove-deprecated-keys

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 1, 2026

Three deprecated sandbox keys—sandbox.mcp.container, sandbox.mcp.version, and sandbox.agent: false—are now rejected in strict mode but gh aw fix couldn't remove them automatically, requiring manual edits across 28+ files in official repos.

New codemods

  • sandbox-mcp-container-removal — removes sandbox.mcp.container; the MCP gateway container is now managed internally
  • sandbox-mcp-version-removal — removes sandbox.mcp.version; same rationale
  • sandbox-agent-false-removal — removes sandbox.agent: false only when the value is boolean false; disabling the agent sandbox firewall is no longer permitted in strict mode

All three codemods are registered in GetAllCodemods() and run as part of gh aw fix --write. They are skipped when the workflow has strict: false in its frontmatter, since that explicitly opts out of strict mode and the deprecated keys remain valid in that context.

Example

Before:

sandbox:
  agent: false
  mcp:
    container: github/gh-aw-mcpg
    version: v0.0.12
    port: 8080

After gh aw fix --write:

sandbox:
  mcp:
    port: 8080

Other mcp: sub-keys (e.g. port, api-key) and non-false agent values are left untouched. Workflows with strict: false are left entirely unchanged.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

Hey @copilot 👋 — great start picking up the sandbox.mcp.* deprecation issue! The PR is correctly scoped and well-described, and it's good to see the issue context captured in the body.

A few things to address before this is ready for review:

  • No changes yet — the diff is currently empty (0 additions, 0 deletions). The codemods to remove sandbox.mcp.container, sandbox.mcp.version, and sandbox.agent: false from the three affected repos still need to be implemented.
  • Add tests — once the codemods land, tests verifying that those keys are rejected (and that gh aw fix or the new codemod handles them) would strengthen confidence in the fix.

When you're ready to implement, here's a prompt to continue:

Implement codemods to remove the following deprecated sandbox keys from the three affected repositories:

1. Remove `sandbox.mcp.container` from all workflow files in `github/gh-aw-mcpg` (8+ files).
2. Remove `sandbox.mcp.version` from all workflow files in `github/gh-aw-firewall` (4 files).
3. Remove `sandbox.agent: false` from all workflow files in `githubnext/gh-aw-test` (16 files).

For each repo:
- Identify all YAML workflow files containing the deprecated key.
- Remove the key (and its parent block if it becomes empty after removal).
- Ensure the resulting YAML is valid and passes strict-mode compilation.

Also add or update tests that assert these keys are flagged and removed correctly by the fix tooling.

Generated by Contribution Check · ● 1M ·

…version, and sandbox.agent: false keys

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2bfe937f-6c94-4adb-99af-e9bf1e4018c7

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix deprecated sandbox.mcp.* keys in 3 official repos Add codemods to auto-remove deprecated sandbox.mcp.* and sandbox.agent: false keys May 1, 2026
Copilot AI requested a review from pelikhan May 1, 2026 10:01
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented May 1, 2026

@copilot these codemods are only enabled if the script does not have strict: false

@pelikhan pelikhan marked this pull request as ready for review May 1, 2026 10:02
Copilot AI review requested due to automatic review settings May 1, 2026 10:02
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🧪 Test Quality Sentinel Report

Test Quality Score: 67/100

⚠️ Acceptable, with suggestions

Metric Value
New/modified tests analyzed 20
✅ Design tests (behavioral contracts) 17 (85%)
⚠️ Implementation tests (low value) 3 (15%)
Tests with error/edge cases 15 (75%)
Duplicate test clusters 0
Test inflation detected ✅ Yes — both new test files exceed 2:1 ratio
🚨 Coding-guideline violations ⚠️ Missing assertion messages on most assertions

Test Classification Details

View all 20 test classifications
Test File Classification Issues Detected
TestGetSandboxAgentFalseRemovalCodemod codemod_sandbox_agent_false_removal_test.go:13 ⚠️ Implementation Checks struct metadata fields only; no behavioral assertion
TestSandboxAgentFalseRemoval_RemovesAgentFalse codemod_sandbox_agent_false_removal_test.go:20 ✅ Design Verifies key removal behavior; missing assertion messages
TestSandboxAgentFalseRemoval_PreservesOtherSandboxKeys codemod_sandbox_agent_false_removal_test.go:55 ✅ Design Verifies sibling key preservation; missing assertion messages
TestSandboxAgentFalseRemoval_NoSandboxKey codemod_sandbox_agent_false_removal_test.go:96 ✅ Design Edge: no sandbox → no-op contract
TestSandboxAgentFalseRemoval_AgentNotFalse codemod_sandbox_agent_false_removal_test.go:122 ✅ Design Edge: agent is string → no-op contract
TestSandboxAgentFalseRemoval_AgentObject codemod_sandbox_agent_false_removal_test.go:150 ✅ Design Edge: agent is object → no-op contract
TestSandboxAgentFalseRemoval_AgentTrue codemod_sandbox_agent_false_removal_test.go:179 ✅ Design Edge: agent=true → no-op contract
TestSandboxAgentFalseRemoval_PreservesMarkdown codemod_sandbox_agent_false_removal_test.go:205 ✅ Design Verifies markdown body is unchanged after transform
TestSandboxAgentFalseRemoval_NoAgentKey codemod_sandbox_agent_false_removal_test.go:224 ✅ Design Edge: no agent key → no-op contract
TestGetSandboxMCPContainerRemovalCodemod codemod_sandbox_mcp_internal_test.go:14 ⚠️ Implementation Checks struct metadata fields only
TestSandboxMCPContainerRemoval_RemovesContainer codemod_sandbox_mcp_internal_test.go:22 ✅ Design Verifies container key removal, sibling preservation
TestSandboxMCPContainerRemoval_NoSandboxKey codemod_sandbox_mcp_internal_test.go:65 ✅ Design Edge: no sandbox → no-op
TestSandboxMCPContainerRemoval_NoMCPKey codemod_sandbox_mcp_internal_test.go:91 ✅ Design Edge: no mcp key → no-op
TestSandboxMCPContainerRemoval_NoContainerField codemod_sandbox_mcp_internal_test.go:118 ✅ Design Edge: no container field → no-op
TestSandboxMCPContainerRemoval_PreservesMarkdown codemod_sandbox_mcp_internal_test.go:145 ✅ Design Verifies markdown body preserved
TestGetSandboxMCPVersionRemovalCodemod codemod_sandbox_mcp_internal_test.go:181 ⚠️ Implementation Checks struct metadata fields only
TestSandboxMCPVersionRemoval_RemovesVersion codemod_sandbox_mcp_internal_test.go:189 ✅ Design Verifies version key removal
TestSandboxMCPVersionRemoval_NoVersionField codemod_sandbox_mcp_internal_test.go:232 ✅ Design Edge: no version field → no-op
TestSandboxMCPVersionRemoval_NoSandboxKey codemod_sandbox_mcp_internal_test.go:258 ✅ Design Edge: no sandbox → no-op
TestSandboxMCPVersionRemoval_BothContainerAndVersion codemod_sandbox_mcp_internal_test.go:278 ✅ Design Verifies version-only removal doesn't disturb container

Flagged Tests — Requires Review

⚠️ TestGetSandboxAgentFalseRemovalCodemod, TestGetSandboxMCPContainerRemovalCodemod, TestGetSandboxMCPVersionRemovalCodemod

Classification: Implementation tests
Issue: These tests only assert that struct fields (ID, Name, Description, IntroducedIn) match hardcoded string literals and that Apply is non-nil. They do not verify any behavioral output.
What design invariant does this test enforce? The codemod is registered with the correct metadata — useful for detecting accidental renames or copy-paste errors.
What would break if deleted? Only a metadata rename would be missed; any behavioral regression in the Apply function would not be caught by these tests alone.
Suggested improvement: These tests have some value as registration checks. Consider folding them into a table-driven metadata test to reduce the three near-identical test bodies into one.

⚠️ Missing assertion messages (non-blocking guideline)

Files: All three test files
Issue: The project guideline requires a descriptive message on every testify assertion (e.g., assert.Equal(t, expected, actual, "context")). Nearly all assertions in the new files are bare two-argument calls such as assert.True(t, applied) or assert.NotContains(t, result, "agent: false") — omitting the message argument.
Impact: Low; test names are descriptive enough to identify failures. But on assertion failure the output won't include context, making CI logs harder to read.
Suggested improvement: Add short inline messages to each assertion, e.g.:

assert.True(t, applied, "codemod should report applied=true when agent: false is present")
assert.NotContains(t, result, "agent: false", "deprecated key should be removed from output")

⚠️ Test inflation (non-blocking)

Test file Test lines Prod lines Ratio
codemod_sandbox_agent_false_removal_test.go 242 49 4.9:1
codemod_sandbox_mcp_internal_test.go 301 75 4.0:1

Both exceed the 2:1 threshold. This is largely unavoidable here — each test case embeds a full YAML frontmatter fixture and a corresponding map[string]any. This is not a sign of low-quality tests; the high ratio reflects the verbosity of the test data, not redundant code.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 20 tests — all unit (//go:build !integration) ✅
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests changed in this PR

Verdict

Check passed. 15% of new tests are implementation tests (threshold: 30%). The behavioral coverage is strong — 17 of 20 new tests verify observable codemod outputs across a thorough set of input scenarios including no-op paths, partial key presence, type variants, and markdown body preservation. The flagged items (metadata-only tests, missing assertion messages, test inflation) are non-blocking suggestions.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §25210508657

🧪 Test quality analysis by Test Quality Sentinel · ● 577K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 67/100. Test quality is acceptable — 15% of new tests are implementation tests (threshold: 30%). See comment for detailed analysis and non-blocking improvement suggestions.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds new gh aw fix codemods to automatically remove deprecated sandbox configuration keys that are now rejected in strict mode.

Changes:

  • Register 3 new codemods in GetAllCodemods() for removing sandbox.mcp.container, sandbox.mcp.version, and sandbox.agent: false.
  • Add implementations for sandbox MCP container/version removal and sandbox agent false removal.
  • Extend codemod registry tests and add new unit tests for the new codemods.
Show a summary per file
File Description
pkg/cli/fix_codemods_test.go Updates codemod registry count and expected ordering to include the new codemods.
pkg/cli/fix_codemods.go Registers the new sandbox-related codemods in the global codemod list.
pkg/cli/codemod_sandbox_mcp_internal.go Implements codemods intended to remove deprecated sandbox.mcp.container and sandbox.mcp.version.
pkg/cli/codemod_sandbox_mcp_internal_test.go Adds unit tests covering the sandbox MCP codemods’ expected behavior.
pkg/cli/codemod_sandbox_agent_false_removal.go Implements codemod to remove deprecated sandbox.agent: false (boolean false only).
pkg/cli/codemod_sandbox_agent_false_removal_test.go Adds unit tests for the sandbox agent false removal codemod.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (1)

pkg/cli/codemod_sandbox_mcp_internal.go:46

  • Same issue as the container codemod: removeFieldFromBlock(lines, "version", "mcp") is not scoped to sandbox.mcp and can remove version: from unrelated mcp: blocks (e.g. tools.<tool>.mcp). Please scope the removal to the sandbox: -> mcp: block only.
		Apply: func(content string, frontmatter map[string]any) (string, bool, error) {
			if !hasSandboxMCPField(frontmatter, "version") {
				return content, false, nil
			}
			newContent, applied, err := applyFrontmatterLineTransform(content, func(lines []string) ([]string, bool) {
				return removeFieldFromBlock(lines, "version", "mcp")
			})
  • Files reviewed: 6/6 changed files
  • Comments generated: 2

Comment on lines +16 to +22
Apply: func(content string, frontmatter map[string]any) (string, bool, error) {
if !hasSandboxMCPField(frontmatter, "container") {
return content, false, nil
}
newContent, applied, err := applyFrontmatterLineTransform(content, func(lines []string) ([]string, bool) {
return removeFieldFromBlock(lines, "container", "mcp")
})
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

removeFieldFromBlock(lines, "container", "mcp") matches any mcp: block in the frontmatter, not specifically sandbox.mcp. Workflows can contain other mcp: sections (e.g. under tools.<id>.mcp, which can include a container key per mcp_add.go), so this codemod can inadvertently delete tool configuration.

Scope the line transform to sandbox: -> mcp: (two-level nesting) before removing container (similar to removeFieldFromPlaywright), or implement a generic helper to remove a field from a nested path like ["sandbox","mcp"].

This issue also appears on line 40 of the same file.

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +33
func TestSandboxMCPContainerRemoval_RemovesContainer(t *testing.T) {
codemod := getSandboxMCPContainerRemovalCodemod()

content := `---
on: workflow_dispatch
sandbox:
mcp:
container: ghcr.io/example/gateway
port: 8080
permissions:
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

The tests for the sandbox.mcp container/version removals don't cover workflows that also have tools.<tool>.mcp blocks (which can include container per pkg/cli/mcp_add.go). Given the current implementation operates on raw lines, add a regression test ensuring the codemod only removes sandbox.mcp.container/sandbox.mcp.version and does not touch tools.*.mcp.container or other tool MCP settings.

Copilot uses AI. Check for mistakes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

Commit pushed: 6278e0f

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🏗️ Design Decision Gate — ADR Required

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

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/29483-automate-removal-of-deprecated-sandbox-keys-via-codemods.md

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-29483: Automate Removal of Deprecated Sandbox Keys via Codemods

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., 29483-automate-removal-of-deprecated-sandbox-keys-via-codemods.md for PR #29483).

🔒 This PR cannot merge until an ADR is linked in the PR body.

References: §25210508659

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 157.5K ·

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 1, 2026

@copilot these codemods are only enabled if the script does not have strict: false

Done in 8384677. Added isFrontmatterStrictFalse helper and early-return guards in all three Apply functions — they now skip without modification when strict: false is present in the frontmatter.

@pelikhan pelikhan merged commit 7866582 into main May 1, 2026
@pelikhan pelikhan deleted the copilot/aw-compat-remove-deprecated-keys branch May 1, 2026 10:13
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.

[aw-compat] Deprecated sandbox.mcp.* keys in 3 official repos not auto-fixed by gh aw fix

3 participants