Skip to content

07 · 人机竞速与超时仲裁

Who decides what

枪声一响,三方赛跑:(点官方面板按钮)、宿主倒计时(唯一权威作者)、LLM 结论(scope 内可抢占)。raceHumanDecisiondecision.ts:L100-141)是仲裁器:

  1. 启动 raceHumanDecision(() => next(), {seconds, action}, handle)
    把「求人」委托给官方 ApprovalPanel(next()),同时宿主开一个 setTimeout(seconds*1000)
  2. 超时先到
    宿主 tap 时钟:记录规范文案 [dsh-auto-approval-llm] no response: auto-approved / auto-rejected (Ns)(文案永远宿主生成),按 timeoutAction 结案 allowed-once | rejectedtimedOut=true。关闭的标签页/headless 永远挂不死审批。
  3. 人先答
    面板 outcome 结案,timedOut=false
  4. LLM 抢先(仅 MEDIUM+scope 内)
    handle.claim('allowed-once'|'rejected'):清定时器、claimed=true、立即结案 —— 这就是「LLM 接管」的唯一可信信号。

7.1 诚实来源标注 approvalSource decision.ts:L158-175 —— 谁决定,就标谁

条件source 标签
宿主倒计时到期timeout-allow / timeout-deny
LLM 接管(claim)llm-allow / llm-deny
客户端自动应答(autoAnswered 标记)auto-allow / auto-deny
真实人工点击human-allow / human-deny
请求被取消/会话销毁abort → 永远 action=reject(不假装有人决定过)
声明规则(G1)/静态名单(G2)rule-deny / rule-allowdenyList-deny / allowlist-allow
策略层无条件硬拒(运行态文件等)policy-deny → 立即 rejected,无倒计时、不计熔断、不发布 review-status

防张冠李戴

仅仅存在一份 advisory 评审结论(表明 LLM 看过)绝不允许把这次决议标成 llm-*。只有 claimed(宿主侧竞速被抢占)才算 LLM 接管。同理,advisory 拒绝 不会计入熔断 —— 熔断只认「LLM 真正拍板的拒绝」。

7.2 反重标的四重防线(防止客户端/迟到 ACK 篡改决议性质)

机制作用
resolvedCallIds(TTL 30s)宿主已结案的 callId;迟到的 FEEDBACK ACK 无法再把它 relabel 成「no response: auto-*」
FEEDBACK 双重门只有当 !decisionFeedback.has && !resolvedCallIds.has 才写 timeoutFeedback;客户端只能传 outcome∈{allowed-once,rejected},其余强制 rejected
outcome 白名单超时标记唯一作者是宿主计时器,客户端只上报 outcome
answer-once Set客户端 answeredApprovals 保证同一审批只答一次、不双写

7.3 follow 阶段与 TTL 家族

ReviewStatus 状态机countdown(倒计时中)→ follow(已结案,等客户端收敛面板)。follow 保留 FOLLOW_STATE_TTL_MS = 120_000(覆盖 Chrome 后台标签节流 ≥1min),客户端 followSweep 每秒清扫。

定时器
FOLLOW_STATE_TTL_MS120 s
RESOLVED_TTL_MS30 s
AUTO_ANSWERED_TTL_MS60 s
feedback 表 TTL / 上限60 s / 256 条
followSweep 周期1 s
客户端 poll 频率500 ms