Skip to content

S2: add Wave 1 protected-files.exclude to squad-deps-worker (#1748) - #1883

Merged
bradygaster merged 5 commits into
devfrom
bradygaster-1748-safe-outputs-s2-d5c
Aug 25, 2026
Merged

S2: add Wave 1 protected-files.exclude to squad-deps-worker (#1748)#1883
bradygaster merged 5 commits into
devfrom
bradygaster-1748-safe-outputs-s2-d5c

Conversation

@bradygaster

@bradygaster bradygaster commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Part of #1748

Scope

This is S2 only -- Wave 1 protected-files.exclude entries for the dependency worker. Deferred out of scope:

  • S3: dispatcher/config routing (squad-deps-worker not yet wired into the dispatcher)
  • S4: PR presentation/evidence/label behavior (dependency-change label, PR body rules)
  • S5: docs/setup reporting

No dependency manifest or lockfile was changed by this PR.

What changed

  • workflows/squad-deps-worker.md: added protected-files.exclude with all Wave 1 basenames (npm/yarn/pnpm manifests + lockfiles, NuGet CPM Directory.Packages.props, Go go.mod/go.sum). Registry/install config (.npmrc, NuGet.Config, bunfig.toml), SDK/tool pins (global.json), and governance docs remain protected. The excluded-files list structurally strips vendored/generated content.
  • test/gh-aw-deps-worker-workflow.test.ts: 19 tests covering authored + compiled safe-output contract, mutation detection (T9), always-protected invariants, general-worker isolation, and T8b path-evaluation coverage using path.matchesGlob (Node 22.5+ built-in) to prove representative nested bin paths are excluded.

Validation evidence

Tests: npx vitest run test/gh-aw-deps-worker-workflow.test.ts -- 19/19 passed (7.99 s)

T8b matcher: path.matchesGlob (Node 22.5.0+ built-in, node:path). No new dependencies. Proven results against extracted excluded-files bin patterns:

  • bin/Staging/package.json → excluded ✓ (matches bin/**)
  • src/App/bin/Staging/package.json → excluded ✓ (matches **/bin/**)
  • a/b/c/bin/x86/Release/out.dll → excluded ✓ (matches **/bin/**)
  • package.json → NOT excluded by bin patterns ✓
  • src/package.json → NOT excluded by bin patterns ✓

Build: npm run build -- fails with 6 pre-existing TypeScript errors in squad-cli (health.ts, cast.ts, nap.ts, upgrade.ts) that are identical on the base branch with my changes stashed. Not caused by this PR (S2 touches only workflow markdown and test files).

Compiled safe-output observations

gh aw compile squad-deps-worker --strict --no-check-update in isolated workspace:

  • protected_files_policy: fallback-to-issue confirmed
  • Wave-1 basenames absent from compiled protected_files: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, npm-shrinkwrap.json, Directory.Packages.props, go.mod, go.sum -- all confirmed absent
  • Always-protected basenames present in compiled protected_files: bunfig.toml, NuGet.Config, global.json, CODEOWNERS, SECURITY.md, CONTRIBUTING.md, CHANGELOG.md, CODE_OF_CONDUCT.md, AGENTS.md -- all confirmed present
  • allowed_files: all 8 Wave-1 manifest/lockfile globs present
  • excluded_files: node_modules/**, vendor/**, .squad/**, .github/workflows/**, bin/**, **/bin/**, etc.
  • protect_top_level_dot_folders: true
  • No .lock.yml files left in workflows/

gh aw compile squad-implement-worker --strict --no-check-update in isolated workspace:

  • Wave-1 basenames remain in compiled protected_files (no leakage confirmed)
  • protected_files_policy: fallback-to-issue

Fresh fixture evidence

Fresh clone of octodemo/aspiregregator-squad-e2e (local path: %TEMP%/fixture-aspiregregator-1497811405, cleaned up after evidence capture). Copied current S2 squad-deps-worker.md into the fixture's .github/workflows/, ran gh aw compile squad-deps-worker --strict --no-check-update from inside the fixture repo:

  • Compiled successfully (1 warning: safe update mode / new secrets -- expected for first-time install)
  • Fixture .lock.yml confirmed: all Wave-1 basenames absent from protected_files, all always-protected present, policy: fallback-to-issue, allowed_files complete, excluded_files correct
  • No dispatch performed: S3 routing (wiring squad-deps-worker into the dispatcher) is intentionally absent in this slice. The /squad deps slash command does not exist yet -- that boundary is by design and documented in S3 scope.
  • No changes pushed to the fixture repo. Local temp clone removed after evidence capture.

Generated lock behavior

The generated .lock.yml bakes the safe-output config at compile time and is structurally immutable at runtime -- the protected-files.exclude list cannot be expanded by the agent, only further restricted. This is the correct security boundary for a dependency-only worker.

Security review

New secrets in compiled output: SQUAD_GITHUB_APP_PRIVATE_KEY and SQUAD_GITHUB_TOKEN -- standard Squad workflow secrets already present in the existing squad-implement-worker and squad.md compiled workflows. The workflow permissions: block is minimal: contents: read, copilot-requests: write, issues: read, pull-requests: read. No elevated permissions.

Architectural review

  • No module boundary changes (workflow markdown + test file only)
  • No SDK/CLI imports touched, no barrel file changes
  • No .squad/ config changes in this feature PR
  • 2 files changed (under 20 threshold)

Wave 1 basenames (npm/yarn/pnpm manifests + lockfiles, NuGet CPM,
Go modules) are now excluded from protected-files in the dependency
worker so the agent can produce a signed PR for those files.
Registry/install config, SDK/tool pins, and governance docs remain
protected. The general worker (squad-implement-worker) is unchanged.
Tests (18/18) validate authored and compiled contracts, mutation
detection, and structural vendored-content exclusions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 25, 2026 21:15
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit e31a957

PR Scope: 🔧 Infrastructure

⚠️ 3 item(s) to address before review

Status Check Details
Single commit 5 commits — consider squashing before review
Not in draft Ready for review
Branch up to date Up to date with dev
Copilot review No Copilot review yet — it may still be processing
Changeset present No source files changed — changeset not required
Scope clean No .squad/ or docs/proposals/ files
No merge conflicts No merge conflicts
Copilot threads resolved 0 active Copilot thread(s) resolved (4 outdated skipped)
CI passing 1 check(s) failing: test

Files Changed (2 files, +404 −165)

File +/−
test/gh-aw-deps-worker-workflow.test.ts +370 −146
workflows/squad-deps-worker.md +34 −19

Total: +404 −165


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

@github-actions

Copy link
Copy Markdown
Contributor

🟡 Impact Analysis — PR #1883

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 2
Files added 0
Files modified 2
Files deleted 0
Modules touched 2

🎯 Risk Factors

  • 2 files changed (≤5 → LOW)
  • 2 modules touched (2-4 → MEDIUM)

📦 Modules Affected

root (1 file)
  • workflows/squad-deps-worker.md
tests (1 file)
  • test/gh-aw-deps-worker-workflow.test.ts

This report is generated automatically for every PR. See #733 for details.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The updated test file introduces an unused import and a few comment/test-description mismatches that can cause lint/TS failures and make the contract tests harder to interpret.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR advances issue #1748 (S2 slice) by enabling the dependency worker to open signed PRs for a Wave 1 set of dependency manifests/lockfiles via protected-files.exclude, while keeping the general implement worker’s protection model unchanged.

Changes:

  • Added Wave 1 protected-files.exclude basenames to workflows/squad-deps-worker.md (npm/yarn/pnpm manifests+lockfiles, Directory.Packages.props, go.mod, go.sum).
  • Updated/expanded workflow contract tests to validate both authored YAML and compiled .lock.yml safe-output behavior, plus mutation-detection guards.
File summaries
File Description
workflows/squad-deps-worker.md Adds Wave 1 protected-files.exclude entries so the deps worker can PR approved manifest/lockfile basenames while preserving always-protected files.
test/gh-aw-deps-worker-workflow.test.ts Updates tests to assert authored + compiled safe-output contract for the deps worker and ensure the general worker remains unaffected; adds mutation tests.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/gh-aw-deps-worker-workflow.test.ts
Comment thread test/gh-aw-deps-worker-workflow.test.ts
Comment thread test/gh-aw-deps-worker-workflow.test.ts
Comment thread test/gh-aw-deps-worker-workflow.test.ts
brady gaster and others added 4 commits August 25, 2026 14:22
Fix two reviewer-flagged defects in gh-aw-deps-worker-workflow.test.ts:

1. Policy mutation test was a tautology: the validator re-applied the
   mutation to depsWorkerFrontmatter independently, so it always saw the
   expected 'allowed' value regardless of whether applyMutationAndValidate
   passed the pipeline-produced output. Thread the mutated frontmatter
   through to the validator signature so the assertion inspects the actual
   pipeline-produced frontmatter; the test now fails if the mutation is not
   applied.

2. T1 'exact Wave-1 exclude list' checked subset membership + negatives but
   not cardinality, so a ninth unrelated exclusion would go undetected. Add
   an exact length assertion against WAVE_1_MANIFEST_BASENAMES.length.

All 18 tests pass.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Remove unused writeFileSync import (nit 1)
- Fix compileDepsWorker doc: returns create_pull_request config, not full compiled config (nit 2)
- Fix applyMutationAndValidate doc: returns void/asserts internally, not true/false (nit 3)
- Rename T7-compiled test: 'Wave-1 basenames remain compiled protected' (nit 4)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Finding A: replace **/bin/Debug/** and **/bin/Release/** with **/bin/**
in squad-deps-worker excluded-files so that arbitrary nested bin
configurations such as src/App/bin/Staging/package.json are
structurally excluded. Top-level bin/** is preserved. T8 arrayContaining
updated to assert both bin/** and **/bin/**. T8b focused test added to
prove nested arbitrary bin paths are covered and narrower patterns absent.

Finding B: replace the tautological general-worker authority mutation test
(which asserted against a hand-built local array without touching any
workflow source) with a genuine compile-based mutation test. The new test
mutates squad-implement-worker.md on disk, runs gh aw compile --strict
through the real pipeline, parses the compiled .lock.yml safe-output
config, and wraps the T7-compiled contract assertion to prove the guard
turns red when package.json is injected into the general worker's
protected-files.exclude list.

Closes #1748 (S2 formal-review findings only)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…clusion

T8b previously only checked that the literal strings 'bin/**' and
'**/bin/**' exist in the authored excluded-files array (tautological).

Strengthen by extracting the bin-specific patterns from the configured
excluded-files and evaluating representative paths against them using
Node 22's built-in path.matchesGlob — a production-equivalent runtime
implementation with semantics appropriate for workflow glob patterns.
No new dependencies; matchesGlob is added to the existing node:path
import already present in the file.

Positive assertions (must be excluded by bin patterns):
  bin/Staging/package.json
  src/App/bin/Staging/package.json
  a/b/c/bin/x86/Release/out.dll

Negative assertions (must NOT be excluded by bin patterns alone):
  package.json
  src/package.json

The negative assertions isolate only the bin patterns (filtered from
excluded-files by /\bbin\b/) so they are not confounded by unrelated
entries (node_modules, vendor, .squad, etc.).

All 19 tests pass. Part of #1748

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bradygaster
bradygaster merged commit fab7865 into dev Aug 25, 2026
25 of 27 checks passed
@bradygaster
bradygaster deleted the bradygaster-1748-safe-outputs-s2-d5c branch August 25, 2026 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants