I checked how this actually works end-to-end. Findings:
Short answer: no. The node1 SSH access is wired up as plumbing only — nothing tells the agents (dev agents or PM) that this capability exists.
What's actually there:
.gitea/workflows/agent.yml:133-164 writes a deploy key and an SSH config alias (Host node1) so ssh node1 <cmd> works, when SWARM_HOST/SWARM_USER/SSH_PRIV_KEY are set (added in #10/#11).
The read-only allowlist (deny ssh * + allow ssh node1 …) lives in the homelab repo's own opencode.json, which permits the command but doesn't explain it.
The runtime prompt built in agent.yml:276-299 (what the model actually reads) has zero mention of SSH/node1/swarm diagnostics.
AGENTS.template.md (copied into homelab-style repos as their AGENTS.md — the doc agents are told to "read and follow exactly") also never mentions it.
So today a dev agent (@junior/@senior/@lead) has no way to discover it can run ssh node1 <read-only cmd> for diagnostics unless it stumbles onto it by trial and error against the permission allowlist. That defeats the point of having wired it up.
Plan:
Add a short section to AGENTS.template.md (in this repo) documenting: ssh node1 is available for read-only swarm diagnostics (e.g. docker service ls, docker service ps <name>, docker service logs <name>), and that it's enforced read-only via the allowlist — so agents actually know to use it when debugging a deploy.
Optionally also mention it briefly in the dev-agent ACTION text in agent.yml so it's visible even in repos not yet using the updated template.
This is a small, low-risk, single-file (mostly docs/prompt-text) change — a good fit for @junior, with @senior as a fallback if it also wants to touch agent.yml's prompt text.
@ffaerber ready to start building? reply yes to proceed.
🤖 **@pm**
I checked how this actually works end-to-end. Findings:
**Short answer: no.** The `node1` SSH access is wired up as plumbing only — nothing tells the agents (dev agents or PM) that this capability exists.
What's actually there:
- `.gitea/workflows/agent.yml:133-164` writes a deploy key and an SSH config alias (`Host node1`) so `ssh node1 <cmd>` works, when `SWARM_HOST`/`SWARM_USER`/`SSH_PRIV_KEY` are set (added in #10/#11).
- The read-only allowlist (`deny ssh *` + `allow ssh node1 …`) lives in the *homelab* repo's own `opencode.json`, which permits the command but doesn't explain it.
- The runtime prompt built in `agent.yml:276-299` (what the model actually reads) has zero mention of SSH/node1/swarm diagnostics.
- `AGENTS.template.md` (copied into homelab-style repos as their `AGENTS.md` — the doc agents are told to "read and follow exactly") also never mentions it.
So today a dev agent (@junior/@senior/@lead) has no way to discover it can run `ssh node1 <read-only cmd>` for diagnostics unless it stumbles onto it by trial and error against the permission allowlist. That defeats the point of having wired it up.
**Plan:**
- Add a short section to `AGENTS.template.md` (in this repo) documenting: `ssh node1` is available for read-only swarm diagnostics (e.g. `docker service ls`, `docker service ps <name>`, `docker service logs <name>`), and that it's enforced read-only via the allowlist — so agents actually know to use it when debugging a deploy.
- Optionally also mention it briefly in the dev-agent `ACTION` text in `agent.yml` so it's visible even in repos not yet using the updated template.
- This is a small, low-risk, single-file (mostly docs/prompt-text) change — a good fit for @junior, with @senior as a fallback if it also wants to touch `agent.yml`'s prompt text.
@ffaerber ready to start building? reply yes to proceed.
@ffaerber — good catch, yes. A dedicated opencode Skill is the right mechanism here, and it's actually cleaner than my original plan.
Why a skill fits better than stuffing it into AGENTS.template.md:
OpenCode skills (SKILL.md under .opencode/skills/<name>/ or ~/.config/opencode/skills/<name>/) are auto-surfaced to the agent via the skill tool's <available_skills> list — the agent sees the name+description up front and loads full instructions only when relevant. That's exactly the "agent doesn't know it can do this" gap.
This workflow is shared across repos and already writes runtime config dynamically (agent.yml:106-125 generates ~/.config/opencode/opencode.json on every run). We can write the skill file the same way, in the same conditional block as the existing "Set up read-only SSH alias node1" step (agent.yml:133-164) — i.e. only emit ~/.config/opencode/skills/node1-ssh/SKILL.md when SWARM_HOST/SWARM_USER/SSH_PRIV_KEY are actually set for that repo.
That's better than editing AGENTS.template.md: it doesn't require every downstream homelab-style repo to have picked up the latest template, it self-documents only when the capability is actually wired up for that repo, and it lives entirely in this shared-workflow repo (single source of truth).
Revised plan:
In .gitea/workflows/agent.yml, right after (or merged into) the existing SSH-alias step, add: mkdir -p ~/.config/opencode/skills/node1-ssh and write a SKILL.md with frontmatter (name: node1-ssh, a description like "read-only diagnostics on the swarm node — use when debugging a deploy or checking a running service") plus a body listing the allowed commands (docker service ls, docker service ps <name>, docker service logs <name>) and the read-only constraint, guarded by the same if secrets missing, skip check already there.
Drop the AGENTS.template.md edit from my original plan — no longer needed for AI discovery (the skill handles that). Optionally keep a one-line human-facing mention in the template for people reading the doc, but that's not required.
Single file (agent.yml), pure YAML/shell heredoc addition, no logic elsewhere touched — still a good fit for @junior.
@ffaerber ready to start building on this revised (skill-based) approach? Reply yes to proceed.
🤖 **@pm**
@ffaerber — good catch, yes. A dedicated **opencode Skill** is the right mechanism here, and it's actually cleaner than my original plan.
**Why a skill fits better than stuffing it into `AGENTS.template.md`:**
- OpenCode skills (`SKILL.md` under `.opencode/skills/<name>/` or `~/.config/opencode/skills/<name>/`) are auto-surfaced to the agent via the `skill` tool's `<available_skills>` list — the agent sees the name+description up front and loads full instructions only when relevant. That's exactly the "agent doesn't know it can do this" gap.
- This workflow is **shared** across repos and already writes runtime config dynamically (`agent.yml:106-125` generates `~/.config/opencode/opencode.json` on every run). We can write the skill file the same way, in the same conditional block as the existing "Set up read-only SSH alias `node1`" step (`agent.yml:133-164`) — i.e. only emit `~/.config/opencode/skills/node1-ssh/SKILL.md` when `SWARM_HOST`/`SWARM_USER`/`SSH_PRIV_KEY` are actually set for that repo.
- That's better than editing `AGENTS.template.md`: it doesn't require every downstream homelab-style repo to have picked up the latest template, it self-documents only when the capability is actually wired up for that repo, and it lives entirely in this shared-workflow repo (single source of truth).
**Revised plan:**
- In `.gitea/workflows/agent.yml`, right after (or merged into) the existing SSH-alias step, add: `mkdir -p ~/.config/opencode/skills/node1-ssh` and write a `SKILL.md` with frontmatter (`name: node1-ssh`, a `description` like "read-only diagnostics on the swarm node — use when debugging a deploy or checking a running service") plus a body listing the allowed commands (`docker service ls`, `docker service ps <name>`, `docker service logs <name>`) and the read-only constraint, guarded by the same `if secrets missing, skip` check already there.
- Drop the `AGENTS.template.md` edit from my original plan — no longer needed for AI discovery (the skill handles that). Optionally keep a one-line human-facing mention in the template for people reading the doc, but that's not required.
- Single file (`agent.yml`), pure YAML/shell heredoc addition, no logic elsewhere touched — still a good fit for @junior.
@ffaerber ready to start building on this revised (skill-based) approach? Reply yes to proceed.
The maintainer approved the skill-based approach. Handing off to @junior to implement it in .gitea/workflows/agent.yml:
Add a step (guarded by the same SWARM_HOST/SWARM_USER/SSH_PRIV_KEY check as the existing SSH-alias block at lines 133-164) that writes ~/.config/opencode/skills/node1-ssh/SKILL.md.
Frontmatter: name: node1-ssh, description: read-only diagnostics on the swarm node — use when debugging a deploy or checking a running service.
Body: document the allowed commands (docker service ls, docker service ps <name>, docker service logs <name>), note it's ssh node1 <cmd>, and state it's enforced read-only via the repo's own allowlist.
No changes to AGENTS.template.md needed.
Single file, low risk — good fit for @junior.
🤖 **@pm**
The maintainer approved the skill-based approach. Handing off to @junior to implement it in `.gitea/workflows/agent.yml`:
- Add a step (guarded by the same `SWARM_HOST`/`SWARM_USER`/`SSH_PRIV_KEY` check as the existing SSH-alias block at lines 133-164) that writes `~/.config/opencode/skills/node1-ssh/SKILL.md`.
- Frontmatter: `name: node1-ssh`, `description: read-only diagnostics on the swarm node — use when debugging a deploy or checking a running service`.
- Body: document the allowed commands (`docker service ls`, `docker service ps <name>`, `docker service logs <name>`), note it's `ssh node1 <cmd>`, and state it's enforced read-only via the repo's own allowlist.
- No changes to `AGENTS.template.md` needed.
- Single file, low risk — good fit for @junior.
🔨@junior is on it — building on branch ai/issue-12. I'll open a PR when it's ready.
🔨 **@junior** is on it — building on branch [`ai/issue-12`](https://git.ffaerber.duckdns.org/ffaerber/agents/src/branch/ai/issue-12). I'll open a PR when it's ready.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
do the agents know that there able to ssh into node1?
@pm here
🤖 @pm
I checked how this actually works end-to-end. Findings:
Short answer: no. The
node1SSH access is wired up as plumbing only — nothing tells the agents (dev agents or PM) that this capability exists.What's actually there:
.gitea/workflows/agent.yml:133-164writes a deploy key and an SSH config alias (Host node1) sossh node1 <cmd>works, whenSWARM_HOST/SWARM_USER/SSH_PRIV_KEYare set (added in #10/#11).deny ssh *+allow ssh node1 …) lives in the homelab repo's ownopencode.json, which permits the command but doesn't explain it.agent.yml:276-299(what the model actually reads) has zero mention of SSH/node1/swarm diagnostics.AGENTS.template.md(copied into homelab-style repos as theirAGENTS.md— the doc agents are told to "read and follow exactly") also never mentions it.So today a dev agent (@junior/@senior/@lead) has no way to discover it can run
ssh node1 <read-only cmd>for diagnostics unless it stumbles onto it by trial and error against the permission allowlist. That defeats the point of having wired it up.Plan:
AGENTS.template.md(in this repo) documenting:ssh node1is available for read-only swarm diagnostics (e.g.docker service ls,docker service ps <name>,docker service logs <name>), and that it's enforced read-only via the allowlist — so agents actually know to use it when debugging a deploy.ACTIONtext inagent.ymlso it's visible even in repos not yet using the updated template.agent.yml's prompt text.@ffaerber ready to start building? reply yes to proceed.
@pm is this not a shard skill?
🤖 @pm
@ffaerber — good catch, yes. A dedicated opencode Skill is the right mechanism here, and it's actually cleaner than my original plan.
Why a skill fits better than stuffing it into
AGENTS.template.md:SKILL.mdunder.opencode/skills/<name>/or~/.config/opencode/skills/<name>/) are auto-surfaced to the agent via theskilltool's<available_skills>list — the agent sees the name+description up front and loads full instructions only when relevant. That's exactly the "agent doesn't know it can do this" gap.agent.yml:106-125generates~/.config/opencode/opencode.jsonon every run). We can write the skill file the same way, in the same conditional block as the existing "Set up read-only SSH aliasnode1" step (agent.yml:133-164) — i.e. only emit~/.config/opencode/skills/node1-ssh/SKILL.mdwhenSWARM_HOST/SWARM_USER/SSH_PRIV_KEYare actually set for that repo.AGENTS.template.md: it doesn't require every downstream homelab-style repo to have picked up the latest template, it self-documents only when the capability is actually wired up for that repo, and it lives entirely in this shared-workflow repo (single source of truth).Revised plan:
.gitea/workflows/agent.yml, right after (or merged into) the existing SSH-alias step, add:mkdir -p ~/.config/opencode/skills/node1-sshand write aSKILL.mdwith frontmatter (name: node1-ssh, adescriptionlike "read-only diagnostics on the swarm node — use when debugging a deploy or checking a running service") plus a body listing the allowed commands (docker service ls,docker service ps <name>,docker service logs <name>) and the read-only constraint, guarded by the sameif secrets missing, skipcheck already there.AGENTS.template.mdedit from my original plan — no longer needed for AI discovery (the skill handles that). Optionally keep a one-line human-facing mention in the template for people reading the doc, but that's not required.agent.yml), pure YAML/shell heredoc addition, no logic elsewhere touched — still a good fit for @junior.@ffaerber ready to start building on this revised (skill-based) approach? Reply yes to proceed.
@pm yes
🤖 @pm
The maintainer approved the skill-based approach. Handing off to @junior to implement it in
.gitea/workflows/agent.yml:SWARM_HOST/SWARM_USER/SSH_PRIV_KEYcheck as the existing SSH-alias block at lines 133-164) that writes~/.config/opencode/skills/node1-ssh/SKILL.md.name: node1-ssh,description: read-only diagnostics on the swarm node — use when debugging a deploy or checking a running service.docker service ls,docker service ps <name>,docker service logs <name>), note it'sssh node1 <cmd>, and state it's enforced read-only via the repo's own allowlist.AGENTS.template.mdneeded.@junior please proceed with issue #12 per the plan above (delegated by pm).
🔨 @junior is on it — building on branch
ai/issue-12. I'll open a PR when it's ready.🤖 @junior — ✅ 1 PR ready for review — @ffaerber please review & merge: