163 lines
8.5 KiB
Markdown
163 lines
8.5 KiB
Markdown
# PR#74: "Du bist dran" Shows the Author Session of a Stuck Agent Pull Request
|
|
|
|
> **WARNING:** This document describes only the change applied in this PR.
|
|
> It may already be outdated once the next PR is merged.
|
|
> Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
|
|
|
|
## Related Links
|
|
|
|
- [werkregie PR#48](https://git.javagil.de/mi/werkregie/pulls/48), `watch-pr`: the watch of a coding agent ends with its session.
|
|
- [werkcrappit PR#68](https://git.javagil.de/mi/werkcrappit/pulls/68) and [werkator PR#161](https://git.javagil.de/mi/werkator/pulls/161),
|
|
stuck in a conflict with `main` on 2026-10-14.
|
|
|
|
## Problem
|
|
|
|
On 2026-10-14, werkcrappit PR#68 had a conflict with `main` after werkcrappit PR#69 merged.
|
|
werkrevisor wrote that the author rebases; its session had ended on 2026-10-12, so its watch had ended too.
|
|
"Du bist dran" showed the human the stuck pull request, but not which session wrote it.
|
|
The human had a coding agent search the transcripts for the branch and send the session the task;
|
|
the session then rebased.
|
|
|
|
The data to find the session exists on the machine of the session:
|
|
each line of a Claude Code transcript carries the `gitBranch` of the session,
|
|
and the session file of Claude Desktop names the `cliSessionId` of its transcript.
|
|
The relay reads both already, but reports only the sessions of the last 24 hours.
|
|
|
|
## Non-Goals
|
|
|
|
- No automatic resume of the session; the human sends the message.
|
|
A probe showed that Claude Desktop ignores a turn that `claude --resume <id> -p` adds from outside (see Solution).
|
|
- No new agent for the fix; the author session has the context of the pull request.
|
|
- No Codex threads; Claude Code only.
|
|
|
|
## Specification
|
|
|
|
### Feature: "Du bist dran" shows the author session of a stuck agent pull request
|
|
|
|
#### Scenario#74.01: a stuck pull request shows its author session
|
|
|
|
… so that the human finds the session that can fix the pull request.
|
|
|
|
- **Given** a pull request of an agent, stuck in a conflict with `main`,
|
|
and a session that last worked on its branch in a checkout of its repository, 3 days ago
|
|
- **When** the human opens "Du bist dran"
|
|
- **Then** the pull request shows the title of the session with a link that opens it in Claude Desktop
|
|
|
|
##### Verified by
|
|
|
|
- [AuthorsTest "a stuck pull request shows the session that worked on its branch, days ago"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/AuthorsTest.kt)
|
|
- [ClaudeCodeSourceTest "a session reports the branch it last worked on, older than the window too, unless it is archived"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/ClaudeCodeSourceTest.kt)
|
|
- [RelayClientTest "reports the sessions by their branch along"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/relay/RelayClientTest.kt)
|
|
- [AuthorsTest "the snapshot attaches the authors of all sources"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/AuthorsTest.kt)
|
|
|
|
#### Scenario#74.02: the message for a conflict asks for a rebase
|
|
|
|
… so that the human sends the task with one copy and one paste.
|
|
|
|
- **Given** a pull request of an agent, stuck in a conflict with `main`, with its author session
|
|
- **When** the human copies the message of the pull request
|
|
- **Then** the message names the repository, the pull request and its address,
|
|
and asks to rebase onto `main`, take the next free version and push
|
|
|
|
##### Verified by
|
|
|
|
- [AuthorsTest "the message for a conflict asks for a rebase onto main, the next free version and a push"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/AuthorsTest.kt)
|
|
|
|
#### Scenario#74.03: the message for RED asks for the review round
|
|
|
|
… so that the agent answers werkrevisor's findings.
|
|
|
|
- **Given** a pull request of an agent, stuck with RED, with its author session
|
|
- **When** the human copies the message of the pull request
|
|
- **Then** the message asks to fix the findings or answer them with evidence, and push
|
|
|
|
##### Verified by
|
|
|
|
- [AuthorsTest "the message for RED asks to fix the findings or answer them with evidence"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/AuthorsTest.kt)
|
|
|
|
#### Scenario#74.04: the last session on the branch is the author
|
|
|
|
… so that a session that left the branch long ago is not shown.
|
|
|
|
- **Given** two sessions that worked on the branch of a stuck pull request
|
|
- **When** the human opens "Du bist dran"
|
|
- **Then** the pull request shows the session with the later line on the branch
|
|
|
|
##### Verified by
|
|
|
|
- [AuthorsTest "the session with the later line on the branch is the author"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/AuthorsTest.kt)
|
|
- [TranscriptBranchTest "the branch of a session is the last one other than a detached HEAD, with the time of its last line"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/TranscriptBranchTest.kt)
|
|
|
|
#### Scenario#74.05: the same branch in another repository is no match
|
|
|
|
… so that a branch name that many repositories share, e.g. `claude-code/sync-agentic-workflow`, finds the right session.
|
|
|
|
- **Given** a stuck pull request of werkator and a session on a branch of the same name in werkcrappit
|
|
- **When** the human opens "Du bist dran"
|
|
- **Then** the pull request shows no session
|
|
|
|
##### Verified by
|
|
|
|
- [AuthorsTest "the same branch in another repository is no match"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/AuthorsTest.kt)
|
|
|
|
#### Scenario#74.06: an archived session is no author
|
|
|
|
… so that a closed piece of work is not woken.
|
|
|
|
- **Given** a stuck pull request whose only session on its branch is archived
|
|
- **When** the human opens "Du bist dran"
|
|
- **Then** the pull request shows no session
|
|
|
|
##### Verified by
|
|
|
|
- [ClaudeCodeSourceTest "a session reports the branch it last worked on, older than the window too, unless it is archived"](../../dashboard/src/test/kotlin/de/hoennig/werkregie/dashboard/sources/ClaudeCodeSourceTest.kt)
|
|
|
|
## Solution
|
|
|
|
- The relay reports each Claude Code session with the branch it last worked on, as `authors` of its report:
|
|
each non-archived session of Claude Desktop and each running one in a terminal, older than the window too.
|
|
The branch is the `gitBranch` of the last line of the transcript that names one other than `HEAD`,
|
|
read from the end in parts of 64 KiB, at most 8 MiB, and cached until the transcript changes.
|
|
- The server attaches to each pull request with a `stuck` flag the author with the latest such line
|
|
on its head branch, in a checkout of a repository of the same name; the flags of a pull request stay as they were.
|
|
- The message names the repository, the pull request, the reasons and the address, and asks for the work:
|
|
after a conflict a rebase onto `main` with the next free version, after RED the findings,
|
|
else to check where it hangs and report.
|
|
It is German, as the human writes to the sessions.
|
|
- "Du bist dran" shows the author below the reason: a button that opens the session, on a phone its Remote Control,
|
|
and a copy symbol for the message.
|
|
- A server older than 0.47.0 ignores `authors` in a report, and a relay older than 0.47.0 sends none;
|
|
both stay compatible.
|
|
- Version 0.47.0.
|
|
|
|
### The Probe of an Automatic Resume
|
|
|
|
The first plan was that the relay resumes the author session itself with `claude --resume <id> -p "…"`.
|
|
A probe on a throwaway session of Claude Desktop on 2026-10-14 showed:
|
|
|
|
- The resumed run worked in permission mode `auto` and wrote its turn into the same transcript.
|
|
- Claude Desktop did not show the turn, and its next turn did not know it:
|
|
it attached to the line before the resumed run, so the transcript forked.
|
|
A rebase by the resumed run would be real in Git and Gitea, but unknown to the session.
|
|
- The CLI has a login of its own; it had expired, while Claude Desktop worked.
|
|
- The auto mode of a coding agent refuses to start another agent in auto mode.
|
|
|
|
The human chose to send the message by hand; `#orch.resume` is dropped in the plan.
|
|
|
|
## Open Questions
|
|
|
|
None.
|
|
|
|
## Prerequisite PRs
|
|
|
|
- [werkregie PR#75](https://git.javagil.de/mi/werkregie/pulls/75) brought `Dashboard`, `RelayClient`, `ClaudeCodeSource`
|
|
and `GiteaSource` to a Mutation-CRAP of at most 15.
|
|
Since werkregie PR#64, a branch fails on each method above 15 in a class it changes.
|
|
|
|
## Follow-up PRs
|
|
|
|
- The demo data get an author session for their pull request in conflict, so that the public demo shows the button.
|
|
This PR leaves `Demo.kt` unchanged: its method `snapshot` is above a Mutation-CRAP of 15
|
|
and would first need tests or a split, see the prerequisite PR above.
|
|
- A Codex thread counts as author of a branch, as a Claude Code session does.
|