How it works

You define the workflow. Goobers runs it.

You describe a workforce and its workflows in files you own. Goobers turns each workflow into a pipeline, runs it against your backlog, and calls you in at the decisions you reserved.

workflow = trigger + stages + gates

None of the three is fixed. Any of five trigger kinds. Any mix of scripted and agentic stages, in any order. Gates and telemetry pointed at what you already run, not a service you adopt.

01

You define the workforce

goobers init --guided proposes one neighboring Goobers Instance and keeps your definitions there by default; --instance-path <path> pins a custom durable location instead. A separate, reviewed configuration source is an advanced opt-in past that default, not the standard model. All of it is Kubernetes-style YAML with apiVersion: goobers.dev/v1alpha1, grouped by who writes it and when.

A goober is a definition. Behavior lives in a markdown instructions file and config in YAML; at runtime it materializes as an ephemeral environment, a fresh git worktree plus a local process.

Why YAML? It's GitOps for your agent workforce: source-controlled, PR-reviewed, diffable, revertable — the same operational model you already run your infrastructure on. A workflow isn't a script you kick off by hand; it's a versioned part of your product.

gaggles/acme-web/
  gaggle.yaml
  goobers/
    coder/
      goober.yaml
      instructions.md
  workflows/
    implementation.yaml
# goober.yaml (abridged)
apiVersion: goobers.dev/v1alpha1
kind: Goober
metadata:
  name: coder
spec:
  gaggle: acme-web
  role: coder
  instructions: instructions.md
  harness: claude-code
  capabilities:
    - repo:push
    - github:issues:write
  workflows:
    - implementation
02

Goobers compiles your pipeline

One execution of a workflow, with pinned inputs. The run records the workflow name, version, and compiled digest, and completes on that version.

A run starts however fits: on demand, on a schedule, or triggered by backlog, signal, or a signed webhook. Stages come in two kinds — deterministic runs a command (inline or a project-owned script), agentic invokes a goober — in any mix, any order you declare. Only envelopes and artifacts pass between stages; agentic stages read and publish them through the automatically supplied goobers-io tools.

What feeds a trigger is pluggable the same way. The shipped examples watch Goobers' own run journal, but a signal source can just as easily be a product-telemetry connector — same interface, no SDK embedded in your app.

trigger plan implement test gate open pr escalated repass pass repasses exhausted
One instance of that shape: the implementation workflow's five stages and one gate. Square stages, gates as stamped diamonds. A gate is a checkpoint after the work — a failing verdict sends the run back to implement, a spent repass budget escalates instead of looping. In a live run, violet marks the stage a goober holds.

One run, from the acceptance record

The trace below is that same run, 924e2b3d, verbatim — recorded 2026-07-15 against the Goobers repository itself. The implementation workflow claimed issue #317, passed its review and CI gates, and opened PR #324 in 505.7 seconds. A different workflow would draw a different shape here — its own trigger, its own stage mix, its own gates.

run:      924e2b3d4d4236521259bf2ea66fbe11
workflow: implementation (v1)
trigger:  manual implementation
phase:    completed (machineState="", lastSeq=39)

[3-8]   stage query-backlog  → success (claimed issue #317)
[9-11]  stage implement      → success
[15]    gate  review         → verdict=pass  target=local-ci
[16-19] stage local-ci       → success
[20]    gate  local-gate     → verdict=pass  target=push-branch
[21-24] stage push-branch    → success
[25-30] stage open-pr        → success  → ref.touched kind=pr id=324
                                url=https://github.com/Agent-Clubhouse/Goobers/pull/324
[31-32] stage ci-poll        → success  (real GitHub Actions `make ci`
                                green, job 87304277074)
[33]    gate  ci-gate        → verdict=pass  target=close-out
[34-38] stage close-out      → success (issue #317 closed out)
[39]    run.finished         → status=completed

The same acceptance record keeps the failing sibling: run 1c93168e failed local-ci four times, burned its three repasses, and finished in status=escalated. The recorded cause was a platform bug, found by reading the journal.

Workflows invoke goobers; goobers never invoke workflows. A goober's own output can become a signal the scheduler admits as a trigger, so chaining between workflows always routes back through the scheduler, never through a direct call. Readiness conditions gate every trigger before a run starts: per-workflow and per-instance max-parallel limits, maxRunsPerHour and maxRunsPerDay budgets, maxOpenPRs, and provider-quota gating all have to clear first — maxChainDepth is part of the same contract but reserved, not yet enforced.

03

Beyond the PR

Landing a PR is not the end of the story. Three workflows run at two altitudes and never call each other directly: implementation is the executor that opens the PR; merge-review is the decider that looks at the whole set of open PRs at once, not just the one it is judging; pr-remediation is the executor that reworks one flagged PR on its own branch. They compose only through durable labels, and each label is paired with a machine-readable sticky comment payload that is the actual source of truth, not the label text — see the full label set in shipped workflow examples.

Draining a cluster of PRs

When several open PRs touch overlapping files, merge-review's elect-lander stage picks one to land, merges it, and post-merge rebases the rest onto it before repeating — draining the whole cluster one PR at a time instead of racing them. Merging itself is never on by default: it is a separate, explicit per-workflow capability grant, gated further by a conjunctive safety check that must also pass.

Escalation feeds decomposition

Escalation is not always a dead end. When an implementer returns a non-retryable ISSUE_OVER_SCOPE or NEEDS_DECOMPOSITION failure, the runner skips review and ends the run escalated — and that terminal state is itself a signal a decomposition workflow consumes. Decomposition mirrors the executor: an agentic stage proposes the split with no issue-write capability of its own, and a deterministic publisher performs every issue mutation from that validated plan, committing the parent issue's published record as a single batch so a backlog query can never claim a half-published child. One oversized issue becomes a batch of independently claimable goobers:ready children.

The journal feeds the Tutor

The run journal is not only an audit trail — it is the Tutor's input too. The tutor workflow mines many runs' history for recurring failure patterns and opens a PR against the config source proposing a better instruction, skill, gate, or workflow stage; the same review-and-gate policy that governs every other change decides whether it lands. The action-root enforcement below is the containment half of that story, not the whole story of what the Tutor is for.

04

It runs by your rules

Claiming is atomic and lease-based, so concurrent runs never fight over one backlog item; declared caps bound how much runs at once.

Changing the workforce takes a PR

A workflow can grant an agent real effects: commit to a run branch, update an issue, open a pull request. Changing the workforce itself is stricter — an autonomous agent never edits active definitions in place, only proposes a PR against the config source, and validation, required CI, and human review decide whether it becomes desired state. The reference Tutor workflow's own PRs go through that same gate, plus one more: its open-pr stage verifies the whole diff resolves inside exactly one declared action root — a config subtree or a skills tree — and fails closed otherwise.

Every artifact and invocation-context pointer Goobers hands to a stage carries a provenance grade — trusted, maintainer, unapproved, or derived. A task's minimumIntegrity is fail-closed: on public repos, an unlabeled backlog item is unapproved by default until a maintainer's trust label grades it up, and a maintainer-only task refuses lower-graded input before its workspace or credentials even provision.

Identity and isolation

What an agent may do is declared, not inherited: capability grants are default-deny, scoped per gaggle and per goober. Where it runs is disposable: a repo-backed stage gets a fresh git worktree on the run branch each time, deterministic stages run with network: none, and sandboxed execution is opt-in and still in preview.

05

It tags you in when it needs you

A human gate parks the run durably at that decision point: reaching one durably records gate.paused. From there, goobers approve <run-id> <gate> resumes it, goobers override --rationale=… force-passes a nondeterministic gate, and goobers rerun-stage --addendum=… re-runs one stage of a run that finished failed or escalated. Every intervention is journaled as a run.resumed event carrying the actor, the decision, and the rationale; a rerun addendum is one-off and is never written back into the workflow definition.

approve override / rerun-stage (ResumeFromTerminal) running completed failed aborted escalated paused
A run's lifecycle. Reaching a human gate parks the run at paused, not a terminal phase; approve resumes it. override and rerun-stage re-enter a run already at a terminal phase (failed or escalated) through ResumeFromTerminal.
A reviewer goober

Escalation is terminal and records a structured cause. goobers escalations show prints the cause and the artifact timeline around each stage. Reaching escalated here parks the issue goobers:needs-remediation — mechanical status (repass exhaustion, an identical-diff loop, an infra failure), not a decision, and nobody is assigned. "Needs you" is the decision queue specifically: an explicit reviewer fail verdict parks goobers:needs-human instead, through aborted, and only that park assigns the configured human.

goobers dashboard serves a read-only portal from the same binary — escalations and every gate verdict are on the run's page. Gaggle and workflow names are pivots: Runs and Insight links scope to them and stay bookmarkable via the URL. An Overview page's Needs attention list surfaces failed and escalated runs; dismissing one is local to your browser, not synced across devices.

06

Your backlog moves

Issues get claimed, work gets implemented, and PRs land under your gate policy.

Work nomination Implementation Backlog curation PR remediation & merge Tutor your telemetry your backlog your repo goobers config goobers journal

Five surfaces, one arrow each. See shipped workflow examples that draw these routes.

One instance, many gaggles. Repo and backlog multiply — one pair per gaggle you run — while goobers config and the run journal stay singleton at the instance level, spanning every gaggle. That's how one instance coordinates multiple projects side by side, each still fully siloed: its own repo, its own backlog, its own isolation boundary.

Every run appends to a content-digested journal on disk; goobers trace reads it back. A run id is a valid OpenTelemetry trace id.

An instance is meant to keep running this loop unattended for a week without an operator: installed as a supervised service, restarting cleanly through one shutdown contract, and self-updating without you touching config. See running it on a server for what that actually takes.

Next: install it and run your own instance.