What happens
Per-repo installation writes configuration to .fullsend/config.yaml (via fullsend github setup), but agent workflows invoke fullsend run with --fullsend-dir defaulting to $GITHUB_WORKSPACE (repo root). The CLI then looks for config at {fullsend-dir}/config.yaml — i.e. config.yaml at the repo root, not .fullsend/config.yaml.
As a result, per-repo config fields are not applied during agent runs:
runtime — on main, fullsend run always uses the default Claude backend and does not consult per-repo config. Setting runtime: dummy (or any other runtime) in .fullsend/config.yaml has no effect.
allowed_remote_resources — tryLoadOrgConfig reads {fullsend-dir}/config.yaml and parses org-config shape only; per-repo config at .fullsend/config.yaml is never loaded for allowlist validation or config-driven agent resolution.
create_issues, status notification defaults, and other per-repo config fields — same path mismatch; not reachable when fullsend-dir is the workspace root.
Separately, the Prepare workspace step in reusable agent workflows (reusable-triage.yml, etc.) always copies upstream harness/agents/skills content to the workspace root (harness/, agents/, …), regardless of install_mode. Only the customized overlay source path differs for per-repo (.fullsend/customized/ vs customized/).
This diverges from ADR 0033, which specifies that per-repo mode should:
- Prepare workspace with root
.fullsend/ (populating .fullsend/harness/, etc.)
- Pass
--fullsend-dir=.fullsend to fullsend run
The implementation never completed that layout. Per-repo installs also do not receive harness wrapper files under .fullsend/harness/ (unlike per-org config repos, which get them via HarnessWrappersLayer). Instead, harness files are materialized at workflow runtime by copying from vendored or sparse-checked upstream defaults into the workspace root.
What should happen
When a repository is installed in per-repo mode:
- Config written to
.fullsend/config.yaml should be read consistently by fullsend run and related CLI paths (runtime selection, allowlist, config-driven agents, status notifications, etc.).
- The directory layout used by reusable workflows (Prepare workspace,
--fullsend-dir, harness resolution) should be internally consistent — either matching ADR 0033 (.fullsend/ as the fullsend root) or documented as an intentional deviation with explicit fallback rules.
How to reproduce
- Run
fullsend github setup owner/repo --vendor --runtime dummy on a test repository.
- Confirm
.fullsend/config.yaml contains runtime: dummy.
- Trigger a triage run via the per-repo shim (
install_mode: per-repo).
- Observe that
fullsend run does not load runtime from .fullsend/config.yaml (on main, Claude runs regardless).
Attempting to align config lookup by passing fullsend-dir: .fullsend in reusable-triage.yml (as explored in #1982) causes a different failure: harness files are still prepared at workspace root, so fullsend run errors with harness file not found: tried triage.yaml and triage.yml.
Context
Discovered while implementing behaviour tests in #1982, which require runtime: dummy from per-repo config. Production per-repo triage may appear to work today because the default Claude runtime matches typical expectations and harness files are copied to workspace root at workflow runtime — but any per-repo config field that fullsend run should honor is effectively unreachable.
Related: ADR 0033 per-repo installation mode, --vendor install path (CollectPerRepoInstallFiles), reusable workflow Prepare workspace step.
What happens
Per-repo installation writes configuration to
.fullsend/config.yaml(viafullsend github setup), but agent workflows invokefullsend runwith--fullsend-dirdefaulting to$GITHUB_WORKSPACE(repo root). The CLI then looks for config at{fullsend-dir}/config.yaml— i.e.config.yamlat the repo root, not.fullsend/config.yaml.As a result, per-repo config fields are not applied during agent runs:
runtime— onmain,fullsend runalways uses the default Claude backend and does not consult per-repo config. Settingruntime: dummy(or any other runtime) in.fullsend/config.yamlhas no effect.allowed_remote_resources—tryLoadOrgConfigreads{fullsend-dir}/config.yamland parses org-config shape only; per-repo config at.fullsend/config.yamlis never loaded for allowlist validation or config-driven agent resolution.create_issues, status notification defaults, and other per-repo config fields — same path mismatch; not reachable whenfullsend-diris the workspace root.Separately, the Prepare workspace step in reusable agent workflows (
reusable-triage.yml, etc.) always copies upstream harness/agents/skills content to the workspace root (harness/,agents/, …), regardless ofinstall_mode. Only the customized overlay source path differs for per-repo (.fullsend/customized/vscustomized/).This diverges from ADR 0033, which specifies that per-repo mode should:
.fullsend/(populating.fullsend/harness/, etc.)--fullsend-dir=.fullsendtofullsend runThe implementation never completed that layout. Per-repo installs also do not receive harness wrapper files under
.fullsend/harness/(unlike per-org config repos, which get them viaHarnessWrappersLayer). Instead, harness files are materialized at workflow runtime by copying from vendored or sparse-checked upstream defaults into the workspace root.What should happen
When a repository is installed in per-repo mode:
.fullsend/config.yamlshould be read consistently byfullsend runand related CLI paths (runtime selection, allowlist, config-driven agents, status notifications, etc.).--fullsend-dir, harness resolution) should be internally consistent — either matching ADR 0033 (.fullsend/as the fullsend root) or documented as an intentional deviation with explicit fallback rules.How to reproduce
fullsend github setup owner/repo --vendor --runtime dummyon a test repository..fullsend/config.yamlcontainsruntime: dummy.install_mode: per-repo).fullsend rundoes not load runtime from.fullsend/config.yaml(onmain, Claude runs regardless).Attempting to align config lookup by passing
fullsend-dir: .fullsendinreusable-triage.yml(as explored in #1982) causes a different failure: harness files are still prepared at workspace root, sofullsend runerrors withharness file not found: tried triage.yaml and triage.yml.Context
Discovered while implementing behaviour tests in #1982, which require
runtime: dummyfrom per-repo config. Production per-repo triage may appear to work today because the default Claude runtime matches typical expectations and harness files are copied to workspace root at workflow runtime — but any per-repo config field thatfullsend runshould honor is effectively unreachable.Related: ADR 0033 per-repo installation mode,
--vendorinstall path (CollectPerRepoInstallFiles), reusable workflow Prepare workspace step.