BlackLine Blog

August 25, 2026

A Tale of 2 Loops: Building a Unified Financial Consolidation Platform

Finance & Accounting Technology
12 Minute Read
KM

Kazim Merchant

Principal Software Engineer

Share Article

Key Takeaways

  • Building a future-ready financial consolidation platform requires deep domain expertise and absolute software precision.

  • A twin-loop development model powered by artificial intelligence automates repetitive coding while keeping human judgment at the center of system design.

  • Pointing AI models at a unified product specification ensures continuous, automated coherence passes that catch logical contradictions before code is written.

  • This highly structured approach mitigates compliance risks, enforces automated testing, and accelerates digital transformation for the Office of the CFO.

Bridging Human Intent & Autonomous Execution in Finance Technology

Two AI-driven loops build a financial consolidation platform from the ground up. We work inside the spec loop, and on the edges of the build loop.

At BlackLine, we're building a new financial consolidation platform — the system large enterprises use to roll hundreds of legal entities, across currencies and charts of accounts, up into a single set of group financials. The domain is deep: multi-currency translation, intercompany eliminations, complex ownership, a calculation engine whose every number has to be explainable. We're building it from the ground up, new engine to new UI, with a small team.

The approach fits in a sentence: two AI-driven loops do the work, and human judgment enters each one at a different depth. The spec loop runs continuously, turning raw inputs into one coherent statement of why, what, and how. We work inside that loop, in working sessions with Claude, because that's where the judgment lives. The build loop turns the spec into merged pull requests, and there we stay on the edges: admitting work, answering when the machine is genuinely stuck, merging. The machine never merges. The two are coupled — the deeper we work in the spec, the further out we can stand on the build.

The rest of this post is how they work, and what it took to make them work.

Two AI-driven loops build a financial consolidation platform from the ground up. We work inside the spec loop, and on the edges of the build loop.

The Spec Loop

It started the way projects do: with a pile of raw inputs, and more always on the way. A product requirement document (PRD), competitor research, notes and transcripts from expert syncs. The material never stops arriving, so we didn't treat design as a phase. It's a loop that's always running.

At the center sits a living wiki in its own repo, inspired by Andrej Karpathy's LLM wiki: a knowledge base built for a machine reader, indexed and lightly duplicated so an agent can reach any fact down a short, cheap path instead of reading everything.

Karpathy's is a personal knowledge base you query. Ours is the thing our agents build from — and maybe because of that, it refused to stay a record of technical design. It quietly became where the product gets pinned down too: not just the data model and the API contracts, but the behavior they're meant to produce and the reasons behind it, drawn from product research and the expert syncs we transcribe. "Design wiki" undersold it. Spec is the truer word — one place for the why, the what, and the how.

For an agent, keeping them together matters. A human engineer holds the intent in their head while reading the mechanics, filling gaps from their own context; an agent has only what it's handed. Put the reasons beside the design and it builds toward what we meant — separate them, and it drifts to the letter of the nearest instruction.

Each new input starts a working session with Claude to trace its consequences. Does the data model change? Which API contracts move? Is there a performance cliff? When two options both look viable, the loop spins off a proof-of-concept and folds the result back in. Every change ships as what we've come to call an English PR — a pull request whose diff is markdown, reviewed like code: 67 merged in the loop's first 14 weeks, carrying 159 line-anchored review threads from six human reviewers. The scrutiny is what we'd give source.

The Coherence Pass

Plenty of review happens as we fold each input in; the collaboration is itself review. But one job is beyond everyone on the team. The spec is 83 pages and roughly 200,000 words, and it keeps growing. Nobody holds all of that in their head, so nobody notices the moment a new page quietly contradicts an old one. A model can hold it — the whole spec fits in context, a vantage point no human reader ever gets. So before a change lands, we point Claude at the entire wiki and have it hunt contradictions. We call it the coherence pass. (Karpathy's wiki sketch includes the same instinct as a "Lint" operation: "periodically health-check the wiki for contradictions, orphans, and gaps.")

Catching contradictions is only half the job. The other half is fixing them well, and that too takes the whole view. See a contradiction locally and the natural fix is a local patch: add a flag, a case, a bridging table. Each patch makes the pages agree and the design bigger. The fix that actually simplifies usually lives somewhere else entirely — one change that makes a whole family of special cases unnecessary — and you can only find it while holding everything at once. So the pass isn't asked to find inconsistencies. It's told to resolve them in whichever direction simplifies the design, and to treat "just add another case" with suspicion.

One contradiction, two fixes. The local patch adds a case and the design grows; the simplifying fix removes the cause, and it shrinks.

The failures this guards against are real. One contradiction slipped past us and made the cost concrete: two pages disagreed on what an account identifier meant, the implementation followed the wrong page, and an entire screen rendered every account as "unmapped" until we traced the discrepancy back to a conflict between the docs. The pass also catches a second, harder kind of drift — possible only because the why and what live next to the how — a design that's internally fine but no longer serves its objective. We specced one of our dashboards behind a mandatory period filter that most of its data didn't have. Consistent on the page, wrong for the purpose. The fix was the deleting kind: the gate went away.

Inconsistency between two parts of a spec is an old, quiet source of waste. Human teams have always burned weeks this way: two people read the same doc two different ways and build to different assumptions. What's new is a loop that surfaces and resolves the contradictions systematically, before they turn into rework. And for an agent building unattended, coherence is the line between building the right thing and confidently building the wrong one.

Tapping the Reservoir

The spec is a reservoir: it accumulates continuously, and every so often we open a tap. The first tap wasn't code — it was a plan. When the spec was coherent enough to commit to a shape, we pulled an execution plan out of it: timeline, milestones, rough scope for each. We did it deliberately early — the plan only needed to be good enough to start executing, not to be right about month six. It lives in the wiki and stays provisional, near-term milestones sharp and later ones rough. That isn't an aspiration; we revised the plan file 44 times in 11 weeks.

At each milestone boundary we tap it again. We refine the slice we're about to build until it's buildable (not perfect), then generate GitHub issues straight from the wiki into the build repo, grouped under a GitHub milestone — each carrying the spec pages it implements and acceptance criteria tight enough for a machine to turn into a test. Those milestones taper exactly the way the reservoir picture predicts: the two we've shipped closed 108 issues between them, the one in flight holds 29, the next holds six, and the last two hold none at all. Sharp where we stand, rough where we haven't looked. Whatever we learn shipping a milestone flows back in as the next round of English PRs.

A reservoir is only worth tapping if the water is clean — which is what the coherence pass buys: not tidiness, but a spec trustworthy enough that anything can draw from it.

The Build Loop

The issues those taps produce flow into the build repo, where a machine picks them up. Today it's one autonomous agent, handling a proven subset: in its first month it merged 21 pull requests — database procedures, ingestion pipelines, read APIs, UI — about a fifth of everything the team shipped in that window. (That fifth shipped unattended — the rest we build with Claude too, just by hand.) A curated fifth, at that: the agent gets the well-specified, low-ambiguity issues. But manufacturing exactly that kind of work is what the spec loop is for. The agent holds no durable state. Everything lives in GitHub, the issue and its labels and the PR, and each issue runs on its own branch; scaling to a fleet is more replicas, not a rewrite.

The agent runs as nested loops. The outer loop is a cron. Every 15 minutes a deterministic triage script (no model) selects one issue in strict priority order — clear a red check or a returned answer before starting anything new — so work converges instead of sprawling. Triage assembles an initial prompt from the issue's recent activity and invokes Claude with a fresh context. From there the worker reads deeper on its own: the full issue and PR history, the relevant spec pages.

The life of an issue: triage moves it through the states, an inner loop drives it to a green test, the review agent signs off — and a human merges. A red check or a new comment sends it back.

Part by part, the whole build is:

  • Runtime. One container image: the Claude Code CLI, gh, warm dependency caches, a headless browser. A cron runner inside fires one iteration per tick; a file lock skips the tick if the previous one is still running.

  • Deployment. One long-lived pod, shipped by the same GitOps pipeline as the services it builds — though nothing about it is Kubernetes-specific. The cron lives in the container, not the platform, so each tick reuses a warm checkout and caches. Any box that can keep a container alive would do.

  • Identity. A GitHub App. Every comment and commit the agent makes is attributable to it, and its tokens expire hourly, so a background loop re-mints them.

  • Triage. One deterministic shell script: bash, jq, and the GitHub API. No model anywhere in the selection path.

  • State. The labels are the state machine — an issue moves through agent-ready, agent:in-progress, agent:in-review, agent:blocked-on-human — and the issue and PR threads are the memory. Every comment the agent writes carries an invisible disposition marker recording what it had already seen when it acted. Triage compares that marker against the newest commit and comment to decide whether anything genuinely new has happened. That same comparison avoids livelock: if nothing has changed since the last marker, there's nothing to react to, so it leaves the issue alone instead of churning on it.

  • Worker. claude -p — the same CLI we use interactively, run headless. Fresh context every tick, an explicit tool allowlist, a hard timeout, the full transcript streamed to disk for debugging.

  • Isolation. Each issue gets its own branch and its own PR, so parallel workers can't collide.

  • Reviewer. A separate GitHub Actions workflow, sharing nothing with the worker but the PR thread. More on it below.

That's it: three shell scripts, a prompt file, a Dockerfile, and a workflow definition. There's no framework, no queue, no database of our own. Everything else is GitHub.

The inner loop begins with the test. The worker writes the end-to-end test first — the executable contract for the feature — confirms it fails for the right reason, then implements until it goes green. The full CI suite on the PR is the real gate. (Anthropic's experiment pointing sixteen parallel Claudes at writing a C compiler landed on the same anchor: very good tests are what keep unattended agents honest.)

By the time a PR reaches us, it's written to be reviewed: what it built, which spec pages it followed, how to run it. Most useful of all is an honest confidence read — what's green, which edge cases it's unsure about, what assumptions it made, and the two or three files most worth a human's eyes. That read is what makes the merge decision fast.

Before a human sees any of it, Claude reviews the PR. A review agent runs on every push in a fresh context that never wrote the code, so it reviews rather than defends. It reads the diff against the spec and posts its critique as PR comments, right where a human reviewer would. (It reviews the humans' PRs too; 9 times out of 10 everything we've merged carries its comments.)

A real exchange from an agent-built PR: the review agent flags an N+1 query pattern; the builder replies with a single set-based rewrite it verified against a live warehouse — two machines, before any human looked.

What follows is a conversation between two machines. The reviewer raises points. Triage reads them as new feedback and brings the builder back. The builder pushes a fix and replies on the thread; the new commit re-triggers the reviewer, which either raises the next thing or falls silent. They go back and forth entirely in PR comments until the reviewer approves. Only then does the PR surface for a human, who reads a change another set of eyes has already signed off on, with the full exchange preserved in the thread.

The builder also knows which calls are its to make. Reversible decisions it takes and notes in the PR: a name, a sensible default the spec didn't pin down. It stops and asks when a wrong call would be expensive to undo — a schema change that needs a real deploy, anything touching auth, an ambiguity that would change the public contract. And when it stops, it asks well: one structured question with options and its own recommendation, and the issue flips to blocked-on-human. We answer with a reply on the thread, like everything else here, and the next tick brings the worker back. If an issue contradicts the spec, it doesn't silently pick a side; it follows the issue and flags the discrepancy for a human to reconcile.

The Edges

So where do the humans actually stand? The answer moves downstream with the work. In the spec loop we're in the room: the sessions are pair work, and the English PRs carry our judgment as much as the machine's. That's deliberate — the spec is where intent gets poured in, early, while it's cheap to change. The build loop is what that buys. By the time an issue reaches it, the judgment is already in the spec, so there we stand fully on the edges: admit work, answer when it's genuinely stuck, merge. In the autonomy world's terms: in the loop for the spec, on the loop for the build. The edge isn't a starting position; it's a direction. Every turn of the spec loop moves more of the build to the far side of it.

None of this is free — the loops burn tokens, and the hours we no longer spend building move upstream, into spec sessions and merge decisions. That's the trade: an hour of judgment poured into the spec compounds in a way an hour of typing doesn't.

One agent today, on a proven subset of issues. "Never merges" has held literally: every one of its PRs was merged by a human hand, most with a human approval on top of the machine's. The architecture says a fleet, and we're aiming to route the majority of build tasks this way — the same two edges, humans standing on them.

Why We Built Our Own

We could have adopted most of this off the shelf — and all of it is open source. For the spec loop, GitHub's Spec Kit and OpenSpec both do spec-driven development — Spec Kit pipeline-driven, per-feature specs feeding an implement step; OpenSpec closer to our shape, a living unified spec that changes fold back into, but only weeks old when we started. For the build loop, self-hosted agents like Hermes already poll an issue tracker, spawn a worker per issue, and open a PR — most of our outer loop, ready-made. We never seriously considered the always-on, broad-access class — Hermes, OpenClaw — the kind our security people instinctively frown on.

So we built our own. It cost little more than adopting someone else's would have — and building means Claude writes the exact loop we want, with no framework's assumptions to bend to and no surface area to inherit. When building gets that cheap, bespoke stops being a luxury and becomes the default.

What's Next

We are currently focusing on five strategic threads, in rough order:

Close the loop on cost

The build loop will record its own token spend per issue, and log the places it churned — retries, re-derivations, wrong paths. Workers vote on previously logged churn when they hit the same wall; enough votes and it becomes a skill candidate: a reusable procedure the agent loads instead of re-deriving, in the spirit of Garry Tan's "thin harness, fat skills". The harness stays thin. The waste becomes the curriculum.

Split the inner loop into phases

Today the test-first discipline is prompt-deep: one invocation is told to write the test, confirm it fails, then build. But an instruction enforced by prompt weakens over a long session — and the context that wrote the test grades itself against it. The fix is structural.

One invocation plans and writes the E2E test. A second, in a fresh context with nothing to defend, reviews that test against the spec and the issue — is this the right contract? — before any implementation exists. A third builds until it passes, mechanically forbidden from touching the test; if it believes the contract is wrong, it proposes a change with evidence, which routes back through the reviewer. The harness enforces the sequence deterministically, and each phase gets a small, focused context. It's the builder/reviewer separation we already trust at PR time, pushed down into the loop — and the shape Anthropic's own guidance recommends: one Claude writes the tests, another writes the code to pass them.

Automate the coherence pass

The sweep can run on a loop the way the build does — read the whole spec, open an English PR for each contradiction it finds. Resolving one is a judgment call, though: usually more than one fix is coherent, and which is simplest isn't always obvious. So the PR would arrive with the agent's chosen fix already applied, and a body that lays out the other options it considered and why it picked this one — enough for a human on the edge to take the default, point to a different option, or ask for more. The mechanical half becomes one more place we merge instead of type; the judgment stays on the edge.

Measure the edges

If the thesis is real, it should show up in three numbers, each with a direction we want. The takeover rate: issues the loop starts but a human has to pull back into an interactive session — falling, and telling us where the agent still needs new skills or better senses. Blocked-on-human escalations: rare, and worth answering when they fire. And bugs traced back to spec gaps, the class a coherent spec should have prevented: trending toward zero. All three fall out of data we already generate — labels, commits, comments, post-mortems.

Widen the intake — and multiply the taps

Inflow: meeting transcripts and chat threads should reach the spec loop without a human ferrying them. Tag a meeting, or seat an agent in the channel, and let it sniff the decisions out of the conversation and open the English PR itself. Outflow: because the two loops touch only at the taps, the reservoir can serve consumers that have nothing to do with building. An agent on a live meeting transcript, checking proposals against the spec as they're spoken and raising its hand in the chat — the coherence pass moved to the point of decision, where a contradiction is cheapest to resolve. Or a spec oracle: a new engineer, a support triager, or an auditor asks "why does it work this way" and gets an answer with the deciding PR attached. Same reservoir, new taps.

Each of these moves one more human task out of the middle and onto an edge.

Where We Are

That's the system: two coupled loops that turn intent into shipped software while we stand at the two edges. It's early — one agent, a spec still growing, plenty that broke along the way. But it already builds a fifth of what we ship, and every part points the same way: more of the middle to the machines, the humans further out, doing the one thing the machines can't — deciding what's worth building.

Scaling your financial operations is more crucial than ever. Read our guide to ensure you're on the right track.

Read the Guide

About the Author

KM

Kazim Merchant

Principal Software Engineer