AI
How Platform runs AI agents: GitHub Agentic Workflows on a self-hosted runner is the recommendation, with opencode-onboard, loop-task, and orbion around it.
The recommendation, up front
To run an agent against a repository, use
GitHub Agentic Workflows on a self-hosted runner with
engine: opencode. That is the Platform default, and it is not one of our tools.
loop-task is the fallback, for work that has no repository event to react to or cannot run
on a runner. Reaching for it first is the wrong instinct.
Alongside that recommendation, Platform maintains three open-source tools. They prepare a codebase for agents, and cover the cases Actions cannot.
| Tool | What it does | When to use it |
|---|---|---|
| opencode-onboard | Prepare any codebase for AI agents | Always, whichever runner you end up on |
| loop-task | Run any command on a cadence | Fallback only: no repository event to react to, or no runner available |
| orbion | Desktop control plane for loop-task instances | Only if you are already running loop-task |
How to run agents on a cadence
Read this before picking a tool, because the default is not one of ours.
Recommended: Agentic Workflows on a self-hosted runner
For work that lives in a GitHub repository, the recommended practice is
GitHub Agentic Workflows running on a self-hosted runner with
an authenticated opencode. Workflows are markdown in .github/workflows/, compiled to Actions
YAML.
The self-hosted runner is what makes this work for us rather than a compromise:
-
Event triggers instead of polling. A workflow fires on the issue comment or review that should have started it. A 20-minute interval means up to 20 minutes of latency and a run every interval that usually finds nothing to do.
-
Your subscription, not an API key. gh-aw ships an
opencodeengine, so point it at the binary on the runner and it uses the session already authenticated there. On a GitHub-hosted runner you would be on theclaudeengine with anANTHROPIC_API_KEY, which does not accept OAuth subscription tokens, and paying per token for a workflow that fires all day.engine: id: opencode # experimental in gh-aw command: /usr/bin/opencode -
A fresh checkout per run. Most of the recovery machinery in a long-lived local loop exists only because state persists between runs on one machine. It disappears here.
-
Local context stays available. VPN-only resources, a local database, licensed tooling.
-
One runner is a mutex. It processes one job at a time, which is the exclusivity that interval loops otherwise have to coordinate by hand.
-
Guardrails. Safe Outputs, staged approval, changes arriving as pull requests, and an audit trail in Actions.
Never attach a self-hosted runner to a public repository
A pull request from a fork would execute arbitrary code on your runner, with whatever credentials it holds. Private and internal repositories only.
The alternative: loop-task
loop-task is what you use when you cannot depend on the above. It is a deliberate fallback,
not a preference:
- The work is not repository-shaped. Health checks, data syncs, deploy polls, report generation. There is no repository event to hang them off.
- You are not on GitHub Actions. Azure DevOps, GitLab, or no CI at all.
- A self-hosted runner is not an option, and API-key billing for a loop that fires every 20 minutes is not acceptable.
- The work needs a specific machine. Anything a runner cannot reach or cannot be trusted with.
- You need to watch it run. Live logs, pause and resume mid-flight, one board across several machines. Actions gives you logs after the fact.
- Sessions are long or stateful in ways a job timeout does not accommodate.
What decides is whether the trigger is an event or a clock, and whether the work can leave the machine it is on. The two compose: a repository loop can live in Actions while a local loop watches something Actions cannot see.
opencode-onboard
Prepare any codebase for AI. A single interactive wizard wires OpenCode, OpenSpec, codegraph, and agentmemory into a multi-agent development workflow powered by native parallel subagents.
Quick start
npx @plainconceptsplatform/opencode-onboard@latestRequires Node.js 18 or higher. You can also run individual steps directly:
npx @plainconceptsplatform/opencode-onboard clean # reset old AI files
npx @plainconceptsplatform/opencode-onboard platform # reconfigure backlog/repository
npx @plainconceptsplatform/opencode-onboard optimization # RTK, codegraph, agentmemory, humanizer
npx @plainconceptsplatform/opencode-onboard --helpWhat the wizard does
The CLI runs a 10-step onboarding wizard:
- Source scope — current repo or sibling source roots
- Clean AI files — removes stale
AGENTS.md,.cursorrules,CLAUDE.md,.agents/ - Choose platform — backlog (GitHub, Azure DevOps, Jira, browser, or None) plus repository (GitHub, Azure DevOps, GitLab, or None). Supports mixed platforms.
- Check platform CLI — verifies
gh,az,acli, orglabas needed - Copy scaffolding — agents, built-in skills, bootstrap docs,
skills-lock.json - Initialize OpenSpec —
npx @fission-ai/openspec initfor structured change management - Choose models — plan, build, and fast tiers from models.dev
- Token optimization — optional RTK, quota, caveman, codegraph, agentmemory, humanizer
- Install browser plugin —
@different-ai/opencode-browserfor agent browser automation - Write onboarding metadata —
.opencode/opencode-onboard.json
Bootstrap sequence
After onboarding, open OpenCode in your project and type:
/repo-initializeFor brownfield projects, it generates ARCHITECTURE.md and DESIGN.md from your actual codebase, archives project history into OpenSpec, and activates the agent team. For greenfield projects, it skips documentation generation and leaves placeholder files you can populate later with /make-architecture and /make-design.
Platform migration skill
platform-onboard
is the Platform Foundations skill for migrating a brownfield repository to the recommended stack.
Use it after the agent setup is in place when the repository needs a deliberate, end-to-end adoption
rather than a theme-only upgrade.
It starts with a binary preflight across six domains, then creates and completes one OpenSpec change per failing domain: agentic infrastructure, architecture documentation, OpenSpec, the frontend stack, loop automation, and .NET guardrails where relevant. Frontend work begins with Playwright characterization tests to protect existing behavior and visual parity.
Key commands
Installed as slash commands in .opencode/commands/:
| Command | Purpose |
|---|---|
/repo-initialize | Initialize project (greenfield vs brownfield), activate agent team |
/plan-propose | Parse a work item URL into proposal, specs, and tasks |
/plan-apply | Implement tasks in parallel subagent waves |
/plan-goal | Autonomous full-lifecycle pipeline (explore → propose → apply → archive) |
/ops-ship | Create a pull request with screenshots |
/make-architecture | Generate or regenerate ARCHITECTURE.md |
/make-design | Generate or regenerate DESIGN.md |
/repo-audit | Read-only health audit across source roots |
/repo-help | Show all commands and when to use each |
Multi-platform
Mix backlog and repository platforms. Examples: Jira backlog plus GitHub repository, browser backlog plus GitLab repository. The matching ob-userstory-* skill is installed based on your backlog choice; PR operations are injected into /ops-* commands based on your repo choice.
loop-task (fallback)
Not the default
Only reach for this once you have established that Agentic Workflows on a runner will not work for the case in hand. If the trigger is a repository event, you are in the wrong section.
Loop engineering for your terminal. A cross-platform CLI that runs shell commands at human-readable intervals. Create loops in the background, manage them from an interactive TUI board, or run them in the foreground.
Quick start
npm install -g @plainconceptsplatform/loop-task
loop-task # open the board
loop-task start # start the daemon, restore persisted loops
loop-task new 30m -- npm test # create a background loop
loop-task new 30m --now -- opencode run "find missing translations and translate them, 3 max"The package is scoped; the command it installs is still loop-task. Requires Node.js 20 or
higher, or run directly with npx @plainconceptsplatform/loop-task.
Use the scoped package
The unscoped loop-task on npm is an earlier release of the same tool and no longer tracks this
one. Installing it gets you a version several minors behind.
Concepts
- Loop — a schedule (defines when). Triggers tasks. Fields: interval, task, description, max runs.
- Task — an executable unit (defines what). Fields: name, command, on-success chain, on-failure chain. Reusable across loops.
- Project — organizational scope for loops. Every loop belongs to one project; the board shows only the active project.
The board
Interactive TUI for managing loops, tasks, and projects. Loops persist to disk and survive reboots. Closing the board or terminal does not stop loops — the daemon keeps running.
Key controls: ↑/↓ move, Enter edit, p pause/play, s stop, n new loop, c copy command, / search, Esc quit.
Chain context sharing
Tasks chain on success or failure. Context flows between them automatically via {{key}} template interpolation. A later task references output from an earlier one without re-querying:
# Task 1: find an issue
gh issue list --label "to implement" --json number,title,body --jq '{number: .[0].number, title: .[0].title, body: .[0].body}'
# Task 2 (on-success): mark in-progress
gh issue edit {{number}} --add-label "implementing" --remove-label "to implement"
# Task 3 (on-success): AI implements it
opencode run "Implement this GitHub issue... Issue number: {{number}} Title: {{title}} Body: {{body}}" --model "opencode/big-pickle"
# Task 4 (on-success): close the issue
gh issue edit {{number}} --remove-label "implementing" && gh issue close {{number}}Driving AI agents
The core loop-engineering pattern: schedule an AI agent to chip away at a backlog on a cadence, unattended:
loop-task new 30m --now -- opencode run "find and implement the next issue, one max"The daemon runs the opencode command every 30 minutes. Use --max-runs to bound unattended sessions, and watch the run history on the board.
HTTP API
The daemon exposes a REST + SSE API on localhost:8845:
curl http://127.0.0.1:8845/api/loops
curl -N http://127.0.0.1:8845/api/loops/abc123/logs/stream # live log followingSwagger UI at /api/docs, OpenAPI spec at /api/openapi.json. Bind host configurable via loop-task http-host (default 0.0.0.0; set to local for loopback only).
orbion
The open-source control plane for loop engineering. A desktop app (Electron + React 19) that manages multiple loop-task instances from a single interface.
What it does
- Instances — register any number of loop-task daemons by HTTP API URL (e.g.
http://127.0.0.1:8845), with connection health dots. Persisted locally. - Loops — live list per instance (status, interval, runs, last exit, next run), filterable from the bottom bar.
- Logs — per-loop log viewer with live follow via SSE streams.
- Projects — view projects and their loops across all instances.
Read-only in v1: no pause, trigger, or edit actions yet. Binary releases are planned; currently run from source.
Run from source
git clone https://github.com/PlainConceptsPlatform/orbion.git
cd orbion
pnpm install
pnpm dev # Electron app (hot reload)
pnpm dev:web # renderer only, with mocked data (no Electron/daemon)Requires Node.js 20 or higher and pnpm. A running loop-task daemon with the HTTP API (loop-task >= 2.1) is needed for real data.
Remote instances (VMs)
The loop-task daemon binds its HTTP API to 0.0.0.0 by default, so a daemon on a VM is reachable from Orbion out of the box. Secure access at the network layer (VPN, SSH tunnel, or firewall), since the API is unauthenticated.
Using them together
The three tools compose into a pipeline. Use any one alone, or chain them:
opencode-onboard loop-task orbion
(prepare codebase for AI) (schedule AI runs) (manage all loops)
│ │ │
▼ ▼ ▼
npx @plainconceptsplatform/ loop-task new 30m -- register instance
opencode-onboard@latest opencode run "..." watch loops + logs
/repo-initialize- Onboard once — run opencode-onboard in your repo to wire agents, OpenSpec, and the full command set.
- Schedule recurring work — create a loop-task loop that invokes
opencode runon a cadence, so an AI agent chips away at a backlog or sync job unattended. - Manage from one place — register the loop-task daemon(s) in orbion and watch every loop across every machine, with live logs.
Each tool holds its own: opencode-onboard is the entry point for any one-off agent session, loop-task works with any shell command (not just AI), and orbion is the observability layer.