Repository navigation
fix(skills): set per-skill directory mode to 0755 through the pinned handle - #129
Merged
Merged
Conversation
…descriptor mkdir's mode argument is masked by the process umask, so under umask 0077 <root>/<key>/ ended up 0700 and a separate agent identity could not read SKILL.md, though the reconcile reported success. The README promises 0755 regardless of the umask. After a successful create, chmod the directory through the descriptor the code already pins, never its path. A directory that already existed keeps its mode, and the managed root is left to the user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Python counterpart: launchdarkly/python-ai-sdk#154 · Spec: https://github.com/launchdarkly/ai-sdks-monorepo/pull/53 |
andrewklatzke
approved these changes
Oct 9, 2026
…mode Linux copies a setgid parent's bit onto a new directory so files created inside inherit the shared group. fchmod sets exactly the bits it is given, so the bare 0755 cleared it. Carry S_ISGID over from the same handle's stat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Setgid follow-up to the spec: https://github.com/launchdarkly/ai-sdks-monorepo/pull/54 (the first spec PR, #53, is merged). |
jeffdupont
approved these changes
Oct 9, 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.
Same finding as the Bugbot comment on launchdarkly/python-ai-sdk#87 (comment 4232816271). The gap is identical in this SDK.
What was wrong:
openOrCreateDirectoryinsafe-fs.tscreated<root>/<key>/withmkdir(directory, 0o755), but the process umask still masks that mode, and nothing set it afterwards. Underumask 0077the directory came out0700, so an agent running as a different identity couldn't readSKILL.md, even thoughwriteSkillsreported success. The README's privilege-separation section promises per-skill directories at0755no matter what the umask is.Fix: after a successful create, the code sets the mode to
0755withFileHandle.chmod(that is,fchmod) on the handleopenDirectoryNoFollowalready returns, the same wayFILE_MODEis applied to files. It never chmods the path, because a swap between the mkdir and the open could redirect a path-based chmod.<root>/<key>/keeps its mode.mkdir(root)inskills-fs.tsand isn't touched here.S_ISGIDbit, andfchmoduses exactly the bits passed, so a bare0755cleared it. Files written inside would then get the reconcile identity's primary group instead of the shared group. The mode is now(mode & S_ISGID) | 0755, with the current mode read throughhandle.stat()on the same descriptor. macOS doesn't propagate the bit, so nothing changes there.Tests (skipped on win32):
creates per-skill directories as 0755 even under a restrictive umaskrunswriteSkillsunderprocess.umask(0o077)and asserts the directory is0755andSKILL.mdis0644. It fails without the fix.keeps a setgid bit the new skill directory inheritedmakes the root2755and asserts the new skill directory is2755. It's skipped unless a probe directory under that root actually inherits the bit, so it runs on Linux and skips on macOS. On Linux (Docker,node:22) it fails without the setgid change.fs.constantshas noS_ISGID, sosafe-fs.tsdefines it locally.leaves the mode of an existing directory alonechecks that an existing0700directory stays0700.Full suite: 1394 passed on macOS (the setgid test skips) and 1405 passed on Linux. biome and tsc are clean.
The Python fix is in a separate PR, linked below. The spec lines are in launchdarkly/ai-sdks-monorepo#53 (merged) and its setgid follow-up.
🤖 Generated with Claude Code