Repository navigation
Description
Summary
workflows/squad-implement-worker.md:170 sets protected-files: request_review. That value is incompatible with signed create-pull-request writes: the run logs that it is handling the protected-path write softly, then hard-refuses the signed push with Signed-commit payload violates file-protection policy.
This blocked the live end-to-end continuation test in bradygaster/aspiregregator-squad-test (finding F from the e2e run).
Mechanism
Verified against gh-aw v0.86.2 source:
create_pull_request.cjscallscheckFileProtection(...), classifiesrequest_reviewas a soft action, and logs that it will open the PR with a caution and a request-changes review.- The same handler then calls
pushSignedCommits(...). push_signed_commits.cjssynthesizes the GraphQLcreateCommitOnBranchpayload and callscheckFileProtectionPostApply(...).- Anything other than
allowthrowsSigned-commit payload violates file-protection policy (...).
So the soft log and the hard refusal happen at different layers. request_review is effectively unusable for signed PR writes touching protected files.
fallback-to-issue takes a different route: the signed push still rejects the payload, but the PR handler has manifestProtectionFallback set, catches the failure, and opens a protected-file review issue instead.
Relevant gh-aw behavior
- Default protected list:
pkg/workflow/runtime_definitions.go:47-239— every ecosystem manifest and lockfile, plusCODEOWNERS,DESIGN.md,README.md,CONTRIBUTING.md,CHANGELOG.md,SECURITY.md,CODE_OF_CONDUCT.mdat:206-214. The Copilot engine addsAGENTS.md(copilot_engine.go:147-151). - Matching is basename-anywhere, not glob:
manifest_file_helpers.cjs:301-305doesfile.split("/").pop(). This is a different matcher fromallowed-filesglobs, where*does not cross/. - The list is not replaceable, only narrowable.
protected-filesparses as a policy (create_pull_request.go:124,163-169); defaults are injected unconditionally (safe_outputs_handler_registry.go:568-572). The object form'sexcludefilters defaults at compile time (config_preprocessing.go:124-162,safe_outputs_config_generation.go:47-55).
Fix
protected-files:
policy: fallback-to-issue
exclude:
- README.mdREADME.md is excluded because it is high-frequency, low-control-plane work that ordinary PR review already covers — protecting it at every depth is inherited from gh-aw's generic manifest-safety model rather than Squad's product model. Under plain fallback-to-issue, every README task would produce a review issue instead of a PR, which is the wrong default for a core Squad use case.
Everything genuinely load-bearing stays protected: dependency manifests and lockfiles, CODEOWNERS, SECURITY.md, CONTRIBUTING.md, CHANGELOG.md, and top-level dot folders. CHANGELOG.md specifically stays protected because in adopting repos it is often generated, is release provenance, and may satisfy a release gate.
Existing excluded-files rules are unchanged — they solve a different problem (stripping paths from the patch before protected-file evaluation) and remain independent.
Notes
- Not
protected-files: allowed. That would let the worker rewrite protected manifests and security docs. - Workflow source changes must be recompiled into the installed
.lock.ymlin any consuming/test repo; editing the Markdown source alone does not affect an already-compiled workflow. - Follow-up (not this issue): document
fallback-to-issueas a deliberate safety handoff rather than a failed worker, and surface protected-file policy as an adoption-time repo configuration choice alongside the finding E Actions-permission preflight.
Validation
node scripts/check-workflow-input-interpolation.mjsnpx vitest run test/gh-aw-quality.test.ts(expect 81 passed / 13 skipped)
Activity
test(workflows): assert implement worker contracts
fix(workflows): fall back protected writes to review issue