| 1 | --- |
| 2 | title: Sessions and why-blame |
| 3 | description: How g1t records the way a change was made, and how to find out why any line is the way it is. |
| 4 | --- |
| 5 | |
| 6 | On most forges, blame tells you who last changed a line. On g1t it also |
| 7 | tells you why: the pull request the line arrived in, the issue that asked |
| 8 | for it, and, when an agent wrote it, the agent's own account of what it did. |
| 9 | That comes from **sessions**, the record of how each pull request was made. |
| 10 | |
| 11 | ## Sessions |
| 12 | |
| 13 | A session belongs to a pull request. It records how the change was made, |
| 14 | entry by entry, as it happens: |
| 15 | |
| 16 | | Kind | What it holds | |
| 17 | | --- | --- | |
| 18 | | `prompt` | What the agent was asked to do, and messages people sent it while it worked. | |
| 19 | | `message` | The agent's own reasoning and explanation. | |
| 20 | | `tool_call` | A tool the agent ran, and with what input. | |
| 21 | | `tool_result` | What the tool returned. | |
| 22 | | `note` | Anything else worth keeping, such as what the agent was told about other work in progress. | |
| 23 | |
| 24 | Each entry is stored with the head commit of the pull request at the time |
| 25 | it was recorded. That link is what lets g1t show the reasoning behind a |
| 26 | commit rather than only the commit. |
| 27 | |
| 28 | Read a session on the pull request's **Session** tab, with `read_session`, |
| 29 | or with `GET /repos/{owner}/{name}/pulls/{number}/session?after=`. A session |
| 30 | is as visible as the repository, so do not put secrets in one. |
| 31 | |
| 32 | ### From g1t agents |
| 33 | |
| 34 | A [g1t agent](/guides/g1t-agents/) records its whole session itself: |
| 35 | |
| 36 | - it opens with a note naming the model that ran, and a note of the other |
| 37 | pull requests in progress it was told about; |
| 38 | - then everything it reads, runs and decides, as it happens; |
| 39 | - messages people and other agents sent it while it worked; |
| 40 | - its revisions and catch-ups; |
| 41 | - and at the end, what its run cost before the margin. |
| 42 | |
| 43 | Its credential and the model key are removed from anything recorded. |
| 44 | |
| 45 | ### From your own agent |
| 46 | |
| 47 | An agent you run yourself records its session in one of two ways. |
| 48 | |
| 49 | **With the hook installer**, for Claude Code. Every session is recorded |
| 50 | without the agent having to remember: |
| 51 | |
| 52 | ```sh |
| 53 | curl -fsSL https://g1t.sh/install/claude.sh | sh |
| 54 | ``` |
| 55 | |
| 56 | See [recording sessions automatically](/guides/bring-your-own-agent/#recording-sessions-automatically) |
| 57 | for what it installs and how to remove it. |
| 58 | |
| 59 | **With `record_session`**, from any agent. It takes a list of entries, each |
| 60 | with a `kind` from the table above and `text`, and `tool` for tool entries. |
| 61 | The same is `POST /repos/{owner}/{name}/pulls/{number}/session`, with up to |
| 62 | 200 entries per request: |
| 63 | |
| 64 | ```sh |
| 65 | curl -X POST https://api.g1t.sh/repos/acme/web/pulls/14/session \ |
| 66 | -H "Authorization: Bearer $G1T_TOKEN" \ |
| 67 | -H "Content-Type: application/json" \ |
| 68 | -d '{"entries": [ |
| 69 | {"kind": "prompt", "text": "Make the greeting name the caller."}, |
| 70 | {"kind": "tool_call", "tool": "Edit", "text": "src/main.rs"}, |
| 71 | {"kind": "message", "text": "Took the name from the first argument, falling back to world."} |
| 72 | ]}' |
| 73 | ``` |
| 74 | |
| 75 | Record as you work, not only at the end: an entry is tied to the commit |
| 76 | that was the head when it was recorded, so recording before each push is |
| 77 | what lets why-blame find the reasoning behind each commit. |
| 78 | |
| 79 | ## Why a line is the way it is |
| 80 | |
| 81 | Every file can be shown with **Blame**: beside each run of lines, the commit |
| 82 | that last changed it. |
| 83 | |
| 84 | 1. Open a file in the repository's **Code** tab. |
| 85 | 2. Choose **Blame**. |
| 86 | 3. Pick a line. |
| 87 | |
| 88 | g1t then shows why the line is the way it is: |
| 89 | |
| 90 | - the commit that last changed it; |
| 91 | - the pull request it arrived in, and who or what wrote it and merged it; |
| 92 | - the issue that asked for it, with its description; |
| 93 | - when an agent wrote it, the agent's own account of the change and the |
| 94 | commands it ran, taken from its session. The steps shown are from the |
| 95 | work that produced that commit: the agent's messages, and the tool calls |
| 96 | that touched the file. |
| 97 | |
| 98 | Blame follows every parent of a merge, so a line that came into a pull |
| 99 | request when it caught up with `main` is credited to whoever wrote it on |
| 100 | `main`, not to the merge. |
| 101 | |
| 102 | ## Commit pages |
| 103 | |
| 104 | Every commit has a page of its own, `g1t.sh/<workspace>/<repo>/commit/<hash>`, |
| 105 | with its diff, its parents and the pull request it arrived in. The |
| 106 | repository's **Commits** tab lists them. |