Event loops

Loops that fire when something happens in your tools: a pull request opened, an issue assigned, a label added. This is what automatic code review actually is — a loop you own, can rewrite, and can switch off.

An event loop fires when something happens in a tool you have connected. No cadence, no assignment ritual, no one typing a prompt: a pull request is opened and the review is underway before anyone has switched tabs.

Its instruction is standing guidance layered on top of whatever the event already carries. The goblin is given the merge request or the issue as context automatically; your instruction tells it what you want done about it.

The events you can loop on

Event Source Fires when
Merge request opened GitLab An MR is opened, reopened, or updated with new commits
Issue assigned GitLab An issue is assigned to the @taskgoblin bot
Pull request opened GitHub A PR is opened, reopened, or updated with new commits
Issue labelled GitHub The taskgoblin label is added to an issue
Issue assigned Linear An issue is assigned to the TaskGoblin agent
Issue assigned Jira An issue is assigned to the TaskGoblin account

Because the "opened" events also cover updates, a review loop reconciles rather than repeats: on a second pass it reads the findings it left last time, resolves the ones you have fixed, and only posts what is genuinely new.

The loops you already have

You do not start from an empty page. The moment a provider comes into existence for your organisation, TaskGoblin seeds that provider's default loops:

  • GitLabReview merge requests and Work on assigned issues.
  • GitHubReview pull requests and Work on labelled issues.
  • LinearWork on assigned issues.
  • JiraWork on assigned issues.

These reproduce what people expect a coding agent to do out of the box. The difference is that they are yours: real loops on your Loops page, with instructions you can read and change.

Seeding happens once, ever. Delete a default loop and it stays deleted — reconnecting the provider will not quietly bring it back.

Rewriting the instruction is the point

The default review instruction asks for correctness, security, and maintainability, and tells the goblin to stay silent when a change is sound. That is a reasonable opening position, not a policy you are stuck with. Teams routinely narrow or widen it:

  • "Only flag security issues and data-loss risks. Nothing else."
  • "Be strict about test coverage — every behaviour change needs a test, say so if one is missing."
  • "Also check that any new endpoint is covered by our rate-limiting middleware."

The instruction is free text, so it can encode the things a linter cannot: your conventions, your past incidents, the mistake this team keeps making.

The default, and a hardened version of it

This is what ships:

Review this merge request. Focus on correctness, security, and maintainability — flag real problems, not style nits a linter would catch. Leave inline comments only where they add value, keep them specific and actionable, and stay silent when the change is sound.

It is deliberately restrained, because a reviewer that comments on everything gets muted. Now here is the same loop after a team has lived with it for a month and had an incident:

Review this merge request for correctness, security, and maintainability. Flag real problems, not style nits.

Additionally, always check: every behaviour change has a test; no new endpoint ships without our rate-limiting middleware; no migration edits an existing migration file; nothing logs a full request body. Raise these as critical even when the rest of the change is fine.

If the MR is over 400 lines, say so in the summary and review the riskiest files first rather than skimming everything. Stay silent when the change is sound.

Nothing about the second version is exotic — it is institutional knowledge that previously lived in a wiki nobody opened, now attached to the moment it matters. That is the difference between a loop you inherited and a loop you own.

The off switch

This is the part worth reading twice, because it explains behaviour that would otherwise look like a bug.

A gated event with no matching active loop starts no run. Pause your review loop and merge requests stop being reviewed. Delete it and the same. TaskGoblin still accepts the webhook — it simply has no standing instruction to act on, so no goblin wakes and nothing is billed.

That is the trade for owning the behaviour rather than having it done to you. If automatic review has stopped, the first place to look is whether its loop is still active.

What is never gated

Explicit human asks always run, whether or not any loop exists:

  • @taskgoblin mentioned on a merge request, pull request, or issue comment
  • A message or mention in Slack or Microsoft Teams
  • A follow-up comment on a Linear issue the goblin is already working
  • A mention on a Jira issue comment
  • Replying @taskgoblin fix to one of its own review comments

If a person asked directly, a goblin answers. Loops govern the unprompted work, and only that.

When several loops match

Nothing stops you running more than one loop on the same event — a general review loop plus a stricter one for security, say. When an event matches several, the goblin is shown all of the candidate instructions and judges which applies, recording the choice on the run so the history stays honest. The work still happens as a single run: loops do not multiply into duplicate reviews on one merge request.

Where to go next