provefab

Last updated

Jira or Linear ticket to pull request, without a hosted agent

Put a label on a Jira or Linear ticket. Provefab, running on your own Mac or Linux server, picks the ticket up, has your coding agents work on it in a separate worktree, and opens a pull request on GitHub with the ticket key in its title. It reports back on the ticket with labels and comments, and it never changes a ticket’s status. A person reviews and merges. Jira and Linear support is in beta: it has been tested against recorded API responses, not yet against live Jira and Linear sites.

Beta: what has been tested

The Jira and Linear reference opens with the same warning: the integration has been tested against recorded API responses, not yet against live Jira and Linear sites. Expect rough edges that only a real site shows.

If something fails, provefab doctor and the task’s reason say what: doctor makes a real call to the tracker and prints its result, and a stopped task records why in provefab log. Please report what you see in an issue.

How a label hands a ticket over

Each repository in provefab.toml has a label, provefab by default. Put that label on a ticket in the configured project or team and Provefab finds it at its next poll, every 3 minutes by default. A poll asks for open tickets carrying the label, up to 1000 at a time:

The label is the authorization. Nobody mentions a bot and nothing listens for webhooks: whoever can put the label on a ticket is the person approving agent time on it. That makes the habit simple and important: read a ticket before you label it. Its title and description reach the agents, and the security notes treat a ticket’s text as untrusted data, like issue text.

What Provefab writes on the ticket

Provefab reports progress with the same labels it uses on GitHub issues:

Label Meaning
provefab:needs-info Provefab asked a question; answer in a comment
provefab:in-pr a pull request is open on GitHub
provefab:failed Provefab stopped; its comment says why
provefab:merged the pull request was merged
provefab:risk-<category> the change touches that risk category, such as CI or dependencies

Jira labels are free text, so nothing is created on the Jira side; a Jira label cannot contain a space, so neither can your repository’s label. On Linear, the labels are created on the team at startup when no label of that name exists in the team or the workspace.

Every comment starts with “Posted by Provefab (automated), not typed by a person.” On Jira the comment is converted to Atlassian Document Format (paragraphs, lists, code, links, emphasis); on Linear it stays Markdown.

Provefab adds and removes only its own labels; a label a person adds at the same moment is kept. It never changes a ticket’s status. Moving the ticket through your workflow stays with your team, or with your tracker’s own automation.

The code, the branches and the pull requests stay on GitHub. For a ticket ENG-123, Provefab names the branch provefab/ENG-123-<title> and titles the pull request ENG-123: <title>. The body starts with Issue: [ENG-123](<link>).

That naming is what the vendors’ own GitHub integrations look for. Atlassian’s page on referencing work items in development work says to use “the key in the branch name” and, for pull requests, to “use the key in the pull request title”, with the key in capital letters. Linear’s GitHub integration docs say to “Include the Linear issue ID (e.g. ID-123) in the title when creating pull requests.”

On Linear the body also says Fixes ENG-123. Linear treats that as a closing magic word: with its GitHub integration enabled, the issue moves to “the status configured for On PR or commit merge when the PR or commit is merged” (Linear docs). So Linear may close the ticket when the pull request merges. That is Linear’s setting, not Provefab’s.

The pull request then waits for a person. The free, source-available core never merges: the security notes state “This binary never merges”, and the pull request text lists the checks that ran and any test the change deletes or disables.

One project per repository

Each repository takes its tickets from one Jira project or one Linear team. Several repositories can share a project, each with its own label; a ticket must carry only one of them, because a ticket carrying two repositories’ labels is queued in both.

You can also hand over a ticket by URL. provefab add <url> accepts Jira’s https://<site>/browse/ENG-123 and Linear’s https://linear.app/<workspace>/issue/ENG-123. When several repositories share the project, the ticket’s label picks the repository, and a ticket with no matching label, or with several, is an error that names the candidates. A Linear ticket from another workspace than the one your key belongs to is refused.

Credentials

For Jira, create an API token for the Atlassian account Provefab will use. The account needs to browse the project, comment and edit labels. Store it with provefab login jira --site acme.atlassian.net, which asks for the account e-mail, then the token.

For Linear, create a personal API key for an account that is a member of the team, and store it with provefab login linear.

On macOS the credentials go to the Keychain. On Linux they go to ~/.provefab/credentials.toml, mode 600, which Provefab refuses to read when others can; the file is protected by its permissions, not encrypted. The environment variables PROVEFAB_JIRA_EMAIL, PROVEFAB_JIRA_TOKEN and PROVEFAB_LINEAR_KEY override the stored values. Credentials never go in provefab.toml, and they never appear in an error, a log or a comment.

The repository’s configuration only names the tracker. For Jira:

[[repos]]
slug = "acme/api"
label = "provefab"
gates = ["make test"]
[repos.tracker]
kind = "jira"
site = "acme.atlassian.net"
project = "ENG"

For Linear:

[repos.tracker]
kind = "linear"
project = "ENG" # the team key, as in ENG-123

Who may answer questions

When Provefab needs details, it labels the ticket provefab:needs-info and asks in a comment. The ticket’s reporter (Jira) or creator (Linear) and any member of the workspace may answer.

Limits

Set it up

Install Provefab, sign in a worker and the tracker, add the repository, put the [repos.tracker] block inside its existing [[repos]] entry (repos add never writes one), then check:

Terminal window
curl -fsSL https://provefab.com/install.sh | sh
provefab login codex # all Claude stages currently refuse
provefab login jira --site acme.atlassian.net # or: provefab login linear
provefab init
provefab repos add acme/api
# add [repos.tracker] under the acme/api [[repos]] entry in ~/.provefab/provefab.toml
provefab doctor

provefab doctor prints a tracker line for each repository with the result of a real call: for Linear, the workspace and whether the team is readable. Then label a ticket you have read.

The Jira and Linear reference has every detail on this page and the edge cases behind it. To let a coding agent write the configuration for you, follow Set up with a coding agent. For what happens between the label and the pull request, from the reproduction to the second model’s review, see how to verify AI-generated pull requests. To keep Provefab running on a server rather than your laptop, see Run Claude Code and Codex on a headless Linux server.

Try it: the source-available core on GitHub, orProvefab Pro.