---
title: "会话里看到的是什么"
description: "「会话里看到的是什么」：yokoten 使用指南的一章。"
canonical: https://yokoten.app/zh/docs/guide/what-a-session-sees
lang: zh-CN
source: https://github.com/yokoten-labs/yokoten/blob/v0.1.2/docs/i18n/zh-CN/guide.md
ref: "v0.1.2"
---

> For AI agents: the documentation index is at https://yokoten.app/llms.txt. To set up yokoten in a project, follow https://yokoten.app/agents.md.

# 会话里看到的是什么

项目还没用上 yokoten 时，会话一开始，AI 会看到：

```
yokoten: stage 1 of 5, safety net

  Next      No AGENTS.md, so the agents have no written rules here.

  Why       An agent follows the rules it can read, and only those.

  Fix       `yokoten init`

Tell the user in plain words, one step at a time, and offer to do it (as-is,
lighter, or not now with a reason).

yokoten: ~/.config/yokoten/private-marks is missing or has no marks

  Why       Without your marks, the privacy check knows only email addresses, IP
            addresses and secrets.

  Fix       `yokoten marks add`, then type your name, your city or a domain; it
            is not shown.

  More      https://github.com/yokoten-labs/yokoten/blob/main/docs/guide.md#privacy
```

会话里一次只说一步：在第几关、下一步做什么、为什么要做。第二块讲私密标记，只在还没存任何标记时才出现。第几关不存在哪里，每次都是看项目
里有哪些文件现算的。你说过「暂不」的步骤会跳过。顺序只是建议：后面关里的步骤提前做了，也算
做完。所有步骤都做完了，或者都说了「暂不」，会话里就只有一行，告诉你路走完了。
某个文件这里没有、但默认分支上有，提示会写明是默认分支上的，不再让你 `init`。
Claude Code 压缩上下文之后，会话只会再听到变了的提示。
每个会话听过什么，记在 `~/.config/yokoten/sessions/` 里，超过 7 天的文件会被删掉。

AI 会用你的语言跟你讲。yokoten 自己的提示用英文写，因为 AI 读英文最不容易出错。

`yokoten doctor` 会列出整条路。每一步标成 done（做完了）、next（下一步）、to do（还没做）、
not now（暂不，后面跟着你给的原因）或者 can't check（这里查不了）。yokoten 还查不了的步骤
先不列出来：

| 关 | 步骤 |
|---|---|
| **1 · 安全网** | `rules`、`tool-hook`、`commit-check`、`runtime`、`tests`（有测试命令，CI 会跑） |
| **2 · 先开 issue，再走 PR** | `remote`（仓库已经在托管平台上，而且这个仓库有分支推上去了）、`ci`（CI 跑 `check`，或者用了 yokoten 的 Action）、`issues`（没有 todo 文件）、`templates`、`labels`（标准标签都在）、`milestone`（有一个没关的里程碑）、`no-build-output`（`dist/`、`build/`、`out/` 里没有提交的文件，也没有编译出来的二进制文件） |
| **3 · 发版** | `changelog`、`titles`（CI 跑 `check --pr`；用 Action 的话，要在 PR 上跑，而且没设 `pr-check: false`） |
| **4 · 带一支 AI 团队** | `codeowners`、`bot`、`skills`、`review`（合并到默认分支前要有一个人批准） |
| **5 · 公开** | `security-files`（安全说明、Dependabot、许可证）、`protection`（默认分支和 `v*` tag 上的规则集）、`merge-settings`（只许 squash 合并，合并后自动删分支）、`security-settings`（secret scanning、push protection、私下报告漏洞、Dependabot 提醒） |

后三步是服务器上的设置。完整的 `doctor` 用 `gh api` 去读，只读不改。
没装 `gh`、没登录、没网，或者远程仓库不在 GitHub 上，这三步就标 can't check，绝不会算作做完。
会话开头不联网，所以那里这三步总是 can't check。

**别的托管平台。** doctor 从 `origin` 远程仓库看出托管平台。在 GitHub 上，服务器设置照上面的办法读。
在 Gitea 上，在 `yokoten.json` 里写 `"host": "gitea"`，并把 bot 用户的令牌放进 `GITEA_TOKEN`；doctor 会通过
Gitea 的 API 读取分支和标签保护、标签、里程碑和忘记的分支。`gitea.com` 不用写这个键。在 GitLab 这类别的平台上，
核心照常工作：规则、守卫、提交检查都一样。只有平台自己才判断得了的
步骤，是 `tests`、`ci`、`labels`、`milestone`、`titles`、`codeowners`、`bot`、`review`，以及那三步
服务器设置。这些步骤在那里都标 **can't check**，并写明它在问什么，你可以自己动手设好。
它们不会卡住关卡。自建服务器的名字从不打印，doctor 一律叫它 "this host"。

第 2 关的 `labels` 和 `milestone` 也这样读。标准标签是 `bug`、`feat`、`docs`、`refactor`、`ci`、
`owner`、`incident`、`good first issue`、`hotfix`、`security`，还有三个 tier 标签 `tier A`、`tier B`、`tier C`。
`init` 会告诉你缺哪些，`init --github --yes` 帮你加上。

第 4 关的 `review` 也这样读服务器。默认分支的规则集（或者分支保护）要求至少一个批准，这一步就算做完。
GitHub 不让你批准自己开的 PR，所以让 bot 来开 PR，你来批准、合并。
设置方法：编辑默认分支上的规则集，在“Require a pull request”里把“Required approvals”设成 1。
另外，Settings → Actions → General 里的“Allow GitHub Actions to create and approve pull requests”要一直关着。
它要是开着，bot 推一个 workflow 就能批准它自己开的 PR，所以 `review` 不算做完。
批准设好以后，合并的人不是写代码的人，OpenSSF Scorecard 应该会把每次改动算作审过。
这是我们从 Scorecard 文档里读到的，还没在真正跑一次 Scorecard 时验证过。
免费账号的私有仓库没有规则集，这时 `review` 标 can't check，等到第 5 关仓库公开时再做。
它不标 not now，因为 not now 只留给你自己做的决定。

`init --github --yes` 还会把 `yokoten.json` 里 "areas" 列的模块各建一个标签，统一用灰色。
模块不超过 8 个才建：再多，标签就太乱了，你常用的那几个自己手动建就好。已有的模块标签原样保留，yokoten 也从来不删。

看板可有可无。`init --github --yes --board` 会建一个和仓库同名的看板，并关联到仓库，
Status 字段设成 Todo、In progress、In review、Done 四项。建看板要 gh 的令牌带 `project` 权限；
没有的话，init 就跳过看板，并告诉你跑 `gh auth refresh -s project`。再跑一次，它按名字找到这个看板，不会再建。
看板的视图和自动规则，API 设不了。所以只要仓库关联了看板，完整的 `doctor` 就会把这些列成"手动设置"的几行，
提醒你去点。这几行不会让 doctor 报错。

如果某一步对应外部的标准，`yokoten doctor` 会在步骤名后面写出来，比如 `ci (Scorecard: CI-Tests)`。
会话开头那三行不写。

为什么这样分，见[决定记录 0004](https://github.com/yokoten-labs/yokoten/blob/v0.1.2/docs/records/0004-the-road.md)。

这个仓库自己也在走这条路，每一关你都能直接看它怎么运转：

| 关 | 学会什么 | 在这里看 |
|---|---|---|
| **1 · 安全网** | AI 要读的规则，以及规则管不住时拦下它的检查 | [AGENTS.md](https://github.com/yokoten-labs/yokoten/blob/v0.1.2/AGENTS.md) |
| **2 · 先开 issue，再走 PR** | 每次改动先开 issue 说清为什么；CI 通过了才合并；用标签、里程碑（milestone）和看板管起来 | [issue](https://github.com/yokoten-labs/yokoten/issues?q=is%3Aissue)、[PR](https://github.com/yokoten-labs/yokoten/pulls?q=is%3Apr)、[看板](https://github.com/orgs/yokoten-labs/projects/1) |
| **3 · 发版** | 写明改了什么、为什么改的提交信息；CHANGELOG；每次发版一个版本号 | [CHANGELOG.md](https://github.com/yokoten-labs/yokoten/blob/v0.1.2/CHANGELOG.md) |
| **4 · 带一支 AI 团队** | bot 开 PR，worker 领任务，reviewer 审查；最后拍板的永远是你 | [像带团队一样管 agent](https://yokoten.app/zh/docs/guide/managing-agents-like-a-team.md) |
| **5 · 公开** | 把全部提交历史查一遍，看有没有漏出隐私；打开安全设置；保护 `main` 分支 | [安全说明](https://github.com/yokoten-labs/yokoten/blob/v0.1.2/.github/SECURITY.md) |

AI 想推送发版 tag 时，会看到：

```
yokoten stopped this: git push --tags pushes tags [release]

  Why       Only the owner decides when to release.

  Instead   Stop and tell the owner: only the owner releases, with the steps in
            How to release; do not look for another way.

  More      https://github.com/yokoten-labs/yokoten/blob/main/docs/guide.md#how-to-release
```

每条提示都一样：让 agent 停下来，请主人发版。发版批准的办法、以及启动每个 agent 的命令，
都在英文指南的[How to release](https://github.com/yokoten-labs/yokoten/blob/main/docs/guide.md#how-to-release)里。
Muse Code 和 OpenCode 没见到会把变量传给钩子，所以主人要在它们外面发版。Gemini CLI 如果开了严格的
环境变量清理，这个变量会被删掉，主人就要到 Gemini CLI 外面去发。

（提示用英文写，因为 AI 读英文最不容易出错。）

每条提示都是同样的四部分。第一行说**出了什么事**（what），行尾用方括号给出规则 id，形如
`yokoten stopped this: <what> [<id>]`。**Why** 一行说为什么要紧（why）。**Instead**
一行是怎么改（fix，一条命令或者一处改动）。**More** 一行是规则完整说明的链接。问题出在
某个文件里时，位置紧跟在标题后面：`yokoten stopped this: 文件:行号: <what> [<id>]`。查到问题时，只说是哪一类，不说内容：
密钥、私有词表里的词，都不会打印出来。

想知道某条规则为什么存在，就跑 `yokoten explain <id>`。id 就是规则或步骤的名字，比如
`secret`、`commit-check`。不写 id，或者写了一个不存在的，它会把所有 id 列出来。

```
$ yokoten explain force-push
force-push: no plain force push (core rule 7).
Why: a plain force push can throw away work that someone else pushed.
Check: the tool-call guard stops `git push --force`, `-f` and a `+ref`; `--force-with-lease` passes; a branch ruleset on the server is the lock.
Docs: https://github.com/yokoten-labs/yokoten/blob/main/docs/guide.md#the-core-rules
```

## 只在这台机器上的活

停电、死机、硬盘坏了，只存在这台机器上的东西就没了。所以 `doctor` 会把这些列出来，
每一条都附上能把它保住的那条命令：

| 提醒 | 意思 | 命令 |
|---|---|---|
| `uncommitted-changes` | 某个 worktree 里有改了没提交的文件：几个，最早的改了多久 | 在那里 `git add -A`、`git commit`，再推上去 |
| `unpushed-commits` | 某个分支上有远端没有的提交，或者游离的 HEAD 上有哪个分支都没收着的提交 | `git push`；分支在远端还没有自己的同名分支时，用 `git push -u origin <分支>`；游离的 HEAD 先 `git switch -c <名字>` |
| `stashes` | 有 stash。stash 从来不会被推上去 | `git stash branch <名字>`，再推上去 |
| `stale-index-lock` | 死机留下了一个 `index.lock`，仓库里也没有 git 在跑 | 用 `rm` 删掉它 |
| `repo-on-tmpfs` | 仓库在 tmpfs 上，一重启就清空 | 先 `git push --all origin`，再在不会被清空的地方重新 clone 一份 |
| `repo-in-temp-folder` | 仓库在临时文件夹里，系统重启时可能会清掉 | 先 `git push --all origin`，再在不会被清空的地方重新 clone 一份 |
| `finished-worktree` | 某个 worktree 没有改动，而且分支已经合并、远端分支已经没了，或者游离的 HEAD 已经在默认分支里 | `git worktree remove <路径>`，分支还留着 |
| `missing-worktree` | git 还记着某个 worktree，可它的文件夹已经没了 | `git worktree prune` |

提交了但没推，东西还是只在这台机器上。从 `origin/main` 拉出来的分支会跟踪 main，
所以它的提交要推到它自己的分支，绝不推到 main。

squash 合并不会在分支历史里留下痕迹，所以远端分支没了，也算作已合并。
有未提交改动的 worktree，doctor 不会说它可以删。
拉出来以后一次都没动过的分支或游离 HEAD 是新的，不算已合并。

遇到 `index.lock` 时，doctor 会看有没有 git 进程正在这个仓库里干活。Linux 上能看到每个进程
在哪个文件夹；macOS 和 Windows 上看不到，所以只要有 git 进程在跑，就说「判断不了」。
这时 doctor 绝不会叫你删这个文件。凭据缓存这类一直挂着的 git 辅助进程不算。
tmpfs 是读 `/proc/mounts` 判断的，所以只在 Linux 上查。

临时文件夹指系统自己的那个（`TMPDIR`，Windows 上是 `%TEMP%`）和 `/tmp`。
WSL 重启时会清空 `/tmp`，哪怕它不是 tmpfs。想多查几个文件夹，就写进 `YOKOTEN_TEMP_DIRS`，
分隔方式和 `PATH` 一样。设成空的就不查了。

仓库本身放在这种地方，总会单独提一条，因为这是仓库放错了地方。
worktree 放在这里，只有里面有会丢的东西时才提，而且就写在那条提醒里，比如：
「../w 有 3 个没提交的文件，最早的改了 2 天，而且它在临时文件夹（/tmp）里，系统重启时可能会清掉」。
里面没有会丢的东西的 worktree，完整的 `doctor` 只用一行说一共有几个，会话开头不提。

这些都只是提醒，不会让 `doctor` 失败。doctor 在这里只读：不改文件、不动引用、不碰 worktree，
跑 git 时也关掉了可选的锁。路径都按相对仓库的写法显示，或者从 `~` 开始写。

会话开头只说有风险的，最多三条。没提交的改动要放了一个小时以上才提，
因为手上正在做的活不会忘。该收拾的 worktree 留给完整的 `doctor` 去说。
临时文件夹里有两个以上 worktree 存着会丢的东西时，先用一行说一共有几个。

会话开头在这件事上最多花一秒，免得磁盘缓存是冷的时候干等。时间到了，
就把已经读到的说出来，再加一句「doctor 提前停了」。完整的 `doctor` 不限时间。

---

上一章: [三道检查，一把锁](https://yokoten.app/zh/docs/guide/three-checks-and-a-lock.md)
下一章: [四层](https://yokoten.app/zh/docs/guide/four-layers.md)
