Skip to content
This text was generated by an LLM (how cgwalters uses LLMs). cgwalters has not reviewed it yet.

Forges

agent-board is meant to work on any forge that has issues and something that can hold a board. Each forge is read into the same normalized snapshot, so item list, item view and reconcile plan work unchanged on top of it. What works today:

ForgeBoard readsWrites, plans and dispatch
GitHubProjects v2Yes
ForgejoIssues of configured repositories, fields from labelsNo (#271)
GitLabNoNo (#294)

Dispatch itself is a GitHub Actions request today on every forge: agent jobs start through one backend interface whose only implementation is workflow_dispatch; status queries and other backends are #295 (dispatch). The design's approach to other forges, capability negotiation rather than weakened guarantees, is in Rust boundaries.

GitHub

The board is an organization Project v2, chosen with --owner ORG --project N and read with a GH_TOKEN that has project and issue read. Status, Priority, Turn, Run and Result are project fields (setup). Every command works here. Only github.com is supported for live reads.

Forgejo

Forgejo's API has no projects, so --board-config agent-board.json (trusted, default branch) can make the board the issues of some Forgejo repositories instead. It is read by snapshot create, project view, item list, item view and reconcile plan; nothing writes to Forgejo.

{
"board": {
"forge": "forgejo",
"url": "https://forge.example/",
"tokenEnv": "FORGEJO_TOKEN",
"repositories": ["example/intake"],
"membership": {"label": "agent-board"},
"recorders": [1234]
}
}

membership is {"label": NAME} (open and closed issues with that label) or "open" (every open issue). Priority comes from one priority/P0..priority/P3 label and Turn from one turn/coordinator, turn/operator, turn/worker, turn/external, turn/none or turn/<policy identity> (read as Worker) label; zero, two or an unknown value leaves the item's fields incomplete and reconcile plan says why. blocked/<reason> labels fill a Blocked list. Run and Result come from the newest comment by a recorders user id (not login, which can be renamed and re-registered) whose first line is <!-- agent-board-run: URL --> or <!-- agent-board-result: URL -->; with no recorders, comments are not read. Coverage is complete only when the issues read match the listing's X-Total-Count. Status and close reasons do not exist there, so they are null. The GitHub token variables are never sent to the Forgejo host. Without board, or with "forge": "github", the board is a GitHub project.

url may be https:// or http:// and may carry a port, as for a Forgejo reached inside a cluster (http://forgejo-http.forgejo.svc:3000/); it may not carry credentials, a query or a fragment. Plain HTTP sends the token unencrypted with each request, so the CLI warns on stderr when an http:// URL names a host that is not loopback, a private, link-local or unique-local address, a single-label name, or a name ending in .svc, .cluster.local, .local or .internal. Item identities keep only the host name, without scheme or port, so two instances on one host cannot share a board. Run and Result marker URLs must still be https://.

Open: there is no write side or dispatch (#271).

GitLab

Not supported yet. #294 starts with a read-only board, as for Forgejo, then plans, records and dispatch.