The Requirements to UAT Pipeline: One Repository From Workshop to Sign-Off
Written by Ahmed at Analyst Engineering, a Senior Technical Business Analyst with 10+ years in banking and payments delivery.
Key takeaways
- Requirements work fails at the handoffs, not inside the documents. Every time a requirement is retyped into a new tool it loses an identifier, and coverage becomes an opinion instead of a query.
- A requirements pipeline is defined by one rule: every stage reads a machine-readable artifact produced by the previous stage, and never a human retelling of it.
- Three formats carry the whole chain. Requirements as YAML with stable identifiers, scenarios as Gherkin tagged with those identifiers, and results as JUnit XML tagged the same way. Everything else is rendering.
- The coverage gate is the piece that changes behaviour. When a build fails because REQ-014 has no scenario, nobody has to chase coverage in a meeting again.
- AI is the labour in this pipeline, not the authority. It drafts every artifact and reviews every artifact, and a named human approves each one before it moves to the next stage.
A requirements pipeline is a chain in which every stage reads the machine-readable output of the previous stage rather than a human retelling of it. A workshop transcript becomes requirement candidates, candidates become identified requirements in YAML, requirements become use cases, use cases become UAT scenarios in Gherkin, and scenarios become test results tagged with the original requirement id. Traceability stops being a spreadsheet and becomes a query.
Requirements work almost never fails inside a document. It fails at the handoffs. The workshop produced a good decision that nobody wrote down in the same words. The business requirement was accurate and the functional requirement that refined it quietly changed a threshold. The test analyst read the functional spec, built a suite, and covered eleven of the fourteen rules because three of them were in a paragraph rather than a table. Then UAT found the gap in week nine, which is the most expensive week to find anything.
Every one of those failures has the same shape. A requirement was retyped into a new tool and lost its identifier on the way. This article is the system that removes the retyping. The rest of the series builds each stage properly: elicitation with an AI note taker, requirements as code, connecting Jira, Confluence, Xray, and Datadog over MCP, analyzing the diagrams you were handed, the blind spot review, use cases and UAT scenarios, and test strategy through to execution. If you want the document templates that sit at each stage, they are in The BA Deliverables Template Pack.
What are the eight stages, and what is the artifact at each one?
The pipeline is only a pipeline because each row’s output is the next row’s input, in a format a script can read.
| Stage | Input | Artifact | Format | Gate before it moves on |
|---|---|---|---|---|
| 1. Elicitation | Meeting, transcript, existing system | Decisions, actions, requirement candidates | Markdown | Every candidate has a named source |
| 2. Business requirements | Candidates plus strategy | BRD, each requirement identified | YAML plus rendered Markdown | Schema valid, every REQ has an owner |
| 3. Functional requirements | BRD plus system artifacts | FRD, each rule testable | YAML | Every FR refines a REQ that exists |
| 4. Use cases | FRD plus actors | Main, alternate, exception flows | YAML | Every FR appears in at least one flow |
| 5. Blind spot review | Everything above | Gap register, new requirements | YAML | Nine lenses run, each gap closed or accepted |
| 6. Test conditions | FRD plus gap register | Conditions with risk rating | YAML | Every FR has at least one condition |
| 7. UAT scenarios | Use cases plus conditions | Gherkin feature files | feature files | Every scenario tagged with a REQ id |
| 8. Execution | Feature files plus environments | Run results, evidence, sign-off pack | JUnit XML plus Markdown | Coverage gate green, results signed |
Read the last column as the real content of the pipeline. Anyone can produce eight documents. The value is that stage five cannot start until stage four passed its gate, and that the gate is a script rather than a review meeting where three people say “looks fine to me”.
What does the repository look like?
One folder per project, in git, next to nothing else. This is the entire structure:
payments-iso-migration/
context/
system.md # the context pack: actors, systems, vocabulary
house-style.md # how we write requirements here
glossary.yaml # terms with one agreed definition each
elicitation/
2026-09-08-kickoff.md
2026-09-15-pacs008-workshop.md
requirements/
business.yaml # REQ-001 ..
functional.yaml # FR-001 .. each refines a REQ
use-cases.yaml # UC-001 .. each realises FRs
gaps.yaml # GAP-001 .. from the blind spot review
tests/
conditions.yaml # TC-001 .. each covers FRs
features/
payment-initiation.feature
rejection-handling.feature
strategy.md
scripts/
validate.py # schema and reference integrity
coverage.py # the traceability matrix and the gate
render.py # YAML to Markdown for humans
publish.py # Confluence pages, Jira issues, Xray tests
.github/workflows/
requirements.yml # runs validate, coverage, render on every push
Two design decisions in there matter more than the rest.
The context/ folder exists so nobody writes a prompt from memory. Every AI step in this pipeline starts by loading system.md, house-style.md, and glossary.yaml. That is what stops a model from inventing an actor called “Payment Service” when your architecture calls it the Processor, and what stops the same field being called debtorAccount in one requirement and payer account in the next. The general technique is context engineering, and it is the single highest leverage file in the repository.
Everything downstream of business.yaml is derived. If you find yourself editing a rendered Markdown document, the pipeline has broken. Fix the YAML and regenerate.
The three formats that carry everything
You do not need a requirements management tool. You need three formats and one shared identifier.
Requirements as YAML. A requirement is a record with an id, a statement, a rationale, an owner, a priority, and acceptance criteria. Structured, so a script can count them, diff them, and check that every functional requirement points at a business requirement that exists. This is the subject of requirements as code.
- id: REQ-014
title: Reject payments above the customer daily limit
statement: >
The platform must reject a payment instruction when it would take the
originating customer above their agreed daily limit for that currency.
rationale: Regulatory exposure and credit risk control.
owner: Head of Payments Operations
priority: must
source: 2026-09-15-pacs008-workshop.md#decision-4
acceptance:
- A payment that would breach the limit is rejected with reason code AM04.
- The customer receives the rejection within 5 seconds of submission.
- The attempt is recorded in the limit breach audit log.
Scenarios as Gherkin, tagged with the requirement id. Gherkin is readable by business users and parseable by machines at the same time, which is the only reason it survived. The tag is what makes the whole pipeline work.
@REQ-014 @FR-031 @uat @priority-high
Scenario: Payment rejected when it breaches the daily limit
Given customer NP-4471 has a daily EUR limit of 50,000
And they have already sent 48,000 EUR today
When they submit a payment of 5,000 EUR
Then the payment is rejected with reason code AM04
And the rejection is returned within 5 seconds
And a limit breach entry appears in the audit log
Results as JUnit XML, carrying the tags through. Every runner worth using emits JUnit XML, and every CI system reads it. Because the scenario name and tags survive into the result file, the execution report can be joined back to business.yaml by requirement id. That join is the traceability matrix, and it is regenerated on every run rather than maintained by hand. The requirements traceability matrix article covers what the matrix is for; this pipeline is how you stop maintaining it manually.
The four gates that make it real
A gate is a script that exits non-zero. That is the whole mechanism, and it is why this works when a checklist does not.
# scripts/coverage.py (the part that matters)
import sys, yaml, glob, re
reqs = {r["id"] for r in yaml.safe_load(open("requirements/business.yaml"))}
frs = yaml.safe_load(open("requirements/functional.yaml"))
# Gate 1: every functional requirement refines a business requirement that exists
dangling = [f["id"] for f in frs if f["refines"] not in reqs]
# Gate 2: every business requirement is refined by at least one functional requirement
refined = {f["refines"] for f in frs}
unrefined = sorted(reqs - refined)
# Gate 3: every requirement is tagged by at least one scenario
tagged = set()
for path in glob.glob("tests/features/**/*.feature", recursive=True):
tagged |= set(re.findall(r"@(REQ-\d+)", open(path, encoding="utf-8").read()))
uncovered = sorted(reqs - tagged)
for label, items in [("dangling FR", dangling), ("unrefined REQ", unrefined),
("uncovered REQ", uncovered)]:
for i in items:
print(f"FAIL {label}: {i}")
sys.exit(1 if dangling or unrefined or uncovered else 0)
Forty lines, and it replaces the recurring meeting where somebody asks whether the test suite covers the new rules. The fourth gate runs after execution: every requirement marked must needs a passing result in the current run before the sign-off pack can be generated. That one belongs to the execution pipeline.
Wire all four into a workflow file and they run on every push:
# .github/workflows/requirements.yml
name: requirements
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install pyyaml jsonschema
- run: python scripts/validate.py
- run: python scripts/coverage.py
- run: python scripts/render.py --out build/
- uses: actions/upload-artifact@v4
with: { name: requirements-pack, path: build/ }
Now a pull request that adds a requirement without a scenario turns red, and the reviewer sees exactly which id is uncovered. Nobody negotiates with a red build the way they negotiate with a checklist.
Where AI sits, stage by stage
The honest division of labour. AI is the typist and the second reader. It is never the approver.
| Stage | What AI drafts | What you decide |
|---|---|---|
| Elicitation | Decisions, actions, candidates, contradictions in the transcript | Which candidates are in scope, who owns each |
| Business requirements | Statement, rationale, acceptance criteria from a candidate | Priority, correctness of the business rule |
| Functional requirements | Refinement into testable rules against the contract | Whether the rule matches the system that exists |
| Use cases | Alternate and exception flows you did not think of | Which exceptions the business accepts |
| Blind spot review | The nine adversarial passes, exhaustively | Which gaps are real and which are noise |
| Test conditions | Conditions from each rule, including boundaries | Risk rating and depth of coverage |
| UAT scenarios | Gherkin from use cases, in business language | Whether a business user would recognise it |
| Execution | Failure triage, defect summaries, the run report | Pass, fail, and the go or no-go call |
The right column is the job. Anyone who thinks AI replaces the analyst has only ever looked at the left column. The reason the pipeline is worth building is that the left column used to consume eighty percent of the week, and it is also the column where machines are genuinely better than tired humans at 17:30 on a Thursday.
The guardrails are not optional. Transcripts contain names, payloads contain customer data, and neither belongs in a prompt without classification. Everything in AI guardrails for analysts applies here, and the pipeline makes compliance easier rather than harder because the redaction step is a script that runs the same way every time.
The build order, four weeks of evenings
Do not build all eight stages before using any of them. Build the spine first and widen it.
- Week one. Create the repo, write
context/system.md, and move your current requirements intobusiness.yamlby hand. This is the boring week and it is the one that pays. - Week two. Write
validate.pyandcoverage.py, and wire the workflow. Accept that the first run fails loudly; that failure list is your actual coverage, probably for the first time. - Week three. Add
render.pyand the publish step so Confluence, Jira, and Xray read the same content without you copying anything. - Week four. Add the Gherkin layer and the execution join, then run the blind spot review on the whole set and watch it find things.
By week four you will have a traceability matrix that regenerates on every push, which is the artifact every audit asks for and almost no team can produce on demand.
What this does not fix
Being clear about the limits keeps the thing credible.
- It does not make stakeholders agree. A pipeline transports decisions; it does not produce them. The workshop still has to happen.
- It does not replace domain knowledge. The pipeline will happily carry a wrong business rule from stage one to stage eight, with perfect traceability.
- It does not work with an unwilling team. If the developers ignore the rendered spec and build from a Slack thread, the traceability is decorative.
- It is not a substitute for testing judgement. Full coverage of the requirements you wrote says nothing about the requirement you never thought of, which is exactly why the blind spot review is a stage rather than a nice idea.
The takeaway
The difference between a folder of documents and a pipeline is that a pipeline has gates. Give every requirement an identifier on the day it is born, keep it in a structured file, carry that identifier into every downstream artifact, and let a script fail the build when the chain breaks. AI then does the drafting at every stage, which is what makes the extra rigour affordable rather than aspirational.
Start with requirements as code, because nothing else in the chain works until the requirement has a stable id. Then read the blind spot review and run it against a spec you have already signed off; it will find something, and that finding is usually what convinces the team. For the templates behind each stage, see The BA Deliverables Template Pack, or browse everything at The Tech BA Toolkit.
Ahmed is a Senior Technical Business Analyst with 10+ years in banking and payments. He builds practical guides and tools for analysts at The Tech BA Toolkit.
Tags: Business Analysis, Requirements Engineering, AI, UAT, Traceability
About the author
Analyst Engineering is written by Ahmed, a Senior Technical Business Analyst with 10+ years of banking and payments delivery experience: ISO 20022 and SWIFT messaging, payments API integration, Kafka event validation, and production support. Every article comes from real delivery work, and each one is reviewed and updated as tools and standards change.
Related articles
- Requirements as Code: BRD and FRD in YAML With a Validator That Fails the Build Write business and functional requirements as structured YAML with stable ids, validate them with a schema, and render the BRD and FRD humans read from the same source.
- Elicitation With an AI Note Taker: The Agenda, the Question Bank, and the Diff How to run a requirements workshop with an AI note taker: generate the agenda from the system, drive a question bank, and diff the transcript against the current spec.
- The Blind Spot Review: Nine Adversarial Passes That Find the Requirements Nobody Wrote A repeatable review that finds the edge cases missing from your specification: nine lenses, one prompt each, run as a script before the requirements are signed off.
- From Use Cases to UAT Scenarios: Main Flow, Alternates, Exceptions, and a Sign-Off Pack Document use cases as structured data, generate UAT scenarios in Gherkin from them, keep the requirement id on every scenario, and produce a sign-off pack automatically.
Free account
Practice on the Labs, keep your progress
A free account, no password: an email link signs you in. It saves your steps and self-assessments on the Labs, shows your missions on a dashboard, unlocks the solutions, and, if you tick the box, sends you new missions and articles when they ship.
Your email is used to sign you in. Nothing else, unless you ask. Privacy.