Update make release to accept bump type as positional argument#34
Merged
Update make release to accept bump type as positional argument#34
make release to accept bump type as positional argument#34Conversation
…x workflow URL Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Update make release command syntax for version bumps
Update Jan 6, 2026
make release to accept bump type as positional argument
lpcox
pushed a commit
that referenced
this pull request
Jan 8, 2026
* Initial plan * Update make release to accept bump type as positional argument and fix workflow URL Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
pelikhan
added a commit
that referenced
this pull request
Feb 4, 2026
OAuth discovery requests to `/.well-known/oauth-authorization-server`
hang instead of returning 404, causing Codex rmcp client to timeout
after 15s per server. Gateway only registers handler at
`/mcp/.well-known/oauth-authorization-server`.
## Changes
- **Route registration**: Add handler at
`/.well-known/oauth-authorization-server` in both unified
(`transport.go`) and routed (`routed.go`) modes
- **Handler reuse**: Both paths now use existing
`handleOAuthDiscovery()` that returns 404
- **Test coverage**: Added test cases for root-level and MCP-prefixed
paths (GET/POST methods)
## Implementation
```go
// OAuth discovery endpoints - return 404 since we don't use OAuth
// Standard path for OAuth discovery (per RFC 8414)
mux.Handle("/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
// MCP-prefixed path for backward compatibility
mux.Handle("/mcp/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
```
Result: OAuth discovery now fails fast with immediate 404 instead of
timing out.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build3835057396/b270/launcher.test
/tmp/go-build3835057396/b270/launcher.test
-test.testlogfile=/tmp/go-build3835057396/b270/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a dler at
/.well-known/oauth-authorization-server for both unified and routed
modes
- Prevents req--norc x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3835057396/b258/config.test
/tmp/go-build3835057396/b258/config.test
-test.testlogfile=/tmp/go-build3835057396/b258/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build3835057396/b270/launcher.test
/tmp/go-build3835057396/b270/launcher.test
-test.testlogfile=/tmp/go-build3835057396/b270/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a dler at
/.well-known/oauth-authorization-server for both unified and routed
modes
- Prevents req--norc x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build3835057396/b270/launcher.test
/tmp/go-build3835057396/b270/launcher.test
-test.testlogfile=/tmp/go-build3835057396/b270/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a dler at
/.well-known/oauth-authorization-server for both unified and routed
modes
- Prevents req--norc x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3835057396/b279/mcp.test
/tmp/go-build3835057396/b279/mcp.test
-test.testlogfile=/tmp/go-build3835057396/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a
64/src/crypto/internal/boring/bbig/big.go
df11d1ebad5122b89293a9cf3b8353f09e1d0c3b3841ebf6471/log.json -g"
"-lresolv" ernal/sys -I 64/pkg/tool/linux_amd64/vet` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>OAuth discovery requests hang instead of returning
404</issue_title>
> <issue_description>## Summary
>
> OAuth discovery requests to `/.well-known/oauth-authorization-server`
hang indefinitely instead of returning a quick 404 response. This causes
Codex MCP connections to timeout after 15 seconds per server.
>
> ## Problem
>
> The Codex rmcp client (Rust MCP client) attempts OAuth discovery at
the **standard path**:
> ```
> GET http://host.docker.internal/.well-known/oauth-authorization-server
> ```
>
> But the MCP Gateway registers the OAuth handler at:
> ```
> /mcp/.well-known/oauth-authorization-server
> ```
>
> Since there's no handler at `/.well-known/...`, the request has no
matching route and hangs instead of returning 404.
>
> ## Evidence
>
> ### Smoke-codex workflow run:
https://github.com/github/gh-aw/actions/runs/21688558782
>
> **Error pattern:**
> ```
> DEBUG session_init: codex_rmcp_client::auth_status: OAuth discovery
requests failed for
> http://host.docker.internal:80/mcp/playwright: error sending request
for url
> (http://host.docker.internal/.well-known/oauth-authorization-server)
>
> Caused by:
> operation timed out
> ```
>
> **Result:**
> - OAuth discovery times out (15 seconds per server)
> - 4 of 6 MCP servers fail to connect
> - Only tavily and safeoutputs succeed (race condition - they complete
before timeout exhausts resources)
>
> **Firewall logs confirm traffic reaches gateway:**
> ```
> ▼ 11 requests | 11 allowed | 0 blocked | 1 unique domain
> | Domain | Allowed | Denied |
> |---------------------|---------|--------|
> | host.docker.internal | 11 | 0 |
> ```
>
> ### Comparison with working run
>
> In run 21653900083 (before chroot mode), using IP address 172.30.0.1,
OAuth discovery was NOT attempted and all 6 MCP servers connected
successfully:
> ```
> ready: ["safeoutputs", "safeinputs", "github", "playwright", "tavily",
"serena"]
> ```
>
> ## Current Route Registration
>
> From `internal/server/transport.go`:
>
> | Route | Handler |
> |-------|---------|
> | `/mcp/.well-known/oauth-authorization-server` | OAuth handler
(returns 404) |
> | `/mcp/` and `/mcp` | StreamableHTTPHandler |
> | `/health` | Health check |
> | `/close` | Graceful shutdown |
> | `/.well-known/*` | **NO HANDLER** ← causes hang |
>
> ## Proposed Fix
>
> Add a handler for OAuth discovery at the standard path (without
`/mcp/` prefix):
>
> ```go
> // In internal/server/transport.go, add alongside existing routes:
> mux.HandleFunc("/.well-known/oauth-authorization-server", func(w
http.ResponseWriter, r *http.Request) {
> http.NotFound(w, r)
> })
> ```
>
> This ensures OAuth discovery requests get an immediate 404 response
instead of hanging.
>
> ## Impact
>
> This fix would:
> 1. Make OAuth discovery fail fast (instant 404 instead of 15s timeout)
> 2. Allow all 6 MCP servers to connect successfully in Codex workflows
> 3. Fix smoke-codex CI failures
>
> ## Related
>
> - gh-aw PR github/gh-aw-mcpg#13792: Removed hardcoded IP from Codex
config (firewall fix - separate issue)</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #672
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/github/gh-aw-mcpg/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
lpcox
added a commit
that referenced
this pull request
Feb 5, 2026
Duplicate code analysis identified ~54 lines of duplication across 2
patterns in the DIFC and config validation modules.
## Changes
### DIFC Label Constructors
Extracted common label-with-tags creation pattern into
`newLabelWithTags()` helper:
```go
// Before: Duplicated logic in both constructors
func NewSecrecyLabelWithTags(tags []Tag) *SecrecyLabel {
label := NewSecrecyLabel()
label.Label.AddAll(tags)
return label
}
func NewIntegrityLabelWithTags(tags []Tag) *IntegrityLabel {
label := NewIntegrityLabel()
label.Label.AddAll(tags)
return label
}
// After: Single helper, constructors simplified
func newLabelWithTags(tags []Tag) *Label {
label := NewLabel()
label.AddAll(tags)
return label
}
func NewSecrecyLabelWithTags(tags []Tag) *SecrecyLabel {
return &SecrecyLabel{Label: newLabelWithTags(tags)}
}
func NewIntegrityLabelWithTags(tags []Tag) *IntegrityLabel {
return &IntegrityLabel{Label: newLabelWithTags(tags)}
}
```
Eliminates ~8 lines of duplication in `internal/difc/labels.go`.
### Docker Inspect Wrappers
Analysis confirmed `checkPortMapping()`, `checkStdinInteractive()`, and
`checkLogDirMounted()` already share the `runDockerInspect()` helper.
Each function has distinct domain logic and return types. No further
abstraction warranted.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build4007704820/b274/launcher.test
/tmp/go-build4007704820/b274/launcher.test
-test.testlogfile=/tmp/go-build4007704820/b274/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo .cfg 64/pkg/tool/linux_amd64/vet -p
vendor/golang.or-unsafeptr=false -lang=go1.25
64/pkg/tool/linux_amd64/vet -I 8340911/b183/ -I rgo/bin/as -g"
"-lresolv" --64 -o 8340911/b183/` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3364410036/b001/config.test
/tmp/go-build3364410036/b001/config.test
-test.testlogfile=/tmp/go-build3364410036/b001/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go
ps140/fips140.go-imultiarch 64/pkg/tool/linux86_64-linux-gnu` (dns
block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build4007704820/b274/launcher.test
/tmp/go-build4007704820/b274/launcher.test
-test.testlogfile=/tmp/go-build4007704820/b274/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo .cfg 64/pkg/tool/linux_amd64/vet -p
vendor/golang.or-unsafeptr=false -lang=go1.25
64/pkg/tool/linux_amd64/vet -I 8340911/b183/ -I rgo/bin/as -g"
"-lresolv" --64 -o 8340911/b183/` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build4007704820/b274/launcher.test
/tmp/go-build4007704820/b274/launcher.test
-test.testlogfile=/tmp/go-build4007704820/b274/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo .cfg 64/pkg/tool/linux_amd64/vet -p
vendor/golang.or-unsafeptr=false -lang=go1.25
64/pkg/tool/linux_amd64/vet -I 8340911/b183/ -I rgo/bin/as -g"
"-lresolv" --64 -o 8340911/b183/` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build4007704820/b283/mcp.test
/tmp/go-build4007704820/b283/mcp.test
-test.testlogfile=/tmp/go-build4007704820/b283/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/net red-by:
lpcox <15877973+lpcox@users.noreply.github.com>
ache/go/1.25.6/x64/pkg/tool/linux_amd64/vet -p
crypto/internal/-unsafeptr=false -lang=go1.25 01.o` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[duplicate-code] Duplicate Code Analysis Report -
f550849</issue_title>
> <issue_description>*Analysis of commit
f550849*
>
> ## Summary
>
> This analysis identified **2 significant duplication patterns** across
the Go codebase, affecting the DIFC (Decentralized Information Flow
Control) module and configuration validation code. A total of
approximately **54 lines** of meaningful duplicated code were detected.
>
> ## Detected Patterns
>
> This analysis found 2 significant duplication patterns requiring
refactoring:
>
> 1. **DIFC Label Constructor Duplication** - Severity: Medium - See
sub-issue #aw_xyz789ghi012
> 2. **Docker Inspect Wrapper Functions** - Severity: Medium - See
sub-issue #aw_mno345pqr678
>
> ## Overall Impact
>
> - **Total Duplicated Lines**: ~54 lines across 2 patterns
> - **Affected Files**: 2 files (`internal/difc/labels.go`,
`internal/difc/agent.go`, `internal/config/validation_env.go`)
> - **Maintainability Risk**: Medium - Duplication increases risk of
inconsistent updates
> - **Refactoring Priority**: Medium - Both patterns are in active
development areas
>
> ## Next Steps
>
> 1. Review individual pattern sub-issues for detailed analysis
> 2. Prioritize refactoring based on severity and impact
> 3. Create implementation plan for highest priority patterns
> 4. Consider using Go generics or helper functions to reduce
duplication
>
> ## Analysis Metadata
>
> - **Analyzed Files**: 60 Go files (excluding tests, workflows, and
agent configs)
> - **Detection Method**: Semantic code analysis using grep and manual
code review
> - **Commit**: f550849
> - **Analysis Date**: 2026-02-05T03:03:56Z
> - **Triggered by**: `@lpcox`
>
>
>
>
> > AI generated by [Duplicate Code
Detector](https://github.com/github/gh-aw-mcpg/actions/runs/21697098717)
> > - [x] expires <!-- gh-aw-expires: 2026-02-12T03:07:40.520Z --> on
Feb 12, 2026, 3:07 AM UTC
>
> <!-- gh-aw-agentic-workflow: Duplicate Code Detector, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/21697098717 -->
>
> <!-- gh-aw-workflow-id: duplicate-code-detector
--></issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
> **Custom agent used: agentic-workflows**
> GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade
AI-powered workflows with intelligent prompt routing
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #678
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
lpcox
added a commit
that referenced
this pull request
Feb 8, 2026
#844) Nightly stress test detected configuration errors in two MCP servers: filesystem expected directories as CLI arguments but received environment variables, and playwright had redundant host list entries. ## Changes **filesystem server** - Changed from `env.ALLOWED_PATHS` to `entrypointArgs: ["/workspace"]` - Server requires directory paths as positional arguments after container name **playwright server** - Simplified allowed-hosts/origins from `localhost;localhost:*;127.0.0.1;127.0.0.1:*` to `localhost:*;127.0.0.1:*` - Removed redundant non-wildcard entries ## Configuration structure Gateway converts workflow YAML to Docker commands following this pattern: ```bash docker run [args...] <container> [entrypointArgs...] ``` - `args`: Docker runtime flags (e.g., `--init`, `--network host`) - before container - `entrypointArgs`: Application arguments - after container ## Testing Added `TestLoadFromStdin_FilesystemServerConfig` and `TestLoadFromStdin_PlaywrightServerConfig` to validate argument placement and prevent similar configuration errors. > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build1254119737/b275/launcher.test /tmp/go-build1254119737/b275/launcher.test -test.testlogfile=/tmp/go-build1254119737/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true /opt/hostedtoolcache/go/1.25.6/x64/src/runtime/cgo 6765506/b184/ ache/Python/3.12.12/x64/bin/as --gdwarf-5 --64 -o as 6765�� d -n 10 -I docker-buildx --gdwarf-5 --64 -o docker-buildx` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build3908585129/b001/config.test /tmp/go-build3908585129/b001/config.test -test.testlogfile=/tmp/go-build3908585129/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4 -nolocalimports -importcfg /tmp/go-build2196765506/b210/importcfg -pack /opt/hostedtoolcache/go/1.25.6/x64/src/net/http/httptest/httptest.go conf�� go k/gh-aw-mcpg/gh-aw-mcpg/tools.go--gdwarf2 ache/Python/3.12.12/x64/bin/bash--64 k/gh-aw-mcpg/gh-/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/compile k/gh-aw-mcpg/gh--o k/gh-aw-mcpg/gh-/tmp/go-build2196765506/b125/_pkg_.a .o` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build1254119737/b275/launcher.test /tmp/go-build1254119737/b275/launcher.test -test.testlogfile=/tmp/go-build1254119737/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true /opt/hostedtoolcache/go/1.25.6/x64/src/runtime/cgo 6765506/b184/ ache/Python/3.12.12/x64/bin/as --gdwarf-5 --64 -o as 6765�� d -n 10 -I docker-buildx --gdwarf-5 --64 -o docker-buildx` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build1254119737/b275/launcher.test /tmp/go-build1254119737/b275/launcher.test -test.testlogfile=/tmp/go-build1254119737/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true /opt/hostedtoolcache/go/1.25.6/x64/src/runtime/cgo 6765506/b184/ ache/Python/3.12.12/x64/bin/as --gdwarf-5 --64 -o as 6765�� d -n 10 -I docker-buildx --gdwarf-5 --64 -o docker-buildx` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1254119737/b284/mcp.test /tmp/go-build1254119737/b284/mcp.test -test.testlogfile=/tmp/go-build1254119737/b284/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true /tmp/go-build2196765506/b218/_pkg_.a 6765506/b184/ p/bin/as -p github.com/githu-unsafeptr=false -lang=go1.25 as 6765�� d -n 10 --debug-prefix-map ache/go/1.25.6/x64/pkg/tool/linux_amd64/vet -I /opt/hostedtoolcmod -I ache/go/1.25.6/x64/pkg/tool/linuf() { test "$1" = get && echo "******"; }; f sto-w` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> ---- *This section details on the original issue you should resolve* <issue_title>[mcp-stress-test] Server Configuration Failures Detected - filesystem & playwright</issue_title> <issue_description>The nightly stress test detected 2 servers with configuration errors (not authentication issues). ## Test Summary - **Test Session:** stress-test-20260208-034257 - **Test Date:** 2026-02-08T03:42:57Z - **Total Configuration Failures:** 2 ## Failed Servers ### 1. filesystem - Command Arguments Error **Container:** mcp/filesystem **Issue Type:** Configuration Error **Error:** `````` Usage: mcp-server-filesystem (allowed-directory) [additional-directories...] `````` **Analysis:** The filesystem server expects allowed directories as positional command-line arguments, but the configuration is passing them as environment variables (`ALLOWED_PATHS`). The docker command structure needs to be updated. **Current Configuration Issue:** The server is launched with environment variable but expects positional args. **Suggested Fix:** Update configuration to pass directories as positional arguments: ``````json { "filesystem": { "type": "stdio", "container": "mcp/filesystem", "args": ["/workspace", "/additional/path"] } } `````` Or update the docker args to include the directory paths: ```````json { "filesystem": { "type": "stdio", "command": "docker", "args": ["run", "--rm", "-i", "-v", "/tmp/mcp-test-fs:/workspace:rw", "mcp/filesystem", "/workspace"] } } `````` **Suggested Investigation:** - [ ] Review filesystem server documentation for correct argument format - [ ] Update gateway configuration to pass directories correctly - [ ] Test with simple single directory first - [ ] Consider if server should be updated to support env vars --- ### 2. playwright - Duplicate Flag Error **Container:** mcr.microsoft.com/playwright/mcp **Issue Type:** Configuration Error **Error:** `````` error: unknown option '--init' `````` **Analysis:** The docker command includes the `--init` flag twice - once as a docker option (correct) and once passed to the playwright binary (incorrect). The playwright binary doesn't recognize the `--init` flag and fails. **Current Configuration Issue:** `````` docker run --rm -i --init --network host mcr.microsoft.com/playwright/mcp --output-dir ... --init --network host ``````` Notice `--init` and `--network host` appear twice. **Suggested Fix:** Remove the duplicate flags from the playwright server arguments: ``````json { "playwright": { "type": "stdio", "command": "docker", "args": [ "run", "--rm", "-i", "--init", "--network", "host", "-v", "/tmp/gh-aw/mcp-logs:/tmp/gh-aw/mcp-logs:rw", "mcr.microsoft.com/playwright/mcp", "--output-dir", "/tmp/gh-aw/mcp-logs/playwright", "--allowed-hosts", "localhost,localhost:*,127.0.0.1,127.0.0.1:*", "--allowed-origins", "localhost;localhost:*;127.0.0.1;127.0.0.1:*" ] } } `````` **Suggested Investigation:** - [ ] Review playwright MCP server documentation - [ ] Remove duplicate `--init` and `--network host` from args array - [ ] Verify correct flag order for playwright binary - [ ] Test with corrected configuration --- ## Gateway Logs From the gateway logs, both issues are clearly configuration-related, not authentication or protocol issues: **filesystem:** - Server expects CLI args but receives env vars - Quick fix: restructure docker command args **playwright:** - Duplicate flags passed to both docker and playwright binary - Quick fix: remove duplicate flags from args array ## Test Configuration Used The test used the following configuration: - Startup Timeout: 60s - Tool Timeout: 30s - Test Method: Sequential server testing - Gateway: Successfully handled all requests ## Impact These configuration issues prevent 2 MCP servers from launching: 1. **filesystem** - Would provide file system access if configured correctly 2. **playwright** - Would provide browser automation if configured correctly Both are fixable with configuration changes and don't require code modifications. ## Next Steps 1. **Priority: High** - Fix filesystem configuration - Update docker args to pass directories as positional arguments - Test with `/workspace` mount 2. **Priority: High** - Fix playwright configuration - Remove duplicate `--init` and `--network host` flags - Verify flag order matches playwright binary expectations 3. Re-run stress test to verify fixes 4. Update documentation with correct configuration examples --- *Generated by Nightly MCP Stress Test* *Test Session: stress-test-20260208-034257* **Full Test Results:** See workflow run artifacts at `/tmp/mcp-stress-results/` > AI generated by [Nightly MCP Server Stress Test](https://github.com/github/gh-aw-mcpg/actions/runs/21791681391) <!-- gh-aw-agentic-workflow: Nightly MCP Server Stress Test, engine: copilot, run: https://github.com/github/gh-aw-mcpg/actions/runs/2179168139... </details> > **Custom agent used: agentic-workflows** > GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade AI-powered workflows with intelligent prompt routing <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #843 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/github/gh-aw-mcpg/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
lpcox
added a commit
that referenced
this pull request
Feb 11, 2026
The Language Support Tester workflow documentation hardcoded
`/workspace/` paths, preventing the agent from locating test samples at
runtime. GitHub Actions workspace paths vary by environment (e.g.,
`/home/runner/work/{repo}/{repo}`).
## Changes
- **Updated path references in
`.github/agentics/language-support-tester.md`**:
- Changed hardcoded `/workspace/` paths to `{workspace}` placeholder
- Added instructions to use workspace path from `github-context` section
- Applied to JavaScript/TypeScript test samples path
- Applied to Python test samples path
- Updated "Important Notes" section references
The agent now receives the actual runtime workspace path via
`__GH_AW_GITHUB_WORKSPACE__` in the github-context and can correctly
construct paths to test samples:
```markdown
- Use the test samples at `{workspace}/test/serena-mcp-tests/samples/js_project/` (use the workspace path from github-context)
```
## Notes
Test sample files already exist in the repository with expected content
(`Calculator` class, `add` method, `format_number` function,
`package.json`). No code changes required.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build380999041/b279/launcher.test
/tmp/go-build380999041/b279/launcher.test
-test.testlogfile=/tmp/go-build380999041/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-o it base64
/usr/bin/dirname/tmp/go-build380999041/b263/_pkg_.a 8.o comm�� /go-build
Fix workflow docgithub.com/github/gh-aw-mcpg/internal/config
x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build380999041/b264/config.test
/tmp/go-build380999041/b264/config.test
-test.testlogfile=/tmp/go-build380999041/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/c-c=4
kdf/cast.go ache/go/1.25.6/x-importcfg cal/bin/git base64 /usr/sbin/git
6.o -c 64/src/runtime/cgo tf "%s%s", sep, $0; sep=RS }
x_amd64/compile --abbrev-ref HEAD /usr/bin/base64 x_amd64/compile` (dns
block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build380999041/b279/launcher.test
/tmp/go-build380999041/b279/launcher.test
-test.testlogfile=/tmp/go-build380999041/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-o it base64
/usr/bin/dirname/tmp/go-build380999041/b263/_pkg_.a 8.o comm�� /go-build
Fix workflow docgithub.com/github/gh-aw-mcpg/internal/config
x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build380999041/b279/launcher.test
/tmp/go-build380999041/b279/launcher.test
-test.testlogfile=/tmp/go-build380999041/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-o it base64
/usr/bin/dirname/tmp/go-build380999041/b263/_pkg_.a 8.o comm�� /go-build
Fix workflow docgithub.com/github/gh-aw-mcpg/internal/config
x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build380999041/b288/mcp.test
/tmp/go-build380999041/b288/mcp.test
-test.testlogfile=/tmp/go-build380999041/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 737903/b083/_pkg_.a
JWKP/08bK8wSDgKwIadp3JWKP x_amd64/vet cal/bin/git /unix /x64=/_/GOROOT
x_amd64/vet o_.o�� ache/go/1.25.6/x-errorsas
ache/go/1.25.6/x-ifaceassert x_amd64/vet 737903/b083/symabash HEAD
ndor/bin/git x_amd64/vet` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[language-support] Missing test samples for
TypeScript/JavaScript and Python language support testing</issue_title>
> <issue_description>## Summary
>
> The Language Support Tester workflow references test sample
directories that do not exist in the repository, preventing proper
testing of TypeScript/JavaScript and Python language support with the
Serena MCP server.
>
> ## Missing Directories
>
> The following test sample directories referenced in
`.github/agentics/language-support-tester.md` are missing:
>
> - `/workspace/test/serena-mcp-tests/samples/js_project/`
> - `/workspace/test/serena-mcp-tests/samples/python_project/`
>
> ## Impact
>
> - **Go language support**: ✅ Successfully tested with existing Go
files
> - **TypeScript/JavaScript support**: ❌ Cannot test - no test samples
exist
> - **Python support**: ❌ Cannot test - no test samples exist
>
> ## Test Results
>
> ### Go Language Support (✅ Working)
>
> Successfully tested Go language support using the main repository
code:
> - `get_symbols_overview` on `main.go` returned functions: `main`,
`buildVersionString`, and constant `shortHashLength`
> - `find_symbol` successfully found the `main` function with correct
location and signature
> - `find_symbol` successfully found the `Version` variable in
`version.go` with complete info including documentation
>
> ### TypeScript/JavaScript Support (⚠️ Unable to Test)
>
> The referenced test directory
`/workspace/test/serena-mcp-tests/samples/js_project/` does not exist.
The repository contains no JavaScript or TypeScript files for testing.
>
> ### Python Support (⚠️ Unable to Test)
>
> The referenced test directory
`/workspace/test/serena-mcp-tests/samples/python_project/` does not
exist. The repository contains no Python files for testing.
>
> ## Reproduction Steps
>
> 1. Run the Language Support Tester workflow
> 2. Agent attempts to locate test samples at the documented paths
> 3. Paths do not exist in the repository
>
> ## Recommended Solution
>
> Create the missing test sample directories with appropriate test
files:
>
> 1. Create `/workspace/test/serena-mcp-tests/samples/js_project/` with:
> - `index.js` or `index.ts` with sample functions/classes
> - `package.json` with project metadata
>
> 2. Create `/workspace/test/serena-mcp-tests/samples/python_project/`
with:
> - `calculator.py` with a `Calculator` class and `add` method
> - `utils.py` with utility functions like `format_number`
>
> Alternatively, update the testing workflow documentation to reference
existing test files or clarify that only Go language support needs
testing.
>
> ## Additional Context
>
> - Serena MCP server version: `ghcr.io/github/serena-mcp-server:latest`
> - Workflow: `.github/workflows/language-support-tester.lock.yml`
> - Task specification: `.github/agentics/language-support-tester.md`
> - Active project: `gh-aw-mcpg` (Go language configured)
>
>
>
>
> > AI generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/21861851918)
> > - [x] expires <!-- gh-aw-expires: 2026-02-17T10:55:01.059Z --> on
Feb 17, 2026, 10:55 AM UTC
>
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/21861851918 -->
>
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
>
> ## Comments on the Issue (you are @claude[agent] in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #875
lpcox
added a commit
that referenced
this pull request
Feb 11, 2026
…ag validation, and lifecycle hooks (#882) Implements Priority 1 and 2 recommendations from Go Fan report for github.com/spf13/cobra v1.10.2. Leverages new Cobra features for cleaner CLI code and better reliability. ## Context-based graceful shutdown Replace manual signal handling with `signal.NotifyContext` for proper cancellation propagation: ```go // Before: manual signal channel ctx, cancel := context.WithCancel(context.Background()) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) // After: v1.10.0 pattern ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM) ``` - HTTP server shutdown with 5s timeout via `httpServer.Shutdown(ctx)` - Context cancellation propagates through unified server ## Declarative flag validation Replace manual preRun validation with Cobra's built-in validation groups: ```go // Flag validation groups cmd.MarkFlagsMutuallyExclusive("routed", "unified") cmd.MarkFlagsOneRequired("config", "config-stdin") ``` - Removes 5 lines of manual validation logic from `preRun` - Produces consistent error messages: `"at least one of the flags in the group [config config-stdin] is required"` - Updates integration test to expect new error format ## Lifecycle hooks - Add `PersistentPostRun` hook for logger cleanup - Moves defer calls from `run()` to `postRun()` for cleaner separation - Logger initialization in run, cleanup in postRun ## Enhanced completions Add ActiveHelp hints for better shell completion UX: ```go cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return cobra.AppendActiveHelp(nil, "Tip: Use --config <file> for file-based config or --config-stdin for piped JSON config"), cobra.ShellCompDirectiveNoFileComp } ``` ## Version template Custom formatting: `MCPG Gateway {{.Version}}` instead of default output. ## Tests - Context cancellation behavior - Flag validation group registration - Version template and postRun hook presence > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build884163099/b275/launcher.test /tmp/go-build884163099/b275/launcher.test -test.testlogfile=/tmp/go-build884163099/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go 95WK6prK2 x_amd64/vet` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build884163099/b260/config.test /tmp/go-build884163099/b260/config.test -test.testlogfile=/tmp/go-build884163099/b260/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a HEAD 64/bin/as TOKEN"; }; f sto/tmp/go-build3472542465/b223/cmd.test go cal/bin/git 512block_amd64.o-test.timeout=10m0s 64/s�� 64/src/runtime/cgo xpwaXSmNs ache/go/1.25.6/x64/pkg/tool/linu--64 --abbrev-ref 2542465/b013/ .12/x64/bin/git 05.o` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build884163099/b275/launcher.test /tmp/go-build884163099/b275/launcher.test -test.testlogfile=/tmp/go-build884163099/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go 95WK6prK2 x_amd64/vet` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build884163099/b275/launcher.test /tmp/go-build884163099/b275/launcher.test -test.testlogfile=/tmp/go-build884163099/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go 95WK6prK2 x_amd64/vet` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build884163099/b284/mcp.test /tmp/go-build884163099/b284/mcp.test -test.testlogfile=/tmp/go-build884163099/b284/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a HEAD x_amd64/vet --abbrev-ref /bidi git x_amd64/vet 64/s�� 64/src/runtime/cgo1.25.6 V8YDPttZl inux.go esnew.go ocknew.go nix_cgo.go nix_cgo_res.go` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> ---- *This section details on the original issue you should resolve* <issue_title>[go-fan] Go Module Review: github.com/spf13/cobra</issue_title> <issue_description># 🐹 Go Fan Report: Cobra CLI Framework ## Module Overview **Cobra** (github.com/spf13/cobra) is the industry-standard CLI framework for Go, powering tools like kubectl, hugo, and GitHub CLI. It provides a powerful structure for building modern command-line applications with commands, subcommands, flags, and shell completions. **Current Version**: v1.10.2 ✅ (Latest: v1.10.2, Dec 3, 2025) **Repository**: https://github.com/spf13/cobra **Popularity**: 40k+ stars ## Current Usage in gh-aw-mcpg **Well-Implemented** ✅ The project uses Cobra appropriately across 7 files in `internal/cmd/`: ### Files & Structure - **root.go** - Root command definition and CLI entry point - **completion.go** - Shell completion commands (bash, zsh, fish, powershell) - **flags*.go** (5 files) - Well-organized flag definitions by domain: - `flags_core.go` - Core configuration flags - `flags_logging.go` - Logging flags - `flags_difc.go` - DIFC feature flags (properly uses `MarkHidden()`) - `flags_launch.go` - Launch configuration - `flags.go` - Registration helpers ### Key Patterns Observed ✅ Clean command structure without unnecessary nesting ✅ Flags well-organized by functional area ✅ Proper use of `MarkHidden()` for experimental features ✅ Comprehensive shell completion support ✅ Version command integration ## Research Findings ### Recent Cobra Updates (v1.10.x) #### v1.10.2 (Dec 2025) - Current Version - **Dependency Cleanup**: Migrated from deprecated `gopkg.in/yaml.v3` to `go.yaml.in/yaml/v3` - Significantly cleaner dependency chain - No action required (transparent upgrade) - Performance improvements (vars → consts) - Enhanced documentation for repeated flags #### v1.10.0 (Sep 2025) - **Context Support**: Commands can now receive and use context for cancellation/timeout - **Customizable ShellCompDirective**: Per-command completion behavior - Improved map flag completions #### v1.9.0 (Feb 2025) - **Linker Deadcode Elimination**: Smaller binaries by removing unused code - **CompletionFunc Type**: Cleaner completion code - **CompletionWithDesc Helper**: Easier completions with descriptions - **ActiveHelp**: Context-sensitive help during tab completion ### Best Practices from Cobra Maintainers 1. **Error Handling**: Use `RunE` instead of `Run` to return errors properly 2. **Flag Validation**: Use built-in flag groups instead of manual validation 3. **Context Usage**: Pass context to commands for cancellation and timeouts 4. **Completions**: Implement dynamic completions for better UX 5. **Lifecycle Hooks**: Use Pre/Post Run hooks for setup and teardown ## Improvement Opportunities ### 🏃 Quick Wins (High Impact, Low Effort) #### 1. Add Context Support (v1.10.0 feature) **Priority**: HIGH | **Effort**: LOW **Current**: No evidence of context usage for graceful shutdown **Opportunity**: Enable proper cancellation and timeout handling ``````go // In root.go ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer cancel() rootCmd.SetContext(ctx) // In command RunE func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() // Get context with cancellation support // Use ctx for HTTP requests, goroutines, etc. return server.Run(ctx) } `````` **Benefits**: - ✅ Proper graceful shutdown on SIGINT/SIGTERM - ✅ Timeout handling for long-running operations - ✅ Request tracing and cancellation propagation - ✅ Better testability with context-based timeouts #### 2. Use Flag Validation Groups **Priority**: HIGH | **Effort**: LOW **Current**: Manual flag validation in code **Opportunity**: Declarative validation with better error messages ``````go // Mutually exclusive flags cmd.MarkFlagsMutuallyExclusive("config", "stdin-config") // Flags required together cmd.MarkFlagsRequiredTogether("log-dir", "enable-file-logging") // At least one required cmd.MarkFlagsOneRequired("config", "stdin-config") `````` **Benefits**: - ✅ Cleaner code (remove manual validation logic) - ✅ Consistent, user-friendly error messages - ✅ Self-documenting flag relationships - ✅ Less maintenance burden #### 3. Enhanced Dynamic Completions **Priority**: MEDIUM | **Effort**: MEDIUM **Current**: Static shell completions **Opportunity**: Dynamic completions for config files, server IDs ``````go // Config file completion cmd.RegisterFlagCompletionFunc("config", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { configs, _ := filepath.Glob("*.toml") suggestions := []string{} for _, c := range configs { suggestions = append(suggestions, c+"\tTOML configuration file") } return suggestions, cobra.ShellCompDirectiveDefault }) // Server ID completion (from loaded config) cmd.RegisterFlagCompletionFunc("server-id", func(cmd *co... </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #874
lpcox
added a commit
that referenced
this pull request
Feb 11, 2026
…tories (#889) Nightly documentation reconciliation identified critical discrepancies between documented and actual default values, plus incomplete internal directory listings. ## Changes ### Critical: Payload Size Threshold Default Updated README.md (3 locations) to reflect actual implementation default of **10240 bytes (10KB)** instead of incorrectly documented 1024 bytes: - CLI flag description (line 206) - Flags usage table (line 281) - Environment variables table (line 319) Implementation sources: - `internal/cmd/flags_logging.go:14` - `defaultPayloadSizeThreshold = 10240` - `internal/config/config_payload.go:11` - `DefaultPayloadSizeThreshold = 10240` ### Minor: Complete Internal Directory Listings Added missing internal packages to project structure documentation: **CONTRIBUTING.md**: Added 9 missing directories (auth, difc, envutil, middleware, sys, testutil, version, tty, timeutil) to both tree diagram and Key Directories section **AGENTS.md**: Added 7 missing directories (difc, envutil, middleware, sys, testutil, tty, version) to project structure list All 16 internal directories now documented in alphabetical order: `auth`, `cmd`, `config`, `difc`, `envutil`, `guard`, `launcher`, `logger`, `mcp`, `middleware`, `server`, `sys`, `testutil`, `timeutil`, `tty`, `version` > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build2370360416/b279/launcher.test /tmp/go-build2370360416/b279/launcher.test -test.testlogfile=/tmp/go-build2370360416/b279/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo git ache/go/1.25.6/x64/pkg/tool/linu-o --global r it 08.o -d go git x_amd64/vet e/REDACTED/work/gh/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet 64/src/runtime/c-unsafeptr=false 64/bin/git x_amd64/vet` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build2370360416/b264/config.test /tmp/go-build2370360416/b264/config.test -test.testlogfile=/tmp/go-build2370360416/b264/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo HEAD ache/go/1.25.6/x64/pkg/tool/linu-fmessage-length=0 get --global rgo/bin/git 06.o -d 1.2.0/auth/auth.go git x_amd64/compile get --global .12/x64/which x_amd64/compile` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build2370360416/b279/launcher.test /tmp/go-build2370360416/b279/launcher.test -test.testlogfile=/tmp/go-build2370360416/b279/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo git ache/go/1.25.6/x64/pkg/tool/linu-o --global r it 08.o -d go git x_amd64/vet e/REDACTED/work/gh/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet 64/src/runtime/c-unsafeptr=false 64/bin/git x_amd64/vet` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build2370360416/b279/launcher.test /tmp/go-build2370360416/b279/launcher.test -test.testlogfile=/tmp/go-build2370360416/b279/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo git ache/go/1.25.6/x64/pkg/tool/linu-o --global r it 08.o -d go git x_amd64/vet e/REDACTED/work/gh/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet 64/src/runtime/c-unsafeptr=false 64/bin/git x_amd64/vet` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build2370360416/b288/mcp.test /tmp/go-build2370360416/b288/mcp.test -test.testlogfile=/tmp/go-build2370360416/b288/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a 64/src/internal/bisect/bisect.go--64 86_64/as --global abis p/bin/git ache/go/1.25.6/x/tmp/go-build2370360416/b059/vet.cfg -d ; then \ $GOPATH/bin/golangci-lint run --timeout=5m || echo "��� Warning: golangci-lint failed /opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/link -wdcAJ1yv x_amd64/vet rt-size '1280, 7/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> ---- *This section details on the original issue you should resolve* <issue_title>📚 Documentation Reconciliation Report - February 11, 2026</issue_title> <issue_description>## Summary Found **1 critical** and **2 minor** discrepancies between documentation and implementation during nightly reconciliation check. - Workflow Run: [§21890623217](https://github.com/github/gh-aw-mcpg/actions/runs/21890623217) - Date: February 11, 2026 - Branch: main ## Critical Issues 🔴 Issues that would cause user confusion or broken workflows if followed: ### 1. Payload Size Threshold Default Value Mismatch **Location:** README.md, lines 206, 281, 319 **Problem:** Documentation states the default payload size threshold is `1024` bytes (1KB), but the actual implementation uses `10240` bytes (10KB). **Actual Behavior:** - Code: `internal/cmd/flags_logging.go:14` defines `defaultPayloadSizeThreshold = 10240` - Code: `internal/config/config_payload.go:11` defines `DefaultPayloadSizeThreshold = 10240` - Tests: `internal/cmd/flags_logging_test.go` confirms default is 10240 bytes **Impact:** Users expecting the documented 1KB threshold will actually get a 10KB threshold, which could result in: - More payloads being stored inline than expected (up to 10KB instead of 1KB) - Less disk I/O than anticipated - Different memory usage patterns - Confusion when testing payload storage behavior **Suggested Fix:** Update README.md to reflect the actual default: ```markdown # Line 206 - CLI flag: `--payload-size-threshold (bytes)` (default: 10240) # Line 281 --payload-size-threshold int Size threshold (in bytes) for storing payloads to disk. Payloads larger than this are stored, smaller ones returned inline (default 10240) # Line 319 | `MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD` | Size threshold in bytes for payload storage (sets default for `--payload-size-threshold` flag) | `10240` | ``` **Code Reference:** - `internal/cmd/flags_logging.go:14` - `internal/config/config_payload.go:11` - `internal/cmd/flags_logging_test.go:46` ## Minor Issues 🔵 Small inconsistencies or missing details: ### 1. Internal Directory Structure Incomplete in CONTRIBUTING.md **Location:** CONTRIBUTING.md, lines 206-233 (Project Structure section) **Problem:** Documentation lists only 7 internal directories, but 16 actually exist. **Missing Directories:** - `internal/difc/` - Data Information Flow Control - `internal/envutil/` - Environment variable utilities - `internal/middleware/` - HTTP middleware (jq schema processing) - `internal/sys/` - System utilities - `internal/testutil/` - Test utilities and helpers - `internal/tty/` - Terminal detection utilities - `internal/version/` - Version management **Impact:** Developers may be unaware of these internal packages when working on the codebase, potentially duplicating functionality or missing useful utilities. **Suggested Fix:** Update the Project Structure section to include all internal directories with brief descriptions. **Code Reference:** Directory listing shows all 16 directories exist and contain working code. ### 2. Internal Directory Structure Incomplete in AGENTS.md **Location:** AGENTS.md, lines 12-20 (Project Structure section) **Problem:** Similar to CONTRIBUTING.md, lists only 9 internal directories instead of 16. **Missing Directories:** Same as above (difc, envutil, middleware, sys, testutil, tty, version) **Impact:** AI agents working with the codebase may not be aware of all available internal packages. **Suggested Fix:** Update the Project Structure section to include all internal directories. **Code Reference:** Same directory listing as above. ## Documentation Completeness ### Accurate Sections ✅ The following sections were verified and found to be accurate: - **Go Version Requirement** - Correctly documented as 1.25.0 (matches `go.mod`) - **Make Targets** - All 11 documented targets exist and work correctly: - `make build`, `test`, `test-unit`, `test-integration`, `test-all` - `make lint`, `coverage`, `install`, `agent-finished` - `make format`, `clean` - **Configuration Fields** - All documented fields match code struct definitions in `internal/config/` - **Environment Variables** - Correctly documented and extensively used (140+ references in code) - **External Links**: - MCP Gateway spec link is valid (returns HTTP 200) - GitHub token URL is valid (redirects properly) - **Feature Documentation**: - HTTP transport correctly marked as "fully supported" - Container field requirement for stdio servers matches validation code - Command field restriction for JSON stdin format accurately documented - Sequential launch flag exists and works as documented - **CLI Flags** - All documented flags exist and match actual implementation - **Docker Configuration Examples** - Format and field names match actual usage - **Configuration Validation** - Documented behavior matches `internal/config/validation*.go` ## Tested Commands All commands from CONTRIBUTING.... </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #886
lpcox
added a commit
that referenced
this pull request
Feb 14, 2026
The Serena MCP container was missing the Python language server, preventing Python code analysis despite having the Python runtime installed. Only Go language support was functional. ## Changes - **Dockerfile**: Added `python-lsp-server[all]` installation between Serena and TypeScript language server setup The container already had: - Go support via `gopls` - TypeScript/JavaScript support via `typescript-language-server` - Startup script correctly configuring all three languages in `.serena/project.yml` Only the Python language server package was missing. The `[all]` extra includes optional dependencies for full LSP functionality. > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build1194592432/b279/launcher.test /tmp/go-build1194592432/b279/launcher.test -test.testlogfile=/tmp/go-build1194592432/b279/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ternal/fips140/bigmod/nat_amd64.--gdwarf-5 HEAD x_amd64/compile /tmp/apt-dpkg-in/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet tar amd64/compile x_amd64/compile add go -v x_amd64/vet -f 4971347/b009/ es x_amd64/vet` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1194592432/b264/config.test /tmp/go-build1194592432/b264/config.test -test.testlogfile=/tmp/go-build1194592432/b264/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo zclWGwGwi ache/go/1.25.7/x64/pkg/tool/linu-o .util; print(imp/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet r/runc-log.json /usr/sbin/tar 06.o ortc�� 64/src/runtime/cgo go x_amd64/compile -f - /usr/sbin/dpkg-d-unreachable=false x_amd64/compile` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build1194592432/b279/launcher.test /tmp/go-build1194592432/b279/launcher.test -test.testlogfile=/tmp/go-build1194592432/b279/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ternal/fips140/bigmod/nat_amd64.--gdwarf-5 HEAD x_amd64/compile /tmp/apt-dpkg-in/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet tar amd64/compile x_amd64/compile add go -v x_amd64/vet -f 4971347/b009/ es x_amd64/vet` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build1194592432/b279/launcher.test /tmp/go-build1194592432/b279/launcher.test -test.testlogfile=/tmp/go-build1194592432/b279/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ternal/fips140/bigmod/nat_amd64.--gdwarf-5 HEAD x_amd64/compile /tmp/apt-dpkg-in/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet tar amd64/compile x_amd64/compile add go -v x_amd64/vet -f 4971347/b009/ es x_amd64/vet` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1194592432/b288/mcp.test /tmp/go-build1194592432/b288/mcp.test -test.testlogfile=/tmp/go-build1194592432/b288/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo 64/src/maps/iter.go ache/go/1.25.7/x64/pkg/tool/linu-o r/runc-log.json abis /systemd-sysctl 08.o main�� ; then \ $GOPATH/bin/golangci-lint run --timeout=5m || echo "��� Warning: golangci-lint failed /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet --auto x_amd64/vet --detach 4971347/b004/ d-dispatcher/off-unreachable=false x_amd64/vet` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>[language-support] TypeScript/JavaScript and Python language support not available in Serena MCP container</issue_title> > <issue_description>## Summary > > Testing of language support for Go, TypeScript/JavaScript, and Python revealed that only **Go language support is working correctly**. TypeScript/JavaScript and Python language servers are not available or configured in the Serena MCP container. > > ## Test Results > > ### ✅ Go Language Support - PASSED > > All Go language operations work correctly: > - **Symbol overview**: Successfully retrieved functions and constants from `main.go` > - **Symbol finding**: Located `main` and `buildVersionString` functions with detailed info > - **Pattern search**: Found function declarations using regex patterns > - **Reference finding**: Discovered all references to `buildVersionString` across multiple files > - **Code body retrieval**: Successfully retrieved complete function implementations > > ### ❌ TypeScript/JavaScript Language Support - FAILED > > **Issue**: Cannot activate TypeScript/JavaScript projects > - The Serena configuration (`.serena/project.yml`) only includes `go` in the `languages:` list > - Attempts to activate a JavaScript project failed with `ProjectNotFoundError` > - `tsserver` binary exists at `/usr/local/bin/tsserver` but no TypeScript language server wrapper found > - Configuration file is owned by root and cannot be modified due to container security restrictions > > ### ❌ Python Language Support - FAILED > > **Issue**: Cannot activate Python projects > - The Serena configuration (`.serena/project.yml`) only includes `go` in the `languages:` list > - Attempts to activate a Python project failed with `ProjectNotFoundError` > - No Python language servers found in the container (checked for `pyls`, `pylsp`, `jedi-language-server`) > - Configuration file permissions prevent adding Python to supported languages > > ## Root Cause > > The Serena MCP container is configured with only Go language support. The `.serena/project.yml` file contains: > > ``````yaml > languages: > - go > `````` > > According to the project configuration documentation, supported languages include: > - `typescript` (also handles JavaScript files) > - `python` (or `python_jedi` as alternative) > > However, these are not enabled in the current configuration, and the configuration file cannot be modified at runtime due to permission restrictions. > > ## Impact > > - **Go projects**: ✅ Fully functional > - **TypeScript/JavaScript projects**: ❌ Cannot be analyzed > - **Python projects**: ❌ Cannot be analyzed > - **Multi-language repositories**: Limited to Go code only > > ## Reproduction Steps > > 1. Start Serena MCP server with current configuration > 2. Activate main Go project: `serena-activate_project` → **Success** > 3. Try to activate TypeScript/JavaScript project: `serena-activate_project` with JS path → **Fails with ProjectNotFoundError** > 4. Try to activate Python project: `serena-activate_project` with Python path → **Fails with ProjectNotFoundError** > 5. Check configuration: `cat .serena/project.yml` shows only `go` in languages list > > ## Recommendations > > 1. **Update Serena container configuration** to include TypeScript and Python language servers > 2. **Modify `.serena/project.yml`** to include: > ``````yaml > languages: > - go > - typescript > - python > `````` > 3. **Install required language servers** in the container: > - TypeScript: `typescript-language-server` or equivalent > - Python: `python-lsp-server` (pylsp) or `jedi-language-server` > 4. **Test sample projects** at `test/serena-mcp-tests/samples/` once language servers are available > > ## Environment Details > > - Repository: github/gh-aw-mcpg > - Sparse checkout: 33% of files (Go code is present, test samples may not be available) > - Serena version: 0.1.4 > - Container: ghcr.io/github/serena-mcp-server:latest > - Test date: 2026-02-12 > > > > > > AI generated by [Language Support Tester](https://github.com/github/gh-aw-mcpg/actions/runs/21943451066) > > - [x] expires <!-- gh-aw-expires: 2026-02-19T10:53:23.898Z --> on Feb 19, 2026, 10:53 AM UTC > > <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot, run: https://github.com/github/gh-aw-mcpg/actions/runs/21943451066 --> > > <!-- gh-aw-workflow-id: language-support-tester --></issue_description> > > ## Comments on the Issue (you are @claude[agent] in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #913
lpcox
added a commit
that referenced
this pull request
Feb 16, 2026
…n() helper (#978) Six MCP method wrappers (`listTools`, `callTool`, `listResources`, `readResource`, `listPrompts`, `getPrompt`) contained identical 3-line session nil checks, creating maintenance burden and risk of inconsistent error messages. ## Changes - **Extract validation helper**: Created `requireSession()` method to centralize session nil checking - **Update all callers**: Replaced inline checks across 6 methods with helper call - **Add test coverage**: Unit test validates helper behavior for nil sessions ## Before/After ```go // Before: Duplicated in 6 methods func (c *Connection) listTools() (*Response, error) { if c.session == nil { return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport") } // ... } // After: Single source of truth func (c *Connection) requireSession() error { if c.session == nil { return fmt.Errorf("SDK session not available for plain JSON-RPC transport") } return nil } func (c *Connection) listTools() (*Response, error) { if err := c.requireSession(); err != nil { return nil, err } // ... } ``` Reduces code by ~12 lines and ensures consistent error messaging across all SDK method wrappers. > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build1651638344/b275/launcher.test /tmp/go-build1651638344/b275/launcher.test -test.testlogfile=/tmp/go-build1651638344/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports -importcfg /tmp/go-build1651638344/b235/importcfg -pack /home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool.go /home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool_func.go rev-�� go 8AG1CVhJp /home/REDACTED/wor-o wright" --viewpo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/compile 5519/field .12/x64/git git` (dns block) > - Triggering command: `/tmp/go-build4267259821/b275/launcher.test /tmp/go-build4267259821/b275/launcher.test -test.testlogfile=/tmp/go-build4267259821/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1638344/b190/_pkg_.a ache/go/1.25.7/x64/src/crypto/in-nolocalimports 1638344/b190=> -p l/ascii -lang=go1.25 /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu-I go_.�� 64/src/net Wvey/P0HIK0znqdopQQs2Wvey x_amd64/compile -I ions =0 x_amd64/compile` (dns block) > - Triggering command: `/tmp/go-build4134285178/b275/launcher.test /tmp/go-build4134285178/b275/launcher.test -test.testlogfile=/tmp/go-build4134285178/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true se 1638344/b069/vet.cfg .cfg --gdwarf-5 --64 -o ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1651638344/b260/config.test /tmp/go-build1651638344/b260/config.test -test.testlogfile=/tmp/go-build1651638344/b260/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go ternal/fips140/a--64 64/pkg/tool/linu-o nner/.nvm credential.helpe-I /home/REDACTED/wor/opt/hostedtoolcache/go/1.25.7/x64/src/net 64/pkg/tool/linu-I rev-�� go HEAD x_amd64/vet list` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build1651638344/b275/launcher.test /tmp/go-build1651638344/b275/launcher.test -test.testlogfile=/tmp/go-build1651638344/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports -importcfg /tmp/go-build1651638344/b235/importcfg -pack /home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool.go /home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool_func.go rev-�� go 8AG1CVhJp /home/REDACTED/wor-o wright" --viewpo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/compile 5519/field .12/x64/git git` (dns block) > - Triggering command: `/tmp/go-build4267259821/b275/launcher.test /tmp/go-build4267259821/b275/launcher.test -test.testlogfile=/tmp/go-build4267259821/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1638344/b190/_pkg_.a ache/go/1.25.7/x64/src/crypto/in-nolocalimports 1638344/b190=> -p l/ascii -lang=go1.25 /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu-I go_.�� 64/src/net Wvey/P0HIK0znqdopQQs2Wvey x_amd64/compile -I ions =0 x_amd64/compile` (dns block) > - Triggering command: `/tmp/go-build4134285178/b275/launcher.test /tmp/go-build4134285178/b275/launcher.test -test.testlogfile=/tmp/go-build4134285178/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true se 1638344/b069/vet.cfg .cfg --gdwarf-5 --64 -o ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build1651638344/b275/launcher.test /tmp/go-build1651638344/b275/launcher.test -test.testlogfile=/tmp/go-build1651638344/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports -importcfg /tmp/go-build1651638344/b235/importcfg -pack /home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool.go /home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool_func.go rev-�� go 8AG1CVhJp /home/REDACTED/wor-o wright" --viewpo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/compile 5519/field .12/x64/git git` (dns block) > - Triggering command: `/tmp/go-build4267259821/b275/launcher.test /tmp/go-build4267259821/b275/launcher.test -test.testlogfile=/tmp/go-build4267259821/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 1638344/b190/_pkg_.a ache/go/1.25.7/x64/src/crypto/in-nolocalimports 1638344/b190=> -p l/ascii -lang=go1.25 /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu-I go_.�� 64/src/net Wvey/P0HIK0znqdopQQs2Wvey x_amd64/compile -I ions =0 x_amd64/compile` (dns block) > - Triggering command: `/tmp/go-build4134285178/b275/launcher.test /tmp/go-build4134285178/b275/launcher.test -test.testlogfile=/tmp/go-build4134285178/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true se 1638344/b069/vet.cfg .cfg --gdwarf-5 --64 -o ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1651638344/b284/mcp.test /tmp/go-build1651638344/b284/mcp.test -test.testlogfile=/tmp/go-build1651638344/b284/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true in.so /lto-wrapper /usr/bin/base64 WebFetch,WebSear/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet a20 rgo/bin/git base64 ortc�� 64/src/runtime/c-errorsas 3-Nd5vpBC ache/go/1.25.7/x-nilfunc --oneline -n /usr/bin/base64 04.o` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> ---- *This section details on the original issue you should resolve* <issue_title>[duplicate-code] Duplicate Code Pattern: MCP Session Nil Validation Checks</issue_title> <issue_description># 🔍 Duplicate Code Pattern: MCP Session Validation Checks *Part of duplicate code analysis: #970* ## Summary The `internal/mcp/connection.go` file contains **6 identical session nil checks** across different MCP method wrappers. Each method performs the exact same validation before executing its SDK call. ## Duplication Details ### Pattern: Repeated Session Nil Validation - **Severity**: Medium - **Occurrences**: 6 instances - **Locations**: - `internal/mcp/connection.go`: - Line 821-823: `listTools()` - Line 833-835: `callTool()` - Line 867-869: `listResources()` - Line 879-881: `readResource()` - Line 901-903: `listPrompts()` - Line 913-915: `getPrompt()` ### Code Sample: ``````go func (c *Connection) listTools() (*Response, error) { if c.session == nil { return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport") } result, err := c.session.ListTools(c.ctx, &sdk.ListToolsParams{}) if err != nil { return nil, err } return marshalToResponse(result) } func (c *Connection) listResources() (*Response, error) { if c.session == nil { return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport") } result, err := c.session.ListResources(c.ctx, &sdk.ListResourcesParams{}) if err != nil { return nil, err } return marshalToResponse(result) } // ... 4 more methods with identical session nil check `````` ## Impact Analysis - **Maintainability**: **Medium Impact** - Error message changes require updating 6 locations - **Bug Risk**: **Medium** - Risk of inconsistent error messages if updates are missed - **Code Bloat**: ~18 lines of duplicate validation code (6 checks × 3 lines each) - **Consistency**: Error messages could diverge over time if not carefully maintained ## Refactoring Recommendations ### 1. **Extract Session Validation Helper** (Recommended) Create a helper method to centralize the session validation: ``````go // In connection.go func (c *Connection) requireSession() error { if c.session == nil { return fmt.Errorf("SDK session not available for plain JSON-RPC transport") } return nil } // Updated methods use the helper: func (c *Connection) listTools() (*Response, error) { if err := c.requireSession(); err != nil { return nil, err } result, err := c.session.ListTools(c.ctx, &sdk.ListToolsParams{}) if err != nil { return nil, err } return marshalToResponse(result) } func (c *Connection) listResources() (*Response, error) { if err := c.requireSession(); err != nil { return nil, err } result, err := c.session.ListResources(c.ctx, &sdk.ListResourcesParams{}) if err != nil { return nil, err } return marshalToResponse(result) } // ... other methods follow same pattern `````` - **Location**: `internal/mcp/connection.go` (add `requireSession` helper method) - **Estimated Effort**: 1 hour - **Benefits**: - Single point of truth for session validation - Consistent error messages across all methods - Easier to enhance validation logic (e.g., add logging, metrics) - Reduces code by ~12 lines ### 2. **Alternative: Method Decorator Pattern** (More Complex) For a more sophisticated approach, consider a decorator that wraps SDK calls: ``````go type sdkCall func() (interface{}, error) func (c *Connection) withSession(call sdkCall) (*Response, error) { if c.session == nil { return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport") } result, err := call() if err != nil { return nil, err } return marshalToResponse(result) } // Usage: func (c *Connection) listTools() (*Response, error) { return c.withSession(func() (interface{}, error) { return c.session.ListTools(c.ctx, &sdk.ListToolsParams{}) }) } `````` - **Estimated Effort**: 2-3 hours - **Benefits**: More DRY, but adds complexity with closures ## Implementation Checklist - [ ] Review duplication findings - [ ] Create `requireSession()` helper method in Connection struct - [ ] Update `listTools()` to use helper - [ ] Update `callTool()` to use helper - [ ] Update `listResources()` to use helper - [ ] Update `readResource()` to use helper - [ ] Update `listPrompts()` to use helper - [ ] Update `getPrompt()` to use helper - [ ] Run `make test-all` to verify no functionality broken - [ ] Run `make lint` to ensure code quality ## Parent Issue See parent analysis report: #970 Related to #970 > AI generated by [Duplicate Code Detector](https://github.com/github/gh-aw-mcpg/actions/runs/22058864442) > - [x] expires <!-- gh-aw-expires: 2026-02-23T10:32:38.091Z --> on Feb 23, 2026, 10:32 AM UTC <!-- gh-aw-agentic-workflow: Duplicate Code Detector, engine: copilot, run: https://github.com/github/gh-aw-mcpg/actions/runs/22058864442 --> <!-- gh-aw-workflow-id: ... </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #972
lpcox
added a commit
that referenced
this pull request
Feb 16, 2026
The Go Fan report identified BurntSushi/toml as a critical dependency
and recommended verifying TOML 1.1 support, error reporting
improvements, and validation patterns. Analysis reveals the
implementation already follows all best practices—no functional changes
needed.
## Changes
**Enhanced inline documentation** (`internal/config/config_core.go`):
- Package-level overview of TOML 1.1 features (multi-line arrays,
duplicate key detection)
- Documented streaming decoder pattern and memory efficiency rationale
- Explained warning-based validation design decision (backward
compatibility vs strict errors)
- Clarified column-level error reporting (v1.5.0+ Position.Line +
Position.Col)
**Comprehensive review document** (`docs/TOML_MODULE_REVIEW.md`):
- Implementation analysis: TOML 1.1 specification support verified
- Multi-layer validation architecture documented (parse → schema →
field-level → variable expansion)
- Test coverage audit: 31+ tests including duplicate key detection,
streaming large files, unknown field warnings
- Best practices: MetaData.Undecoded() for typo detection, dual
type-check for ParseError compatibility
## Implementation Status
All Go Fan recommendations already implemented:
- ✅ TOML 1.1 compatibility (v1.6.0 default)
- ✅ Column-level error reporting with Position.Line and Position.Col
- ✅ Unknown field detection via MetaData.Undecoded() with warnings
- ✅ Streaming decoder for memory efficiency
- ✅ Comprehensive test coverage
## Example
Current error reporting with line and column numbers:
```go
if perr, ok := err.(*toml.ParseError); ok {
return nil, fmt.Errorf("failed to parse TOML at line %d, column %d: %s",
perr.Position.Line, perr.Position.Col, perr.Message)
}
```
TOML 1.1 multi-line arrays in use:
```toml
[servers.github]
args = [
"run", "--rm", "-i",
"--name", "awmg-github-mcp"
]
```
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build247104886/b279/launcher.test
/tmp/go-build247104886/b279/launcher.test
-test.testlogfile=/tmp/go-build247104886/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD 86_64/as toml k/gh-aw-mcpg/gh--unsafeptr=false
ache/Python/3.12-unreachable=false .o rev-�� go ac/hmac.go
x_amd64/compile toml 64975/b009/ /opt/hostedtoolc-unreachable=false
x_amd64/compile` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build247104886/b264/config.test
/tmp/go-build247104886/b264/config.test
-test.testlogfile=/tmp/go-build247104886/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
64/src/unicode/casetables.go
ache/go/1.25.7/x64/pkg/tool/linux86_64-linux-gnu toml is rgo/bin/grep .o
rev-�� 64/src/runtime/cgo go x_amd64/compile toml
k/gh-aw-mcpg/gh--unsafeptr=false p/bin/grep x_amd64/compile` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build247104886/b279/launcher.test
/tmp/go-build247104886/b279/launcher.test
-test.testlogfile=/tmp/go-build247104886/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD 86_64/as toml k/gh-aw-mcpg/gh--unsafeptr=false
ache/Python/3.12-unreachable=false .o rev-�� go ac/hmac.go
x_amd64/compile toml 64975/b009/ /opt/hostedtoolc-unreachable=false
x_amd64/compile` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build247104886/b279/launcher.test
/tmp/go-build247104886/b279/launcher.test
-test.testlogfile=/tmp/go-build247104886/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD 86_64/as toml k/gh-aw-mcpg/gh--unsafeptr=false
ache/Python/3.12-unreachable=false .o rev-�� go ac/hmac.go
x_amd64/compile toml 64975/b009/ /opt/hostedtoolc-unreachable=false
x_amd64/compile` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build247104886/b288/mcp.test
/tmp/go-build247104886/b288/mcp.test
-test.testlogfile=/tmp/go-build247104886/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
ternal/fips140/nistec/fiat/cast.--64 64/pkg/tool/linux_amd64/asm toml
k/gh-aw-mcpg/gh--unsafeptr=false k/_temp/ghcca-no-unreachable=false
64/pkg/tool/linu/tmp/go-build247104886/b068/vet.cfg -w ; then \
$GOPATH/bin/golangci-lint run --timeout=5m || echo "��� Warning:
golangci-lint failed
/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet security
x_amd64/vet OUTPUT 64975/b004/ 168.63.129.16 x_amd64/vet` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
----
*This section details on the original issue you should resolve*
<issue_title>[go-fan] Go Module Review: BurntSushi/toml - TOML
Configuration Parser</issue_title>
<issue_description># 🐹 Go Fan Report: github.com/BurntSushi/toml
## Module Overview
**BurntSushi/toml** is the de-facto standard TOML parser for Go,
providing robust parsing and encoding of TOML configuration files with
full reflection support. It's the most popular and well-maintained TOML
library in the Go ecosystem, used by thousands of projects including the
MCP Gateway for parsing `config.toml` files.
- **Version**: v1.6.0 (latest, December 18, 2025)
- **Repository**: https://github.com/BurntSushi/toml
- **Stars**: 4,898 ⭐
- **License**: MIT
- **Maintainer**: Martin Tournoij (`@arp242`)
- **Last Update**: February 16, 2026 (updated just hours ago! 🔥)
## Current Usage in gh-aw-mcpg
**Note**: Analysis based on configuration files and documented patterns,
as the source code is not available in the sparse checkout.
### Configuration Files
- `config.toml` - Main gateway configuration
- `config.example.toml` - Comprehensive example (154 lines)
- `config.example-payload-threshold.toml` - Payload configuration
### Key Configuration Elements
The gateway uses TOML for:
1. **Gateway Settings** - Port, API key, timeouts, payload directory
2. **MCP Server Definitions** - Docker container configurations with:
- Command and arguments arrays
- Environment variable mappings
- Tool filtering lists
3. **Modern TOML 1.1 Syntax** - Multi-line inline arrays, nested tables
### Example Configuration Pattern
``````toml
[gateway]
port = 3000
startup_timeout = 60
tool_timeout = 120
[servers.github]
command = "docker"
args = [
"run", "--rm", "-i",
"--name", "awmg-github-mcp",
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN"
]
[servers.github.env]
GITHUB_PERSONAL_ACCESS_TOKEN = ""
``````
## Research Findings
### 🔥 Recent Updates (Just Released Hours Ago!)
The repository was updated **today** (February 16, 2026) at 04:57 UTC,
making it an excellent time to review!
### Latest Version: v1.6.0 (December 18, 2025)
🎉 **Major Update**: **TOML 1.1 is now the default!**
**Key Changes**:
1. ✨ **TOML 1.1 Default** - Newlines in inline tables now allowed (huge
usability improvement!)
2. 🐛 **Fixed Duplicate Array Detection** - Now correctly detects
duplicate array keys as errors
3. 🔧 **Float Encoding** - Large floats round-trip correctly with
exponent syntax (e.g., `5e+22`)
**This is perfect timing!** The gateway's configs already use TOML 1.1
syntax with multi-line arrays, which is exactly what v1.6.0 enables by
default.
### Previous Versions
**v1.5.0 (March 18, 2025)**:
- Added `Position.Col` for **column-level error reporting** (line AND
column!)
- Allow custom string types as map keys
- Enhanced `ParseError.Message` to always be set
- Multiple encoding bug fixes
**v1.4.0 (May 23, 2024)**:
- **Added `toml.Marshal()`** - Convenient marshaling function
- Requires Go 1.18+
- Improved error position wrapping for custom types
### Best Practices from Module Documentation
1. **Detailed Error Handling**:
``````go
var config Config
meta, err := toml.DecodeFile("config.toml", &config)
if err != nil {
// ParseError includes line/column info
log.Fatalf("Config error: %v", err)
}
``````
2. **Strict Decoding** (Catch Typos):
``````go
dec := toml.NewDecoder(file)
dec.DisallowUnknownFields() // Errors on "prot" instead of "port"
if err := dec.Decode(&config); err != nil {
return fmt.Errorf("invalid config: %w", err)
}
``````
3. **Metadata for Validation**:
``````go
meta, _ := toml.Decode(data, &config)
if !meta.IsDefined("required_field") {
return errors.New("missing required field")
}
// Check for unrecognized keys
if undecoded := meta.Undecoded(); len(undecoded) > 0 {
log.Warnf("Unknown config keys: %v", undecoded)
}
``````
4. **Marshal for Output**:
``````go
data, err := toml.Marshal(config)
if err != nil {
return err
}
``````
## Improvement Opportunities
**Important Note**: These recommendations are based on the module's
capabilities and common patterns. Implementation requires accessing the
full repository source code (currently unavailable due to sparse
checkout).
### 🏃 Quick Wins
#### 1. Verify TOML 1.1 Compatibility ✅
**Impact**: Low (already working) | **Effort**: Very Low
The gateway configs use TOML 1.1 syntax (multi-line arrays), which is
perfect since v1.6.0 makes it the default.
**Action**:
- Verify no `BURNTSUSHI_TOML_110` environment variable workarounds in
code
- Confirm clean usage of TOML 1.1 features
**Benefit**: Ensure idiomatic usage of the latest TOML spec
#### 2. Leverage Enhanced Error Reporting (v1.5.0 Feature)
**Impact**: Medium | **Effort**: Low
v1.5.0 added `Position.Col` for column-level errors.
**Action**:
- Update error messages to show both line AND column: `"error at line
%d, column %d"`
- Th...
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #969
lpcox
added a commit
that referenced
this pull request
Feb 19, 2026
The jq middleware payload preview size (500 characters) was hardcoded in
multiple locations, making it difficult to adjust consistently.
## Changes
- **Added `PayloadPreviewSize` constant** in
`internal/middleware/jqschema.go`
- Replaces hardcoded `500` in preview truncation logic
- Replaces hardcoded `500` in logging statements
- Updates function documentation
- **Updated references** in documentation (`README.md`, `AGENTS.md`) and
tests to reference the constant
## Example
Before:
```go
truncated := len(payloadStr) > 500
if truncated {
preview = payloadStr[:500] + "..."
}
```
After:
```go
truncated := len(payloadStr) > PayloadPreviewSize
if truncated {
preview = payloadStr[:PayloadPreviewSize] + "..."
}
```
The constant provides a single point of configuration for payload
preview behavior across the middleware package.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build3360590955/b279/launcher.test
/tmp/go-build3360590955/b279/launcher.test
-test.testlogfile=/tmp/go-build3360590955/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 4047529/b162/_pkg_.a
64/src/runtime/cgo x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3360590955/b264/config.test
/tmp/go-build3360590955/b264/config.test
-test.testlogfile=/tmp/go-build3360590955/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
3E2y/lfIxJsLvVk-kDynw3E2y .12/x64/bin/as` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build3360590955/b279/launcher.test
/tmp/go-build3360590955/b279/launcher.test
-test.testlogfile=/tmp/go-build3360590955/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 4047529/b162/_pkg_.a
64/src/runtime/cgo x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build3360590955/b279/launcher.test
/tmp/go-build3360590955/b279/launcher.test
-test.testlogfile=/tmp/go-build3360590955/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 4047529/b162/_pkg_.a
64/src/runtime/cgo x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3360590955/b288/mcp.test
/tmp/go-build3360590955/b288/mcp.test
-test.testlogfile=/tmp/go-build3360590955/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se
4047529/b025/vet.cfg rgo/bin/as -p internal/msan -lang=go1.25
/opt/hostedtoolcache/go/1.25.7/x-trimpath go_.��
lcache/go/1.25.7/x64=/_/GOROOT Rd x_amd64/vet -p hash/maphash
-lang=go1.25 x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build1404549538/b001/mcp.test
/tmp/go-build1404549538/b001/mcp.test
-test.testlogfile=/tmp/go-build1404549538/b001/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -tes��
io.containerd.runtime.v2.task/moby/63201cdb6593143a21722511515a1/run/containerd/io.containerd.rugofmt
-test.timeout=10m0s k/gh-aw-mcpg/gh-aw-mcpg/awmg se
4047529/b025/vet--norc ffbfb0094a8a3294--noprofile
k/gh-aw-mcpg/gh-aw-mcpg/awmg -tes�� -test.paniconexit0 y
by/71af78b18fce5832ab10e180bbc3a77cfee5908e386c9517dcf943eeea458c34/log.json
ntime.v2.task/mo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
Rd t",
"REQUESTS_CA_B-c iginal` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
lpcox
added a commit
that referenced
this pull request
Feb 19, 2026
The Language Support Tester workflow failed because it referenced the
registry image `ghcr.io/github/gh-aw-mcpg` without building it locally
first, causing Docker daemon connectivity issues and missing Serena MCP
tools.
## Changes
Added local container build steps following the `smoke-copilot.md`
pattern:
- **Docker Buildx setup** - Added `docker/setup-buildx-action@v3` step
- **Local MCP Gateway build** - Builds `local-awmg:v0.1.4` with embedded
`awmg` binary
- **Container reference** - Updated `sandbox.mcp.container` from
`ghcr.io/github/gh-aw-mcpg` to `local-awmg`
```yaml
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build local MCP Gateway container
run: |
VERSION="dev-$(git rev-parse --short HEAD)"
docker build -t local-awmg:v0.1.4 --build-arg VERSION=${VERSION} .
sandbox:
mcp:
container: "local-awmg" # Changed from registry reference
```
This ensures the MCP Gateway is available without external registry
dependencies, enabling Serena tools (`activate_project`, `find_symbols`,
etc.) for Go, TypeScript/JavaScript, and Python language testing.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> -
`https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3`
> - Triggering command: `/usr/bin/gh gh api
/repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha`
(http block)
> - `https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.46.1`
> - Triggering command: `/usr/bin/gh gh api
/repos/github/gh-aw/git/ref/tags/v0.46.1 --jq .object.sha` (http block)
> - `https://api.github.com/user`
> - Triggering command: `/usr/bin/gh gh api user --jq .login
-main/dist/indexuser.name` (http block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[language-support] Serena MCP server tools unavailable —
language support tests could not run</issue_title>
> <issue_description>## Summary
>
> The Language Support Tester workflow (run #34, run ID
22164360544) could not complete language support testing for **Go**,
**TypeScript/JavaScript**, and **Python** because the Serena MCP server
tools were not available in the sandbox environment.
>
> ## Failure Details
>
> ### Root Cause
>
> The Docker daemon is not accessible from within the sandbox container:
>
> ```
> Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is
the docker daemon running?
> ```
>
> Because Docker is unavailable, the Serena MCP server container
(`ghcr.io/github/serena-mcp-server:latest`) cannot be started. As a
result, none of the language server tools (`activate_project`,
`find_symbols`, `get_definition`, etc.) were present in the agent's
available tool list.
>
> ### Diagnostic evidence
>
> - `/tmp/gh-aw/mcp-logs/` — empty (no MCP server logs, no `tools.json`)
> - `/tmp/gh-aw/mcp-config/` — contains only `jq-error.log`, no MCP
configuration JSON files
> - `docker images` / `docker ps` — command fails: daemon not reachable
> - `awmg` binary — not found in `PATH`
> - Serena tools (`activate_project`, `find_symbols`, etc.) — absent
from agent function-call interface
>
> ### Languages affected
>
> | Language | Status |
> |---|---|
> | Go | ❌ Not tested — Serena unavailable |
> | TypeScript/JavaScript | ❌ Not tested — Serena unavailable |
> | Python | ❌ Not tested — Serena unavailable |
>
> ## Steps to Reproduce
>
> 1. Trigger the **Language Support Tester** workflow
> 2. Observe that no Serena MCP tools appear in the agent's available
tools
> 3. `docker ps` inside the sandbox returns a daemon connection error
>
> ## Expected Behavior
>
> - Serena MCP server starts successfully
> - `activate_project`, `find_symbols`, `get_definition` tools are
available
> - Language support is verified for Go, TypeScript/JavaScript, and
Python
>
> ## Suggested Investigation
>
> - Verify that the sandbox container has access to the Docker daemon
(Docker-in-Docker or DooD)
> - Confirm the workflow's `tools: serena:` configuration is correctly
translating into MCP server setup
> - Check whether the pre-pull step (`docker pull
ghcr.io/github/serena-mcp-server:latest`) is succeeding before the agent
starts
>
>
>
>
> > Generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/22164360544)
> > - [x] expires <!-- gh-aw-expires: 2026-02-26T01:14:02.300Z --> on
Feb 26, 2026, 1:14 AM UTC
>
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/22164360544 -->
>
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #1088
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
lpcox
added a commit
that referenced
this pull request
Feb 23, 2026
…ddleware chaining code (#1311) ## Summary Consolidates duplicate middleware chaining pattern (`WithSDKLogging` → `rejectIfShutdown` → `applyAuthIfConfigured`) that was replicated verbatim between `CreateHTTPServerForMCP` (transport.go) and `CreateHTTPServerForRoutedMode` (routed.go). ## Changes - **Added `wrapWithMiddleware` helper** in `http_helpers.go` that encapsulates the standard middleware stack with documented spec references (5.1.3 for shutdown, 7.1 for auth) - **Updated both server factories** to use the helper, reducing 9 lines of duplicate code per location to a single function call - **Added comprehensive tests** covering auth scenarios, shutdown behavior, middleware ordering verification, and log tag variations ## Example Before: ```go // Duplicated in both transport.go and routed.go loggedHandler := WithSDKLogging(handler, "unified") shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:transport") finalHandler := applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP) ``` After: ```go // Single call, consistent across both modes finalHandler := wrapWithMiddleware(handler, "unified", unifiedServer, apiKey) ``` ## Impact Adding new middleware layers (rate limiting, tracing, etc.) now requires changes in one location instead of two, with spec references and ordering documented centrally. > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build1187723181/b275/launcher.test /tmp/go-build1187723181/b275/launcher.test -test.testlogfile=/tmp/go-build1187723181/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go HEAD ndor/bin/as --global r = get && echo "--abbrev-ref ortcfg rev-�� 64/src/runtime/c-c=4 64/src/os/dir_un-nolocalimports x_amd64/vet get --global ache/Python/3.12/home/REDACTED/go/pkg/mod/github.com/google/jsonschema-go@v0.4.2/jsonschema/annotations.go x_amd64/vet` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1187723181/b260/config.test /tmp/go-build1187723181/b260/config.test -test.testlogfile=/tmp/go-build1187723181/b260/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ortcfg s.go 64/pkg/tool/linu-o --global go x86-64.so.2 64/pkg/tool/linu-buildtags ortc�� 1554416/b013/_pk-errorsas 64/src/crypto/in-ifaceassert 64/pkg/tool/linu-nilfunc unset --global 86_64/uname 64/pkg/tool/linu-tests` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build1187723181/b275/launcher.test /tmp/go-build1187723181/b275/launcher.test -test.testlogfile=/tmp/go-build1187723181/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go HEAD ndor/bin/as --global r = get && echo "--abbrev-ref ortcfg rev-�� 64/src/runtime/c-c=4 64/src/os/dir_un-nolocalimports x_amd64/vet get --global ache/Python/3.12/home/REDACTED/go/pkg/mod/github.com/google/jsonschema-go@v0.4.2/jsonschema/annotations.go x_amd64/vet` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build1187723181/b275/launcher.test /tmp/go-build1187723181/b275/launcher.test -test.testlogfile=/tmp/go-build1187723181/b275/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go HEAD ndor/bin/as --global r = get && echo "--abbrev-ref ortcfg rev-�� 64/src/runtime/c-c=4 64/src/os/dir_un-nolocalimports x_amd64/vet get --global ache/Python/3.12/home/REDACTED/go/pkg/mod/github.com/google/jsonschema-go@v0.4.2/jsonschema/annotations.go x_amd64/vet` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1187723181/b284/mcp.test /tmp/go-build1187723181/b284/mcp.test -test.testlogfile=/tmp/go-build1187723181/b284/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true go 64/src/internal/-ifaceassert 64/pkg/tool/linu-nilfunc --global user.email ache/Python/3.12--abbrev-ref 64/pkg/tool/linuHEAD abis�� toml@v1.6.0/decode.go toml@v1.6.0/deprecated.go u/13/cc1 -tree /cgroup k/_temp/ghcca-node/node/bin/node/opt/hostedtoolcache/go/1.25.6/x64/src/net u/13/cc1` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>[duplicate-code] Duplicate Code Pattern: Middleware Chaining and HTTP Server Construction</issue_title> > <issue_description>*Part of duplicate code analysis: #1283* > > ## Summary > > The three-step middleware wrapping chain (`WithSDKLogging` → `rejectIfShutdown` → `applyAuthIfConfigured`) and the final `http.Server` construction are duplicated verbatim between `CreateHTTPServerForMCP` (transport.go) and `CreateHTTPServerForRoutedMode` (routed.go), along with identical comments. > > ## Duplication Details > > ### Pattern: Middleware chain + http.Server construction > - **Severity**: Low > - **Occurrences**: 2 (one per HTTP server factory function) > - **Locations**: > - `internal/server/transport.go` (lines 118–135) > - `internal/server/routed.go` (lines 140–162, inside per-backend loop) > > **`transport.go`**: > ````go > // Wrap SDK handler with detailed logging for JSON-RPC translation debugging > loggedHandler := WithSDKLogging(streamableHandler, "unified") > > // Apply shutdown check middleware (spec 5.1.3) > // This must come before auth to ensure shutdown takes precedence > shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:transport") > > // Apply auth middleware if API key is configured (spec 7.1) > finalHandler := applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP) > > mux.Handle("/mcp/", finalHandler) > mux.Handle("/mcp", finalHandler) > > return &http.Server{Addr: addr, Handler: mux} > ```` > > **`routed.go`** (inside per-backend loop, then after): > ````go > loggedHandler := WithSDKLogging(routeHandler, "routed:"+backendID) > shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:routed") > finalHandler := applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP) > > mux.Handle(route+"/", finalHandler) > mux.Handle(route, finalHandler) > > // ... (outside loop) > return &http.Server{Addr: addr, Handler: mux} > ```` > > ## Impact Analysis > > - **Maintainability**: Adding a new middleware layer (e.g., rate limiting, tracing) requires changes in both files. The spec references in comments (5.1.3, 7.1) would also need to be kept in sync. > - **Bug Risk**: Low, since the middleware order is mechanically enforced, but adding middleware only in one place is a realistic mistake. > - **Code Bloat**: Minor (~6 lines duplicated). > > ## Refactoring Recommendations > > 1. **Extract a `wrapWithMiddleware` helper** in `transport.go` or `http_helpers.go`: > ````go > // wrapWithMiddleware applies the standard middleware stack to an SDK handler. > // Order: SDK logging → shutdown check (spec 5.1.3) → auth (spec 7.1) > func wrapWithMiddleware(handler http.Handler, logTag string, unifiedServer *UnifiedServer, apiKey string) http.HandlerFunc { > loggedHandler := WithSDKLogging(handler, logTag) > shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:"+logTag) > return applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP) > } > ```` > > 2. **Optionally extract `buildHTTPServer`**: > ````go > func buildHTTPServer(addr string, mux *http.ServeMux) *http.Server { > return &http.Server{Addr: addr, Handler: mux} > } > ```` > > 3. **Estimated effort**: ~20 minutes > 4. **Benefits**: Middleware order documented and enforced in one place; easier to add new middleware globally > > ## Implementation Checklist > > - [ ] Review duplication findings > - [ ] Extract `wrapWithMiddleware` helper > - [ ] Update `transport.go` and `routed.go` to use the helper > - [ ] Verify middleware order is preserved > - [ ] Verify no functionality broken > > ## Parent Issue > > See parent analysis report: #1283 > Related to #1283 > > > > > > Generated by [Duplicate Code Detector](https://github.com/github/gh-aw-mcpg/actions/runs/22269224479) > > - [x] expires <!-- gh-aw-expires: 2026-03-01T03:02:48.820Z --> on Mar 1, 2026, 3:02 AM UTC > > <!-- gh-aw-agentic-workflow: Duplicate Code Detector, engine: copilot, run: https://github.com/github/gh-aw-mcpg/actions/runs/22269224479 --> > > <!-- gh-aw-workflow-id: duplicate-code-detector --></issue_description> > > ## Comments on the Issue (you are @claude[agent] in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #1284
lpcox
added a commit
that referenced
this pull request
Feb 23, 2026
The language-support-tester workflow was failing at runtime because
Serena MCP tools (`serena-get_symbols_overview`, `serena-find_symbol`)
were unavailable, blocking Go, TypeScript, and Python language support
tests.
## Root Cause
The `.lock.yml` file was compiled with gh-aw v0.48.3 and out of sync
with its source. The workflow needed recompilation to pick up:
- MCP gateway upgrade (v0.1.4 → v0.1.5)
- Compiler improvements (v0.48.3 → v0.49.2)
- Updated prompt handling
## Changes
- Recompiled `.github/workflows/language-support-tester.lock.yml` using
`gh aw compile`
- Updated compiler metadata and dependency versions
## Configuration Verification
The source `.md` file was already correct:
- Serena tool specification: `serena: ["go", "typescript", "python"]`
(array format) ✓
- Container config: `ghcr.io/github/serena-mcp-server:latest` ✓
- Entrypoint: `start-mcp-server --context codex --project
${GITHUB_WORKSPACE}` ✓
- Test samples present for all three languages ✓
Serena tools should now be available when the workflow runs.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build546163221/b275/launcher.test
/tmp/go-build546163221/b275/launcher.test
-test.testlogfile=/tmp/go-build546163221/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build546163221/b160/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/crypto/x509/cert_pool.go rev-��
go HEAD /usr/bin/base64 it base64
ache/Python/3.12/tmp/go-build546163221/b182/_pkg_.a 64/pkg/include` (dns
block)
> - `https://api.github.com/repos/actions/setup-go/git/ref/tags/v6`
> - Triggering command: `/usr/bin/gh gh api
/repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha
/home/REDACTED/.cargo/bin/git base64 tnet/tools/git /usr/bin/base64 git
/usr/local/.ghcup/bin/git base64 -d t git ndor/bin/git 0,
length(NVM_DIbase64 HEAD bin/git git` (http block)
> -
`https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3`
> - Triggering command: `/usr/bin/gh gh api
/repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha`
(http block)
> - Triggering command: `/usr/bin/gh gh api
/repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha
/home/REDACTED/.lo/home/REDACTED/.nvm/Dockerfile base64 cal/bin/git
/usr/bin/base64 with v0.49.2).
-20 /usr/bin/sed base64 -d .12/x64/git sed
/home/REDACTED/.lo/home/REDACTED/.nvm/nvm-exec s/^session\.savebase64
ons/[^/]*)?/[^/]-d /) exit(2);
/home/REDACTED/.nvm/rename_test.sh git` (http block)
> - `https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.49.2`
> - Triggering command: `/usr/bin/gh gh api
/repos/github/gh-aw/git/ref/tags/v0.49.2 --jq .object.sha ndor/bin/git
git /usr/bin/base64 --abbrev-ref HEAD /usr/bin/base64 base64 -d
/usr/bin/awk base64 /usr/bin/base64 /g awk /usr/bin/which t }
}
{ printf "%s%s", sep, HEAD` (http block)
> - Triggering command: `/usr/bin/gh gh api
/repos/github/gh-aw/git/ref/tags/v0.49.2 --jq .object.sha
/usr/local/.ghcup/bin/git base64 it /usr/bin/base64 git ndor/bin/git
base64 -d nfig/composer/vendor/bin/git git /snap/bin/git --abbrev-ref
HEAD ache/uv/0.10.4/x86_64/git git` (http block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build546163221/b260/config.test
/tmp/go-build546163221/b260/config.test
-test.testlogfile=/tmp/go-build546163221/b260/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go
ternal/fips140/a--gdwarf2 64/pkg/tool/linu--64 ^/home/REDACTED/.nas git
/usr/bin/base64 64/pkg/tool/linu-I rev-�� go lang.org/x/text/--64
64/pkg/tool/linu-o
nfig/composer/ve/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet
base64 bin/git 64/pkg/tool/linu/tmp/go-build546163221/b193/vet.cfg` (dns
block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build546163221/b275/launcher.test
/tmp/go-build546163221/b275/launcher.test
-test.testlogfile=/tmp/go-build546163221/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build546163221/b160/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/crypto/x509/cert_pool.go rev-��
go HEAD /usr/bin/base64 it base64
ache/Python/3.12/tmp/go-build546163221/b182/_pkg_.a 64/pkg/include` (dns
block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build546163221/b275/launcher.test
/tmp/go-build546163221/b275/launcher.test
-test.testlogfile=/tmp/go-build546163221/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build546163221/b160/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/crypto/x509/cert_pool.go rev-��
go HEAD /usr/bin/base64 it base64
ache/Python/3.12/tmp/go-build546163221/b182/_pkg_.a 64/pkg/include` (dns
block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build546163221/b284/mcp.test
/tmp/go-build546163221/b284/mcp.test
-test.testlogfile=/tmp/go-build546163221/b284/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true _.a HEAD
64/pkg/tool/linux_amd64/compile de/node/bin/git tail /) exit(2);
-unreachable=false 64/pkg/tool/linu/tmp/go-build546163221/b120/vet.cfg
/hom�� go Usv7CWTeK x_amd64/vet bin/git base64 /usr/bin/head
x_amd64/vet` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>[language-support] Serena MCP tools unavailable —
language support testing blocked (Go, TypeScript/JavaScript,
Python)</issue_title>
> <issue_description>## Summary
>
> The automated language support tester ran and attempted to test Go,
TypeScript/JavaScript, and Python language support using the Serena MCP
server. All three tests failed because the required Serena MCP tools are
not available in the agent's tool inventory.
>
> ## Failed Tests
>
> | Language | Tool Attempted | Result |
> |----------|---------------|--------|
> | Go | `serena-get_symbols_overview` (relative_path:
`internal/server`) | ❌ Tool not available |
> | Go | `serena-find_symbol` | ❌ Tool not available |
> | TypeScript/JavaScript | `serena-get_symbols_overview`
(relative_path:
`test/serena-mcp-tests/samples/js_project/calculator.js`) | ❌ Tool not
available |
> | TypeScript/JavaScript | `serena-find_symbol` | ❌ Tool not available
|
> | Python | `serena-get_symbols_overview` (relative_path:
`test/serena-mcp-tests/samples/python_project/calculator.py`) | ❌ Tool
not available |
> | Python | `serena-find_symbol` | ❌ Tool not available |
>
> ## Error Details
>
> When the agent attempted to call `serena-get_symbols_overview` and
`serena-find_symbol`, neither tool appeared in the available tool set.
The Serena MCP server does not appear to be running and connected as an
MCP server in this workflow environment.
>
> ## Steps to Reproduce
>
> 1. Trigger the `language-support-tester` workflow
> 2. Observe that `serena-get_symbols_overview` and `serena-find_symbol`
are not listed as available tools
> 3. All Serena-based language tests fail
>
> ## Expected Behavior
>
> The Serena MCP server should be running and its tools should be
available with the `serena-` prefix, as documented in
`.github/agentics/language-support-tester.md`.
>
> ## Possible Causes
>
> - The Serena MCP server is not configured or not started in this
workflow
> - The MCP gateway is not routing Serena tool calls correctly
> - The `serena` tool configuration in the workflow definition may be
missing or incorrect (should use array format: `serena: ["go",
"typescript", "python"]`)
>
> ## References
>
> - Workflow definition: `.github/workflows/language-support-tester.md`
> - Agent prompt: `.github/agentics/language-support-tester.md`
>
>
>
>
> > Generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/22292141786)
> > - [x] expires <!-- gh-aw-expires: 2026-03-02T03:49:03.671Z --> on
Mar 2, 2026, 3:49 AM UTC
>
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/22292141786 -->
>
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
>
> ## Comments on the Issue (you are @claude[agent] in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #1309
lpcox
added a commit
that referenced
this pull request
Mar 10, 2026
…cies exist (#1741) The v0.1.12 auto-detection introduced a timing bug where guards were downgraded to noop during registration, before DIFC auto-enablement ran. This broke AllowOnly enforcement in smoke tests. ## Problem Guard registration (line 180) happens before auto-detection (line 188). When `requireGuardPolicyIfGuardEnabled` finds no resolved policy during registration, it falls back to noop. By the time `hasServerGuardPolicies(cfg)` triggers auto-enablement, the guard is already noop. ## Solution Modified `requireGuardPolicyIfGuardEnabled` to check `serverCfg.GuardPolicies` before falling back: ```go if policy == nil { // Keep non-noop guard if server has guard policies configured if serverCfg, ok := us.cfg.Servers[serverID]; ok && len(serverCfg.GuardPolicies) > 0 { return g, nil // Guard will be initialized on first use } return guard.NewNoopGuard(), nil } ``` This preserves the WASM guard discovered from `/guards/{serverID}/` when guard policies exist, allowing proper initialization during `ensureGuardInitialized`. ## Changes - **internal/server/unified.go**: Added guard policy check before noop fallback - **internal/server/require_guard_policy_test.go**: Tests for fallback behavior with/without policies - **internal/server/guard_policy_parsing_test.go**: Tests for `parseServerGuardPolicy` and `resolveGuardPolicy` - **internal/server/has_server_guard_policies_test.go**: Tests for policy detection logic > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build2269947796/b332/launcher.test /tmp/go-build2269947796/b332/launcher.test -test.testlogfile=/tmp/go-build2269947796/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 --abbrev-ref 877973+lpcox@userev-parse ache/Python/3.12--abbrev-ref base64 -d 64/pkg/tool/linu--abbrev-ref base64 /usr/bin/dirname x_amd64/compile 64/pkg/tool/linu-d ndor/bin/git t } } { printf "%s%s", sep, HEAD` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build2269947796/b314/config.test /tmp/go-build2269947796/b314/config.test -test.testlogfile=/tmp/go-build2269947796/b314/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 m/CLAUDE.md m/CODE_OF_CONDUC-o ache/go/1.25.7/x/tmp/go-build1778197618/b062/_pkg_.a base64 -d m/LICENSE.md m/Makefile /home/REDACTED/go/-lang=go1.25 m/README.md m/ROADMAP.md Policy_ServerGuaccs13v1iKv05Y3GP5cax/ccs13v1iKv05Y3GP5cax git` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build2269947796/b332/launcher.test /tmp/go-build2269947796/b332/launcher.test -test.testlogfile=/tmp/go-build2269947796/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 --abbrev-ref 877973+lpcox@userev-parse ache/Python/3.12--abbrev-ref base64 -d 64/pkg/tool/linu--abbrev-ref base64 /usr/bin/dirname x_amd64/compile 64/pkg/tool/linu-d ndor/bin/git t } } { printf "%s%s", sep, HEAD` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build2269947796/b332/launcher.test /tmp/go-build2269947796/b332/launcher.test -test.testlogfile=/tmp/go-build2269947796/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD /usr/bin/base64 --abbrev-ref 877973+lpcox@userev-parse ache/Python/3.12--abbrev-ref base64 -d 64/pkg/tool/linu--abbrev-ref base64 /usr/bin/dirname x_amd64/compile 64/pkg/tool/linu-d ndor/bin/git t } } { printf "%s%s", sep, HEAD` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build2269947796/b341/mcp.test /tmp/go-build2269947796/b341/mcp.test -test.testlogfile=/tmp/go-build2269947796/b341/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD ptables --abbrev-ref 877973+lpcox@use-c tnet/tools/git base64` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details>
lpcox
added a commit
that referenced
this pull request
Mar 11, 2026
Addresses duplicate code analysis findings: ~60 lines of repeated mutex-locking and logging patterns across logger and DIFC packages. ## Changes **DIFC Tag Mutation (#1767)** - 21 lines reduced - Extracted `modifyTag` helper to consolidate mutex-lock + dual-logging pattern - Refactored `AddSecrecyTag`, `AddIntegrityTag`, `DropIntegrityTag` ```go // Before: duplicated 7-line pattern in each method func (a *AgentLabels) AddSecrecyTag(tag Tag) { logAgent.Printf("Agent %s adding secrecy tag: %s", a.AgentID, tag) a.mu.Lock() defer a.mu.Unlock() a.Secrecy.Label.Add(tag) log.Printf("[DIFC] Agent %s gained secrecy tag: %s", a.AgentID, tag) } // After: unified helper func (a *AgentLabels) AddSecrecyTag(tag Tag) { a.modifyTag("secrecy", "adding", "gained", tag, func() { a.Secrecy.Label.Add(tag) }) } ``` **Global Logger RWMutex Access (#1768)** - 40 lines reduced - Created generic `withGlobalLogger` helper with `closableLogger` constraint - Refactored 8+ call sites across file_logger, markdown_logger, jsonl_logger, server_file_logger, tools_logger, rpc_logger ```go // Before: duplicated RWMutex pattern globalLoggerMu.RLock() defer globalLoggerMu.RUnlock() if globalLogger != nil { globalLogger.DoSomething(args...) } // After: type-safe generic helper withGlobalLogger(&globalLoggerMu, &globalLogger, func(logger *Logger) { logger.DoSomething(args...) }) ``` **Logger Initialization (#1766)** - No changes required - Reviewed existing `initLogger` generic - already well-abstracted - Documented pattern rationale in common.go ## Documentation Added "Global Logger RWMutex Access Pattern" section to `internal/logger/common.go` explaining the refactoring approach and benefits. > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build2039083650/b332/launcher.test /tmp/go-build2039083650/b332/launcher.test -test.testlogfile=/tmp/go-build2039083650/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true se stmain.go ache/go/1.25.7/x64/pkg/tool/linux_amd64/link . --gdwarf2 --64 ache/go/1.25.7/x64/pkg/tool/linuHEAD -I 7410264/b320/difc.test -I 86_64/git --gdwarf-5 --64 -o Rlvht1SmvPjlx/EgKV67uNxy1s5Sk4WJTJ/FFffmGA1P5hLrHEAD` (dns block) > - Triggering command: `/tmp/go-build139309952/b332/launcher.test /tmp/go-build139309952/b332/launcher.test -test.testlogfile=/tmp/go-build139309952/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg /opt/hostedtoolc-goversion 64/pkg/tool/linux_amd64/vet -bool -buildtags ache/go/1.25.7/x/tmp/go-build139309952/b319/_pkg_.a 64/pkg/tool/linu-trimpath rev-�� .cfg HEAD ache/go/1.25.7/x-lang=go1.25 --abbrev-ref HEAD tnet/tools/git tf "%s%s", sep, -goversion` (dns block) > - Triggering command: `/tmp/go-build311971124/b336/launcher.test /tmp/go-build311971124/b336/launcher.test -test.testlogfile=/tmp/go-build311971124/b336/testlog.txt -test.paniconexit0 -test.timeout=10m0s star��` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build2039083650/b314/config.test /tmp/go-build2039083650/b314/config.test -test.testlogfile=/tmp/go-build2039083650/b314/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 7410264/b253/_pkg_.a /tmp/go-build1837410264/b068/vet.cfg ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet -dumpbase ntio/asm/base64 -dumpbase-ext ache/go/1.25.7/xHEAD eU_a�� /opt/hostedtoolcache/go/1.25.7/x64/src/net -I rgo/bin/git 7410264/b253/symbase64 --64 -o /opt/hostedtoolcache/go/1.25.7/xHEAD` (dns block) > - Triggering command: `/tmp/go-build139309952/b314/config.test /tmp/go-build139309952/b314/config.test -test.testlogfile=/tmp/go-build139309952/b314/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ; s#^/home/REDACTED/.nvm/##; \#^[^v]# d; \#^versions$# d; tr /opt/hostedtoolcache/go/1.25.7/xHEAD 64/pkg/tool/linux_amd64/vet pkg/mod/github.cgit pkg/mod/github.crev-parse ache/Python/3.12--abbrev-ref 64/pkg/tool/linuHEAD /usr�� .cfg /opt/hostedtoolc-test.timeout=10m0s 64/pkg/tool/linux_amd64/vet github.com/segmebase64 -trimpath .12/x64/git 64/pkg/tool/linux_amd64/vet` (dns block) > - Triggering command: `/tmp/go-build311971124/b318/config.test /tmp/go-build311971124/b318/config.test -test.testlogfile=/tmp/go-build311971124/b318/testlog.txt -test.paniconexit0 -test.timeout=10m0s .pro�� /opt/hostedtoolc--abbrev-ref /opt/hostedtoolcHEAD d-dispatcher/off.d/chrony-onoffline /tmp/go-build186dirname git 64/pkg/tool/linux_amd64/compile d-dispatcher/off.d/chrony-onoffline -nam�� moby -id /usr/bin/runc.original -address /run/containerd/-d docker-buildx /usr/bin/runc.original` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build2039083650/b332/launcher.test /tmp/go-build2039083650/b332/launcher.test -test.testlogfile=/tmp/go-build2039083650/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true se stmain.go ache/go/1.25.7/x64/pkg/tool/linux_amd64/link . --gdwarf2 --64 ache/go/1.25.7/x64/pkg/tool/linuHEAD -I 7410264/b320/difc.test -I 86_64/git --gdwarf-5 --64 -o Rlvht1SmvPjlx/EgKV67uNxy1s5Sk4WJTJ/FFffmGA1P5hLrHEAD` (dns block) > - Triggering command: `/tmp/go-build139309952/b332/launcher.test /tmp/go-build139309952/b332/launcher.test -test.testlogfile=/tmp/go-build139309952/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg /opt/hostedtoolc-goversion 64/pkg/tool/linux_amd64/vet -bool -buildtags ache/go/1.25.7/x/tmp/go-build139309952/b319/_pkg_.a 64/pkg/tool/linu-trimpath rev-�� .cfg HEAD ache/go/1.25.7/x-lang=go1.25 --abbrev-ref HEAD tnet/tools/git tf "%s%s", sep, -goversion` (dns block) > - Triggering command: `/tmp/go-build311971124/b336/launcher.test /tmp/go-build311971124/b336/launcher.test -test.testlogfile=/tmp/go-build311971124/b336/testlog.txt -test.paniconexit0 -test.timeout=10m0s star��` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build2039083650/b332/launcher.test /tmp/go-build2039083650/b332/launcher.test -test.testlogfile=/tmp/go-build2039083650/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true se stmain.go ache/go/1.25.7/x64/pkg/tool/linux_amd64/link . --gdwarf2 --64 ache/go/1.25.7/x64/pkg/tool/linuHEAD -I 7410264/b320/difc.test -I 86_64/git --gdwarf-5 --64 -o Rlvht1SmvPjlx/EgKV67uNxy1s5Sk4WJTJ/FFffmGA1P5hLrHEAD` (dns block) > - Triggering command: `/tmp/go-build139309952/b332/launcher.test /tmp/go-build139309952/b332/launcher.test -test.testlogfile=/tmp/go-build139309952/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg /opt/hostedtoolc-goversion 64/pkg/tool/linux_amd64/vet -bool -buildtags ache/go/1.25.7/x/tmp/go-build139309952/b319/_pkg_.a 64/pkg/tool/linu-trimpath rev-�� .cfg HEAD ache/go/1.25.7/x-lang=go1.25 --abbrev-ref HEAD tnet/tools/git tf "%s%s", sep, -goversion` (dns block) > - Triggering command: `/tmp/go-build311971124/b336/launcher.test /tmp/go-build311971124/b336/launcher.test -test.testlogfile=/tmp/go-build311971124/b336/testlog.txt -test.paniconexit0 -test.timeout=10m0s star��` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build2039083650/b341/mcp.test /tmp/go-build2039083650/b341/mcp.test -test.testlogfile=/tmp/go-build2039083650/b341/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true /opt/hostedtoolcache/go/1.25.7/x64/src/net -I iptables --gdwarf-5 --64 -o as -I /opt/hostedtoolcache/go/1.25.7/x64/src/net -I 7410264/b248/vet.cfg --gdwarf-5 --64 -o */bin.*$") { next } } { printf "%s%s", sep, HEAD` (dns block) > - Triggering command: `/tmp/go-build139309952/b341/mcp.test /tmp/go-build139309952/b341/mcp.test -test.testlogfile=/tmp/go-build139309952/b341/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -importcfg 4E-sSYy/pwgIjRIG-w ache/go/1.25.7/x-buildmode=exe --abbrev-ref HEAD nfig/composer/ve--version ache/go/1.25.7/x-extld=gcc` (dns block) > - Triggering command: `/tmp/go-build311971124/b345/mcp.test /tmp/go-build311971124/b345/mcp.test -test.testlogfile=/tmp/go-build311971124/b345/testlog.txt -test.paniconexit0 -test.timeout=10m0s /usr�� 1dedc330cd146d1731f9c903fe295e422bb440808c4a20ae /var/run/docker/runtime-runc/moby 86_64/git /run/containerd//opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet --log-format json 1a2fc60e6817294b-buildtags /usr�� --root /var/run/docker/-ifaceassert by/7842e098fbefc-nilfunc /run/containerd/bash 1a2fc60e6817294b/usr/bin/runc json 1a2fc60e6817294b-tests` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details>
lpcox
added a commit
that referenced
this pull request
Mar 11, 2026
## Summary Eliminates ~71 lines of duplicate code across the DIFC package by extracting two generic helpers. Addresses issue #1719 patterns 2 and 3 (pattern 1 was previously resolved). ## Changes ### CheckFlow Consolidation (`labels.go`) **Problem**: `SecrecyLabel.CheckFlow` and `IntegrityLabel.CheckFlow` contained 58 lines of nearly identical nil handling, locking, and tag iteration logic with only semantic differences (subset vs superset checks). **Solution**: Extracted `checkFlowHelper` that parameterizes flow semantics: ```go // Generic helper with parameterized semantics func checkFlowHelper(srcLabel *Label, targetLabel *Label, checkSubset bool, labelType string) (bool, []Tag) // Thin wrappers (10 lines each) func (l *SecrecyLabel) CheckFlow(target *SecrecyLabel) (bool, []Tag) { return checkFlowHelper(l.Label, target.Label, true, "Secrecy") // subset check } func (l *IntegrityLabel) CheckFlow(target *IntegrityLabel) (bool, []Tag) { return checkFlowHelper(l.Label, target.Label, false, "Integrity") // superset check } ``` ### EvaluationResult Initialization (`evaluator.go`) **Problem**: Three evaluation functions repeated identical 5-line initialization blocks. **Solution**: Extracted `newEmptyEvaluationResult()` helper used by `Evaluate`, `evaluateRead`, and `evaluateWrite`. ## Testing - Added 12 comprehensive test cases for new helpers - All existing tests pass (100+ in difc package) - No behavior changes > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build817523219/b332/launcher.test /tmp/go-build817523219/b332/launcher.test -test.testlogfile=/tmp/go-build817523219/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.7/x64/src/runtime/c-errorsas J4aB/2fPHF0HdMhn8ydxhJ4aB 64/pkg/tool/linux_amd64/vet -I /tmp/go-build151-n -I 64/pkg/tool/linux_amd64/vet go_.�� 8036719/b171=/tmp/go-build .cfg 64/pkg/tool/linux_amd64/vet -p ache/go/1.25.7/x-d -lang=go1.16 64/pkg/tool/linux_amd64/vet` (dns block) > - Triggering command: `/tmp/go-build2582390263/b336/launcher.test /tmp/go-build2582390263/b336/launcher.test -test.testlogfile=/tmp/go-build2582390263/b336/testlog.txt -test.paniconexit0 -test.timeout=10m0s [ �� --prefix=/net/ipv4/neigh/veth8c3e74e --prefix=/net/ipv6/conf/veth8c3e74e ache/uv/0.10.9/x86_64/git --64 ache/go/1.25.7/x-d /snap/bin/git bash /usr�� --root /var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet /run/containerd/bash --log-format 619fd60bb04098d5--version 64/pkg/tool/linux_amd64/vet` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build817523219/b314/config.test /tmp/go-build817523219/b314/config.test -test.testlogfile=/tmp/go-build817523219/b314/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true o QT x_amd64/vet -p g/x/net/idna -lang=go1.25 x_amd64/vet go_.�� 64/src/net ache/go/1.25.7/x64/src/runtime/c-nolocalimports ache/go/1.25.7/x64/pkg/tool/linu-importcfg 8036719/b171/ crypto/internal/-d` (dns block) > - Triggering command: `/tmp/go-build2582390263/b318/config.test /tmp/go-build2582390263/b318/config.test -test.testlogfile=/tmp/go-build2582390263/b318/testlog.txt -test.paniconexit0 -test.timeout=10m0s e755�� moby -address x_amd64/vet -publish-binary /usr/bin/contain/home/REDACTED/work/_temp/ghcca-node/node -id x_amd64/vet de/n�� /run/containerd/io.containerd.runtime.v2.task/moby/d20f582628202OUTPUT delete /opt/containerd/bin/bash s-through=-lpthrbase64 ache/go/1.25.7/x-d ine bash` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build817523219/b332/launcher.test /tmp/go-build817523219/b332/launcher.test -test.testlogfile=/tmp/go-build817523219/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.7/x64/src/runtime/c-errorsas J4aB/2fPHF0HdMhn8ydxhJ4aB 64/pkg/tool/linux_amd64/vet -I /tmp/go-build151-n -I 64/pkg/tool/linux_amd64/vet go_.�� 8036719/b171=/tmp/go-build .cfg 64/pkg/tool/linux_amd64/vet -p ache/go/1.25.7/x-d -lang=go1.16 64/pkg/tool/linux_amd64/vet` (dns block) > - Triggering command: `/tmp/go-build2582390263/b336/launcher.test /tmp/go-build2582390263/b336/launcher.test -test.testlogfile=/tmp/go-build2582390263/b336/testlog.txt -test.paniconexit0 -test.timeout=10m0s [ �� --prefix=/net/ipv4/neigh/veth8c3e74e --prefix=/net/ipv6/conf/veth8c3e74e ache/uv/0.10.9/x86_64/git --64 ache/go/1.25.7/x-d /snap/bin/git bash /usr�� --root /var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet /run/containerd/bash --log-format 619fd60bb04098d5--version 64/pkg/tool/linux_amd64/vet` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build817523219/b332/launcher.test /tmp/go-build817523219/b332/launcher.test -test.testlogfile=/tmp/go-build817523219/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.7/x64/src/runtime/c-errorsas J4aB/2fPHF0HdMhn8ydxhJ4aB 64/pkg/tool/linux_amd64/vet -I /tmp/go-build151-n -I 64/pkg/tool/linux_amd64/vet go_.�� 8036719/b171=/tmp/go-build .cfg 64/pkg/tool/linux_amd64/vet -p ache/go/1.25.7/x-d -lang=go1.16 64/pkg/tool/linux_amd64/vet` (dns block) > - Triggering command: `/tmp/go-build2582390263/b336/launcher.test /tmp/go-build2582390263/b336/launcher.test -test.testlogfile=/tmp/go-build2582390263/b336/testlog.txt -test.paniconexit0 -test.timeout=10m0s [ �� --prefix=/net/ipv4/neigh/veth8c3e74e --prefix=/net/ipv6/conf/veth8c3e74e ache/uv/0.10.9/x86_64/git --64 ache/go/1.25.7/x-d /snap/bin/git bash /usr�� --root /var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet /run/containerd/bash --log-format 619fd60bb04098d5--version 64/pkg/tool/linux_amd64/vet` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build817523219/b341/mcp.test /tmp/go-build817523219/b341/mcp.test -test.testlogfile=/tmp/go-build817523219/b341/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true p=/opt/hostedtoolcache/go/1.25.7/x64=/_/GOROOT .cfg 64/pkg/tool/linux_amd64/vet --gdwarf-5 --64 -o 64/pkg/tool/linux_amd64/vet 8036�� /server/auth.go /server/handlers.go 64/pkg/tool/linux_amd64/vet /tmp/go-build151/usr/bin/runc.original -imultiarch x86_64-linux-gnu 64/pkg/tool/linux_amd64/vet` (dns block) > - Triggering command: `/tmp/go-build2582390263/b345/mcp.test /tmp/go-build2582390263/b345/mcp.test -test.testlogfile=/tmp/go-build2582390263/b345/testlog.txt -test.paniconexit0 -test.timeout=10m0s crea�� b1f0f2a3ed4d89922f26e357de08e619fd60bb04098d570e /run/containerd/io.containerd.runtime.v2.task/moby/f41fcf883e64cbb1a392bb10395bbjson 64/pkg/tool/linux_amd64/vet /run/containerd//usr/bin/runc.original l || true && eva--version /usr/bin/base64 64/pkg/tool/linux_amd64/vet /usr�� .cfg /var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet /run/containerd/bash --log-format json with other checks..."; \ elif command -v golan` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details>
lpcox
added a commit
that referenced
this pull request
Mar 13, 2026
Addresses duplicate code analysis identifying ~50 lines of structural
duplication across two patterns in `internal/server/unified.go`.
## Changes
### Pattern 1: Backend Tool Call Execution (~40 lines eliminated)
Extracted `executeBackendToolCall` helper consolidating:
- Connection management via `launcher.GetOrLaunchForSession`
- `tools/call` request dispatch
- Backend error checking
- Result unmarshaling
**Before:**
```go
// guardBackendCaller.CallTool and callBackendTool Phase 3 each had:
conn, err := launcher.GetOrLaunchForSession(us.launcher, serverID, sessionID)
if err != nil { ... }
response, err := conn.SendRequestWithServerID(ctx, "tools/call", ...)
if err != nil { ... }
if response.Error != nil { ... }
var result interface{}
json.Unmarshal(response.Result, &result)
```
**After:**
```go
result, err := executeBackendToolCall(ctx, us.launcher, serverID, sessionID, toolName, args)
```
### Pattern 2: Sys Tool Delegation (~10 lines eliminated)
Extracted `callSysServer` helper consolidating:
- Tool name marshaling
- `sysServer.HandleRequest` delegation
**Before:**
```go
// sysInitHandler and sysListHandler each had:
params, _ := json.Marshal(map[string]interface{}{
"name": toolName,
"arguments": map[string]interface{}{},
})
result, err := us.sysServer.HandleRequest("tools/call", json.RawMessage(params))
```
**After:**
```go
result, err := us.callSysServer("sys_init")
```
## Impact
- Eliminates copy-paste error risk when modifying backend call or sys
server logic
- Follows existing helper patterns (`newErrorCallToolResult`,
`parseToolArguments`)
- No functional changes—pure refactoring
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build4242760615/b336/launcher.test
/tmp/go-build4242760615/b336/launcher.test
-test.testlogfile=/tmp/go-build4242760615/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -uns�� ache/go/1.25.7/x64/src/net
/tmp/go-build1249286257/b024/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet unset position.go
.12/x64/bin/git ache/go/1.25.7/x64/pkg/tool/linuHEAD -W -I
/tmp/go-build1249286257/b165/
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b332/launcher.test
/tmp/go-build2320097585/b332/launcher.test
-test.testlogfile=/tmp/go-build2320097585/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/bin/git ortcfg
/usr/sbin/bash submodules | heanode 9286257/b132/vet-v ndor/bin/git bash
/usr�� runtime-runc/moby ortcfg csi/net-interface-handler
aw-mcpg/internal/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/asm
aw-mcpg/internal-V=full` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build4242760615/b318/config.test
/tmp/go-build4242760615/b318/config.test
-test.testlogfile=/tmp/go-build4242760615/b318/testlog.txt
-test.paniconexit0 -test.timeout=10m0s --de�� c.test --debug-prefix-map
64/bin/git -I /opt/hostedtoolc-unsafeptr=false ut-1969789729.c
VF78F_aidvBPXKXaKR/S4HB-3OSyH3DKHEAD` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b314/config.test
/tmp/go-build2320097585/b314/config.test
-test.testlogfile=/tmp/go-build2320097585/b314/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 17fb9960acf3cdef
-importcfg ine by/b2276789a3c14/usr/bin/chronyc -w -buildmode=exe ine
--ve�� 85e4fa5c5748c5dd -extld=gcc /opt/hostedtoolcache/go/1.25.7/xjson
aw-mcpg/internalbase64 9286257/b151/vet-d ns
/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu--listen` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build4242760615/b336/launcher.test
/tmp/go-build4242760615/b336/launcher.test
-test.testlogfile=/tmp/go-build4242760615/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -uns�� ache/go/1.25.7/x64/src/net
/tmp/go-build1249286257/b024/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet unset position.go
.12/x64/bin/git ache/go/1.25.7/x64/pkg/tool/linuHEAD -W -I
/tmp/go-build1249286257/b165/
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b332/launcher.test
/tmp/go-build2320097585/b332/launcher.test
-test.testlogfile=/tmp/go-build2320097585/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/bin/git ortcfg
/usr/sbin/bash submodules | heanode 9286257/b132/vet-v ndor/bin/git bash
/usr�� runtime-runc/moby ortcfg csi/net-interface-handler
aw-mcpg/internal/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/asm
aw-mcpg/internal-V=full` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build4242760615/b336/launcher.test
/tmp/go-build4242760615/b336/launcher.test
-test.testlogfile=/tmp/go-build4242760615/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -uns�� ache/go/1.25.7/x64/src/net
/tmp/go-build1249286257/b024/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet unset position.go
.12/x64/bin/git ache/go/1.25.7/x64/pkg/tool/linuHEAD -W -I
/tmp/go-build1249286257/b165/
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b332/launcher.test
/tmp/go-build2320097585/b332/launcher.test
-test.testlogfile=/tmp/go-build2320097585/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/bin/git ortcfg
/usr/sbin/bash submodules | heanode 9286257/b132/vet-v ndor/bin/git bash
/usr�� runtime-runc/moby ortcfg csi/net-interface-handler
aw-mcpg/internal/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/asm
aw-mcpg/internal-V=full` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build4242760615/b345/mcp.test
/tmp/go-build4242760615/b345/mcp.test
-test.testlogfile=/tmp/go-build4242760615/b345/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -I ache/go/1.25.7/x64/src/net -I
if (a[i] && a[i] !~ /^[0-9]+$/) exit(2);
if (a[i] < b[i]) exit(3);
else if (a[i] > b[i]) exit(0) --gdwarf-5 --64 -o
ache/go/1.25.7/x64/pkg/tool/linuHEAD -o
/tmp/go-build1249286257/b210/_pkg_.a -trimpath
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet -p
github.com/githu/tmp/go-build3632611954/b228/vet.cfg -lang=go1.25
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b341/mcp.test
/tmp/go-build2320097585/b341/mcp.test
-test.testlogfile=/tmp/go-build2320097585/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/internal/strutil/truncat6662819a7d6931901c1593745131476bbash
y CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt",
"REQUESTS_CA_BUNDLE=/etc/ssl/c--version
by/bd0209c110101/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/link
aw-mcpg/internal-o
ache/go/1.25.7/x/tmp/go-build2320097585/b314/config.test docker insp��
551622d230bb31fc-s by/bd0209c110101-w rtificates.crt",-buildmode=exe
by/a501e7528e5b9bash e330148d0ce51d5e/usr/bin/runc` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>
lpcox
added a commit
that referenced
this pull request
Mar 19, 2026
…edup logic (#2123) The trim→skip-empty→deduplicate→optional-sort pattern was reimplemented inline in three separate packages, with behavioral drift already present (silent skip vs. error on duplicate, whitespace rejection in one but not others). ## Changes - **`internal/strutil/deduplicate.go`** — new `DeduplicateStrings(input []string, sorted bool) []string` canonical helper - **`internal/strutil/deduplicate_test.go`** — table-driven tests covering nil input, trim, dedup, sort, and order preservation - **`internal/difc/sink_server_ids.go`** — replace 14-line inline loop with `strutil.DeduplicateStrings(serverIDs, true)`; log when entries are dropped - **`internal/cmd/flags_difc.go`** — `parseDIFCSinkServerIDs`: keep the embedded-whitespace error check (not handled by the helper), delegate dedup to `strutil.DeduplicateStrings` - **`internal/config/guard_policy.go`** — unchanged; `normalizeAndValidateScopeArray` returns an error on duplicates rather than silently dropping them, so it doesn't share the same contract ## Before / After ```go // Before — ~15 lines repeated inline in SetSinkServerIDs unique := make(map[string]struct{}, len(serverIDs)) normalized := make([]string, 0, len(serverIDs)) for _, serverID := range serverIDs { trimmed := strings.TrimSpace(serverID) if trimmed == "" { continue } if _, exists := unique[trimmed]; exists { duplicateIDs = append(duplicateIDs, trimmed) continue } unique[trimmed] = struct{}{} normalized = append(normalized, trimmed) } sort.Strings(normalized) // After normalized := strutil.DeduplicateStrings(serverIDs, true) ``` > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `example.com` > - Triggering command: `/tmp/go-build1731765213/b332/launcher.test /tmp/go-build1731765213/b332/launcher.test -test.testlogfile=/tmp/go-build1731765213/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s conf�� 1.4.0/auth/auth.go 1.4.0/auth/client.go x_amd64/compile` (dns block) > - Triggering command: `/tmp/go-build908205860/b328/launcher.test /tmp/go-build908205860/b328/launcher.test -test.testlogfile=/tmp/go-build908205860/b328/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --version y 06bc07c272bb18e2 ntime.v2.task/mosystemd-run containerd.sock x_amd64/vet ctl insp�� .go {{.Config.OpenSt--property=CPUQuota=5% /usr/libexec/doc--property=MemoryHigh=170M 64/src/net ache/go/1.25.8/xinfo x_amd64/vet 45045761271a86c7-collect-logs` (dns block) > - `invalid-host-that-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1731765213/b317/config.test /tmp/go-build1731765213/b317/config.test -test.testlogfile=/tmp/go-build1731765213/b317/testlog.txt -test.paniconexit0 -test.timeout=10m0s conf�� .go` (dns block) > - Triggering command: `/tmp/go-build908205860/b313/config.test /tmp/go-build908205860/b313/config.test -test.testlogfile=/tmp/go-build908205860/b313/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 9c9123b84b4d4e8c -tests ash b8a4de3a75e76448grep fe9 x_amd64/compile fe9/init.pid --ve�� c48959766ef0f63f b8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502 "CURL_CA_BUNDLE=/--systemd-cgroup b8a4de3a75e76448git` (dns block) > - `nonexistent.local` > - Triggering command: `/tmp/go-build1731765213/b332/launcher.test /tmp/go-build1731765213/b332/launcher.test -test.testlogfile=/tmp/go-build1731765213/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s conf�� 1.4.0/auth/auth.go 1.4.0/auth/client.go x_amd64/compile` (dns block) > - Triggering command: `/tmp/go-build908205860/b328/launcher.test /tmp/go-build908205860/b328/launcher.test -test.testlogfile=/tmp/go-build908205860/b328/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --version y 06bc07c272bb18e2 ntime.v2.task/mosystemd-run containerd.sock x_amd64/vet ctl insp�� .go {{.Config.OpenSt--property=CPUQuota=5% /usr/libexec/doc--property=MemoryHigh=170M 64/src/net ache/go/1.25.8/xinfo x_amd64/vet 45045761271a86c7-collect-logs` (dns block) > - `slow.example.com` > - Triggering command: `/tmp/go-build1731765213/b332/launcher.test /tmp/go-build1731765213/b332/launcher.test -test.testlogfile=/tmp/go-build1731765213/b332/testlog.txt -test.paniconexit0 -test.timeout=10m0s conf�� 1.4.0/auth/auth.go 1.4.0/auth/client.go x_amd64/compile` (dns block) > - Triggering command: `/tmp/go-build908205860/b328/launcher.test /tmp/go-build908205860/b328/launcher.test -test.testlogfile=/tmp/go-build908205860/b328/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true --version y 06bc07c272bb18e2 ntime.v2.task/mosystemd-run containerd.sock x_amd64/vet ctl insp�� .go {{.Config.OpenSt--property=CPUQuota=5% /usr/libexec/doc--property=MemoryHigh=170M 64/src/net ache/go/1.25.8/xinfo x_amd64/vet 45045761271a86c7-collect-logs` (dns block) > - `this-host-does-not-exist-12345.com` > - Triggering command: `/tmp/go-build1731765213/b341/mcp.test /tmp/go-build1731765213/b341/mcp.test -test.testlogfile=/tmp/go-build1731765213/b341/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build1731765213/b271/vet.cfg flib/difflib.go main x_amd64/cgo` (dns block) > - Triggering command: `/tmp/go-build908205860/b337/mcp.test /tmp/go-build908205860/b337/mcp.test -test.testlogfile=/tmp/go-build908205860/b337/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true y x_amd64/vet by/027a141771b2cb8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502/log.json azero@v1.11.0/bugrep azero@v1.11.0/ca-qE x_amd64/vet 709/log.json 92b4�� by/027a141771b2cb8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502 --bundle by/027a141771b2cb8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502/init.pid 6efe353b9d178502bash 77a1358e1f687d17/usr/bin/runc x_amd64/vet table.d/chrony-onoffline` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT TIPS --> --- 📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs), [Azure Boards](https://gh.io/cca-azure-boards-docs) or [Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in one click without leaving your project management tool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changed
make releasesyntax frommake release BUMP=patchtomake release patchand corrected the workflow URL.Changes
$(filter-out $@,$(MAKECMDGOALS))to capture bump type as positional argument instead of Makefile variable%: @:rule to prevent make from treating the argument as a separate targetrelease.mdtorelease.lock.ymlUsage
Error handling remains unchanged - validates bump type and prompts for confirmation before creating tags.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.