What happens
When a config-registered agent (ADR-0058) references a skill directory in a different repository than the one the minted GH_TOKEN is scoped for, the git sparse checkout fetch fails with:
Error: loading harness: resolving URL-sourced resources: base skills[0]: fetching skill directory skills/issue-labels:
gitfetch: git fetch: exit status 128: fatal: could not read Username for 'https://github.com': terminal prompts disabled
fetchBaseSkillDir in internal/harness/compose.go always passes opts.GitToken to FetchTree. When the token is an installation token scoped to repo A (e.g. ggallen-sandbox/integration-service) but the skill directory lives in repo B (e.g. fullsend-ai/agents), GitHub returns 401 — even though repo B is public. Sending an invalid-for-this-repo Authorization: Bearer header causes GitHub to reject the request instead of allowing anonymous access.
What should happen
Fetching skill directories from public repositories should succeed regardless of the GH_TOKEN scope. When an authenticated git fetch fails with an auth error, the fetch should retry without the token so that public repos remain accessible.
How to reproduce
- Configure a config-registered agent whose harness references a skill directory in a public repo (e.g.
fullsend-ai/agents)
- Run the agent from an org where the minted
GH_TOKEN is scoped to a different repo (e.g. ggallen-sandbox/integration-service)
- The harness loading fails at the skill directory fetch step
Observed in workflow run 28487585922 in ggallen-sandbox/.fullsend (v0.25.0). The triage harness in fullsend-ai/agents references skills/issue-labels; the minted triage token is scoped to ggallen-sandbox/integration-service.
Context
Introduced by #2735 / PR #2736 (replaced GitHub Contents API with git sparse checkout). The previous ForgeClient-based approach used the GitHub REST API which handled token scoping differently.
This blocks testing config-driven agent registration (ADR-0058) for any agent whose skills live in a different repo than the target. Related: #2805, #2806 (URL-sourced resource resolution fixes, both merged and in v0.25.0).
What happens
When a config-registered agent (ADR-0058) references a skill directory in a different repository than the one the minted
GH_TOKENis scoped for, the git sparse checkout fetch fails with:fetchBaseSkillDirininternal/harness/compose.goalways passesopts.GitTokentoFetchTree. When the token is an installation token scoped to repo A (e.g.ggallen-sandbox/integration-service) but the skill directory lives in repo B (e.g.fullsend-ai/agents), GitHub returns 401 — even though repo B is public. Sending an invalid-for-this-repoAuthorization: Bearerheader causes GitHub to reject the request instead of allowing anonymous access.What should happen
Fetching skill directories from public repositories should succeed regardless of the
GH_TOKENscope. When an authenticated git fetch fails with an auth error, the fetch should retry without the token so that public repos remain accessible.How to reproduce
fullsend-ai/agents)GH_TOKENis scoped to a different repo (e.g.ggallen-sandbox/integration-service)Observed in workflow run
28487585922inggallen-sandbox/.fullsend(v0.25.0). The triage harness infullsend-ai/agentsreferencesskills/issue-labels; the minted triage token is scoped toggallen-sandbox/integration-service.Context
Introduced by #2735 / PR #2736 (replaced GitHub Contents API with git sparse checkout). The previous
ForgeClient-based approach used the GitHub REST API which handled token scoping differently.This blocks testing config-driven agent registration (ADR-0058) for any agent whose skills live in a different repo than the target. Related: #2805, #2806 (URL-sourced resource resolution fixes, both merged and in v0.25.0).