From ab78bc0c95ab9bb6b155e160fc156f5a3b3740ec Mon Sep 17 00:00:00 2001 From: brady gaster Date: Tue, 18 Aug 2026 01:16:53 -0700 Subject: [PATCH 1/2] fix(workflows): allow nested source files and package-registry egress Two defects found during a live end-to-end run against a real .NET repository. Both compile clean and fail only at agent runtime. allowed-files matched the repository root only. The 40 extension globs were declared bare (`*.cs`, `*.csproj`, `*.java`, ...), and `*` does not cross `/`, so nothing outside the root matched. The supplementary directory globs are all lowercase conventional names, so a repository using top-level project folders -- the default .NET solution layout -- had no file the worker was permitted to change. Observed live: 5 `.csproj`, 3 `.cs`, and one dotfile path all rejected; the run reported success and no pull request appeared. Each extension now has a `**/*.ext` mirror alongside the root form, `Dockerfile*` and `Makefile` gained nested variants, and `*.razor` was added -- it was missing entirely, which blocked Blazor components at any depth. network.allowed granted no package registry. `[defaults]` covers GitHub and certificate infrastructure only, so the agent could not restore dependencies and therefore could not build or test its own work. Observed live: `dotnet restore` took a proxy 403 against api.nuget.org, and the worker correctly reported the task incomplete rather than guessing. Added the ecosystem identifiers containers, dotnet, go, java, node, python, ruby, and rust. Scoped to the worker. `workflows/squad.md` plans and routes rather than restoring packages, so its network surface stays narrow. Closes #1743 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 090e9874-9835-489a-b38d-05a450b3fc53 --- workflows/squad-implement-worker.md | 55 ++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md index fb9e81272..b6401f4cc 100644 --- a/workflows/squad-implement-worker.md +++ b/workflows/squad-implement-worker.md @@ -32,6 +32,14 @@ concurrency: network: allowed: - defaults + - containers + - dotnet + - go + - java + - node + - python + - ruby + - rust imports: - shared/squad.md tools: @@ -51,48 +59,93 @@ safe-outputs: - "squad/implement-*" allowed-files: - "*.c" + - "**/*.c" - "*.cc" + - "**/*.cc" - "*.cjs" + - "**/*.cjs" - "*.cpp" + - "**/*.cpp" - "*.cs" + - "**/*.cs" - "*.csproj" + - "**/*.csproj" - "*.css" + - "**/*.css" - "*.fs" + - "**/*.fs" - "*.fsproj" + - "**/*.fsproj" - "*.go" + - "**/*.go" - "*.gradle" + - "**/*.gradle" - "*.h" + - "**/*.h" - "*.hpp" + - "**/*.hpp" - "*.html" + - "**/*.html" - "*.java" + - "**/*.java" - "*.js" - - "*.jsx" + - "**/*.js" - "*.json" + - "**/*.json" + - "*.jsx" + - "**/*.jsx" - "*.kt" + - "**/*.kt" - "*.kts" + - "**/*.kts" - "*.md" + - "**/*.md" - "*.mjs" + - "**/*.mjs" - "*.php" + - "**/*.php" - "*.props" + - "**/*.props" - "*.py" + - "**/*.py" + - "*.razor" + - "**/*.razor" - "*.rb" + - "**/*.rb" - "*.rs" + - "**/*.rs" - "*.sh" + - "**/*.sh" - "*.sln" + - "**/*.sln" - "*.slnx" + - "**/*.slnx" - "*.sql" + - "**/*.sql" - "*.svelte" + - "**/*.svelte" - "*.swift" + - "**/*.swift" - "*.targets" + - "**/*.targets" - "*.toml" + - "**/*.toml" - "*.ts" + - "**/*.ts" - "*.tsx" + - "**/*.tsx" - "*.vue" + - "**/*.vue" - "*.yaml" + - "**/*.yaml" - "*.yml" + - "**/*.yml" - "Dockerfile*" + - "**/Dockerfile*" - "LICENSE*" + - "**/LICENSE*" - "Makefile" + - "**/Makefile" - "api/**" - "app/**" - "bin/**" From 7251b14d49af793c2cd71c418ad79eea8961f8cf Mon Sep 17 00:00:00 2001 From: brady gaster Date: Tue, 18 Aug 2026 08:54:47 -0700 Subject: [PATCH 2/2] fix(workflows): exclude workflow and squad config from the widened allowlist Adding nested `**/*.md`, `**/*.yml`, and `**/*.json` patterns made paths writable that root-anchored globs had blocked structurally -- among them .github/workflows/, .github/agents/, .github/aw/, and .squad/. The prompt already forbids changing those in prose, but that turned a structural guarantee into instruction-following, and it would let the worker rewrite its own workflow definition or the squad configuration that routes it. excluded-files strips those paths from the patch before the commit is created, restoring the guarantee without narrowing the nested globs that the widening exists to provide. .github/copilot-instructions.md stays writable, since only the four named subdirectories are excluded. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 090e9874-9835-489a-b38d-05a450b3fc53 --- workflows/squad-implement-worker.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md index b6401f4cc..89c816461 100644 --- a/workflows/squad-implement-worker.md +++ b/workflows/squad-implement-worker.md @@ -168,6 +168,21 @@ safe-outputs: - "tools/**" - "web/**" protected-files: request_review + excluded-files: + # The nested `**/*.md`, `**/*.yml`, and `**/*.json` patterns above would + # otherwise let this worker rewrite its own workflow definition, agent + # charters, or squad configuration -- paths the prompt forbids in prose + # ("Do not change ...") but which were previously blocked structurally, + # because root-anchored `*.md` never matched them. Stripping them from the + # patch keeps that enforcement structural rather than instruction-following. + - ".github/workflows/**" + - "**/.github/workflows/**" + - ".github/agents/**" + - "**/.github/agents/**" + - ".github/aw/**" + - "**/.github/aw/**" + - ".squad/**" + - "**/.squad/**" max-patch-files: 500 expires: 14d add-comment: