Spec-driven development: an invoice export walkthrough
Finance needs a file for reconciliation. That request sounds concrete until the team asks what the file must mean when an invoice changes during assembly, when access is revoked, or when two invoices look identical in the output. Those answers affect the contract, the design and the evidence needed before a delivery can be accepted.
This article follows a hypothetical investigation of those questions. The clauses and observations are illustrative; they do not describe a completed project or a complete production specification. No development experiment was run for this article, and no production feature acceptance occurred. The point is to show how a bounded investigation can expose a broken mechanism, an unmade decision and a requirement that was wrong before implementation began.
Follow the export through a changed decision
Find the decisions hidden in the request
Before designing an exporter, confirm that a file rather than a report view serves the reconciliation workflow. Even after that choice, “matching the requested filters” leaves a consequential question: should membership and values reflect request time, processing time or download time? An invoice updated halfway through assembly makes the choice visible. So does an administrator losing account access after the file has been prepared.
Discussing those cases also establishes the supported selection size and defers scheduling, notifications and large-export support. One feasibility question remains: can the existing data-access path provide a consistent snapshot at the selected size? Developing examples together to settle the behaviour is BDD discovery. Benchmarking the access path tests whether the mechanism can satisfy the desired rule.
Assume that domain discussion selects these rules for investigation:
- EXP-01: A permitted administrator may request an export for one account and an explicit filter.
- EXP-02: Membership and values reflect one logical snapshot established when the request is accepted.
- EXP-03: Up to 10,000 matching invoices are supported. A larger selection is rejected without making a partial file available.
- EXP-04: Only a complete result becomes downloadable. Exporting does not change invoice state.
- EXP-05: Each new download request requires current authorisation for the account, including requests through direct storage URLs if the design uses them.
These are selected clauses for an investigation, not a declaration that the feature is ready to release. Retry and retention behaviour remain undecided. They are required before exposing a retained-export API, while the snapshot and access boundaries can still be investigated without pretending that the entire capability is ready to build.
The rules support acceptance examples whose expected outcomes can be agreed before anyone writes the checks:
Scroll horizontally to see all columns.
| Example | Agreed expectation | Main rule |
|---|---|---|
| An invoice is updated after request acceptance. | The export retains its snapshot value. | EXP-02 |
| Exactly 10,000 invoices match. | The selection is permitted. | EXP-03 |
| 10,001 invoices match. | The selection is rejected and no file is available. | EXP-03 |
| Assembly fails before completion. | No partial result can be downloaded. | EXP-04 |
| Access is revoked before a new download request. | The request is denied. | EXP-05 |
The last row has a maintained acceptance scenario in Part 3’s BDD and acceptance evidence article. A queue, object store, helper function or database layout remains a design choice.
Assign an investigation the agent can actually perform
Suppose the team assigns a two-hour prototype to investigate snapshot consistency and download authorisation. Its deliverable is a record of observations, blockers and a recommendation. Temporary fixtures and output formats are experimental choices; they create no external API commitment. Delivering a retained-export API remains outside the assignment.
The agent needs the clauses, the existing snapshot access path, the account-authorisation boundary and the available integration checks. In a brief read-back, it identifies EXP-02 and EXP-05 and locates the mechanisms for changing an invoice and revoking access in the test environment. If it cannot reach those mechanisms, the team must provide access or narrow the assignment. A fake that always denies access demonstrates only that the fake denies access.
Build one path from an authorised request to a complete temporary file, including denial and failure behaviour. Where needed, compare synchronous and background processing against the same rules. The investigation must exercise both the snapshot and authorisation boundaries to assess whether their guarantees can be achieved together.
For EXP-05, establish revoked access through the relevant permission mechanism, request the actual download boundary and check that no protected data is returned. Smaller internal behaviour can be developed through TDD inside this acceptance check, but its expected results need an independent basis. Use an agreed export fixture rather than calculating the expected result by calling the production export query again.
Separate a broken mechanism from a missing decision
Suppose the initial design returns a long-lived direct object-store URL. A former administrator can still use it after revocation. Checking access only when creating the link plainly fails EXP-05 for later requests. The mechanism must change unless the commitment is explicitly reconsidered through Part 4’s disagreement and contract-correction process. That process distinguishes a code defect from a deliberate change in the obligation; weakening a check until it passes does not make the original rule wrong.
There is a separate unanswered question: what happens if access changes after an authorised download has started? Correcting the direct-link mechanism does not supply that domain decision. Assume the product decision is authorisation at the start of each download request, so an already authorised transfer may finish. Refine EXP-05 to state that boundary and retain the denied-download scenario. Add a separate scenario for revocation during an active transfer: the transfer may complete or be interrupted, but any new request must be denied.
Requiring immediate interruption would impose a stronger promise and stronger demands on the design and its feasibility evidence. Either choice needs an explicit decision. A mediated download is one possible design, but introducing a proxy does not establish the freshness or failure behaviour of its permission boundary.
Report what the investigation established
The selected record below is also hypothetical. It shows why an investigation can produce useful evidence without producing an accepted feature:
Scroll horizontally to see all columns.
| Obligation | Observation from the hypothetical investigation | Review outcome |
|---|---|---|
| EXP-03, selection limit | Boundary checks accept 10,000 invoices and reject 10,001 without exposing a file. | Supported for those checked boundaries. |
| EXP-05, download authorisation | A revoked administrator can start a new download through the existing direct link. | Violated; the mechanism needs correction. |
| EXP-02, snapshot consistency | The fixture never changes invoice values during assembly. | Unverified for that case; strengthen the evidence. |
Attach each finding to the code state and configuration actually assessed. The responsible person can accept the investigation’s findings while deferring feature acceptance: there is a demonstrated violation and a case the checks never exercised. The next work is to correct the access mechanism, examine the missing snapshot case and resolve the remaining delivery obligations. None of that makes the prototype acceptable for release.
For the snapshot follow-up, coordinate the relevant reads and mutations instead of hoping that their timing overlaps. One possible check pauses assembly after request acceptance and before subsequent reads, commits changes to a selected invoice’s value and to which invoices match, then resumes assembly and compares the result with the agreed pre-change snapshot. Instrumentation must reach the actual data boundary, and the record should include the interleaving exercised. This gives repeatable evidence for that case; it does not establish every concurrent execution.
Examine a spec that was wrong from the outset
The following is a separate hypothetical branch, not the next event in the direct-link investigation. Imagine an initial specification that requires an authorisation check at export creation and says nothing about later downloads. Code and scenarios can satisfy those clauses while allowing a former administrator to start a new download.
Suppose a review uncovers an account-access policy that already applied when the specification was approved: revocation must prevent new downloads. The original specification omitted an existing obligation. Its defect was present before implementation began, even if every scenario derived from it passes.
Preserve the policy evidence, correct the rule, add the revocation example and change any implementation that conflicts with the corrected contract. Code that already performs the stronger check may survive unchanged. If the policy had been newly adopted, the diagnosis would instead be a changed requirement with transition obligations. The record should preserve why the earlier decision was valid in that case.
Check whether the export supports reconciliation
Here is another separate hypothetical branch. It need not conflict with a written policy. The proposed file contains invoice dates and amounts, and finance tries a sample against its existing reconciliation records. Two invoices share those values, so the user cannot tell which record to reconcile because the required reference is absent. The sample satisfies every proposed column rule while failing the task that motivated it.
Keep that observation and revisit the output decision with finance. Assume the domain review establishes which existing reference identifies the record. Add it to the output requirement and retain the ambiguous pair as an acceptance example. Have finance repeat the reconciliation using the revised sample before committing to the representation. This corrects an overlooked need in the existing workflow; it supplies no evidence about production snapshot or access behaviour.
Resolve the remaining questions before release
Keep these three cases as separate records. Do not combine their findings or infer that proposed corrections were verified. An eventual delivery must retain the findings, revised rules, reasons, affected scenarios and actual verification results, and revisit unfinished tasks that depended on the earlier interpretation.
A delivery assignment still needs answers about retry and retention behaviour, file representation and applicable operational bounds. Resolve the questions blocking that work, then review the revised contract and the agent’s assignment. Release requires reviewing the implementation and evidence against those obligations. If a later accepted delivery reaches users, examine whether finance can complete representative reconciliations and whether operational behaviour remains acceptable. The sample exercise informs the output decision; actual use can expose conditions it missed.
Try the approach on one bounded change
The walkthrough shows what the discipline can expose. A local trial asks whether this preparation and review are worth keeping in a particular team’s work while preserving quick feedback. The trial must be measured; it cannot be inferred from the hypothetical investigation above.
Choose a change and record the starting point
Select one maintained capability that repeatedly causes ambiguity. Identify the next useful behaviour and the uncertainty most likely to invalidate it. Before the trial, select a few recent changes and record why they are reasonably comparable by work and constraints, rather than just by ticket label.
Agree observable measures and a rule for retaining, simplifying or dropping the added practices. One possible rule is a reduction in ambiguity-related rework within an agreed limit on delay to useful feedback. Record the human effort spent preparing, implementing, reviewing and correcting the earlier changes, the elapsed time taken to reach useful feedback, and agent and tool expenditure where material. If history is incomplete, record what is missing and which comparisons remain possible.
Specify, implement and review one increment
Agree the observable behaviour, relevant failure cases, promises to preserve and a few decisive acceptance examples. Investigate any unresolved question that blocks the chosen scope. Add Gherkin only if it improves shared understanding; the notation is optional, and the expected outcome still needs a basis independent of the implementation.
Give the agent the current contract, relevant repository context and available checks. Review the result against the agreed obligations, retaining discoveries and correcting decisions when their basis fails. After a later release, examine whether the change serves its intended use and behaves acceptably in operation.
Examine the cost evidence
The recommendations here remain engineering judgements, not a complete method validated by the studies below. The evidence can identify costs that a local trial should measure; it cannot establish that this proposed workflow earns them for a particular team or feature.
Eberhardt’s 2025 Spec Kit experiment reported 3.5 hours of review for a circuit-management increment and about two hours for a GPS addition, with much of that time spent reviewing Markdown. This is one developer’s account of one application with the tools available then. Review time belongs in the local comparison because it is part of the workflow’s cost.
Spec Kit Agents, April 2026 preprint
Spec Kit Agents compared a full agent workflow with a version adding grounding and validation. Across 32 tasks in five repositories, the quality score, weighted by feature count, rose from 3.51 to 3.66 on a 1–5 scale. Another language model judged qualities such as correctness and maintainability. That score is an evaluation proxy, not direct evidence of user value.
Among 16 pairs of completed runs under a 90-minute budget, mean latency rose from 24.0 to 37.2 minutes. The latency analysis excluded incomplete and rate-limited runs. Rate-limited runs could still contribute quality scores when a pull request was available.
Human reviewers subsequently compared pull requests produced with and without the additions. Across six tasks, their 60 judgements included 33 ties, 19 preferences for the workflow without the additions and eight for the augmented workflow.
During agent execution, plan-review checkpoints were automatically approved; the human preference review happened afterwards. The study therefore cannot establish the value of human review during development. The comparison is small and leaves the additions’ value for a particular team unresolved. Measure the trade-off locally, including the time spent on the whole workflow.
Decide which parts earned their cost
Compare the trial with earlier changes and, where practical, across several changes. Did clearer requirements reduce ambiguity-related rework? Did preparation and review delay useful feedback? Which checks found material mistakes? Record differences in difficulty, tools and available evidence. This informs a local decision; it does not establish a general productivity result.
No development experiment was run for this article, so the invoice-export investigation and the external study cannot answer that local question. Retain the preparation and review practices whose reduction in misunderstanding, rework or risk justifies their cost. Simplify or drop additions that do not earn their place.