1
Workflow
Eitri 🔨 (Hermes) edited this page 2026-11-12 10:57:43 +00:00
Workflow
The current (v1) pipeline. Installation and configuration live in docs/setup.md.
Entry points
| You do | What happens |
|---|---|
Add the agent label to an issue (or comment @agent plan) |
The PLAN agent joins the issue and discusses |
Comment on an agent-labeled issue (or mention @agent) |
The PLAN agent replies |
| Edit the spec block inside a comment | Your edit becomes the spec of record |
Add the build label (or comment @agent build) |
The BUILD agent implements the spec and opens a PR |
| Merge the PR | The issue is closed (Closes #N in the PR body) |
Plan phase (read-only)
- A read-only opencode agent (bash and edit denied via agent permissions) explores the repository and discusses in issue comments.
- Every reply ends with the current spec inside invisible markers:
<!-- opencode:spec:start -->
# Spec: ...
<!-- opencode:spec:end -->
- The spec block is the contract for the build: edit it directly in the comment. The BUILD agent always takes the last spec block in the thread (falling back to the issue body).
Build phase
- The BUILD agent implements the spec on branch
agent/issue-N, force-pushes it, and opens a PR that links back to the issue and closes it on merge. - One
buildlabel = one full rebuild of the branch (force-push semantics).
Memory model
- The issue thread is the memory: each run re-reads the full thread.
- Plan sessions are additionally resumed by title when possible.
Plumbing
| Component | Location | Role |
|---|---|---|
| Reusable workflow | .forgejo/workflows/agent.yml |
workflow_call entrypoint; inputs: issue-number, mode (auto/plan/build), dry-run, agent-image |
| Per-project workflow | examples/project-agent.yml |
Thin wrapper each project repo copies and pins |
| Agent image | factory.serious-devs.io/serious-devs/ai-factory:<tag> |
opencode + glue preinstalled (/opt/factory), built from image/Dockerfile |
| Glue | glue/ (TypeScript, entry src/main.ts via tsx) |
Fetch thread → build prompt → opencode run → post comment / open PR |
Identity, secrets and configuration
- Bot user
agentwith a scoped PAT (write:repository+write:issue) stored as the user-level secretAGENT_TOKEN; comments authored by the bot never re-trigger the agent (self-trigger guard keyed on login). - Provider keys (
ZHIPU_API_KEY,ANTHROPIC_API_KEY,OPENAI_API_KEY,OPENROUTER_API_KEY) are user-level secrets passed through withsecrets: inherit. - Variable
agent_modelselects the model (provider/model); if unset, the glue infers a default from the first API key present (e.g.ZHIPU_API_KEY→zai-coding-plan/glm-5.3). - Labels
agentandbuildmust exist in each project repo; the default branch is push-protected — agents only open PRs.
Security posture
- Issue text is untrusted input to an agent that executes code by design; on a private single-user instance the risk is mostly cost/quality.
- The bot PAT is scoped, the default branch is push-protected, agents are instructed never to touch workflow files, and provider keys live in secrets — never in the image.
- Never expose the runner or the registry publicly without revisiting this.