fix(skills): block agent mutations to server feed skill directories - #1466
Merged
Aaronontheweb merged 5 commits intoJun 24, 2026
Merged
Conversation
Aaronontheweb
force-pushed
the
claude-wt-skillfeeds-readonly
branch
from
June 23, 2026 21:59
856919e to
a359e96
Compare
Aaronontheweb
enabled auto-merge (squash)
June 23, 2026 22:27
Fixes the gap described in netclaw-dev#1449. Agents could freely edit, patch, delete, and write files into .server-feeds/ skill directories via both the skill_manage tool and direct file write tools (file_write, file_edit). Changes made through either path are silently overwritten on the next sync cycle, making them wasteful at best and misleading about session state at worst. Two enforcement layers added: skill_manage tool (SkillManageTool.cs): - Added IsServerFeedSkill guard that checks whether a skill's file path sits within paths.ServerFeedsDirectory (.server-feeds/ is inside the native skills root, so the existing IsExternalSkill check did not catch it) - Extracted GuardReadOnly(skill, verb) to eliminate five copies of the system/feed/external three-check block Direct file write tools (Program.cs): - Added paths.SystemSkillsDirectory and paths.ServerFeedsDirectory to writeDenyList and shellIndicatorList so file_write, file_edit, and shell commands are denied at the ToolPathPolicy layer — the same layer that already protects config, secrets, and keys Test changes (SkillToolTests.cs): - Removed four tests added in 9d89936 that claimed to cover netclaw-dev#1449 but actually tested system and external skill guards — protections that predate the issue and were already covered elsewhere - Added five tests that exercise the actual attack vector: a skill scanned from a .server-feeds/my-feed/ directory is rejected by all five skill_manage mutation actions
- ToolPathPolicyTests: update CreateProductionPolicy() mirror to include SystemSkillsDirectory and ServerFeedsDirectory in writeDeny and shellIndicators; add InlineData entries so IsDenied_blocks_control_plane_files exercises both paths - SkillToolTests: restore the three guard-coverage tests removed in the prior commit — RemoveFile_rejects_system_skill, WriteFile_rejects_external_skill, RemoveFile_rejects_external_skill — these cover specific actions that Edit/Delete tests do not - ScanFeedSkills: switch from ReplaceAll to Register so feed skills are merged into the registry rather than replacing it; prevents future tests that mix native and feed skill populations from silently losing one side
Aaronontheweb
force-pushed
the
claude-wt-skillfeeds-readonly
branch
from
June 23, 2026 22:27
a359e96 to
e9a7e26
Compare
This was referenced Jun 24, 2026
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.
Closes #1449
Summary
.server-feeds/skills live insideSkillsDirectory, so neither the.systemcategory check nor the "external skill" (outside native root) check caught them — mutations viaskill_manageand directfile_write/file_editboth went through unblockedSkillManageToolnow rejects all mutations on server-feed skills via a newIsServerFeedSkillguard;ToolPathPolicywrite deny list inProgram.csnow includesSystemSkillsDirectoryandServerFeedsDirectorysofile_write,file_edit, and shell commands are blocked at the policy layerGuardReadOnly(skill, verb)to eliminate five copies of the system/feed/external three-check blockTest plan
SkillManage_ServerFeedSkill_Blocks*tests exercise all mutation actions against a.server-feeds/my-feed/skillRemoveFile_rejects_system_skill,WriteFile_rejects_external_skill,RemoveFile_rejects_external_skill— specific actions not covered by the pre-existing edit/delete external testsToolPathPolicyTests.CreateProductionPolicy()updated to mirror the newProgram.csdeny lists;IsDenied_blocks_control_plane_fileshasInlineDatafor child paths under both new directoriesScanFeedSkillshelper switched fromReplaceAlltoRegisterso future tests mixing native + feed skill populations don't silently drop one side