One line from the requirement to a signed record.
Nine links. A product requirement becomes a ticket. The ticket becomes an agent run. The run becomes code. The code becomes a merge. The merge becomes a checked, truthful ticket state. All of it becomes a record nobody can quietly edit afterwards.
Fastpace holds the agent and code half. GroundTruth holds the record half. Below, one real-shaped ticket travels all nine links so you can see the same thing move.
ENG-318 is an illustration, not a customer. Everything described around it is how the product works.
Each one hands something to the next.
If any link is missing, the ones after it are guesswork. That is the whole reason to care about the chain rather than the parts.
The product requirement
A product requirements document is prose. Prose on its own delivers nothing, and nobody can check it off. So the first job is to turn it into work.
GroundTruth reads the requirements document, derives the technical design from it, turns that design into a sequenced plan, and writes the resulting initiatives, epics and tickets into your tracker.
One sentence in the requirements document, "a customer must not be able to place an order with an empty basket", becomes one ticket: ENG-318, "Reject checkout when the basket is empty".
Hands off to the next linkA ticket on its own still does not say what finished looks like. That is the next link.
Intent, written so it can be checked
Intent is what you actually asked for, put in words a machine can test. That is all acceptance criteria are.
GroundTruth scores the criteria on a ticket, calls out the phrases nobody can verify ("works correctly", "user friendly"), and drafts a testable checklist in their place. You edit it and accept it. Nothing downstream can be verified without this step, which is why it comes second and not last.
ENG-318 ends up with three criteria: an empty basket returns a 400 error and the message "Your basket is empty"; a basket with one or more items still returns a 200 and an order id; an automated test covers both cases and passes in continuous integration.
Hands off to the next linkAn agent is about to be pointed at this ticket. The next three links record what that agent did.
Which agent acted
Most teams now run more than one coding agent, and the mix changes every few months. Fastpace does not try to be your agent. It records the runs, which is why it survives a change of vendor.
Every agent call writes a receipt: which agent, which model, which endpoint, a hash of the prompt and a hash of the reply, and a receipt id unique to the repository. Hashes, not the text. No prompt or reply is written to disk in plain form.
The receipt also names the ticket the run was for, and records how it knows: the agent declared it, the commit message said it, the environment set it, or the branch name carried it. That one field is what turns the step from the ticket to the run behind it into a stated fact rather than a guess. When nobody said, the receipt says nobody said.
The run that changed the checkout service carries the agent name, the model behind it, the ticket ENG-318, and a receipt id of the form 2026-10-14T09-22-05-118Z-2c8a4f.
Hands off to the next linkKnowing who acted is only half of it. The other half is what they were allowed to do.
Under what policy
A policy is the plain list of what an agent may do: which commands it may run, which files it may touch, which models it may call, which network destinations it may reach, which external tools it may load.
You write that policy once in Fastpace. A compiler then emits it in each agent tool’s own enforcement format, so one rule set covers a mixed fleet. Every decision the policy makes, allowed and blocked alike, lands in the audit chain.
An honest caveat: those tools do not all enforce equally hard. Some settings are protected by the operating system and some a determined developer can route around. The compiler reports what each target can and cannot enforce rather than claiming they are the same.
On ENG-318 the run was allowed into the checkout service and its tests, and blocked from the directory holding payment credentials. Both facts are recorded, including the block that never became code.
Hands off to the next linkNow the run produces changes. Those changes need to stay attached to the run.
What it wrote
A diff on its own is anonymous. Fastpace stamps the commit with trailer lines at the bottom of the commit message, pointing back at the run receipt.
From a commit hash you can walk the other way: read the trailers, load the receipt, check its signature, and see the agent, the model and the prompt hash behind that change. That is the join between the code and everything recorded about how it came to exist.
AI-Agent: write AI-Model: <the model the run used> AI-Manifest-Id: 2026-10-14T09-22-05-118Z-2c8a4f AI-Prompt-Hash: sha256:9f2c... AI-Ticket: ENG-318 AI-Audit-Seq: 412
The commits on branch feature/ENG-318-empty-basket each carry that block. The ticket key is in the trailer and in the receipt it points at. If those two ever disagree, the check fails and says so, because a wrong join is worse than no join.
Hands off to the next linkEverything so far happened inside the repository. The record side starts here.
Merged
A pull request is not a delivery. A merge is. GroundTruth reads source control directly: branches, pull requests, reviews, checks and merges.
This is the part people mean by ground truth. It is what happened, not what somebody remembered to type into a tracker afterwards.
The pull request for ENG-318 merges into the main branch with its checks green. GroundTruth sees the merge within minutes, and ties it to ENG-318 by the key in the branch and the commit messages.
GroundTruth reads GitHub, GitLab and Bitbucket this way. Where a platform exposes less through its API, we record less, and the chain shows which link is thin rather than filling the gap with an assumption.
Hands off to the next linkMerged still does not mean done. The criteria from link two have to be met.
Criteria verified
Two different checks happen here, and it matters that they are different.
The first is mechanical. Are there criteria at all? Are the boxes ticked? Did the checks pass? Has the review stalled? Those are decided by rules, with no model involved, and they are the same answer every time.
The second is a judgment: does this merged diff actually satisfy this sentence? That one is read criterion by criterion against the diff by a language model, and it reports a confidence. Above the threshold it counts as met. Below it, nothing is applied, and the finding goes to a person with the criterion and the diff side by side.
On ENG-318 the first two criteria are matched to the new error branch and the untouched success path. The third is matched to the new test file and a passing test run. Three for three, so the ticket is genuinely done rather than merely merged.
If a criterion was never written, there is nothing to check. GroundTruth raises that as a finding instead of quietly treating silence as a pass.
Hands off to the next linkOnly now is it safe to change what the ticket says.
What the ticket should therefore say
With the merge seen and the criteria checked, the tracker can be told the truth. GroundTruth moves the ticket to the state the code proves.
It runs the other way too. A ticket sitting in Done with nothing merged behind it is also a finding, and so is a ticket nobody has moved in two weeks while its pull request waits for review.
It starts in shadow mode. For as long as you like, it shows you every change it would make and writes nothing. You turn writing on when the suggestions stop surprising you.
ENG-318 moves from In Review to Done, with the merge and the three verified criteria recorded as the reason it moved.
Full sync on Jira, Linear and Azure DevOps: GroundTruth reads the work and writes real transitions. Asana is read plus coarse write, so GroundTruth can read the work and make simple updates there, and cannot drive a full workflow.
Hands off to the next linkOne thing is left: making all of it hard to rewrite later.
Signed
Both halves append to the same log. Each entry carries a hash of the entry before it, so changing an old line breaks every line after it. Entries are signed with a key held by your install.
One command walks the chain and reports any break. Every automated tracker change records the finding behind it, the confidence, and whether it ran in shadow or live mode, so it can be explained later and reversed.
For ENG-318 the chain holds the run receipt, the policy decisions including the block, the commit provenance, the merge, each criterion verdict, and the status change, in order, with the ticket key on every one. That is the single line from the requirement to the signed record.
Separately, each half proves a fragment.
Both halves are useful alone. Neither alone answers the question an auditor, a director or a worried customer actually asks, which is: show me this specific requirement, and show me it got built the way it was asked for.
A perfect record of agent work, floating free.
You know which agent ran, on which model, under which policy, and exactly which commits it produced. What you cannot show is whether the thing the business asked for was delivered. The chain stops at the repository boundary.
A truthful tracker with an anonymous author.
You know what merged, whether the acceptance criteria were really met, and what each ticket should therefore say. What you cannot show is who or what wrote the code, or what it was permitted to do while writing it.
One line, across any agent vendor.
Pick any merged change and read backwards: the status it set, the criteria that justified it, the merge, the commits, the policy in force, the agent and model behind it, the intent it was meant to serve, and the requirement that intent came from. Pick a requirement and read forwards to the same place. The direction does not matter, because it is one chain, and it does not care which agent tool your team happens to be using this quarter.
Two good categories of tool, each stopping early.
Coding agents stop at the repository.
They are excellent at links three to five, and getting better fast. Their records are their own: tied to their own model, their own console, their own log format. Governance bound to one vendor stops being governance the day you add a second vendor. And none of them follows a change out to the ticket or the requirement, because that is not their job.
Reporting tools describe the record without writing back.
Dashboards read your tracker and chart it beautifully. If the tracker is wrong, the chart is a confident picture of something untrue. They describe the record rather than correcting it, and they do not verify a single acceptance criterion against the code that is supposed to satisfy it.
We can hand you the record. We cannot hand you compliance.
Article 12 of the EU AI Act asks for automatic logging of events relevant to traceability, tamper-evident, and retained for at least six months. We can tell you what the article asks for, and we can produce a tamper-evident, signed record of these nine links.
What we will not tell you is that any tool, ours included, makes your organisation compliant with that regulation or any other. Compliance is a judgment made about your organisation by people who are not us. Fastpace holds no certification, and claims none. What we offer is evidence that stands up when someone reads it closely.
What the chain does not do.
It records and it verifies. Those are narrower jobs than they sound, and the gap between them and what people hope for is worth stating plainly.
It does not say the thing was worth building.
Nine green links prove the work matches the requirement. They say nothing about whether the requirement was a good idea. A fully proven chain around a bad bet is still a bad bet, documented.
It cannot prove a criterion nobody wrote.
If a ticket says “works correctly”, there is no sentence to check the diff against. GroundTruth will tell you the criterion is unverifiable and help you rewrite it. It will not invent a standard and then declare the code met it.
It does not replace review.
Where the judgment is genuinely hard, the chain routes it to a person rather than guessing. Human decisions stay human. We record them, attach the evidence, and stay out of the way.
It is only as complete as the signals a tool exposes.
Where an agent tool or a tracker exposes little, we record little, and we tell you which link is thin rather than filling the gap with an assumption. Thin links are visible in the chain, not hidden in it.
A ticket link is either stated or inferred, and we label which.
The run receipt and the commit both carry the ticket key, and each one records where that key came from: declared by the agent, read from the commit message, set in the environment, or taken from the branch. When nobody wrote it anywhere, GroundTruth infers the link from other signals, scores its confidence, and marks it inferred. A weak join goes to a person instead of moving a ticket.
Running it inside your own walls is a conversation.
Self-hosted and air-gapped deployment is an Enterprise capability, arranged with our team. It is not something you can switch on yourself from a pricing page, and we would rather say so here than let you find out later.
Follow your own ticket through all nine.
Start in shadow mode on one repository and one project. Nothing is written until you say so.
Start free trial See the integrations