guide-and-verify
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGuide and verify
指导与验证
Some changes are not yours to make. The system has no API you may write to, the credentials are not
yours, the change is legally or organisationally the human's, or the safe boundary of the task says a
person clicks and you only read. In every one of those cases the deliverable is the same: a runbook a
person can follow, plus proof that following it worked.
The failure this skill prevents is the vague handover — "remove that field from the forms and the
views" — which reads as complete, sends the person hunting through a UI, and ends with nobody able to
say whether it is done. The cure is measurement on both ends and a step shape tight enough to follow
while tired.
有些变更并非由你执行。系统没有可供你写入的API,你没有相关凭据,变更在法律或组织层面必须由人类完成,或者任务的安全边界规定仅由人类点击操作、你只能读取数据。在所有这些情况下,交付物都是相同的:一份人类可遵循的操作手册(runbook),以及遵循手册操作后生效的验证依据。
本技能旨在避免模糊的工作移交——例如“从表单和视图中移除该字段”,这类表述看似完整,实则会让用户在UI中盲目摸索,最终无人能确认变更是否完成。解决方法是在变更前后进行测量,并制定足够清晰、即使疲惫也能遵循的步骤。
The boundary comes first
先明确边界
Before anything else, settle who acts. If the change is the human's, print the steps and stop. Do
not do it for them, do not do "just the easy half", and do not quietly widen your access to finish it.
A boundary that you cross once stops being a boundary.
Say the boundary out loud in the handover, because it tells the person that waiting for you is not an
option: "I read this system. I do not write to it. Every change below is yours."
首先要确定谁来执行操作。如果变更由人类完成,列出步骤后停止操作。不要替他们执行,不要只做“简单的一半”,也不要悄悄扩大权限来完成任务。边界一旦被跨越一次,就不再是边界。
在移交时明确说明边界,让对方知道不能等待你完成:“我仅能读取该系统数据,无法写入。以下所有变更均需由你执行。”
The five phases
五个阶段
1. Measure the baseline — before you write a single instruction
1. 测量基线——在编写任何指令之前
Never write a runbook from a document. Tickets, wikis, past handovers and your own earlier notes
were true when written and drift silently. Read the live system and count what is actually there.
Two numbers matter and they are not the same:
- the raw count — how many times a name appears in the underlying data
- the actionable count — how many things the person must actually click
They diverge constantly, because systems store a name once for the real object and again in indexes,
dependency lists, labels and audit fields. Reporting the raw count sends the person hunting for objects
that do not exist. Parse the structure and count the objects; use the raw count only as a cross-check.
Then locate each one precisely. "Somewhere on the form" is not a location. "Tab X → section Y →
field Z" is. If you cannot say where it is, you have not measured enough to write the step yet.
Write the baseline down where it survives the session — the ticket, the runbook header, a commit. It is
the only thing that makes the after-measurement mean anything.
Record each measurement when you take it, not in a batch at the end. Every time you read the live
system, write that reading onto the ticket before the next read — the number, what it was measured
against, and the time. A session that measures twenty things and records them once at the end has an
unwritten ticket for its whole length: a crash, a compaction or a parallel session loses every fact,
and anyone reading meanwhile sees the document's stale claim instead of the system's answer. The rule
is per-check, not per-session — a measurement that contradicts the document is the one most worth
writing immediately, because it is the one nobody can reconstruct.
Save the full state, not only the numbers you will assert. For every object a step will touch, write
its complete serialized form — the XML, the JSON, the config, the record — before the person acts. The
assertion proves whether something moved; only the snapshot proves what. Do this even when the edit
looks reversible: a platform undo you cannot name the target of is not a recovery.
Put it where it outlives the session — attached to the ticket, committed, or a directory named in
the runbook. A snapshot in a scratchpad is not a snapshot. It dies with the session and leaves the next
person exactly as blind as if you had never taken it.
Ask first only when the snapshot needs the person. If you can read the objects yourself, take it
read-only and say you took it — asking there costs them a turn and buys nothing. If it needs their hands
or a permission you do not hold — an export, a portal download, a wait — ask in one line: "I will save
the current state of first — is that all right?" Only an explicit no is a decline. A
vague reply, a changed subject and silence all count as no answer, so you take the snapshot. On an
explicit no, or when you cannot read the objects at all, use the two options in the next paragraph:
borrow their eyes for one export, or label the runbook "no before-snapshot, by the operator's
decision" and carry that label into every later claim, the way an unverified baseline is carried.
<the objects>If you cannot read the system either. This is common — often the same missing credentials that stop
you writing also stop you reading. Do not treat that as permission to fall back on the document, which
is how the vague handover gets written in the first place. You have two honest options:
- Borrow the person's eyes. Give them one read-only check, and ask them to paste the result back. That result becomes the baseline, and it is genuine measurement — it just travelled through them.
- Declare the baseline unverified. Write it as "inherited from ,
<source>, not verified against the live system", and carry that label into every later claim. An unmeasured baseline that looks measured is worse than no baseline, because the after-check then certifies a number nobody ever confirmed.<date>
Choose the first when you can. What you must never do is state a count in a runbook without saying
where it came from.
绝不要根据文档编写操作手册。工单、维基百科、过往移交记录以及你自己的早期笔记在编写时是准确的,但会悄然失效。读取实时系统数据,统计实际存在的内容。
有两个重要的数字,它们并不相同:
- 原始计数——某个名称在底层数据中出现的次数
- 可操作计数——用户实际需要点击操作的对象数量
这两个数字经常不一致,因为系统会为真实对象存储一次名称,又在索引、依赖列表、标签和审计字段中重复存储。报告原始计数会让用户寻找不存在的对象。解析系统结构并统计对象数量;仅将原始计数用作交叉核对。
然后精确定位每个对象。“表单上的某处”不是有效位置,“标签页X → 区域Y → 字段Z”才是。如果你无法说明位置,就说明你还没有完成足够的测量来编写步骤。
将基线记录在能留存会话的地方——工单、操作手册页眉或提交记录中。它是让后续测量有意义的唯一依据。
测量时即时记录,不要在最后批量记录。每次读取实时系统数据时,在下一次读取前将记录写入工单——包括数值、测量对象和时间。如果一个会话测量了20项内容但仅在最后记录一次,那么整个会话期间都相当于存在一份未记录的工单:崩溃、压缩或并行会话会丢失所有信息,期间查看文档的人看到的是过时的内容而非系统的真实状态。规则是每次检查都要记录——与文档矛盾的测量结果最值得立即记录,因为没人能重新还原它。
保存完整状态,而非仅保存你要断言的数值。对于每个步骤将涉及的对象,在用户操作前记录其完整序列化形式——XML、JSON、配置或记录。断言只能证明是否有变更;只有快照能证明变更了什么。即使编辑看起来可逆也要这样做:如果你无法指定目标对象,平台的撤销操作也无法恢复数据。
将快照存储在能留存会话的地方——附加到工单、提交保存,或存储在操作手册指定的目录中。临时记事本中的快照不算真正的快照,它会随会话结束而消失,让后续人员和你从未拍摄快照一样一无所知。
仅当快照需要用户协助时才先询问。如果你能自行读取对象数据,就以只读方式获取并告知用户你已完成——此时询问只会浪费他们的时间,毫无意义。如果需要用户操作或你没有相关权限(如导出、门户下载、等待),用一句话询问:“我将先保存<对象>的当前状态——可以吗?” 只有明确的“不”才算拒绝。模糊的回复、转移话题或沉默都视为未答复,你可以直接拍摄快照。如果明确被拒绝,或者你完全无法读取对象数据,请使用下一段中的两个选项:借用用户的视角完成一次导出,或在操作手册中标注*“无前置快照,由操作员决定”*,并在后续所有断言中保留该标签,就像未验证的基线一样。
如果你也无法读取系统数据。这种情况很常见——通常阻止你写入数据的缺失凭据也会阻止你读取数据。不要以此为依据退而求其次使用文档,这正是模糊工作移交产生的原因。你有两个诚实的选择:
- 借用用户的视角。让他们完成一次只读检查,并将结果粘贴回来。该结果将成为基线,这是真实的测量——只是通过用户传递。
- 声明基线未验证。标注为*“继承自<来源>,<日期>,未针对实时系统验证”*,并在后续所有断言中保留该标签。看似已测量的未验证基线比没有基线更糟,因为后续检查会验证一个从未被确认的数值。
尽可能选择第一个选项。绝对不要在操作手册中声明计数却不说明来源。
2. Decide the assertion before the person acts
2. 在用户操作前确定断言内容
State now what the numbers must become. , , .
An after-measurement with no pre-declared target is a description, not a check — you will find yourself
reading the result and deciding it looks fine.
1 control → 013 rows → 0status pending → activeThe predicted outcome is a claim, and it needs evidence like any other. Phase 1 forbids taking
counts from a document; the same applies to what you say will happen. "The save will be refused
because the field is required" is a platform-behaviour claim — verify it against the vendor's docs or
a live probe before it enters the runbook. A wrong prediction is worse than none: the person reads a
correct result as a failure, or a broken one as a pass, and the runbook has taught them the wrong
success condition.
Include a blast-radius assertion: name what must not change. Count the neighbours now (the other
28 handlers, the other 5 rules, the other 12 records) so that after the change you can say nothing else
moved. This is what catches the person deleting one thing too many, which no success check ever does.
现在说明数值必须变成什么。例如、、。没有预先声明目标的后续测量只是描述,而非检查——你会发现自己看着结果觉得“看起来没问题”。
1个控制项 → 013行 → 0状态:待处理 → 已激活预测结果是一种断言,和其他断言一样需要证据。第一阶段禁止根据文档获取计数;同样的规则适用于你所说的将会发生的情况。“由于字段为必填项,保存操作会被拒绝”是一种平台行为断言——在写入操作手册前,需根据供应商文档或实时探测验证该断言。错误的预测比没有预测更糟:用户会将正确结果视为失败,或将错误结果视为成功,操作手册会教会他们错误的成功条件。
包含影响范围断言:说明哪些内容必须保持不变。现在统计相关对象(其他28个处理程序、其他5条规则、其他12条记录),以便变更后你可以确认没有其他内容被改动。这能发现用户误删内容的情况,而任何成功检查都无法做到这一点。
3. Write the step in a fixed shape
3. 以固定格式编写步骤
One step is one reversible unit of work. Use this shape every time — the person learns it once and then
reads it fast:
undefined一个步骤对应一个可逆的工作单元。每次都使用以下格式——用户只需学习一次,之后就能快速阅读:
undefinedStep N — <what this achieves, in plain words>
Step N — <what this achieves, in plain words>
Go to: <a real address or an exact navigation path>
Do:
- <one action>
- <one action>
...
Do not:
- <thing> — <why, in one clause>
How to verify yourself: <a read-only check the person can run alone>
Then report: <who to tell, and where the result is written down>
Rules that make the shape work:
- **One action per numbered line.** "Select the field and delete it and save" is three lines.
- **A real address beats a description.** Give the URL. If it may not resolve, give it anyway and add
the click path as a fallback in one line.
- **Every "do not" carries its reason.** A prohibition without a reason gets ignored the moment it is
inconvenient. *"Do not stop after Save — Save writes a draft, and a draft looks identical."*
- **Include the destructive near-misses.** The dangerous instruction is not the one you gave; it is the
adjacent thing that looks like it. If they must remove a field from a screen, say explicitly that the
underlying column stays. If they must disable one rule, name the rule next to it that must not be
touched, and say what happens if it is.
- **Order by dependency, and say when order does not matter.** People reorder steps that look
independent. If step 2 must follow step 1, say why in half a sentence.
- **Never batch.** One step, verify, then the next. Batching saves the person a few minutes and costs
everyone an afternoon when something breaks and nobody knows which change did it.
- **Capture the before-state of anything structured, not only the irreversible.** Ask "if the person
edits the wrong element, can I name which one?" If you cannot, you owe a before-snapshot, and Phase 1
says where it goes. That covers ordinary edits to forms, views, configs and records, not just
deletions and key rotations. For the genuinely one-way — deleting a record, rotating a key, dropping
a column — "one step, verify, then the next" buys you nothing, because there is nothing to go back to:
add a numbered line before it that reads the present value and writes it somewhere retrievable, and
say plainly in the step that this action is not reversible. A person who knows a step is one-way reads
it twice.
- **Aim the report line at whoever will actually be there.** In a live session it is *"tell me and I
measure it"*. In a runbook that ships ahead of a release window it must name a destination that
outlives you — *"record the result and the measurement on `<ticket>`"*. Getting this wrong produces a
document that tells a reader six weeks from now to report to an agent who is long gone, and the
result then goes nowhere.
Keep the prose short. The person is reading this with a console open in the other window.Go to: <a real address or an exact navigation path>
Do:
- <one action>
- <one action>
...
Do not:
- <thing> — <why, in one clause>
How to verify yourself: <a read-only check the person can run alone>
Then report: <who to tell, and where the result is written down>
让格式有效的规则:
- **每条编号行对应一个操作**。“选择字段并删除然后保存”应拆分为三行。
- **真实地址优于描述**。提供URL。如果可能无法解析,仍需提供URL,并在一行中添加点击路径作为备选方案。
- **每个“禁止操作”都要说明原因**。没有原因的禁令在不方便时会被忽略。例如:*“保存后不要停止——保存仅会写入草稿,草稿与已生效状态看起来完全相同。”*
- **包含易混淆的危险操作**。危险的不是你给出的指令,而是看起来相似的相邻操作。如果用户必须从屏幕上移除某个字段,要明确说明底层列需保留。如果用户必须禁用一条规则,要指明旁边不能触碰的规则,并说明触碰后的后果。
- **按依赖关系排序,并说明顺序无关的情况**。用户会重新排序看似独立的步骤。如果步骤2必须在步骤1之后执行,用半句话说明原因。
- **绝不要批量操作**。完成一个步骤,验证,再进行下一个。批量操作能为用户节省几分钟,但当出现问题且无人知道是哪次变更导致时,会让所有人浪费一下午时间。
- **捕获任何结构化内容的前置状态,不仅是不可逆操作**。问自己:“如果用户编辑了错误元素,我能指出是哪一个吗?”如果不能,你需要拍摄前置快照,第一阶段说明了存储位置。这适用于对表单、视图、配置和记录的普通编辑,不仅限于删除和密钥轮换。对于真正不可逆的操作——删除记录、轮换密钥、删除列——“完成一个步骤,验证,再进行下一个”没有意义,因为无法恢复:在步骤前添加一条编号行,读取当前值并存储到可检索的地方,并在步骤中明确说明该操作不可逆。知道步骤不可逆的用户会仔细阅读两次。
- **报告对象要指向实际在场的人**。在实时会话中是*“告知我,我来测量”*。在发布窗口前交付的操作手册中,必须指定一个能长期留存的目标——*“将结果和记录写入<工单>”*。如果这一点出错,文档会告诉六周后的读者向早已不在的Agent报告,结果会石沉大海。
保持文字简洁。用户会在另一个窗口打开控制台的同时阅读这些内容。4. Verify — read-only, in a different channel
4. 验证——通过只读的不同渠道
When they report a step done, measure it against the baseline and report before → after. Assert the
success condition and the blast radius.
Verify through a different channel from the one they used to change it. If they edited in a UI, read
the machine state — an API, a CLI, an export, a query. The editing UI is the one surface guaranteed to
show you what it thinks it just saved, including from its own cache. A second channel is what turns
"it looks right" into evidence.
When there is no second channel, which is normal for consumer-grade admin pages, routers and many
SaaS settings screens: say so, and change your wording. The result is then "reported by the operator,
not independently measured" — never "verified". This distinction is the whole value you are adding, so
losing it to keep a tidy report defeats the exercise. An unsatisfiable rule gets satisfied creatively:
if you leave yourself no honest way to say "I could not check this", you will accept a screenshot and
call it proof.
If the check fails, say so plainly with the numbers, and diagnose before proposing a redo. Half-applied
is the common outcome, and telling them to "try again" on a step that partly landed makes it worse.
当用户报告步骤完成时,将结果与基线对比,报告变更前后的情况。同时断言成功条件和影响范围。
通过与用户变更操作不同的渠道进行验证。如果用户在UI中编辑,读取机器状态——API、CLI、导出文件或查询。编辑UI是唯一会显示它认为已保存内容的界面,包括自身缓存中的内容。第二个渠道能将“看起来正确”转化为证据。
当没有第二个渠道时,这在消费级管理页面、路由器和许多SaaS设置界面中很常见:说明情况,并更改措辞。结果应标注为*“由操作员报告,未独立测量”*——绝不要标注为“已验证”。这种区分是你能提供的核心价值,为了保持报告整洁而忽略这一点会使整个流程失去意义。无法满足的规则会导致变通处理:如果你没有诚实的方式说明“我无法检查此项”,你会接受截图并将其称为证据。
如果检查失败,用数值明确说明,并在建议重新操作前进行诊断。部分生效是常见结果,告诉用户“再试一次”会让情况变得更糟。
5. Teach the self-check, and record the result
5. 教授自我检查方法,并记录结果
Give the person a check they can run without you, in that second channel. This is the part that
outlives the session: they will do this again when you are not there, and a runbook whose only verifier
is an agent is a runbook that rots.
Prefer a check that is one action — open a URL, run one command, look at one screen. If the natural
check needs three steps, it is too heavy and they will skip it.
Then write the outcome where the next person finds it, with the measurement attached. "Done" is worth
little. "Done — 1 control on each form became 0, other 28 handlers unchanged, measured 09:14Z" is worth
the whole session.
为用户提供无需你协助即可执行的检查方法,使用第二个渠道。这是能留存会话的部分:当你不在时,他们还会再次执行此操作,而仅能由Agent验证的操作手册会逐渐失效。
优先选择只需一步的检查——打开一个URL、运行一条命令、查看一个屏幕。如果自然检查需要三步,就过于繁琐,用户会跳过。
然后将结果记录在后续人员能找到的地方,并附上测量数据。“已完成”几乎没有价值。“已完成——每个表单上的1个控制项变为0,其他28个处理程序未变更,测量时间:09:14Z”才是整个会话的价值所在。
The trap that catches nearly every system: saved is not applied
几乎所有系统都会遇到的陷阱:已保存不等于已生效
Most systems that a human edits by hand have two states for the same object — an edit that exists and an
edit that is live. The names differ; the failure is identical. A plain read usually returns the live
copy, so a saved-but-not-applied change reads as "nothing happened". People then redo correct work, or
conclude the tool is broken.
| System | Edited state | Live state |
|---|---|---|
| CRM / low-code platform | draft customisation | published |
| DNS | edited record | resolving for clients |
| Cloud console | saved configuration | running revision |
| CI / CD | edited definition | definition the next run uses |
| SaaS admin | staged setting | rolled out to users |
| Database GUI | uncommitted transaction | committed |
What closes the gap is either an explicit apply action (publish, deploy, commit, restart) or a
propagation delay you have to wait out — and sometimes both. Find out which one you are dealing with
before you write the step, because they need different instructions: an apply action is a line in the
runbook, and a delay is a warning not to re-do work that already succeeded.
So do two things. Put the apply step in the runbook as its own numbered line, never as a clause
inside another line. And tell the person that their self-check doubles as an apply-detector: "if the
old value is still there, you did not apply it." Where the system offers a read of the pending state,
give them that too, so they can tell "not applied" apart from "not saved" — those have different fixes.
大多数需要人类手动编辑的系统中,同一对象有两种状态——已存在的编辑内容和已生效的内容。名称各不相同,但问题本质相同。普通读取通常返回生效副本,因此已保存但未生效的变更会显示为“未发生任何变化”。用户会重复执行正确操作,或认为工具已损坏。
| 系统 | 编辑状态 | 生效状态 |
|---|---|---|
| CRM / 低代码平台 | 草稿自定义 | 已发布 |
| DNS | 已编辑记录 | 对客户端生效 |
| 云控制台 | 已保存配置 | 运行中的版本 |
| CI / CD | 已编辑定义 | 下次运行将使用的定义 |
| SaaS管理后台 | 待生效设置 | 已向用户推送 |
| 数据库GUI | 未提交事务 | 已提交 |
填补差距的方式要么是明确的生效操作(发布、部署、提交、重启),要么是需要等待的传播延迟——有时两者都需要。在编写步骤前确定你面对的是哪种情况,因为它们需要不同的指令:生效操作是操作手册中的一条步骤,延迟则是提醒用户不要重复已成功完成的工作。
因此要做两件事。将生效步骤作为独立的编号行写入操作手册,不要作为其他步骤中的从句。并告诉用户他们的自我检查同时可作为生效检测器:*“如果仍显示旧值,说明你未执行生效操作。”*如果系统提供待生效状态的读取方式,也要告知用户,这样他们就能区分“未生效”和“未保存”——这两种情况的解决方法不同。
Write for someone who is tired and clicking
为疲惫且正在操作的用户编写内容
Short sentences. One instruction per sentence. Plain words. Match the user's own vocabulary for their
domain — if their glossary distinguishes two similar terms, hold that distinction, because a runbook
that blurs it is the thing that makes them act on the wrong object.
Do not editorialise about risk in the steps. Put the reason in the "do not" clause and move on.
短句。每句对应一个指令。用词平实。匹配用户所在领域的词汇——如果他们的术语表区分两个相似术语,要保持这种区分,因为模糊术语的操作手册会导致用户操作错误对象。
不要在步骤中对风险发表评论。将原因放在“禁止操作”条款中,然后继续。
Say what you could not measure
说明你无法测量的内容
Some part of the picture will be out of reach — a permission you do not hold, an endpoint that refuses
you, a number that lives only in a UI. Name it, name where the human can see it, and do not let the
gap hide inside a confident summary. A verification that quietly skipped a check reads as coverage it
did not have, and the next person inherits that as fact.
Same for staleness: if your baseline came from a feed that refreshes on a delay, say how old it is.
部分内容可能无法获取——你没有权限、端点拒绝访问、数值仅存在于UI中。明确说明这些内容,以及用户能在哪里看到它们,不要让缺口隐藏在自信的总结中。悄悄跳过检查的验证会看似覆盖了所有内容,后续人员会将其视为事实。
对于过时数据也要说明:如果你的基线来自延迟刷新的数据源,要说明其时效性。
When the whole thing is deferred
当整个流程被推迟时
Sometimes nobody can verify today — the change rides a release, a window, an approval. Then the runbook
is the deliverable, and it has to survive months without you. Write every identifier in full, record
the baseline inside the document rather than pointing at a session, and state which checks were actually
run and which are still owed. A checklist that cannot tell a new fault from a known one is what turns a
deferred verification into an argument.
有时无人能在今天完成验证——变更需等待发布、窗口期或审批。此时操作手册就是交付物,它必须在没有你的情况下留存数月。完整写入每个标识符,将基线记录在文档内而非指向会话,并说明哪些检查已实际执行、哪些仍未完成。无法区分新故障和已知问题的检查表会将推迟的验证变成争议。