Teams
The agent change record
When someone asks who changed a piece of code, which agent did it, why, and who approved it, this is the answer for every change Graft made in your organization's forks. Owners and reviewers download it from the Team tab, for any range of dates, as CSV or as a JSON bundle signed by Graft.
Last updated: October 30, 2026
For a security or procurement review (data flow, subprocessors, retention, separation of duties, what Graft doesn't have), see security: for a security review.
The record comes with Team and Enterprise. It is put together from what Graft already keeps for each run: the run's report, the review step, the resolutions handed in, the agent transcripts and the run's signed record. Nothing new is collected to make it.
What each row says
One row for every change Graft carried, rewrote or dropped in a run for one of the organization's copies that finished in the range. A change Graft couldn't carry (stuck) changed nothing, so it has no row. A run can rewrite a change and still not move the copy: the tests failed, a reviewer sent the move back, or it is still waiting for review. Those rows are there too, marked as not landed, so you can see what was tried.
- Where: the repository, branch and copy, the copy's owner, and the release it moved from and onto.
- What: the change as its commit names it, and its outcome: kept as is, rewritten for the new release, or dropped because the release already has it.
- Landed: yes when the run moved the copy onto the release and a reviewer approved the move (or the organization had review off); no when the copy stayed, the move was sent back or still waits for review, or the organization keeps no code (report only).
- Why: the reason recorded with the change (from its commit message), the route Graft gave it, and why the step went the way it did.
- Who decided: Graft by rule, an agent (its name and the models the run used), or a person. Any resolution or answer handed in for that change, with who handed it in and for which account.
- The tests: the verdict (pass, fail, or not run) and each check's result.
- Who approved: the review step's outcome (approved, waiting, or sent back), the reviewer, the time and their note; or "not required" when the organization had review off.
- Evidence: the run's id, its outcome and what was delivered, its signed record (the file, the signing key's id and the file's SHA-256), and the SHA-256 of each agent transcript from the run.
The JSON bundle
The bundle has the same rows, and two more lists:
- Agent actions: every time an agent, using a member's API token, registered one of the organization's copies (the MCP tool
track_changeorPOST /api/v1/copies), handed in a resolution, or answered a question. Each names the account, the token and when. - The organization's audit log for the range: members added and removed, copies moved in and out, moves held, approved, asked about or sent back, and each download of this record.
Each download is itself written to the organization's audit log and to Graft's append-only ledger, with the file's SHA-256.
The API gives the same bundle to a token with the read scope whose owner is an owner or reviewer of the organization: GET /api/v1/orgs/{id}/agent-record?from=&to= (API docs).
How to check it
The bundle is signed with the same Ed25519 key as every run's record. Its payload is the record's exact JSON text and the signature covers its bytes, so any change to it fails the check. Anyone can check it, with no account:
npm install -g graftfork graft verify-record graft-agent-record.json
The agent change record needs graftfork 0.1.1 or later; an older client checks the signature but can't describe the bundle. That fetches Graft's public keys from /.well-known/graft-record-key and says whether the signature holds. To go further, each row names its run's signed record: ask the copy's owner for it (from /app or GET /api/v1/runs/{id}/record), check it the same way, and compare its SHA-256 and the transcripts' SHA-256s with the row. The CSV is for spreadsheets and is not signed; when a file has to stand on its own, keep the JSON bundle.
How long it can go back
The record is made when you download it, from what Graft keeps. These are the periods from the privacy policy:
- Runs' reports and signed records: seven years after the run.
- Agent transcripts: in full for 90 days, then stripped of tool output, file contents, diffs and code (each replaced by its SHA-256) and kept for seven years. The record names both SHA-256s.
- Agent actions through a token: the API log is kept for three years, so older ranges have no agent actions.
- The organization's audit log: seven years, also after the organization is deleted, with each entry's copy in the ledger.
A run belongs to the organization its copy was in when the run started. Disconnecting a copy, or moving it out of the organization, does not take its past changes, signed records or transcripts out of the record. Disconnecting does delete the copy's conflicts, because they hold its code, so those rows no longer list the per-file resolutions, and agent actions on those conflicts drop out. A copy's runs from before it joined the organization are not in it.
A legal hold on an account stops any of its data being deleted until the hold is released.
What it doesn't do
- Runs of a copy that was disconnected, or had left the organization, before Graft started keeping each run's organization can't be matched to the organization and are not in it.
- It covers changes Graft made. Changes your people or agents make outside Graft are not in it.
- One download covers up to 366 days and 2,000 runs; for more, download shorter ranges.
- Graft has no SOC 2 or ISO 27001 report, and this record isn't a certification. It is evidence you can check.
Questions by email to support@graftfork.com.