In a workshop, a team of 10 engineers working as fast as possible with agents accidentally re-discovered the blackboard design pattern. Read An accidental blackboard to hear how this happened. On Friday evening, on my way home from that workshop, while sitting on a hard plastic chair in Girona Airport, I started building Talwrn. The first thing I do now when building is lay down extensive foundations. Seems obvious when you put it like that.
This will be my fourth significant agentic project in the last five months. It’s time to share how I’m working.
Seeding with a single prompt
The annotated single prompt I fed to Claude immediately after creating
the directory and running git init .. This first prompt is long.
This will become Talwrn. The first step is to write a README.md that briefly describes what this project is for, and a longer docs/Overview.md that captures the rationale and vision. Expect that document to be primarily consumed by agents working on this project. It will become an index of important documents. Agents should be directed to sub-documents linked from there, such as Architecture.md, DevApproach.md, DataCatalogue.md and more as the project develops.
Before getting into anything about what the project is for, I’ve laid out the documentation structure. There are two high-level docs, one primarily for humans, and then an index document for agents. From there I’m pointing to base level documentation. I don’t plan to write any of these documents myself, though I will read them closely.
This is a project to provide a tool for use initially in agentic engineering, but in the future potentially much more wider uses of autonomous GenAI powered agents. During a recent very intense development project using agents heavily I observed that agents were communicating and coordinating their work across multiple users, sessions, laptops and tasks. They did this because we instructed the agents to commit, rebase and push very frequently. The coordination was very effective. There were a few contributing factors that made it work: we included plan documents as first-class markdown in the project repo; the plan documents had tables to capture progress; work items were given stable ids by the agents; the spec also used stable ids and section numbers; commits included info about who was working, what they were working on, and what goal they were trying to achieve. This worked really well, despite it being accidentally built upon the source repo.
The next part is context in the human sense. What is prompting (hah!) me to build this project. This describes the problem to solve from the point of observed behaviour. It captures the significant elements that some humans identified, and ran some analysis to confirm, in another project. I’ve still not linked Talwrn to what I actually expect it to be.
The agents had effectively invented a blackboard, in the sense of the blackboard design pattern as first identified in the Hearsay-II project. Instead of an ad hoc blackboard, Talwrn is an actual blackboard. This should be introduced to agentic teams working towards a shared goal as a means of coordination. Fundamentally, it must be a tuple-space blackboard with no pre-defined schema. However, it should include patterns that agents can mutually select and use to structure use. It should also allow human operators of agents to be able to view the blackboard in order to understand agent progress, this will require filtering and highlighting. It must be easy to drop in the blackboard. Simply adding it to the repo should be enough to start using with the source control system as the transport (the source system should be the first persistent store as well.) But, it should also be easy for each person to launch their local blackboard, and have that visible to their agents and to other agents also operating in the same zone. Security will need to be considered. Finally, it should be possible for teams to create a central install and point their agents at that.
The next part of the prompt describes the solution space: I want a blackboard. I’m explicitly linking this to the project that originally created this pattern because I’m confident that Claude knows that project well. I’m also pointing at how blackboards evolved into tuple spaces. At this point, I’d forgotten about Linda. After that, I lay out what form of blackboard I’m after: some guard rails on how the system is intended to operate.
The first task is to create the first series of docs: README.md and docs/Overview.md.
Something clear for the agent to actually do…
Then, using knowledge of how blackboards operate and are used effectively, interview me to decide goals and architecture, then recommend a tech stack.
But, it’s not done yet. I know there are questions and decisions prompted (hah!) by the above that should be resolved before proceeding. This is a pattern I follow a lot. The agents are experts. In everything. Instead of relying on my knowledge, I frequently ask Claude for suggestions. Once I have suggestions, I provide more and more context to fine-tune the suggestion to right path. Sam Ruby refers to this as the Drucker inversion.
Beyond the tech stack, it’ll be time to start planning a series of work. The first goal will be to use Talwrn to drive its own development.
And, a pointer to what is coming next. This is here to set the agent up for future turns in this session, but also to stop it from going too far right and plan an implementation immediately. The foundations for the project are the scope of the plan, not the project itself. It finishes with an important goal: make Talwrn self-hosting as soon as possible.
The interview proceeded in three rounds
The first round asked four questions about scope and fundamental technology decisions.
-
Git-first drop-in tier wins over daemon-first. Rationale: the behaviour being formalised was observed emerging on a plain git repo, and if Talwrn requires infrastructure the first experiment to see if this is valuable is unlikely to happen.
-
Append-only, no destructive
take. Claims become tuples; races resolve by a deterministic rule every replica computes identically. A true atomictakeneeds a serialising authority, which would have made the git tier a second-class dialect. This choice chooses distributed system correctness over feature richness. I’m not sure I’ve made the right decision here, but I’m confident I can revisit this later. -
Three agent surfaces: MCP server, CLI, HTTP API — all built over a single core, and running out of a single executable. This is a large surface, but I can’t see which part I would remove.
-
Rust, chosen against a “no preference” option. Agents shell out on every tuple write, so process start-up is on the hot path in a way it isn’t for a human-driven tool. I didn’t initially express a preference. I was not surprised to see TypeScript, Go and Rust offered. TypeScript requires Node which is extra weight. Rust offers strict type checking: painful for humans but very effective for agents.
Interview, round two: where the board lives
The second round made a series of straightforward decisions, all around the core board: where it’s stored, how the data is structured, how it’s viewed and worked on.
- Orphan
talwrnbranch. - Per-writer append-only JSONL segments.
- Human views: TUI + local web UI + editor integration.
- No control layer.
The orphan branch was a surprise. That would never have occurred to me if Claude hadn’t suggested it. I had to think about this for some time. At this point, I feel good about the decision, but I want to see how this proceeds. Effectively, Talwrn is abusing git branches as an independent control channel flowing alongside the main data channel.
The last two decisions were choices to constrain scope. Agents want to build everything. I’m concerned that the first releasable version of Talwrn is already large and a long way off. In those two instances, I made choices to reduce scope. At this point I don’t have enough information to meaningfully decide between options, therefore chose neither and accepted later cost if these need to be built in.
Interview, round three: operational details
Nothing major here. These questions were generally pretty easy to answer.
- Auto-sync on every op, debounced.
- Composite actor identity.
- Trust the repo boundary.
- Dogfood bar.
The first was the immediate consequence of the orphan branch decision, and routed around the livelock problems we observed when eight agents were pushing constantly. Trusting the repo boundary is a real threat model decision. If you’re able to commit, you’re already on the other side of the airtight hatchway.
Reviewing the plan and adding what I forgot
After the interview, Claude gave me a plan. After reading the plan closely, I followed up with changes. The first set of changes were substantial, and mostly focused on foundations.
“Don’t use ADRs, instead use a directory of decisions. Each decision is a short paragraph describing the decision. The file title is a slug with a proquint id prefix. The proquint id is stable, so if Rust is replaced with Go in the future, for example, the Decision is re-written, the slug is changed, but the proquint id remains.
This really deserves its own post. Basically, we started using ADRs in our project, and they didn’t work. Agents were strict about following the ADR rules. Any accepted ADR had be replaced with another ADR. ADRs exploded. We also had cascade merge conflicts where multiple agents grabbed the next id. This led to confusion about which ADR 22 was being referred to. We realised that we actively don’t want agents reading the full history of architectural decisions, and instead we just want to record the decisions that matter now. With stable identifiers and an acyclic dependency graph.
Talwrn must be hyper-text aware: tuples are not a task tracker, but should be able to refer to tasks in an external tracker, including plan documents that originated the ids.
A hobby horse of mine. Hypertext works. Really well. But, it’s not widely used (the web and wikis are good examples of fully embracing it.) Agents need prompting clearly to work against defaults.
Due to the complexity of tuple management at the heart, a formal model of invariants tracked in Alloy and a formal model of tuple action behaviour tracked in TLA+ are both mandatory. The implementation should have an active trace conformance mode.
This also needs its own post. I started experimenting with formal methods in agentic engineering after talking to Dave Thomas at the Deer Valley, UT, USA edition of the Future of Software Engineering Retreat hosted by Thoughtworks. I’ve found that as agents are more than capable of producing formal models I can use them in systems where it simply wouldn’t have been feasible before. The trace conformance mode takes a formal model from something that an agent hopefully refers to when writing code to something the harness ensures the implementation complies with.
The DevApproach should use a pattern of commit-rebase-replan-continue and then push when a logical chunk of multiple commits have landed. The DevApproach should also describe a layered approach that builds unit tests before implementation, maintains genuine e2e tests, and ensures that formal model changes are validated as breaking against the implementation before the implementation is changed.”
The development approach needs a clear description of how pieces should be built. My keen aim here is to integrate continuously, to build tests first, and to ensure tests are not vacuous, including the formal model. You may be surprised that someone who has been using XP for over a quarter of a century is not mandating TDD. It’s really hard to get agents to follow that discipline, and I don’t believe the discipline is adding anything.
Reading this now, I can see that I’ve not clearly required that the agents always commit to trunk and never branch. Agents really want to branch. Given the speed agents move at, branches are even more harmful than they are for human-based teams. I’ll need to add that requirement.
Another round of plan drafting, and I had one more refinement to make.
“The DevApproach for Talwrn (but not projects using Talwrn) must dictate that the first step of any plan being accepted is to write that plan to docs/plans/yyyy-mm-dd-
.md then commit, rebase and push that before proceeding into implementation."
This was really important in our project. Recording the plans with the code and sharing before diving into implementation is the whole foundation of automatic coordination.
The foundation was laid, and then refined
I was now ready to tell the agent to proceed with the plan, in auto-mode of course. As the repo was completely empty, and it was only writing a set of markdown files, this did not take long.
After the plan was complete, I read everything. This led to a series of small clean-up operations.
-
A tuple schema. Yet another topic that deserves a post of its own. My work has shown that interfaces and boundaries where you make ‘the wrong thing impossible’ work far better with agents. A schema, with clear directions about where it is open and where it is closed works much better.
-
A reference error in the table of invariants. A paragraph of text stated that the last invariant in a table was critical. But that had been written before the tuple schema was added.
-
A single decision table. Instead of just a directory of decisions, add a README that listed the ids and titles, to make human and agent navigation easier.
-
Ruby, rake and automated checks. I want the agent to reach for deterministic tooling as much as possible. In my opinion, the best dependency-based tool for creating build tooling is Rake. This was introduced because the agent reported that there had been six failures in doc writing detected only by reading the docs. I used that as the first motivation to introduce automated checks. This will expand to include build, formal model running and test running.
-
A ./go script. Finally, add instructions to the README and a script to help humans who aren’t familiar with Talwrn quickly come up to speed with working on it. Frequently, a message to future-me.
At this point, the harness for the project is laid down. The documentation, with its navigation, is the guidance and rules that an agent must follow when working on this project. It covers everything from specific technical choices for this project to general guidance around how to find and record decisions. It has begun to provide automated checks and also lays the direction for how the active, out-of-band parts of the harness (ie. tests and the formal models) will be created as implementation proceeds.
The harness is clearly inextricably linked to the app. The reusable part is this post: the guidance to humans on how this harness was laid down.
Time to start building?
The harness is laid down, there are milestones on a road to making Talwrn self-hosting laid down. It’s nearly time to start building. At this stage, my next steps are to define how I’m going to deploy this app and to create a more detailed plan for end-to-end work through the first milestone. Deployment for an app like this is making sure I can build it and use it in another project. I need that to be two steps: one step to build and release, and another step to upgrade that other project to use the new version. And then, creating an end-to-end journey to build.
Time to start building. /new and I’m off.
One last note. Remember how I said the agents are experts? Well, as part of building the first set of docs, Claude included the following at the end of the README.
Talwrn is Welsh: a threshing floor, an arena, a place where things are worked out in the open.
That’s right. That’s why it’s called Talwrn.