spec-probes

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Spec probes

规格说明探测

A verifier only checks assertions that exist, and it is confidently wrong about edges the spec never stated. The fix is not a better verifier; it is spec completeness. Run these two passes over each requirement before code, in this order.
验证器只会检查已明确的断言,对于规格说明未提及的边缘场景,它会笃定地给出错误判断。解决办法不是使用更优的验证器,而是确保规格说明的完整性。在编写代码前,按以下顺序对每一项需求执行这两轮检查。

Pass 1: edge probe

第一轮:边缘探测

Classify each requirement's data shape:
numeric-range
,
collection
,
text
,
stateful
,
io
. Then raise only the categories whose shapes intersect it. A pure-text requirement is never asked about overflow. The taxonomy is closed on purpose: eight categories the author clears beat thirty nobody finishes.
CategoryShapesAsk
Boundary valuesnumeric-rangeWhat happens exactly at each min, max, or threshold, and one step either side?
AdjacencycollectionWhen two things are exactly equal or just touch, do they merge, collide, or stay separate?
Empty / degeneratecollection, textWhat is the result for empty, single-element, or null input?
EncodingtextWhose definition of length and equality applies: bytes, code points, grapheme clusters, normalized form?
Ordering / stabilitycollectionWhen elements compare equal, is output order specified and stable?
Precision / overflownumeric-rangeWhere can rounding, tie-breaking, precision loss, or overflow occur, and what is the exact contract: half-up or half-even, floor or truncate?
IdempotencystatefulWhat happens if this runs twice on the same input?
Concurrency / effect orderstateful, ioIf interrupted or run in parallel, what is guaranteed?
A requirement with prose but no matching shape gets one soft "unclassified, review by hand" item, not silence.
The defects this catches: "merge overlapping intervals" says nothing about
[1,2]
and
[2,3]
, which only touch. "Round half to nearest" leaves half-even rounding 2.5 to 2 unstated. "Truncate to N characters" does not say whether a character is a byte, a code unit, a code point, or a grapheme.
对每项需求的数据形态进行分类:
numeric-range
(数值范围)、
collection
(集合)、
text
(文本)、
stateful
(有状态)、
io
(IO)。然后只针对与该需求形态匹配的类别提出问题。纯文本需求无需询问溢出相关问题。我们特意采用封闭分类体系:作者只需梳理8个类别,远胜于没人能完成的30个类别。
分类形态问题
边界值numeric-range在最小值、最大值或阈值的精确位置,以及超出边界一步的位置,会发生什么?
相邻性collection当两个对象完全相等或恰好接触时,它们会合并、冲突还是保持独立?
空值/退化情况collection、text输入为空、单个元素或null时,结果是什么?
编码规则text长度和相等性采用哪种定义:字节、代码点、字符簇还是标准化形式?
排序/稳定性collection当元素比较结果相等时,输出顺序是否明确且稳定?
精度/溢出numeric-range可能在哪些地方发生舍入、平局处理、精度损失或溢出?具体规则是什么:四舍五入、银行家舍入、向下取整还是截断?
幂等性stateful对同一输入执行两次操作会发生什么?
并发/执行顺序stateful、io如果操作被中断或并行执行,有哪些保证?
仅包含描述性文字但无匹配形态的需求,会标记一个“未分类,需人工评审”的软提示,而非直接忽略。
该步骤能发现的问题:“合并重叠区间”未提及
[1,2]
和
[2,3]
这种仅接触的情况;“四舍五入到最近整数”未说明2.5采用银行家舍入法会得到2;“截断为N个字符”未明确“字符”指字节、代码单元、代码点还是字符簇。

Pass 2: prohibition probe

第二轮:禁止项探测

Edge shapes cannot surface "the reminder must not shame the user". For each requirement ask: what could this feature silently become that the author would not want, but the spec does not forbid? Cast wide first; ten raw candidates per requirement is expected.
Then one precision pass:
  • Drop routine engineering: must not mutate its input, must not throw on empty, must not leak a handle. Those belong to pass 1 or to code review.
  • Keep values, fairness, privacy, transparency, and safety items: must not use shaming framing, must not proxy on protected attributes, must not store raw PII in plaintext.
  • Refer, do not mint, anything a dedicated tool already owns (injection, path traversal, data-retention law, generic bias canon): one breadcrumb to the security or compliance step, then stop.
Two or three bespoke items per feature is the normal yield. A pure utility yields zero, and that is the right answer, so a non-empty list always carries signal.
边缘形态无法覆盖类似“提醒不得羞辱用户”这类要求。针对每项需求,需询问:该功能可能悄然演变成哪些不符合作者预期但规格说明未禁止的状态? 先广泛发散,每项需求通常会产生10个初步候选项。
随后进行一轮精准筛选:
  • 剔除常规工程约束:不得修改输入、不得为空输入抛出异常、不得泄露句柄等。这些属于第一轮检查或代码评审的范畴。
  • 保留涉及价值观、公平性、隐私、透明度和安全性的项:不得使用羞辱性表述、不得代理受保护属性、不得明文存储原始PII(个人可识别信息)等。
  • 引用而非新增已有专门工具负责的内容(如注入攻击、路径遍历、数据保留法规、通用偏见准则):只需标记一个指向安全或合规环节的线索,无需深入展开。
每个功能通常会筛选出2-3个定制化项。纯工具类功能可能筛选出0个,这是合理结果,因此非空列表始终具有参考价值。

Resolve every raised item

解决所有提出的问题

Each item ends in exactly one state:
  • resolved: an acceptance criterion states the answer (
    explicit
    , checked by an ordinary test); or a held-out or property-based test will stand in for an edge you know but cannot fully write down (
    backstop
    ); or, for a prohibition that needs human judgment rather than a test,
    judgment
    .
  • dismissed, with a reason. "N/A, input is a bounded enum, no boundary exists" is valid; silence is not. The reason is the audit trail.
  • unresolved: carried forward as an explicit gap the plan must surface, never dropped silently.
Write the
backstop
and
judgment
tags into the spec itself. A reviewer later abstains on those instead of passing them by inspection; without the tag it cannot see its own blind spot.
Reply: per requirement, the items raised and their states; then the coverage count: applicable, resolved, unresolved, and how many are
backstop
or
judgment
.
每个问题最终必须处于以下三种状态之一:
  • 已解决:验收标准明确给出答案(
    explicit
    ,可通过常规测试验证);或者用预留测试或基于属性的测试来覆盖已知但无法完整书面描述的边缘场景(
    backstop
    );或者对于需要人工判断而非测试的禁止项,标记为
    judgment
    。
  • 已驳回,并给出理由。“不适用,输入为有限枚举,无边界存在”是有效的理由;但不能无理由直接忽略。理由可作为审计线索。
  • 未解决:作为明确的缺口记录在案并跟进,绝不能悄然忽略。
将
backstop
和
judgment
标签直接写入规格说明。后续评审人员看到这些标签会跳过检查,而非凭直觉通过;没有这些标签,评审人员无法发现自身的盲点。
反馈要求:针对每项需求,列出提出的问题及其状态;然后统计覆盖情况:适用项数量、已解决数量、未解决数量,以及其中
backstop
和
judgment
的数量。