If you scrolled through the landing, you saw a Lab section with a product called Barabara and a first module called Barter. This is the note that explains both. Why the word, and why the build.
The two halves belong together. The word is the reason the product is the way it is. The build is the reason the word ended up on a landing page for an architecture practice.
The word
In 1865, around a hundred and fifty Welsh immigrants boarded the Mimosa, crossed the Atlantic, and landed on the Patagonian coast under an agreement with the Argentine government. They walked inland and settled the Chubut valley. They were not running from famine or war. They were running from the slow disappearance of their language. They needed a place far enough from the British Empire to keep speaking Welsh. They called the colony Y Wladfa.
The valley was not empty. It was home to the Tehuelche, a nomadic people who had lived across Patagonia for thousands of years, tall enough and self-possessed enough that the Spanish had earlier named the region Patagonia after them, and largely left them alone.
The standard colonial contact story of the century is ugly. This one is not. By most accounts, Welsh settlers and Tehuelche families built one of the more genuinely peaceful coexistences documented in the Americas. They learned fragments of each other's languages, traded across the seasons, and helped each other through the winters that would have otherwise killed the settlers outright.
Two items dominated the trade. The Tehuelche offered guanaco hides, which kept the Welsh alive those first brutal winters. The Welsh baked bread, which the Tehuelche came to want. The Welsh word for bread is bara.
Over time, when a Tehuelche rider approached a Welsh settlement ready to trade, the opening call was the word they had learned first. Doubled. Bara bara.
Not a negotiation. Not a price. A declaration that exchange is open, on the strength of having each built something the other wants.
That is the word the company is named after. Barabara is what you say when you are ready to trade without money changing hands, because what you have is worth what they have and both of you know it.
Why I built Barter
I sell Greenfield engagements. Four weeks, fixed fee. A client hands me a product idea and I hand back a production codebase: domain modeling, bounded contexts, hexagonal architecture, a transactional outbox for cross-aggregate flows, Supabase-backed auth, a Claude configuration that keeps their agents inside the guardrails, a deploy pipeline. The pitch is that the first four weeks of a product are the weeks that decide whether the next two years cost you velocity.
That pitch is only credible if I can show what the starter actually behaves like after week four. After one feature, then another, then a refactor, then a new bounded context. That surface is invisible in consulting. Client work sits behind NDAs. What a prospect can see is the pitch and, eventually, the outcome. What lives between those two stays private.
So I built Barter. It is the first Barabara product. A trust-focused marketplace where people list items, discover matches, negotiate, and complete exchanges without money. I built it with the exact starter I sell. Same stack. Same patterns. Same opinions. Tested by the only thing that actually tests an architecture, which is shipping features into it for months.
Naming it after a trade ritual from 1865 was not random. Bara bara is the oldest and purest example of trust-based non-monetary exchange I know of in the history of the land I live on. Barter is the product that tries to bring that idea forward.
The architecture, honestly
This is the part where, in consulting decks, you usually get adjectives. Scalable. Modular. Cloud-native. I will try to be more specific, because the point of running my own product on the starter is to be able to point at the actual shape of the thing.
Python 3.13, FastAPI, DDD with hexagonal boundaries. Bounded contexts are real folders. account owns identity, authentication, and role assignment. core holds the product logic: Profile, Listing, Offer, Trade, each an aggregate with its own domain, application, and infrastructure layers. taxonomy handles the category ontology: concepts, aliases, relations, attribute definitions. shared is the cross-cutting kernel where AggregateRoot, DomainEvent, and the authorization primitives live.
Use case per directory. Every application use case is its own folder with three files: command.py, port.py, handler.py. No service layer with thirty methods. No god object. The Claude config knows this shape, so when an agent generates a new use case it follows the pattern without being told.
Aggregates collect events. Events connect bounded contexts. When an Offer is accepted inside core, it registers an OfferAccepted event. After commit, handlers in other contexts pick that up to create the Trade and lock the corresponding Listing. Cross-aggregate flows do not go through direct calls or synchronous cascades. They go through events.
Transactional outbox with a PostgreSQL trigger. Events are written to an outbox table inside the same transaction that produced them. A trigger on that table calls pg_net.http_post() against a relay endpoint, which processes pending entries synchronously inside the HTTP request. A Cloud Scheduler cron hits the same endpoint every five minutes as a safety net. The relay is protected by an internal API key compared via hmac.compare_digest, sourced from a PostgreSQL GUC. This is the specific shape of "reliable event processing" my Greenfield clients inherit. I did not invent it. I opinionated the details and committed to them.
Protocol-based repositories, SQLAlchemy imperative mapping. The domain defines protocols. Infrastructure implements them with SQLAlchemy, but the domain objects themselves stay ORM-free. Aggregates are dataclasses with behavior. That separation is what makes a swap or a targeted test cheap later. It is also the single thing that disappears fastest when a project "starts lean" and never puts it back.
Dishka DI at Scope.REQUEST. Dependencies resolve per request, which keeps FastAPI handlers and test fixtures clean to wire. Providers live under shared/infrastructure/config/di/.
Per-context Unit of Work. AccountUnitOfWork, CoreUnitOfWork, TaxonomyUnitOfWork. Each owns commit and rollback inside its transactional boundary. Cross-context consistency is eventual, handled by the outbox.
Row Level Security, always. Every migration that creates a table also enables RLS and adds at least one policy, even for tables the backend service role writes exclusively. Supabase gives this for free. It is still amazing how often projects forget to use it.
Explicit state machines. A Listing moves ACTIVE → IN_TRADE → TRADED. An Offer moves PENDING → ACCEPTED | DECLINED | CANCELED. A Trade moves AGREED → COMPLETED | DISPUTED | CANCELED. These transitions are guarded by the aggregates themselves. Invalid ones raise domain errors. The Claude config knows to check the state machine before proposing a change that would cross a boundary.
React 18, TypeScript, Vite on the frontend. Typed API client, bearer token auto-injected, three contexts for auth, theme, and language. English and Spanish from day one, because Barabara is meant for both audiences.
Claude configuration. .claude/ has subagents for running tests, applying migrations, and opening PRs against the convention checklist. .mcp.json wires in Supabase and Linear. When a new use case is written, the conventions fire on their own.
What this proves
Everything in Barter is something I would build for a client paying for Greenfield work. Nothing here is research. Nothing is experimental technology looking for a home. The features themselves are not the point. The point is that by the time a client is five weeks into their own Greenfield engagement, the starter they are extending has already been pressure-tested by me, on my own dime, across months of real feature work.
The word is older than the code. The code is honest because the word demands it.