Journal
5 min read

Two seconds after the merge

I had written that changing tracking tools would no longer cost me a rewrite. I plugged in Linear to check. One ticket closed by itself, seven more written into a read-only archive, and a 5,853-line adapter.

On September 23, at 4:49 and 20 seconds p.m., I merge a PR.

At 4:49 and 22 seconds, another ticket moves to "Done" all by itself. Its own PR is still a draft. Its ten acceptance criteria are all open.

That ticket was the one for the migration to Linear.

Checking my own promise

Less than three weeks ago, I wrote here that my tracking tool was no longer hard-wired, and that the next one wouldn't cost me a rewrite. In Foundry, the tracker is a socket: the pipeline on one side, an adapter on the other.

What I'm after with Foundry is that it depends on nothing. Not on the model, not on the tracking tool. On the model side, that's already true: the same commands run on Claude Code and on Codex. I want to be able to say the same of the tracker: that it's used the same way, whatever sits behind it.

Except a socket with a single device plugged into it proves nothing. YouTrack was the only real adapter. As long as there wasn't a second one, my "whatever" was a promise.

So I plugged in Linear. On one repository only: Foundry's own. Orfeo and Luchamon stay on YouTrack, and that's part of the test too — two tools at once, each in its repository.

The plan

No big move this time. Only the four tickets still open went to Linear. Everything else stayed in YouTrack, declared a read-only archive.

And before touching anything, I wrote down the rollback rule: possible as long as nothing has been written to Linear. After the first write, no going back. We repair forward.

The switch happened on September 22.

Two seconds

So the next day, I merge a small PR that prepared the ground for the migration ticket. And Linear closes the migration ticket.

It wasn't a bug. It was a feature. Linear has a GitHub automation: when a PR is merged, the tickets linked to it move to "Done". Very handy when a human keeps the board. Disastrous when a tool guarantees that a ticket is only done once its criteria are verified.

I had two systems, each believing it was in charge of the ticket's state.

I switched the automation off. And since I don't trust myself never to switch it back on, Foundry now refuses to merge while it exists.

Writing without being able to lock

The real underlying problem is elsewhere. Linear offers no way to say: change this field, but only if nobody has touched it since I read it. If two writes cross, the last one wins, silently.

For a human moving cards around, that doesn't matter at all. For a tool that wants to prove a ticket went to review and then to done, in that order, it's a hole.

So Foundry replaces nothing in Linear. It appends. Each step — in progress, in review, done — is a comment, and a ticket's real state is derived from the sequence of comments.

It works. It comes at a slightly ridiculous price: the Linear board shows the original fields. Most of my delivered tickets appear there as "In Progress". The truth is in the comments.

The blank line

I also keep my architecture decisions in the tracker. Twenty-seven to import. And for a decision, I want one simple guarantee: what I read back is exactly what I wrote.

Linear rewrites Markdown. List dashes become asterisks. Angle brackets get escaped. Blank lines move.

Each rewrite means a text read back that no longer matches the text written, so an alert. I spent several tickets on this. One of them existed because of a single blank line, removed out of two.

Before importing the twenty-seven, I ended up doing what I should have done at the start: send trap texts into a throwaway project, and watch how Linear returned them.

Seven tickets in the archive

On September 26, I run a command from a copy of the repository that didn't yet have the marker saying "this one is on Linear". Without the marker, Foundry fell back to my machine's default tool.

YouTrack. The archive.

Seven tickets created in it before the command failed.

"Read-only" only meant one thing: the up-to-date Foundry refused to write there. The server itself knew nothing about it. All it took was one path the guard didn't cover.

The migration ticket had a criterion: YouTrack strictly read-only during the operation. It is not met, and I didn't tick it. The ticket was merged under a waiver, with the trace. On the dashboard it now reads: done, 0 criteria out of 10.

I'd rather have an honest 0 out of 10 than an arranged 10 out of 10.

So, that promise?

I didn't rewrite the pipeline. The skills still don't know which tool they're talking to. I wrote an adapter, as announced.

The YouTrack adapter is 878 lines.

The Linear adapter is 5,853. It's the biggest file in the project.

So the promise holds, to the letter. Changing tools means writing an adapter. I just hadn't specified the size.

What I learned is more useful than the promise: two tracking tools don't differ by their screens. They differ by what they guarantee when you write to them. And no product page tells you that. You find out two seconds after a merge.

— Pato