You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mcp__trinity__deploy_local_agent (POST /api/agents/deploy-local) — the archive-based deploy path used by the /trinity:onboard skill from the abilityai/abilities marketplace — is unreliable when the agent has no GitHub repository. Deployments either fail outright or succeed but produce empty agents (container starts with no template files, no CLAUDE.md, no skills).
Root cause
In src/backend/services/agent_service/deploy.py (the templates_dir writability probe at the "Copy to templates directory" step), the writability check on /agent-configs/templates always fails because that mount is bind-mounted read-only in both docker-compose.yml and docker-compose.prod.yml:
./config/agent-templates is relative to the backend container's WORKDIR (/app) — it resolves to /app/config/agent-templates/<version-name>, which is not host-mapped. The extracted template lives only inside the backend container filesystem.
When create_agent_internal (in src/backend/services/agent_service/crud.py, elif config.template.startswith("local:") branches around the template_volume setup) then tries to bind-mount the template into the new agent container, it does two things, both broken:
Checks if template_path_in_backend.exists() against /agent-configs/templates/<name> — the read-only mount where the template was not written. Existence returns False, so template_volume stays None and the new agent container is created without the template mounted at /template → empty workspace, "empty agents" failure mode.
If the directory happens to exist (race / stale state), the bind source path is computed from HOST_TEMPLATES_PATH (${PWD}/config/agent-templates/<name>), which doesn't exist on the host → Docker volume mount fails → "deploy fails" failure mode.
Net effect: the documented /trinity:onboard flow for archive-based deploy is broken on every standard deployment (dev + prod compose files both mark the templates dir :ro).
How to reproduce
From a Claude Code agent without an associated GitHub repo, install the public marketplace plugin:
Run /trinity:onboard and choose "Deploy to Trinity".
The skill packages the local directory as a base64 tar.gz and calls mcp__trinity__deploy_local_agent.
Observe either a hard failure or a "success" response where the new agent's /api/agents/{name}/files listing shows no template content (no CLAUDE.md, no template.yaml, no .claude/skills/).
Acceptance criteria
POST /api/agents/deploy-local reliably extracts the archive to a host-mapped location (or another path that the new agent's bind-mount will actually see)
The fallback path no longer silently writes to a container-only directory; either it writes somewhere the new agent will read, or it fails fast with a clear error code
After a successful mcp__trinity__deploy_local_agent response, the new agent's workspace contains template.yaml, CLAUDE.md, .claude/skills/, and any other files from the archive
Repeated /trinity:onboard runs against the same agent name produce the expected versioned redeploy (<base>-2, etc.) with full content, not empty workspaces
An integration test covers archive → deploy → verify-content on a clean Trinity instance using the stock docker-compose.yml
Regression test added for the writable-templates-dir resolution so the read-only mount fallback can't silently degrade again
src/backend/services/agent_service/crud.py — local:-prefixed template resolution, template_volume construction
src/backend/services/template_service.py — is_trinity_compatible (CLAUDE.md is a warning, not an error; an archive missing it still passes validation)
docker-compose.yml and docker-compose.prod.yml — ./config/agent-templates:/agent-configs/templates:ro (read-only mount that makes the writability probe always fall back)
Suggested fix direction: make /agent-configs/templates writable (either drop :ro in compose, or mount a dedicated writable subdirectory for deployed-local templates while keeping the curated catalog read-only), and harden the fallback to fail loudly instead of writing into the container FS
Consider tightening is_trinity_compatible so deploys missing CLAUDE.md or expected agent structure either fail or produce a structured warning surfaced in the deploy response, so users notice empty agents at deploy time instead of first interaction
Summary
mcp__trinity__deploy_local_agent(POST/api/agents/deploy-local) — the archive-based deploy path used by the/trinity:onboardskill from theabilityai/abilitiesmarketplace — is unreliable when the agent has no GitHub repository. Deployments either fail outright or succeed but produce empty agents (container starts with no template files, no CLAUDE.md, no skills).Root cause
In
src/backend/services/agent_service/deploy.py(thetemplates_dirwritability probe at the "Copy to templates directory" step), the writability check on/agent-configs/templatesalways fails because that mount is bind-mounted read-only in bothdocker-compose.ymlanddocker-compose.prod.yml:- ./config/agent-templates:/agent-configs/templates:roThe probe catches the
OSErrorand falls back to:./config/agent-templatesis relative to the backend container's WORKDIR (/app) — it resolves to/app/config/agent-templates/<version-name>, which is not host-mapped. The extracted template lives only inside the backend container filesystem.When
create_agent_internal(insrc/backend/services/agent_service/crud.py,elif config.template.startswith("local:")branches around thetemplate_volumesetup) then tries to bind-mount the template into the new agent container, it does two things, both broken:if template_path_in_backend.exists()against/agent-configs/templates/<name>— the read-only mount where the template was not written. Existence returnsFalse, sotemplate_volumestaysNoneand the new agent container is created without the template mounted at/template→ empty workspace, "empty agents" failure mode.HOST_TEMPLATES_PATH(${PWD}/config/agent-templates/<name>), which doesn't exist on the host → Docker volume mount fails → "deploy fails" failure mode.Net effect: the documented
/trinity:onboardflow for archive-based deploy is broken on every standard deployment (dev + prod compose files both mark the templates dir:ro).How to reproduce
/trinity:onboardand choose "Deploy to Trinity".mcp__trinity__deploy_local_agent./api/agents/{name}/fileslisting shows no template content (noCLAUDE.md, notemplate.yaml, no.claude/skills/).Acceptance criteria
POST /api/agents/deploy-localreliably extracts the archive to a host-mapped location (or another path that the new agent's bind-mount will actually see)mcp__trinity__deploy_local_agentresponse, the new agent's workspace containstemplate.yaml,CLAUDE.md,.claude/skills/, and any other files from the archive/trinity:onboardruns against the same agent name produce the expected versioned redeploy (<base>-2, etc.) with full content, not empty workspacesdocker-compose.ymlTechnical notes
src/backend/services/agent_service/deploy.py—deploy_local_agent_logic, templates-dir writability probe, template copy stepsrc/backend/services/agent_service/crud.py—local:-prefixed template resolution,template_volumeconstructionsrc/backend/services/template_service.py—is_trinity_compatible(CLAUDE.md is a warning, not an error; an archive missing it still passes validation)docker-compose.ymlanddocker-compose.prod.yml—./config/agent-templates:/agent-configs/templates:ro(read-only mount that makes the writability probe always fall back)src/mcp-server/src/tools/agents.ts—deployLocalAgentMCP tool/trinity:onboardskill (SKILL.md v4.7) inabilityai/abilities— callsmcp__trinity__deploy_local_agentand writes.trinity-remote.yaml/agent-configs/templateswritable (either drop:roin compose, or mount a dedicated writable subdirectory for deployed-local templates while keeping the curated catalog read-only), and harden the fallback to fail loudly instead of writing into the container FSis_trinity_compatibleso deploys missingCLAUDE.mdor expected agent structure either fail or produce a structured warning surfaced in the deploy response, so users notice empty agents at deploy time instead of first interaction