Problem
ClaudeAgentSdkProvider passes setting_sources=[] unconditionally (src/conductor/providers/claude_agent_sdk.py:944). No workflow can opt in, so a step can never load the settings tier of the repository it operates on.
That rules out a whole class of workflow: an agent working on a target repo cannot use that repo's own .claude/skills/, CLAUDE.md, or .claude/rules/*.md. The repo's conventions have to be duplicated into the workflow's prompts instead of being read from the repo.
Why the empty list is right as a default
Not a bug on its own. The SDK re-defaults an unset setting_sources to ["user", "project"] whenever skills is set, so an explicit [] is the only way to get a hermetic run — otherwise behaviour depends on whose machine started it. The gap is that there's no escape hatch, not that the default is wrong.
Why the existing options don't cover it
The CLI has --plugin-dir but no --skill-dir, and ClaudeAgentOptions.skills takes skill names, not paths. So the only way to reach a target repo's skills today is to synthesise a per-repo plugin manifest — a lot of machinery for something setting_sources already expresses.
Proposal
An opt-in runtime.provider.setting_sources accepting user / project / local, defaulting to [] so current behaviour is unchanged. Loading a tier stays the workflow author's explicit decision.
Two things this turned out to need beyond the plumbing, both found by running it:
- The
Skill tool has to be granted when setting_sources is non-empty. CLI-discovered skills never pass through conductor's resolved skill list, so gating the grant on that list alone leaves the model seeing the repo's skills in its listing with no tool to invoke them.
ClaudeAgentOptions.skills has to become "all" when tiers are enabled and the workflow named no skills. Otherwise every call fails with "not in this session's skills allowlist" — observed with 28 discovered skills, all rejected.
Security note
project loads the entire tier, hooks included. Pointing it at untrusted code means executing that code's hooks. Worth documenting explicitly at the schema. Keeping the default at [] means nobody gets this without asking. Whether user should be permitted at all is a fair question — it makes a run depend on the operator's machine.
Verified
Tested against claude-agent-sdk 0.2.87 with a fixture repo whose .claude/rules is a symlink to a tool-agnostic .agents/rules, and a CLAUDE.md that never references it. With setting_sources=[] the agent reports no rule; with ["project"] it returns the rule's contents and its marker token. So skills, CLAUDE.md, and .claude/rules all arrive through the one tier, symlinks included.
Happy to open a PR — we have this running on a fork and can upstream it.
Problem
ClaudeAgentSdkProviderpassessetting_sources=[]unconditionally (src/conductor/providers/claude_agent_sdk.py:944). No workflow can opt in, so a step can never load the settings tier of the repository it operates on.That rules out a whole class of workflow: an agent working on a target repo cannot use that repo's own
.claude/skills/,CLAUDE.md, or.claude/rules/*.md. The repo's conventions have to be duplicated into the workflow's prompts instead of being read from the repo.Why the empty list is right as a default
Not a bug on its own. The SDK re-defaults an unset
setting_sourcesto["user", "project"]wheneverskillsis set, so an explicit[]is the only way to get a hermetic run — otherwise behaviour depends on whose machine started it. The gap is that there's no escape hatch, not that the default is wrong.Why the existing options don't cover it
The CLI has
--plugin-dirbut no--skill-dir, andClaudeAgentOptions.skillstakes skill names, not paths. So the only way to reach a target repo's skills today is to synthesise a per-repo plugin manifest — a lot of machinery for somethingsetting_sourcesalready expresses.Proposal
An opt-in
runtime.provider.setting_sourcesacceptinguser/project/local, defaulting to[]so current behaviour is unchanged. Loading a tier stays the workflow author's explicit decision.Two things this turned out to need beyond the plumbing, both found by running it:
Skilltool has to be granted whensetting_sourcesis non-empty. CLI-discovered skills never pass through conductor's resolved skill list, so gating the grant on that list alone leaves the model seeing the repo's skills in its listing with no tool to invoke them.ClaudeAgentOptions.skillshas to become"all"when tiers are enabled and the workflow named no skills. Otherwise every call fails with "not in this session's skills allowlist" — observed with 28 discovered skills, all rejected.Security note
projectloads the entire tier, hooks included. Pointing it at untrusted code means executing that code's hooks. Worth documenting explicitly at the schema. Keeping the default at[]means nobody gets this without asking. Whetherusershould be permitted at all is a fair question — it makes a run depend on the operator's machine.Verified
Tested against claude-agent-sdk 0.2.87 with a fixture repo whose
.claude/rulesis a symlink to a tool-agnostic.agents/rules, and aCLAUDE.mdthat never references it. Withsetting_sources=[]the agent reports no rule; with["project"]it returns the rule's contents and its marker token. So skills,CLAUDE.md, and.claude/rulesall arrive through the one tier, symlinks included.Happy to open a PR — we have this running on a fork and can upstream it.