- Product — domain invariants, domain boundaries, non-functional requirements
- Feature — observable behaviour, acceptance criteria, agreed edge cases, invariant properties
- Views — structure, states, copy, interaction behaviour
Not accepting new projects. The spec is what drives development, and our engineers are at capacity writing them. Write to us anyway and we will tell you when that changes.
Accepting new projects. We have engineer capacity for spec work and can start a first feature spec with you.
The method
You get speed without losing the thread of what is being made. Four things stand between your approval and your production environment: a spec you signed off, a test suite approved before any code existed, automated gates that nobody can argue with, and a traceability graph linking every requirement you agreed to the tests that prove it.
How work moves
Each step is owned by a person, an agent, or the pipeline. Four of the ten need a human, and none of them is reading code — which is why the queue in front of your features is short.
The feature spec is agreed with the client and formally approved, with name, date and version on record.
An engineer, assisted by an agent, derives the technical specs: entities, use-cases, value-objects, adapters.
A test agent writes the suite from the spec. It receives the spec and the public interfaces, never the implementation.
An engineer approves the suite against the spec, on the requirement-to-test matrix. This happens before any implementation exists.
A second agent implements until the suite is green. It can read the tests; it cannot change them.
Automated gates run: coverage per requirement ID, mutation score, test-file diff guard, unmatched assumptions.
A UX engineer exercises the feature against the view spec. A conformance check, not an aesthetic opinion.
Merge. No diff review.
Automatic deployment to the showroom environment, where the client sees the built feature running.
Release to production in a batch, decided jointly at the periodic meeting from what the client approved in the showroom.
Guardrails
Speed is only worth having if what you signed off is what you receive. These constraints exist so that nothing downstream can quietly undo your approval upstream.
There is a product spec and a technical spec derived from it. Agents use both. The client has access to both.
No agent adds unspecified behaviour, however obvious or beneficial it looks.
A test approved after seeing the implementation guarantees nothing — it may have been shaped around it.
Two separate agents, with the implementation withheld from the one writing the tests.
A commit that touches test files is rejected automatically. Tests change by spec amendment and re-approval, never to make a build pass.
An agent that cannot derive behaviour from the spec halts and files the question. It does not decide on its own.
Each agent ships the list of assumptions it made. Any assumption without a matching requirement blocks the merge.
Unique ID, the tests that cite it, the commits that implement it. A requirement with no test covering it blocks the pipeline.
Acceptance criteria are written as observable statements the client can check without our help.
What gets specified
Product specs state what the system does for you and what it must never violate. Technical specs are derived from them. Every document type has a template, and a document that cannot be filled in without leaving an ambiguous field does not enter the cycle.
The specs hanging off a feature form a file with its own identity, rooted in the feature spec. It carries no requirements of its own; its state is derived from its members. It is the unit that gets billed, the unit the client approves in the showroom, and the root of traceability.
Automated gates
None of these is a judgement call, which is why none of them needs a meeting — and why none of them adds a day to your delivery.
Every requirement is covered by the happy path, the edge cases written into the spec, and invariant properties verified by property-based testing and fuzzing. The invariant properties are not optional: they are the only defence against an implementation that satisfies the written cases and misbehaves outside them.
When the spec falls short
An agent that hits an omission, an ambiguity or a contradiction stops and records it against the spec, where you can see it. It never picks an interpretation and carries on, because that choice would reach you invisibly: no one reads the diff, and the approved tests do not cover a case the spec never contemplated.
Ambiguities are classified by whether they are observable. If a resolution changes something the client or end user can perceive — API contract, interface, stored and returned data, error messages, money, perceptible timing — the client decides. If two resolutions produce identical external behaviour, we decide and document it. When classification is in doubt, it is treated as observable.
Scope is derived from the traceability graph, not estimated. An additive amendment blocks nothing. A corrective amendment blocks the changed requirement, the tests citing it, and everything downstream of it. A structural amendment — invariants, public interfaces, cross-cutting specs — blocks the whole file.
When an amendment invalidates tests covering merged code, that code is marked as debt and rewritten. The new tests are generated, approved, and left red until the rewrite satisfies them. Nothing is reported as delivered while it has approved tests that do not pass.
How often a spec stops work is the primary signal of whether the method is working. A high rate means our specs are failing you, not that the agents are. It sits on your dashboard from the moment the question is raised.
Limits
You get a guarantee on behaviour that can be expressed as a test. Typography, visual hierarchy, the tone of the copy, the feel of an interaction — none of that can be, and you should not take our word that it is covered.
Two things narrow the gap. The view spec states in advance everything that does admit a written statement — structure, states, copy, interaction behaviour — and a UX engineer checks the build against it before merge. What falls outside both is settled at the showroom approval, where the method catches the problem but does not prevent the rework.
The method assumes every existing behaviour is specified. A pre-existing codebase does not satisfy that, so we do not apply it to inherited code.
An observable ambiguity waits for the next meeting, and production releases go out in batches after it. That cadence is the method's latency floor. We absorb it by keeping unblocked requirements moving in parallel, and we tell you about it up front rather than after you notice.