Platform Foundationsv0.2.0
AI

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.

ToolWhat it doesWhen to use it
opencode-onboardPrepare any codebase for AI agentsAlways, whichever runner you end up on
loop-taskRun any command on a cadenceFallback only: no repository event to react to, or no runner available
orbionDesktop control plane for loop-task instancesOnly 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.

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 opencode engine, 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 the claude engine with an ANTHROPIC_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@latest

Requires 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 --help

What the wizard does

The CLI runs a 10-step onboarding wizard:

  1. Source scope — current repo or sibling source roots
  2. Clean AI files — removes stale AGENTS.md, .cursorrules, CLAUDE.md, .agents/
  3. Choose platform — backlog (GitHub, Azure DevOps, Jira, browser, or None) plus repository (GitHub, Azure DevOps, GitLab, or None). Supports mixed platforms.
  4. Check platform CLI — verifies gh, az, acli, or glab as needed
  5. Copy scaffolding — agents, built-in skills, bootstrap docs, skills-lock.json
  6. Initialize OpenSpecnpx @fission-ai/openspec init for structured change management
  7. Choose models — plan, build, and fast tiers from models.dev
  8. Token optimization — optional RTK, quota, caveman, codegraph, agentmemory, humanizer
  9. Install browser plugin@different-ai/opencode-browser for agent browser automation
  10. Write onboarding metadata.opencode/opencode-onboard.json

Bootstrap sequence

After onboarding, open OpenCode in your project and type:

/repo-initialize

For 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/:

CommandPurpose
/repo-initializeInitialize project (greenfield vs brownfield), activate agent team
/plan-proposeParse a work item URL into proposal, specs, and tasks
/plan-applyImplement tasks in parallel subagent waves
/plan-goalAutonomous full-lifecycle pipeline (explore → propose → apply → archive)
/ops-shipCreate a pull request with screenshots
/make-architectureGenerate or regenerate ARCHITECTURE.md
/make-designGenerate or regenerate DESIGN.md
/repo-auditRead-only health audit across source roots
/repo-helpShow 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 following

Swagger 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
  1. Onboard once — run opencode-onboard in your repo to wire agents, OpenSpec, and the full command set.
  2. Schedule recurring work — create a loop-task loop that invokes opencode run on a cadence, so an AI agent chips away at a backlog or sync job unattended.
  3. 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.