Merged PRs move tickets and post a digest
Every pull request that lands gets matched to its ticket, moved forward on the board, and rolled into one summary for the team.
- TriggerTriggered
Webhook on pull request merged
- Completed
Find what merged
- CompletedClaudeLinear
Match to a ticket
- CompletedLinear
Move the ticket forward
- CompletedSlack
Post the team summary
Keeping a board honest against what actually shipped is a standing chore, not a one-time setup: someone has to remember which PR closed which ticket, click into each one, move it, and then separately tell the team what landed — and on a busy day, the last part is the first one to get skipped.
Both halves already exist as data. A code host already knows exactly what merged and when; an issue tracker already knows every open ticket's status. The work is reading one, matching it to the other, and writing back — the same join, every day, at whatever hour nobody wants to do it by hand.
What you get
Every merged pull request is reflected on the board, the matching ticket moves forward with a comment explaining why, and the team gets one short summary of what shipped.
The part worth getting right
Matching discipline is where this either earns trust or loses it fast: an explicit reference in the PR text is a fast, precise match, but a keyword fallback against open tickets has to be conservative. A wrong match moves the wrong piece of work forward, and the person who notices is rarely the one who ran the automation — better to leave a PR unmatched than guess.
Never moving a ticket backwards matters more than it sounds like it should. A ticket already past "code merged" — in review, waiting on a specific person, already shipped — stays exactly where it is. The job is catching the board up, not overriding a call a human already made more recently than this run.
Merged and shipped aren't the same fact, and conflating them is the fastest way to lose trust in the board. Some repos deploy the instant a pull request lands on the main branch; others need a separate, deliberate step before anything is actually live. Telling the two apart — instead of marking everything "done" the moment it merges — is what keeps "Done" meaning done.
The prompt
The real prompt behind the steps above — detailed enough that an agent with a people-search tool, email/phone enrichment, and CRM access can run it as written.
# Turn merged into Slack notif and ticket update
You have access to issue tracking and team messaging, plus your own read
access to wherever your team's code lives (most coding assistants already
have this — a code host isn't something Tulina connects to). Run this
for **[your repos]**.
## 0. Set up (skip if you're already connected)
If you don't already have live tool access for this, connect it first —
this prompt is only as real as the tools behind it:
1. Create a free account at app.tulina.ai.
2. Add Tulina's MCP server to your assistant: https://mcp.tulina.ai/mcp
3. In Tulina, connect your own API keys for the tools this prompt uses —
issue tracking and team messaging.
4. Separately, confirm your assistant already has read access to your
code host — that part runs outside Tulina, through whatever access
your assistant already has.
Once connected, your assistant has real tool access and the rest of this
prompt runs as written.
## 0b. Already on Tulina? Three things around the run
An account and the MCP server are not the whole setup. Two of these come
before the run below and one after it, and together they turn this from a
one-off answer into a process your workspace keeps:
1. **Activate this process's connectors first.** Call
`oto_connector(op="list")`, match it against the tools named in step 3
above, and `oto_connector(op="select", name="...")` every one that
isn't active yet. Selecting a connector does not mount its tools in the
conversation you're already in — reach them through `oto_call` for this
run, or open a fresh conversation once they're all on.
2. **Attach the work to an existing project.** `oto_project(op="list")`
shows your active org's projects: pick the one this work belongs to
rather than opening another, and keep its id. The project is where this
process, the tables it writes to and the connectors it uses hang
together.
3. **When the run is done, save it as a process — with its graph.** Write
the body with `oto_procedure(op="set", ...)`, then attach it with
`oto_project(op="link", project_id=..., target_type="procedure",
target_ref="<your slug>")`. The body has to carry a drawing: read
`oto_guide(op="read", slug="procedure-flowchart")` and follow it
exactly — ONE untagged fenced block in that grammar, opening with the
trigger and a quoted example of what you'd type to start a run. Tulina
parses that drawing back into the graph it renders as the process's
default view, which is what makes it come out in the same style as
every other process in the app; a drawing the grammar can't read falls
back to raw characters instead. Saving a process needs org-admin
rights — without them, hand the finished body to someone who has them.
## 1. Find what merged
- Pull every pull request merged in the last day, across every repo that
matters — title, description, and merge time.
- Keep the lookback window short (a day, not a week). That's what makes
this idempotent: run it twice by accident and the second pass just
re-confirms what the first already did, instead of re-processing a
growing backlog.
## 2. Match each one to a ticket
- Check the PR title and description first for an explicit ticket
reference — most PRs opened against a real ticket mention it
somewhere, and that match is fast and precise.
- If nothing explicit turns up, compare the PR's title against your
team's open tickets by keyword. Only take this match if you're
genuinely confident — a wrong match is worse than leaving a PR
unmatched, since it moves the wrong piece of work forward.
- A PR with no confident match still counts for the summary in step 4 —
it just doesn't touch the board.
## 3. Move the ticket forward
- Before changing anything, read the ticket's current state. Never move
a ticket backwards, and never touch one that's already further along
than "code merged" would suggest.
- Leave a comment naming the specific PR — title and link — before
changing status. A status that changes with no trace of why is
indistinguishable from a status that's wrong.
- Decide the target state from what you actually know: merged alone is
one signal, confirmed live in your preprod or staging environment is a
stronger one. Don't claim the stronger one without checking — some
repos deploy the moment a PR lands on the main branch, others need a
separate step first, and the two are easy to conflate if you don't
check per repo.
## 4. Post the team summary
- One short message, grouped by repo, skipping repos with nothing
merged.
- For each PR: title, the ticket it maps to if any, and whether it's
just merged or confirmed live.
- If nothing merged anywhere today, say that too — a routine that stays
quiet on a quiet day is indistinguishable from a routine that's
broken.
## Output
Report: how many PRs found, how many matched to a ticket, how many
tickets moved, and anything skipped and why.
Questions about this process
Related processes
- Call feedback becomes tickets and docs
Every call recorded during the day is distilled overnight, with bugs and feature requests routed to the right team as tickets and docs, plus a Friday digest.
- Triage and route bug reports
An incoming report is read, matched against open issues to catch duplicates, and filed to the right team's board with severity attached.
- Prepare for a customer call
Before the call, the last conversations, the account's state, how the product is actually being used, and where their requested features stand, in one brief.