ploeg

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: Apache-2.0

README

Ploeg

Assign a ticket on your own board and Ploeg spins up an ephemeral team of AI agents on your Kubernetes cluster that works it, opens a pull request, reports the outcome, and disappears — every run leased, audited, and crash-safe, with no lock-in on tracker, forge, or agent harness.

An open-source, self-hostable dispatch plane. Bring your own board, forge, and agent harness.

Ploeg is Dutch for a work crew or shift. Teams of specialist agents pick up a ticket, work it, report an outcome, and disappear.

Status: pre-alpha. Ploeg is being extracted from a running autonomous-agent setup (a "dark factory": agents working a ticket board unattended on a homelab Kubernetes cluster). The dispatch core and both executors (KEDA ScaledJob and a KEDA-free CronJob) ship in the chart — opt-in via executor.enabled — and dispatch the originating factory today; a local prototype runs the same core over Docker Compose (see below). Provider write-backs, a Forgejo forge provider, and team manifests are still to come. Watch, don't install.

What Ploeg is

  • A dispatch plane, not a board. Your tracker (Vikunja, Jira, GitHub Issues, …) stays the source of truth for what to do. Ploeg owns how work gets executed: assignment events in, ephemeral agent runs out.
  • Event-driven, never polling. Assigning a ticket fires a webhook; Ploeg spawns a Kubernetes Job for it. No heartbeat crons burning tokens to discover there is no work.
  • Ephemeral by design. Every run is a Job that starts, produces a structured outcome, and dies. Durable state lives in Postgres (work items, leases, checkpoints, outcomes, audit) and in git (branches, PRs) — never in a long-lived agent process.
  • Leased, not labeled. Claims are rows with a TTL renewed by the running Job. A crashed pod releases its ticket mechanically; nothing depends on an agent behaving well at death.
  • Teams of specialists. A work item is claimed by a team — a declarative manifest of specialist roles (implementer, reviewer on a different model family, tester) — not by a single agent identity.
  • Audited end to end. Every mutation, lease, run, and outcome is a Postgres row. Grafana dashboards ship as code.

What Ploeg is not

  • Not another kanban UI. The market has plenty; Ploeg has none.
  • Not a persistent-agent platform (see kagent) or model serving.
  • Not a promise of every integration. Ploeg ships a small, stable provider SPI and two reference providers (Vikunja tracker, Forgejo forge). Further providers are community-owned.

Architecture (v0 sketch)

tracker webhook ─┐                        ┌─> KEDA ScaledJob (per team) ─> agent Job (ephemeral)
forge webhook  ──┼─> ploegd ─> Postgres ──┤        │ lease renewal · checkpoints
                 │   (ingest,  (work items,        └─> outcome report ─> ploegd ─> tracker/forge writeback
                 │    SPI)      leases, runs,
                 └─────────────  audit)  ──────> Grafana (dashboards as code)
  • ploegd — single Go binary: webhook ingest, provider SPI, lease manager, outcome ingestion.
  • Executor — KEDA ScaledJob with the Postgres scaler is the flagship default; executors are pluggable behind the run-API contract (docs/contracts/executor.md) — a KEDA-free CronJob executor ships in the same chart (executor.type).
  • Harness contract — an agent container receives a TaskSpec, must emit an OutcomeReport (schemas). Harness adapters live behind pkg/harness.Adapter: openhands (default), exec (any binary), claude-code — selected per team, along with the agent image, via the team's harness block.

Try the prototype

docker compose -f ops/local/docker-compose.yml up -d --build
ops/local/demo.sh

The demo plays both tracker and agent: a signed Vikunja webhook queues a work item, a claim leases it (FOR UPDATE SKIP LOCKED + TTL lease), checkpoint and outcome complete it, and the audit trail records every step as a Postgres row. Crash-safety is real: claim an item, report nothing, and the sweeper releases the lease and re-queues the item when the TTL expires.

Roadmap

  1. Extraction — core service, Vikunja + Forgejo providers, one harness adapter, audit + dashboards. Exit criterion: the originating dark factory runs on Ploeg in production.
  2. Teams & follow-ups — team manifests, checkpoint/resume, PR-feedback ingestion routed to the owning team, a dry-run grooming worker.
  3. On demonstrated pull — GitHub provider, CRD/operator graduation, agent-sandbox runtimes, further providers by contribution.

License

Code: Apache-2.0.

The name Ploeg and the Ploeg mark are trademarks — §6 of that licence grants no rights in them, deliberately. docs/brand/TRADEMARK.md says what you may do with them without asking (reproduce them, link, say your software works with Ploeg) and the two things that need permission (shipping a fork under the name, implying endorsement). Settled in ADR-0022.

Directories

Path Synopsis
cmd
ploeg-worker command
ploeg-worker runs as the main container of an executor-spawned Job (docs/contracts/executor.md): it claims one work item from ploegd, drives a headless harness run via the adapter selected by PLOEG_HARNESS (design §5), and reports an OutcomeReport before exit.
ploeg-worker runs as the main container of an executor-spawned Job (docs/contracts/executor.md): it claims one work item from ploegd, drives a headless harness run via the adapter selected by PLOEG_HARNESS (design §5), and reports an OutcomeReport before exit.
ploegd command
ploegd is Ploeg's single daemon: webhook ingest, provider SPI host, lease manager, outcome ingestion.
ploegd is Ploeg's single daemon: webhook ingest, provider SPI host, lease manager, outcome ingestion.
internal
ledger
Package ledger holds the consistency gate for the ADR corpus in docs/adrs/ (ADR 0001).
Package ledger holds the consistency gate for the ADR corpus in docs/adrs/ (ADR 0001).
pkg
config
Package config loads ploegd's routing and roster configuration from a FILE rather than from environment variables.
Package config loads ploegd's routing and roster configuration from a FILE rather than from environment variables.
forgebroker
Package forgebroker is the credential seam between Ploeg and a git forge: mint a repo-scoped, write-scoped token for one writing Run, hand it over, and revoke it when the Run settles or its Lease lapses.
Package forgebroker is the credential seam between Ploeg and a git forge: mint a repo-scoped, write-scoped token for one writing Run, hand it over, and revoke it when the Run settles or its Lease lapses.
harness
Package harness defines the contract between Ploeg and an agent harness: TaskSpec in, OutcomeReport out.
Package harness defines the contract between Ploeg and an agent harness: TaskSpec in, OutcomeReport out.
harness/adapters/acp
Package acp adapts any agent speaking the Agent Client Protocol (ACP wire version 1) to Ploeg's harness seam — opencode, Gemini CLI, Goose and OpenHands natively, plus Codex and Claude Code through npm adapter processes.
Package acp adapts any agent speaking the Agent Client Protocol (ACP wire version 1) to Ploeg's harness seam — opencode, Gemini CLI, Goose and OpenHands natively, plus Codex and Claude Code through npm adapter processes.
harness/adapters/claudecode
Package claudecode adapts the Claude Code CLI (backlog #62): a headless `claude -p` run with a JSON result envelope mapped into OutcomeReport usage (cost, tokens, session id).
Package claudecode adapts the Claude Code CLI (backlog #62): a headless `claude -p` run with a JSON result envelope mapped into OutcomeReport usage (cost, tokens, session id).
harness/adapters/execbin
Package execbin is the generic escape-hatch adapter: run any binary against the published task contract.
Package execbin is the generic escape-hatch adapter: run any binary against the published task contract.
harness/adapters/openhands
Package openhands adapts the OpenHands agent-runner image: the prompt is written to a task file and the image's baked entrypoint runs it headless.
Package openhands adapts the OpenHands agent-runner image: the prompt is written to a task file and the image's baked entrypoint runs it headless.
harness/harnesstest
Package harnesstest is the adapter conformance kernel (backlog #69): every adapter must satisfy these properties regardless of which harness it wraps.
Package harnesstest is the adapter conformance kernel (backlog #69): every adapter must satisfy these properties regardless of which harness it wraps.
httpapi
Package httpapi exposes ploegd's two surfaces: webhook ingest (tracker → queued work) and the run API an agent container uses (claim, renew, checkpoint, outcome) per the worker-claims-at-startup convention (backlog #48).
Package httpapi exposes ploegd's two surfaces: webhook ingest (tracker → queued work) and the run API an agent container uses (claim, renew, checkpoint, outcome) per the worker-claims-at-startup convention (backlog #48).
litellm
Package litellm wraps the LiteLLM proxy admin API for per-run key lifecycle (mint + revoke, list + batch delete).
Package litellm wraps the LiteLLM proxy admin API for per-run key lifecycle (mint + revoke, list + batch delete).
llmbroker
Package llmbroker is the credential seam between Ploeg and an LLM gateway: mint a budgeted per-run credential before the harness starts, revoke it on every return path, and reconcile leaks from ploegd's sweeps.
Package llmbroker is the credential seam between Ploeg and an LLM gateway: mint a budgeted per-run credential before the harness starts, revoke it on every return path, and reconcile leaks from ploegd's sweeps.
plan
Package plan parses and validates Team plans: the ordered list of Rounds a Shift works through, each naming Roles with their writes flag and per-Run spending cap (run-multi-agent-shifts design.md D5).
Package plan parses and validates Team plans: the ordered list of Rounds a Shift works through, each naming Roles with their writes flag and per-Run spending cap (run-multi-agent-shifts design.md D5).
provider
Package provider defines Ploeg's SPI.
Package provider defines Ploeg's SPI.
provider/clickup
Package clickup is a TrackerProvider for ClickUp, the sibling of pkg/provider/vikunja: webhook verification and parsing, plus the API write-backs that let a run reach a person (backlog #31).
Package clickup is a TrackerProvider for ClickUp, the sibling of pkg/provider/vikunja: webhook verification and parsing, plus the API write-backs that let a run reach a person (backlog #31).
provider/forgejo
Package forgejo is the reference ForgeProvider (design §4): the first implementation of an interface that has been declared since the SPI was carved and had no caller until the blackboard needed one (ADR-0011).
Package forgejo is the reference ForgeProvider (design §4): the first implementation of an interface that has been declared since the SPI was carved and had no caller until the blackboard needed one (ADR-0011).
provider/gitlab
Package gitlab is a ForgeProvider for GitLab (self-managed or gitlab.com), the sibling of pkg/provider/forgejo.
Package gitlab is a ForgeProvider for GitLab (self-managed or gitlab.com), the sibling of pkg/provider/forgejo.
provider/vikunja
Package vikunja is the reference TrackerProvider (design §4): webhook verification and parsing, plus the API write-backs that let a run reach a person (backlog #31).
Package vikunja is the reference TrackerProvider (design §4): webhook verification and parsing, plus the API write-backs that let a run reach a person (backlog #31).
shiftengine
Package shiftengine owns the Shift lifecycle: when a Shift opens, how a Round advances, when a Shift closes, and what happens when either is left half-done (run-multi-agent-shifts, shift-orchestration spec).
Package shiftengine owns the Shift lifecycle: when a Shift opens, how a Round advances, when a Shift closes, and what happens when either is left half-done (run-multi-agent-shifts, shift-orchestration spec).
store
Package store is Ploeg's Postgres data layer: work items, leases, checkpoints, runs, and the audit log.
Package store is Ploeg's Postgres data layer: work items, leases, checkpoints, runs, and the audit log.
target
Package target resolves where a Work Item's changes land.
Package target resolves where a Work Item's changes land.
work
Package work defines Ploeg's core semantics: work items, leases, checkpoints, and outcomes.
Package work defines Ploeg's core semantics: work items, leases, checkpoints, and outcomes.
worker
Package worker is the run orchestrator that executes one claimed work item: claim → clone → compose prompt → mint credential → harness adapter run → forge-poll outcome resolution → outcome report.
Package worker is the run orchestrator that executes one claimed work item: claim → clone → compose prompt → mint credential → harness adapter run → forge-poll outcome resolution → outcome report.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL