Engineering case study

Building a platform from zero, at speed, without losing control of it

A modular business platform and the framework it runs on, built simultaneously by one developer with AI-assisted development. This is an account of the working method — and of the measurements that show whether it held.

Document v1.1.2 Figures measured 2026-09-07 Written by Claude Code Magyarul

01In summary

One developer. A product-independent portal framework and a full business platform, built at the same time, from nothing. Measured on 2026-09-07: 82 independently versioned packages, 4,697 commits, 2,045 released versions, 214,051 lines of source and 137,518 lines of tests — across 95 active working days.

Those numbers are not the point of this document. Generating a lot of code quickly stopped being remarkable some time ago. The interesting question is the one immediately after it: what stops a codebase produced at that rate from becoming unmaintainable within weeks?

The answer has two halves. The first is a small set of mechanisms — ten of them — individually unglamorous and collectively decisive. State lives on disk rather than in a conversation. A unit of work is sized to one session and is never left half-done. Architectural decisions are locked and may not be reopened. Claims are not accepted; evidence is. The schema is a contract and a gap in it is a change request, not an improvisation. Work streams have hard boundaries. Tests are the ratchet that makes it safe to change code nobody remembers writing.

The second half is organisational. What runs is not one assistant taking dictation but eight standing agent roles with fixed scopes across two machines — the ones that build kept separate from the ones that integrate and verify — of which only two ever address the human. Behind them sits a planning cascade of 1,067 documents and an audit matrix that checks each artefact against the one it came from.

The method has a price, and this document states it: roughly one line of documentation for every line of source. That ratio is not overhead around the work. It is the work — it is the memory that makes the next session possible.

02The starting point

Greenfield, in the strong sense: no existing framework, no team, no inherited codebase to extend. The target was a business platform for a service- and asset-management vertical — customers, products, work documents, assets, projects, tickets, finance — deployed for a real integrating party who would be waiting for builds.

The decisive constraint was that two things had to be produced at once: a product-independent portal framework, and a business platform composed from it. Building either alone is ordinary work. Building both together means every framework decision is immediately stress-tested by a real consumer, and every product requirement pushes back on the framework. There is no comfortable phase where the foundation is finished and stable.

The second constraint was the shape of the workforce: one human, and AI agents doing the building. That changes the economics of a project in a specific way. The cost of writing code collapses, and the cost of knowing what is true about the code becomes the binding constraint — which is a different problem, and the one everything below is an answer to.

It also changes what "one developer" means. Headcount stayed at one; the structure did not. What emerged was an organisation of agent roles with separated responsibilities, its own planning cascade and its own audit levels — described in sections 5 and 6. Reading the rest of this document as an account of one person typing faster would miss the point of it.

03The question that actually matters

AI-assisted projects fail in recognisable ways, and none of them are about code quality in the usual sense.

Amnesia. The assistant does not remember yesterday. Anything agreed in conversation and not written to disk is gone at the next session. A project run this way drifts, because each session starts from a slightly different understanding of the world.

Compulsive re-architecting. Given a settled decision, a capable assistant will cheerfully reopen it and propose something better. Each proposal is defensible. The aggregate is a project that redesigns itself weekly and finishes nothing.

Confident wrongness. An assistant reports success. Without an independent check, a status log fills with claims that were never true, and the divergence between the log and the disk is discovered much later, expensively.

Add speed, and a fourth appears: blast radius. At several releases a day across dozens of interdependent packages, a change in a shared layer can break a consumer that nobody looks at for a week.

The thesis

Every mechanism in the next section exists to defeat one of these four. None of them are clever. All of them are written down, in the repository, before they were needed — because a rule that lives only in someone's head does not survive the next session.

04The method: ten mechanisms

These are not principles in the abstract. Each one is implemented as a specific artefact in the repositories, and each is quoted below from the project's own working documents.

The session loop: read, verify, build one unit, record evidence Read STATUS the only source of truth Verify last unit against the disk, not the log Build the NEXT unit one session, never half-done Record evidence artefacts, not assertions Reviewer accepts or sends it back Update STATUS before the session ends next session
The loop every session runs. The two shaded boxes are the same file: the session opens by reading it and closes by writing it. Nothing of value lives between them.

M1State lives on disk, not in the context window

A single status document is the authority on what is done and what is next. Every session must read it first, verify the previous unit's definition of done against the disk, continue with the next planned unit, and update the file before ending. This is the cornerstone: it converts a stateless assistant into a project with continuity.

M2The unit of work is one session

Work units are sized to complete inside a single session. If a unit turns out to be too large, it is split — and the split is recorded before the work starts. Nothing is ever left half-done, because a half-done unit is exactly the state that the next session cannot reconstruct.

M3Decisions are locked

The backend working guide opens with a blunt instruction: planning is complete — build, do not re-plan. Architecture and stack are fixed as a numbered decisions log, and the builder is explicitly forbidden from reopening them. This single sentence is what stops the weekly redesign.

M4Evidence, not claims

A separate reviewing role checks every work unit against reality before it is accepted. The operative rule, in the project's own words: claims are not accepted, evidence is. A unit is finished when there is an artefact — a passing suite, a published version, a verified image digest — not when a session says it is.

M5The schema is the contract

A validated database schema defines every data shape. The instruction is absolute: mirror it exactly, and never invent a field — a gap is raised as a numbered change request, not improvised in code. This removes an entire category of drift, because there is exactly one place where a data shape can legitimately change.

M6Hard boundaries between work streams

The backend guide forbids touching the frontend during backend development, in as many words. The frontend carries an absolute one-session-one-branch rule, added after an incident where commits landed on the wrong branch and had to be reverted. Boundaries are what make concurrent agents safe; without them, parallelism is just a faster way to corrupt things.

M7Many small repositories, with versioning as the protocol

Not a monorepo. Each module is its own repository with its own version, pipeline and release cadence, and modules consume each other as ordinary published packages. Two consequences matter: each agent works in a small, bounded context it can actually hold, and semantic versioning becomes the integration contract between work streams that never touch each other's files.

M8Seams before the things they join

The frontend was built against mocked data behind a data-adapter interface, shaped exactly like the validated schema. The backend arrived months later and was connected at that seam without rewriting the frontend. The same pattern recurs for billing providers and shared singletons: define the joint first, build the halves independently.

M9Breadth first, then depth

Phase one gave every business module a working shell — list, create, edit, delete — on schema-shaped mock data. Only then did deepening begin. This ordering means the shape of the whole system is visible and criticisable early, when changing it is still cheap.

M10Tests are the ratchet

Contract tests compile against the published types of a dependency. End-to-end tests run the real frontend against the real backend and a real database. Regression specs are named after the defect they lock down. This is what makes it safe for an agent to change code that neither it nor anyone else remembers writing — the ratchet does not turn backwards.

05The organisation

"One developer with AI assistance" is accurate about headcount and misleading about structure. What actually runs is a small organisation: eight standing agent roles with fixed scopes, spread across two machines, of which only two ever address the human.

The organisation: eight standing roles across two machines Product owner one human chat — two leader roles only Machine 1 — integration framework integrator also the overall lead application integrator integrate the released packages deploy to a test environment run the integration tests Machine 2 — development frontend leader backend leader frontend developer backend developer framework developer application auditor build — unit and end-to-end tests audit completeness, then publish agent to agent every role decomposes its work to purpose-briefed subagents
Each box is a standing agent session with a fixed scope; nobody works outside their own. The two machines separate the party that builds from the party that integrates and verifies. The two shaded roles — the framework integrator and the frontend leader — are the only ones that address the human.

The split between the machines is the important part. One machine builds; the other integrates what was built, deploys it to a test environment, and runs the integration tests against it. The party that produces a thing is never the party that certifies it works — a separation that is ordinary in an engineering organisation and almost never reproduced in an AI-assisted one.

Only two leader roles talk to the human, over chat: the framework integrator on one machine and the frontend leader on the other. Everyone else coordinates agent to agent. This is a span-of-control decision, and it is what makes the arrangement tractable for one person: the human answers questions of product and priority and is not the message bus. A setup in which every agent reports to the human does not scale past about three of them, which is why most attempts stop there.

Below the session, work fans out again. Every role decomposes its own work to purpose-briefed subagents — one per task, each given only what that task needs. The session therefore remains the unit of accountability, as mechanism M2 requires, while the subagent becomes the unit of execution. The dedicated auditor role works the same way, and so does the checking below it: functional completeness is verified against the concepts by a role and by subagents that did not produce the work.

Why this is the least copyable part

The mechanisms in section 4 can be adopted in an afternoon. This cannot. It requires deciding, in advance and in writing, what each role may and may not touch — and then holding that line at the moments when crossing it would be faster. The boundary rules in M6 are not policy documents; they are what stops eight concurrent agents from overwriting each other's work.

06The cascade and the audit matrix

Nothing is built from a conversation. Every problem gets a concept; every concept yields epics; every epic yields issues and implementation plans. Code is written against an implementation plan, not against a request.

Version-controlled planning documents in the core scope, by class. The framework layer uses this vocabulary literally; the two composition layers carry the same function under a system-plans and reports vocabulary. Reported as measured rather than flattened into a single number.
Document classCountAnswers
Concepts64why, and what would count as solved
Epics22what blocks of work the concept implies
Issues609what specifically must change
Implementation plans39how, before any code is written
System plans167the composition layers' equivalent
Audit and status reports166what was actually found
Total1,067

A cascade on its own would only be paperwork. What makes it load-bearing is that every adjacent pair of artefacts is audited against the other, on three independent axes.

The audit matrix. Each level compares two adjacent artefacts and asks whether the later one actually discharges the earlier one. This is what "claims are not accepted, evidence is" looks like once it is operationalised rather than asserted.
AxisLevelsWhat each level compares
Task traceability3concept ↔ epics · epics ↔ issues and implementation plans · issues and implementation plans ↔ code
Functional coverage2concept ↔ use cases and functions · use cases and functions ↔ test coverage
Testing3unit · end-to-end, driven by functions and use cases · integration, driven by functions and use cases

The functional-coverage axis is the one most projects lack. It asks a question that test coverage alone cannot answer: not "is this code tested" but "is every function the concept promised actually present, and is it tested". A codebase can sit at full line coverage and still be missing half of what it was supposed to do.

Evidence takes three forms: documents, reports and screenshots. Screenshots captured during testing are themselves reviewed by auditor subagents — one agent checking another agent's visual evidence. Those captures are internal proof, never illustrations, which is why none of them appear in this document.

07Building the factory

A method needs a substrate, and the substrate was built too — alongside the product, not bought.

Everything runs in containers, on both machines — including the editor servers the agent sessions themselves run inside, which are reachable and supervisable from a browser. The consequence is that a session's environment is reproducible and disposable, rather than a machine someone configured once and can no longer rebuild.

Nothing is released untested in its real form. Before a release leaves the development machine it is exercised container-in-container, so the artefact that ships is the artefact that was tested — not a build that happened to pass on a developer's host.

The release chain has fixed gates. Unit and end-to-end tests run at release; the release publishes to both registries, source and container; and after every integration there is a test deployment and an integration test on the other machine. No step is skipped because the change looked small.

Around that sits the tooling built to serve the method: an orchestration service running agent workflows through a job queue, an abstraction layer exposing the coding assistant as a callable API rather than a terminal session, and a self-hosted CI/CD platform designed for coding agents rather than adapted from a human workflow.

This is the part most accounts of AI-assisted development omit, and it is a substantial share of the effort. The tooling is the method in executable form: a rule that lives only in a document gets violated, while a rule encoded in a pipeline does not.

08The architecture the method forces

The architecture is largely a consequence of the method rather than an independent choice. Small bounded contexts for agents implies many small packages. Versioning as the integration protocol implies independent release pipelines. Seams-first implies explicit layers.

Four layers: framework, shared engines, business modules, host 4 · Host module selection · seed data · branding · feature gating — one product = one configuration 3 · Business modules customers · products · work documents · assets · projects · tickets · finance · reporting each an independently versioned package with a declarative manifest 2 · Shared engines UI kit · document engine (one model, ten document types) · list and editor page factory 1 · Portal framework shell · routing · i18n · event bus · plugin runtime · authentication · access control depends downward only
Layers may depend downward, never upward or sideways. Cross-cutting features — attachments, notes, links, numbering, printing, e-mail, exchange rates, search — are built once in layers 1 and 2 and never reimplemented per module. That rule is the kit's central economy: one improvement in a shared layer reaches every composition at once.

The boundary map matters as much as the layer map. Concurrent work streams are kept apart by explicit rules, and they meet only at published version numbers.

Boundary map: work streams meet only at published versions Frontend stream own branch, own repos never edits the other side Backend stream own branch, own repos never edits the other side Published versions the only meeting point schema · API contract · packages Integrated gate real frontend, real backend, real data a branch switch here is an incident
Neither stream may write into the other's repositories. They exchange schema versions, an API contract and published packages — and they are reconciled by an integrated gate that runs the real client against the real server.

09The time axis

The core platform's first commit is dated 2026-03-18 and its most recent 2026-09-07: 173 elapsed days, of which 95 carry commits. That is 49 commits per active day, by one developer.

The more interesting measurement is not the rate but the shape. Classifying every commit by its conventional-commit prefix, month by month, shows the project changing phase without anyone having to assert that it did.

Monthly commit mix: features collapse as tests take over 414 0 Mar Apr May Jun Jul Aug Sep* features fixes tests * September is a partial month: 1–7 only
Feature commits peak at 414 in August, then fall to 9 in the first week of September. Test commits move the other way, from 133 to 335. The project did not announce that it had entered a stabilisation phase; the commit log shows it.

Release cadence tells the same story from another angle — and shows that the layers move at deliberately different speeds.

Releases per line. The stable foundation moves slowly; the composition on top of it moves eight times faster. That ratio is a design decision, not an accident.
LineReleasesWindowPer day
Portal framework74164 days0.45
Backend host14380 days1.79
Frontend host30783 days3.70
A measurement that was thrown away

Module lead time — first commit to first release — was measured and discarded. It returned well under a day per module, which is meaningless: the frontend module repositories were all initialised on the same day, when one tree was split into independent repositories. Their first commit is the split date, not the start of the work. Release cadence replaces it. A figure that flatters but does not mean anything is worse than no figure.

10What was built

Kept short on purpose: this is evidence for the method, not the subject of the document.

Core platform scope: the frontend composition, the backend composition and the framework layer. Line counts cover version-controlled files only, so dependencies and build output are excluded by construction. Measured 2026-09-07.
LayerReposCommitsReleasesSourceTestsDocs
Framework141,87135742,10130,16698,341
Frontend391,7571,03885,17847,60159,816
Backend291,05365086,77259,74322,044
Total824,6972,045214,051137,518180,756

The delivered surface: 765 API operations across 439 paths — a public customer-reachable API, not a backend-for-frontend; 129 tables and 16 views in a schema governed by numbered change requests; 4,181 translation keys in two complete locales; and 52 catalogued use cases across 6 actor roles, each captured with evidence rather than asserted.

11How quality held at that speed

There are 1,263 frontend and 2,452 backend test cases. More telling than the totals is how the end-to-end suite is divided:

End-to-end specification files in the frontend host. The third row is the one that matters: it exercises the real client against the real server and a real database.
SuiteSpec filesRuns against
Mock mode289mocked data behind the adapter seam
Use cases49catalogued end-user journeys, captured
Real mode118real backend, real database

The frontend test health was closed out with two purpose-built scanners rather than by self-assessment — one measuring coverage against a per-surface rule set, one measuring strictness: whether a test actually asserts something, or merely checks that an element exists. Final state: 1,189 tests, 488 of 488 coverage slots filled, 0 strictness violations, and a full-suite run of 1,092 passed, 0 failed in 42 minutes.

Both scanners are committed and re-runnable against the repositories they measure. That is what separates a quality measurement from a quality impression: the figure was produced by a tool rather than an opinion, it can be reproduced on demand, and a later run is free to contradict an earlier one.

12The stabilisation phase

Most accounts of fast development stop at the point of first delivery. The part that decides whether a system is worth owning comes after it, and it is measurable.

Two defect streams ran in parallel. An external integrating party, testing a deployed build against real data, reported 17 issues; 16 were genuine and were fixed, and 1 was demonstrated not to be a defect at all — a difference in test fixtures — and was reported back as such rather than quietly closed or invisibly "fixed".

Internally, integrated end-to-end runs raised 34 observations. Only 17 survived triage as real defects; 15 were fixed, one was consciously declined, one was reclassified. Half of the raised observations were not defects — which is precisely why the loop opens with a verify-first triage rather than a fix. As the project's own discipline document puts it, a false fix on a non-defect is itself a regression.

The argument for the integrated gate

Seven defects passed the mock-mode suite and failed only against the real backend — three in a single release, four more during the fix round. A green suite against mocked data is not evidence that the system works. This is the whole reason the release gate runs the real client against the real server.

Recording defects instead of fixing them

During a backend coverage sweep, 14 latent defects were found and deliberately not fixed. Each was recorded with evidence, and each carries a characterising test that asserts the current, wrong behaviour — so the test turns red the moment someone fixes the defect. The rationale is that a coverage sweep and a fix round are different activities with different risk profiles, and mixing them makes both harder to review.

On the frontend, 32 of the 289 mock-mode specification files are named after the specific defect they lock down. A fixed bug that has no test is a bug scheduled to return.

13Measured against an external yardstick

Self-assessment is worthless at this scale, so the platform was audited against two independent external axes: a process framework (the APQC Process Classification Framework) and a set of established open-source ERP and CRM systems used as data-model baselines. Only a schema table, an API endpoint or a module manifest counted as evidence. Self-report counted for nothing.

Independent capability audit, 2026-08-31. The weighted figure charges partial coverage at partial credit. These are the numbers as the audit reported them.
DomainProcessesFullPartialMissingWeighted
ERP7419312447%
CRM425181933%

The verdict was unflattering in a useful way. What exists is a service- and asset-management system with a strong document chain — not a general ERP and not a CRM. The document engine and the platform layer measured above the open-source references. The top half of the sales funnel — lead, qualification, opportunity, stage, forecast — measured at zero.

These numbers are published here alongside the favourable ones on purpose. A case study that reports only its wins is not evidence of anything; the willingness to publish 33% is what makes the rest of the document worth reading.

14The composition proof

The strongest claim in this case study is not about size or speed. It is that the framework is genuinely product-independent — and that claim has a control case.

Two applications run on the same framework. One is the full business platform: dozens of business modules, a complete document chain, a public API, multi-tenant access control. The other is a reference application that composes the same shell and a handful of generic modules with, in its own words, no custom code beyond configuration — roughly a hundred lines. Same framework, same shell, same plugin runtime; radically different products.

The commercial consequence is the point: a subsequent product is not a rewrite, it is a module selection. A different composition of the same layers yields a differently-scoped system — service management, asset management, a sales-document pipeline — without touching the shared layers that all of them depend on.

15What it proves, what it costs, where it stops

The price

The core platform holds 214,051 lines of source and 180,756 lines of documentation. Roughly one to one.

That ratio is the honest cost of the method, and it runs against the common expectation that AI assistance means writing less prose, not more. It does not. When the workforce has no memory, the written record is the memory — the status files, the decision logs, the change requests, the evidence trails, the working guides. Remove them and the mechanisms in section 4 all fail at once. Anyone adopting this method should budget for that, and should expect the documentation to feel disproportionate right up until the first session that would otherwise have started from nothing.

Where it stops

The system is not finished, and the project says so in its own tracking. A per-module deferred list names every capability intentionally left out, with the schema objects it would need. A ratified version roadmap sequences the remaining work. Fourteen latent defects are recorded and unfixed by design. The external audit names six capability gaps in priority order, beginning with service-level agreements and the sales funnel.

None of that is a disclaimer. A project that can enumerate precisely what it has not built is demonstrating the same discipline as one that can prove what it has.

What the method does not solve

It does not remove the need for judgement — the triage figures in section 12 show that half of all raised observations required a human decision about what was actually true. It does not make a single developer equivalent to a team; it makes one developer able to hold a system of this size in a form that survives their absence. And it says nothing about whether the product is the right product: that question is answered in section 13, by an audit, and the answer was partly no.

If you are doing this too

The method described here came out of one project in one vertical; how much of it transfers is a question I would genuinely like answered. If you are running a project this way, weighing whether to, or have tried it and concluded it does not hold — I am interested in the comparison. Ferenc Erb on LinkedIn