settle

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Settle

收尾

Settle the current session in four steps. Each step finishes before the next starts.
分四步完成当前会话的收尾。每一步结束后再开始下一步。

1. Read live state

1. 读取实时状态

The session's memory of its repositories and pull requests may be hours old. For every repository the session touched, run
git fetch
, then read
git status
,
git worktree list --porcelain
, and
git branch -vv
. For every pull request the session opened or pushed to, read
gh pr view
with
state
,
headRefOid
,
labels
,
comments
, and
statusCheckRollup
. Base every later check on this output.
会话记录的 repository 和 Pull Request 信息可能已是数小时前的状态。对会话涉及的每个 repository,运行
git fetch
,然后读取
git status
、
git worktree list --porcelain
和
git branch -vv
。对于会话创建或推送过的每个 Pull Request,使用
gh pr view
读取
state
、
headRefOid
、
labels
、
comments
和
statusCheckRollup
。后续所有检查都应以这些输出为依据。

2. Clear the loose ends

2. 清理遗留事项

A loose end is anything that keeps the session from being settled. The session is settled when every check below passes, or the user has chosen to leave what fails.
For each repository the session touched:
  • git status
    is clean and no branch is ahead of its upstream.
  • No stale branch or worktree remains (see below).
  • The primary checkout is on the default branch and up to date. When it sits on a stale branch, switch it to the default branch and pull.
For each pull request the session opened or pushed to:
  • It is merged, or the user chose to leave it open.
  • It has a
    recommend-*
    label and a review comment. When either is missing on a merged pull request, stop any review still running for it and list it as merged without review. Start no new review.
For the session itself:
  • No offer, question, or follow-up the session raised is still unanswered. Search the whole session, not only the last message: "Want me to…", "Should I…", failures found on the default branch, and anything reported as skipped or not verified.
  • No scratch directory, temporary file, or background process it started remains. That includes
    mktemp -d
    directories, local servers, and
    tailscale serve
    entries.
**遗留事项(loose end)**是指任何妨碍会话完成收尾的事项。当下列每项检查都通过,或用户选择保留未通过的内容时,会话即为 settled(已收尾)。
对于会话涉及的每个 repository:
  • git status
    干净,且没有任何 branch 领先于其 upstream。
  • 没有残留 stale(陈旧) branch 或 worktree(见下文)。
  • 主 checkout 位于 default branch 且已是最新。如果它位于 stale branch,则切换到 default branch 并 pull。
对于会话创建或推送过的每个 Pull Request:
  • 它已合并,或用户选择保持打开。
  • 它带有
    recommend-*
    label 和一条 review comment。如果已合并的 Pull Request 缺少其中任意一项,则停止仍在为它运行的任何 review,并将其列为“已合并且未审查”。不要发起新的 review。
对于会话本身:
  • 会话提出的任何提议、问题或后续事项都没有悬而未决。搜索整个会话,而不只是最后一条消息,包括:“要我……吗?”、“我应该……吗?”,在 default branch 上发现的失败项,以及任何被报告为已跳过或未验证的内容。
  • 没有遗留任何由会话启动的 scratch directory、临时文件或后台进程。这包括
    mktemp -d
    创建的目录、本地服务器和
    tailscale serve
    条目。

Stale branches and worktrees

Stale branches 与 worktrees

A branch other than the default branch is stale when its local head, and its fetched remote head if the remote branch still exists, each either is contained in the default branch or equals the
headRefOid
of its merged pull request. Stale status does not depend on which session created the branch. Find a branch's worktree by the
branch
line of
git worktree list --porcelain
, since a worktree's directory name can differ from its branch.
Delete without asking only a stale branch that no linked worktree has checked out and no other local branch tracks as upstream. Its commits exist on the default branch or in its merged pull request, so nothing is lost. Delete stacked branches child first.
Every other branch the session left behind is a loose end, and so is every linked worktree, however clean it looks: Git settings and index flags can hide a worktree's files from
git status
. When asking about one, name what deleting it would lose:
  • its unique commits;
  • every path
    git status --porcelain --ignored --untracked-files=all
    lists in its worktree, ignored files such as
    .env
    included;
  • every path whose
    git ls-files -v
    tag is not
    H
    , such as
    h
    for assume-unchanged or
    S
    for skip-worktree;
  • the herdr pane whose cwd is inside the worktree (
    herdr pane list
    ).
To delete a branch, whether asked or not: if the user chose to delete its worktree, first run
git worktree remove --force <path>
. Then run
git branch -D
, and delete the remote branch when one still exists, leased to the remote head you checked:
git push --force-with-lease=<branch>:<sha> origin :<branch>
. Run
git worktree prune
for worktrees whose directory is gone.
当一个非 default branch 的 local head,以及(若 remote branch 仍存在)获取到的 fetched remote head,各自均满足以下条件之一时,该 branch 就是 stale(陈旧):被包含在 default branch 中,或等于其已合并 Pull Request 的
headRefOid
。是否为 stale 与创建该 branch 的会话无关。
通过
git worktree list --porcelain
输出中的
branch
行查找某个 branch 对应的 worktree,因为 worktree 的目录名可能与 branch 不同。
只有在没有任何 linked worktree 检出该 stale branch、且没有其他 local branch 将其作为 upstream 跟踪时,才可以不经询问直接删除它。它的 commits 已存在于 default branch 或其已合并的 Pull Request 中,因此不会丢失任何内容。删除 stacked branches 时,先删除 child。
会话留下的其他每个 branch 都是遗留事项,每个 linked worktree 也都是遗留事项,无论它看起来多么干净:Git settings 和 index flags 可能使 worktree 的文件不会显示在
git status
中。
就其中任何一个询问用户时,必须明确说明删除它会丢失什么:
  • 它独有的 commits;
  • 其 worktree 中
    git status --porcelain --ignored --untracked-files=all
    列出的所有路径,包括
    .env
    等 ignored 文件;
  • git ls-files -v
    的 tag 不是
    H
    的所有路径,例如表示 assume-unchanged 的
    h
    或表示 skip-worktree 的
    S
    ;
  • cwd 位于该 worktree 内的 herdr pane(
    herdr pane list
    )。
无论是否经过询问,删除 branch 时:如果用户选择删除其 worktree,先运行
git worktree remove --force <path>
。然后运行
git branch -D
;如果 remote branch 仍存在,则将其删除,并以你检查过的 remote head 作为 lease:
git push --force-with-lease=<branch>:<sha> origin :<branch>
。对于目录已不存在的 worktree,运行
git worktree prune
。

Asking

询问用户

Ask about every remaining loose end in one batch through native structured input (
AskUserQuestion
in Claude Code,
request_user_input
in Codex). Offer the choices that fit each one, such as finishing it now, filing an issue, keeping or deleting an artifact, or leaving it. A worktree another pane is in stays until that pane's session settles itself, so offer only waiting or leaving it. Do what the user picks, then run the checks again. This step is done when the session is settled.
通过原生结构化输入,一次性批量询问所有剩余的遗留事项(Claude Code 中使用
AskUserQuestion
,Codex 中使用
request_user_input
)。为每项提供合适的选项,例如立即完成、创建 issue、保留或删除 artifact,或者暂不处理。如果某个 worktree 正被另一个 pane 使用,则应保留到该 pane 的会话自行完成收尾,因此只提供等待或保留选项。按用户的选择执行,然后重新运行检查。本步骤在会话完成收尾时结束。

3. File the lessons

3. 归档经验

A lesson is something from the session that would change what a future session does or knows: a decision and its reason, a gotcha, a working recipe, a fact that took real digging to find. Work that a repository, its history, an issue, or a pull request already records is not a lesson.
When the session has no lesson, write nothing and say so in one line.
Otherwise, read
~/ghq/github.com/wkentaro/secondbrain/AGENTS.md
and search secondbrain for the page each lesson belongs on. Cross-project tool lessons usually belong on a page under
references/tools/
. Propose every lesson with its target page in one multi-select question. For each lesson the user approves, update the existing page in place, or create one per the target domain's
AGENTS.md
. Redact credentials and personal data the lesson does not need. Commit and push to
main
, and confirm the push succeeded.
**经验(lesson)**是指会话中那些会改变未来会话行为或认知的内容:某项决策及其原因、一个容易踩的坑、一套有效做法,或一个需要深入挖掘才能发现的事实。repository、其 history、issue 或 Pull Request 已经记录的工作不属于经验。
如果会话没有经验,则不要写入任何内容,并用一行说明这一点。
否则,读取
~/ghq/github.com/wkentaro/secondbrain/AGENTS.md
,并在 secondbrain 中搜索每条经验所属的页面。跨项目工具类经验通常应归入
references/tools/
下的页面。在一个多选问题中同时提出每条经验及其目标页面。对于用户批准的每条经验,原地更新现有页面,或依照目标领域的
AGENTS.md
新建一页。删去该经验不需要的凭据和个人数据。将变更 commit 并 push 到
main
,然后确认 push 成功。

4. Close the pane

4. 关闭 pane

Do this last, since it ends the session. When
HERDR_PANE_ID
is set, read the pane's current tab from
herdr pane get "$HERDR_PANE_ID"
, since
HERDR_TAB_ID
keeps the tab the pane started in after it moves. Then read
herdr tab get
for that tab. Run
herdr tab close
on it when its
pane_count
is 1, and
herdr pane close "$HERDR_PANE_ID"
otherwise. When
HERDR_PANE_ID
is not set, say that no herdr pane was found and stop.
最后执行此步骤,因为它会结束会话。设置了
HERDR_PANE_ID
时,通过
herdr pane get "$HERDR_PANE_ID"
读取 pane 当前的 tab,因为在 pane 移动后,
HERDR_TAB_ID
仍会保留 pane 启动时所在的 tab。然后对该 tab 执行
herdr tab get
。当其
pane_count
为 1 时,运行
herdr tab close
;否则运行
herdr pane close "$HERDR_PANE_ID"
。未设置
HERDR_PANE_ID
时,说明未找到 herdr pane 并停止。