← Back to home@gh-gongjin

dsh-plugin-gh-trending

dsh 插件:GitHub 日/周/月热榜监控 + 仓库详情中文描述与 README 节译(全程只读 GET)

Stars
0
Language
JavaScript
Created
Oct 7, 2026
Updated
Oct 15, 2026

Introduction

dsh-plugin-gh-trending

DSH(deepseek HARNESS)的 GitHub 热榜监控插件:在侧边栏「插件」下方增加一个入口,盯三件事 —— 日榜 / 周榜 / 月榜各自怎么变、哪些仓库同时在多张榜上、本机第一次见到的仓库。变化只记录在本插件面板里,不推任何外部通知。

对 github.com 全程只读 GET(每轮三发 = 三张榜各一发;只有传输类失败——连不上/超时——才对那一榜补发,单榜含补发最多 3 发,成功即停):不带 key、不带 cookie、不 POST、不下载 zip、不 clone。 ★ 第二十三轮(10-09)加的那一路有尾巴:开了「全站高星」那一档 ⇒ 一轮最坏四发(三榜 + /search/repositories 一发),那一发每轮上限一枚、不补发、不重试,且出厂关着 ⇒ 关着时上面那句"每轮三发"照旧一字成立;填了 GitHub 令牌时它也走同一条 Authorization 请求头那一路(只进请求头,不进 URL)。 ★ 同日就地改判(用户裁定「开启的时候默认拉取一次」):把开关从关拨到开的那一趟 ⇒ 另加一发、当场花(它不属于任何检查轮,所以那一轮的"四发"账不因为它变成五发)。口径钉三条:认的是库里的转换(已经开着再存一次 true、改别的键时顺带带上、连点 ⇒ 一律不派),回执之前发完(保存偏好的响应回来时那一批已经在库里也在载荷里,不留"点完了但结果在别处"),发过就追帧(坏轮的故障三格同样当场让界面看见)。匿名 search 一小时才 10 发 ⇒ 这一发是用户点下去授权的,不是插件自己起的。 ★ 同日第二条裁定(「上次间隔时间范围内已经拉取过就不要拉取了」):那一趟从"必发"改成当场决定发不发 —— 库里最后一次成功取回(ok===true 的 at)距此刻不到一份检查间隔(prefs.intervalMin,设置页那一格,出厂 60 分)⇒ 0 发,直接把库里那一批端上来(挡下的一趟不写库、不追帧,开关位跟着同一次回执上屏)。窗口不另造常数、界面上看得见的那个数字就是它;⚠️ 上一发是坏的(403 / 超时)时照旧重试 —— 判据吃 at 而不是 lastFetchAt,不许让用户为了重试去等下一轮检查;这一道闸只挂在开启那一趟,检查轮"每轮一发"的节律一字不动。 需要代理时走插件自己的 CONNECT 隧道(lib/services/net.js):它不改本机任何代理设置,也不起监听端口,只在需要时向代理发起一条 CONNECT github.com:443,之后仍是标准 TLS + HTTPS GET。

它是什么

  • 三张榜独立闸门:日 / 周 / 月各一份状态,坏在哪一榜就只冻结哪一榜,绝不连冒横幅。
  • 变化流水:board_enter / board_exit / board_move / first_on_board / renamed / rising_cross / cooling_cross / source_error / source_recover / baseline(枚举与中文标签只在宿主侧 lib/domain.js,界面只查表)。位次挪动日/周 ≥3、月 ≥2 才记 board_move。
  • 跨榜同现:同时出现在 ≥2 张榜 = 持续升温,只剩 1 张 = 热度回落。三张榜在同一次检查里拿到,这块分析零额外请求。
  • 明星仓库那一屏(★ 第二十三轮(10-09)新增,第七个页签):答「哪些仓库反复上榜、谁在往上走」,原料全在本地(三榜这一轮的行 + 观测史 seen)⇒ 打开这一签零请求;七列里「今日新增」只吃日榜、证据不足 3 轮时「在榜」那一列整列置灰并说清为什么(不藏列)。另有一档「全站高星」(GET /search/repositories)出厂关着 —— ★ 10-09 改判:点「开」的那一刻宿主立刻发一发(不等下一轮检查),之后每轮最多一发、结果进缓存,关掉不删已攒的那批,详见「界面」那节;★ 10-10 第三条裁定:开着时它那一批行也参与描述列的现译(与榜面共享那 12 发,关掉只是不上屏、不删译文)。
  • 改名识别:靠条目里的 record_id 认出同一个仓库换了 owner/name ⇒ 记 renamed 而不是「掉榜 + 新进」两笔假账。
  • 项目收藏(★ 第三十二轮(10-13)新增,第八个页签):三榜每一行的末尾、明星仓库那一屏的每一行、以及详情弹框的标题行,共三处入口摆同一枚 ☆(同一个组件、点它只改收藏 ⇒ 不跳转、不开弹框、不滚动);收进来的仓库进「收藏」那一屏,七列 # / 仓库 / 描述 / 语言 / 累计 ★(那一刻)/ 收藏于 / ★(★ 第三十五轮(10-13)撤掉「这一轮」那一列:用户指着屏上那一列说「去掉这个」,裁定「只删那一列,右侧那枚 ★(取消收藏的入口)照旧留着」⇒ 八列变七列,屏上不再有「在日榜 / 在月榜 / 未上榜」那个读数;宿主侧那一格派生、载荷格、相关判据与台账一并撤干净,不留死码)。★ 第三十三轮(10-13)描述那一格换成"本机已有的那一份中文":内置预译或已付过额度的现译,命中判据与榜面同一个函数(lib/board-zh.js 的 descZhHits,这一屏不重写第二遍)⇒ 周榜上有中文的那一行,收藏那一屏逐字同;中文长在载荷那一行的 descZh 那一格(★ 旧台账叫它「第 11 格」,那个序号吃的是「那一行共有十一格」—— 第三十五轮撤掉末尾的「这一轮」之后只剩十格,序号名一并作废,改叫格名),desc 那一格恒是收藏那一刻的原文(覆盖掉就没有第二处能证明"快照不刷新"了)。这一路零出网、零新增额度:那一格是被动的 —— 本机哪天译过那句原文它就上屏,没译过就念原文,屏上永远不欠一次请求。 两条口径决定这一屏的形状:① 存的是收藏那一刻的快照,不是引用 —— 星数与描述不随榜面刷新(所以那一列表头写着「那一刻」,卡脚那句 note 把这件事说明白,要新值点仓库名走详情那条链)⇒ 打开这一签与收藏那一发都恒零出网(★ 第三十二轮的出网账裁定:收藏这一路 0 发,不为了补快照去问 GitHub);② 「这一轮」那一格是宿主本地比出来的成品句(拿收藏键与同一帧屏上那几批行比,命中念「在日榜 / 在周榜 / 在月榜 / 在明星」的优先级单值,没命中念「未上榜」),★ 比键时把榜行的 renamedFrom 一起铺进去 —— 仓库改名后不铺就会把"明明在榜"念成"未上榜"(用户收的默认:误念比缺念更糟) ★ 第三十五轮(10-13)这一条整条作废(用户指着屏上那一列说「去掉这个」,裁定「只删那一列,右侧那枚 ★ 照旧留着」):那一格连同它的派生一起撤 —— 优先级单值、renamedFrom 归一、FAV_ON_BOARD_PRIORITY、FAV_COL_ON_BOARD、FAV_OFF_BOARD_CELL 全部零出处(留入参就是死接口,favs 那套里有一条专门喂旧的那三档原料验它长不出那一格)⇒ 这一屏的形状现在只剩上面那一条律,屏上不再有「在日榜 / 未上榜」那个读数,收藏与榜面的关系只从「来自 <榜名>」那一枚出处牌读。 收藏不裁行、不设上限、不参与 LRU(10-13 裁定:与 repo / trans 那两张表故意不同 —— 按时刻裁等于"收藏久了被系统悄悄删掉"),那一行的五格读数由宿主派生(favSeedOf 四路:三榜切片行 → 全站高星那一批 → 榜史 seen → 详情缓存 repo 表),浏览器只递 {repo, action} 两个字段;形状细节与判据见 docs/design-spec.md §8.15。
  • 仓库详情按需取:点榜面条目的仓库名才弹出一张详情对话框,并在这一下点击去 api.github.com 要元数据 + README,把 GitHub 自己给的字段拼成一张结构化段表(sections[] 四段:项目是什么 / 热度与元数据 / 仓库自己怎么介绍它 / 中文摘要,★ 第十一轮起替代旧的那一整句 narrative;段序、段名、哪句摆在哪一段、哪句算小字全在宿主拼死,客户端只按 kind 摆),并探测仓库自己写的中文 README(★ readmeSource 五档:zh_default 默认 README 本身就是中文 / zh_file 仓库另写了一份中文 README(★ 第十五轮起这一档有两条路:根目录列表里命中 README-zh_CN.md 那类,或默认篇首屏那行语言切换里写着的相对路径命中(真机 docs/i18n/README.zh-CN.md 那一类,根目录压根没有)—— 两条路共用同一发正文请求,编排仍是 4 发封顶) / zh_section 默认篇是外文但整篇里嵌着一段中文小节(第十一轮新增,吃已经在手的那份正文,零额外请求)/ en_default 只有英文篇 / none 没 README)。 描述那一句若命中内置离线词表,会在「项目是什么」那一段里多一个块「中文描述(内置离线预译 · <日期>,不是现译)」,原文紧跟着另起一块照给;没命中而现译开关开着时,换成「中文描述(<这一行当初是谁译的> · <日期 时刻>)」(免费接口 / 百度 / 腾讯 / 阿里 / 模型现译 五选一,库里旧行还可能有历史档名 官方接口,§8.4),原文照样另起一块(译文不替换仓库自己写的那句)。
  • 描述列中文(内置离线预译表,lib/desc-zh.js):榜面与详情里的仓库描述,命中表里的就给一句人工预译的中文,没命中就只显示原文。三条口径: 离线(这份文件是死数据,零 import、零 fetch、零模型调用,dz-6 从源码钉住);带来源与时间戳(卡头与悬停都念「内置离线预译 · 2026-10-06」,界面不自己编日期); 原文改过就不译(命中判据是「仓库主键 + 原文与表里记的那一句逐字相同」,仓库把描述改了 ⇒ 静默退回原文显示,绝不拿旧译文指鹿为马)。 表由脚本生成、不是手抄(tmp/gen-desc-zh.mjs:src 那一列由解析器从真榜面逐字取出,中文那一列是人工写好再合并进去的),当前 73 条;★ 覆盖面会随时间衰减 —— 表只认整理那天在榜上的那些仓库,掉榜/新上榜的描述就是原文。 ★ 第二十二轮(10-08)起,榜面那一列不再只靠这张表:内置表没命中的那几行由每轮检查后的补译批次接上(现译那一路、同一张 trans 表、同一把逐字复用判据)⇒ 一列里从此可能两种来源并存, 所以落款跟着每一行走(悬停给「原文 + 这一行自己的来源 + 注」),卡头那句「描述中译为…」换成宿主按这一张榜算好的条数(内置预译 N 条 · 现译 M 条)。B 那三条口径一个字没动,表命中的行照旧不重发。 ★ 10-10 第三条裁定起,这一路吃的参与行变成两组:三榜那一批 +「全站高星」那一档开着时它那一批(同一张 trans 表、同一把逐字复用判据、同一份 12 发共享预算,榜面先吃饱)⇒ 那一屏的描述列从此也可能两种来源并存;关掉那一档就一行都不进(已攒的译文留着但不上屏)。"参不参与"这件事的出处只有一处(descZhRows),视图与批次两处都调它。 ★ 第三十三轮(10-13)起,"命中判据"也只剩一处:那一圈「内置优先 → 与库里那行原文逐字比对」从 descZhView 抽成导出的纯函数 descZhHits(rows, transRows) ⇒ {hits, counts},榜面读 descZhView 里的那一份、收藏读这一份 ⇒ 两侧一旦漂移,屏上就会出现"榜面有中文、收藏没中文"(你报的正是这一形)。★ 抽函数而不是复制粘贴:lib/favs.js 与 client.js 从此连比对的口径都不认(hc-23 拿四类判据字面 + 合成正样本 + import 名单三头钉住);「哪些行去排队补译」仍由 descZhRows 单独管,收藏那批行不进那个集合 ⇒ 抽函数没有把出网账抽多一根线。
  • 现译引擎五档(D,2026-10-06 第九轮加三档、同日第十轮扩成五档,lib/services/web-translate.js + lib/services/llm.js):内置表没命中的那一句描述(以及 README 英文节选的摘要),交给你在设置页选的那一档现译: 免费接口 = Google 网页版翻译(免注册免密钥,★ 不是官方授权接口,且这台机器直连不通、必须经代理)/百度 = 百度翻译开放平台通用文本翻译(AppID + 密钥,签名 MD5,境内直连可达)/腾讯 = 腾讯云机器翻译 TextTranslate(Version 2018-03-21、地域广州;SecretId + SecretKey,签名 HmacSHA1 v1,直连可达)/阿里 = 阿里云机器翻译通用版 TranslateGeneral(Version 2018-10-12;AccessKeyId + AccessKeySecret,签名 RPC V2 的 HMAC-SHA1,直连可达)/宿主模型 = 第八轮那一路(lib/services/llm.js,花宿主的模型额度)。默认落免费接口(用户裁定「两条都做,设置页选」+「与宿主模型并存,二选一」+「分段器并排五档」)。★ 三家云要不要花钱、有多少免费额度以官网计费页为准(这一轮没能复核到可引用的数字,所以界面上不念数字,只把注册入口摆出来)。五条口径五档共用: 只在点开详情那一刻、只译当前这一条(榜面永远零现译,一轮三发榜面照旧) ★ 第二十二轮(10-08,用户回「按C来」)改判这一条:现译发生在两处 —— 点开详情那一刻译当前这一条(原样)+ 每轮检查之后给榜面上内置表没命中的那几行补一批(用户三条裁定:「检查轮次后补」/「每轮 12 发 · 并发 2」/「复用「描述现译」这一档」⇒ 设置页不新增开关)。 ★ 改判的是什么时候发,不是发多少:读路径恒零发(打开面板 / 重开面板 / SSE 首帧一发都不派 ⇒ 界面永不"因为翻译而转圈"),配额严格按检查节拍花(出厂 60 分钟一轮,手动「重新取一次」也算一轮,一轮最多 12 发、同时在途 2 发、同一行失败 30 分钟内不再试);榜面那三发 GitHub 请求照旧(补译不打 github.com)。形状见 docs/design-spec.md §8.7; B 优先(表命中的行压根不派活,两个来源不会在同一屏打架); 三道源侧闸门(★ 第十一轮加两道、第十九轮补第三道,都排在派活之前:仓库自己写的描述就是中文 ⇒ 不派描述那一发;README 已经有中文 ⇒ 不派摘要那一发 —— ★ 第十八轮把这一句点名到三档:zh_default 默认篇整篇是中文 / zh_file 仓库另写的那份中文篇(根目录名或默认篇里的语言切换行指到的)/ zh_section 整篇里嵌一段达标中文小节,只有默认篇是英文(en_default)才译;none 由"没有节选"挡。★ 第十九轮(用户改判「这两种也算有中文」)补第三道 readmeZhOnScreen(节选):即便档名是 en_default,只要要派出去的那段节选里 CJK ≥ 8(中英混排篇,真机 thedotmack/claude-mem 9 字)或出现「中文」两字(中文篇在子目录没抓到、只剩那行语言切换字样)⇒ 摘要那一发也不派,self 段名跟着补那半句实话(「(节选里已有中文)」/「(这行写着有中文版)」)。★ 第三十轮(10-12,你那句「我开了摘要现译,这个点开没有翻译」)把这一道收窄成只认 cjk 那一支(api.js 派活那侧读 .via !== 'cjk'):「这行写着有中文版」是个推测,推测兑现的仓库档名本来就会落在 zh_file / zh_section(上面那道档名闸已经挡住),推测没兑现的(真机 debpalash/VoiceStudio:中文那份在根目录、库里那行又被 304 冻在 en_default)被它挡下来的结果就是"屏上既没中文、也没摘要"⇒ 派。⚠️ 段名后缀那两支照旧都给(那半句说的是关于这篇 README 的事实,与派不派活是两件事,这一轮第一次把两种用途分列)。★ 判节选不判档名:README_ZH_MIN_CJK = 20 那条一字未动(它管的是「默认 README 本身就是中文」这句档名敢不敢说,降到 8 会把只有一行切换标签的英文篇改名成中文);「日本語」不算中文、国名「中国」不算声明、英文 Chinese 不认(挡了就是删了用户在用的那一屏)。三道都在源上挡,不是译完了再挑译文。★ 第十五轮的第三道闸门不在这里,在那一路服务自己声明的 kinds() 里:免费 / 百度 / 腾讯 / 阿里只有翻译能力,「整理成一段简体中文摘要」那一路只派给 宿主模型 ⇒ 那四档连 enabled('readme') 都问不到,设置页那一行开关也跟着不摆 ★ 第十七轮(10-07)这一条被用户改判:那一发放回来了,五档都派两发(原话「我前面是有摘要现译的,你在哪一次改坏了,给我放出来」);kinds() 那道口与三道源侧闸门都还在,只是翻译四档现在也报 readme。保留的只有措辞:那四档给的是节选的节译,段名与设置页那句说明跟着档位走,只有宿主模型那档叫「摘要」); 落库复用(按「仓库主键 + 原文逐字相同」判,仓库改了描述就重译,绝不拿旧译文指鹿为马。★ 第十一轮把「换了引擎,旧译文照样复用」这一条钉成裁定:现行行为就是要的行为 ⇒ 零代码改动,只补判据与文档,落款署的是那一行当初的来源,不冒充新引擎);两档开关各开各的(描述出厂开、摘要出厂关,都关掉时那一屏与 C/D 之前逐字相同。★ 第十五轮:那两行不再是写死的两行 —— 摆几行由当前那一路自己声明的 kinds() 决定,载荷从 descOn / readmeOn / switchLabels 三格换成一张 switchRows[]。★ 第十七轮(10-07)改判后那份机制一字未动,动的是服务那份声明:翻译四档现在也报 readme ⇒ 五档都摆两行)。 ★ 选路只有一处(pickTranslator):没选中的那四路连"你开着吗"都不问,五路服务互相不知道对方在 ⇒ 不会变成一次点击发五发。 ★ 落款跟着那一行自己的引擎:换了引擎不作废旧译文,也不拿新引擎的名字盖它 —— 库里那行署它当初的来源(trans 表行内 engine 字段)。 ★ 额度分两本账:宿主模型 那一发不打任何 HTTP(走宿主连接);另外四发在插件的出网账里(同一份 net.js、同一档 15s 超时),但不吃 GitHub 那 60 次/小时(另四个域名)。 ★ 密钥的边界(第十轮把这一格从"只有百度一家"扩成三家 × 六格):密钥本体只参与摘要那一步,出网 URL 里只有各家的标识符 + 一次性数 + 签名 (appid/salt/sign、SecretId/Nonce/Signature、AccessKeyId/SignatureNonce/Signature);密钥不进 URL、不出网、不回显、不进日志, 界面上只看得到「库里已存(留空不改动)」那一句。★ 标识符能进查询串是翻译域的例外,GitHub 那一域默认零凭据(★ 第二十一轮改判那句"仍然零凭据":出厂 ghToken 空 ⇒ 与旧版一样一发凭据头都不带;填了才带一条 Authorization: Bearer,只进请求头、绝不进 URL,且这一把密钥与那三把走同一套回显闸门 PREF_SECRET_KEYS;cookie 那三类头全域仍禁,全程仍只读 GET)。 失败的话各说各的:模型那八档(开关没开 / 宿主没给模型 / 没设默认模型 / 超时 / 答错 + 回执原话 / 读不出中文 / 太长 / 没存下来)+ HTTP 那四路九档(多出的三档是 no_credential、http、bad_json —— 网页接口改了形状必须点得名,不许混进"没中文"),一律原文照给。
  • 语言过滤:可配一档语言(prefs.language,页面 slug 的小写形式),保存时就地 GET 一张周榜验 <title>,站点不认这个 slug 就拒收并说明原因。空 = 全站榜。
  • 出网方式:跟随系统(先环境变量 HTTPS_PROXY/ALL_PROXY/HTTP_PROXY,再 Windows 注册表的系统代理)/ 自定义地址(只认设置页那一行,形如 127.0.0.1:7897,只支持 http 代理的 CONNECT 隧道)/ 直连。默认 跟随系统 —— 这台机器上直连 github.com 会超时,而注册表里就写着 127.0.0.1:7897。
  • 设置:检查频率(1 / 3 / 12 / 24 小时)、榜单条数(525,默认 15)、事件保留条数(502000,默认 300)、详情缓存(★ 第十二轮立起、★ 第二十七轮(10-10 用户亲手)整行撤掉、★ 第三十一轮(10-12 用户再次亲手改判)摆回来:6 / 12 / 24 / 72 小时 四档分段器,出厂 24 小时,裁定原文「还是改成以前那种模式,默认缓存24小时,可以配置,不要用60秒这种」 ⇒ TTL 之内一发都不问(连验证器都不问),改档下一发详情就按新档判新鲜(getTtlMs() 现取现算,装配时锁死是第十二轮那笔账的形状),失败档那 5 分钟照旧不进设置页):那一档的存与废走的是同一条链的五个点(domain 那三个名字 + DEFAULT_PREFS 那格 + prefsRecord 声明 + clampPrefs 名单 + index.js 的 getTtlMs 接线与 prefsView 初始格 + api.js 的 400 校验 + hc-11 键表 + 设置页那一行与 hc-20 那条正则),缺一处就是第二真相;★ 那一段键从没真正消失过(第二十七轮只是让 open() 静默丢弃它 ⇒ 删格方向由 tmp/probe-schema-drop.txt 实测安全、域 version 恒 1、零迁移),本轮改回 optionalInt 声明把它收住(追加/恢复键一律 optional,requiredInt 那条 10-07 血案律照守),POST 脏档照旧 400 拒收(不像第二十七轮那一版走白名单丢弃 —— 它现在决定"这一问出不出网");替代物 DETAIL_RECHECK_MS(固定 60 秒防连点)整键删掉,hc-20 反过来钉「domain 那一侧一个字都不许认得它」⇒ 界面上多回一个控件、少一条出网承诺,语言过滤、出网方式、现译引擎(并排五档分段器,出厂「免费接口」;选中「百度 / 腾讯 / 阿里」任何一家时才多出一行那一家的两格(标识符 + 密钥,密钥框是 password)带「保存」/「清除」,并另起一行给出那家的注册地址(要注册才用得着,链接新开标签页、不带走面板))、现译开关行(★ 第十五轮改口径:摆几行由当前那一路服务的 kinds() 决定,不是客户端写死两行;★ 第十七轮(10-07)用户改判放回:翻译四档的 kinds() 现在也报 readme ⇒ 五档都摆两行(描述现译 出厂开、摘要现译 出厂关),那一行行名不变、"这一段是什么"跟着档位走 —— 翻译四档那句说明念「这一段是节译不是摘要」,只有 宿主模型 那档念「另给一段中文摘要」(domain.switchRowLabel);每行 {key,kind,row,label,on} 五格、客户端只念 key/row/label/on,点一下即存。真机那两屏 tmp/shots/68-r15-set-keyless.png / 69-r15-set-host-llm.png 是第十五轮那一版的读数(免费档只有一行开关),第十七轮放回后还没重拍 ⇒ 挂在 §9.3 那条走查清单上,要重启宿主才看得见新那两行)、GitHub 令牌那一行 + 「创建令牌」那一行(★ 第二十一轮新增,用户裁定「设置页加一个 GitHub token,配额抬到 5000/h」:它不在现译那一叠分段器里,是 GitHub 那一域的凭据、与翻译无关 ⇒ 单独两行,全部读 snap.github:框是 password + autoComplete:'new-password'、maxLength 与字段名来自那张派生表、密钥格 value 恒空(存过只把 placeholder 换成「库里已存(留空不改动)」)、库里存过才摆「清除」(点了只发 {ghToken:''} 这一格)、「保存」只在草稿 ≠ 库里那份时可用;下面那一行给 github.com/settings/tokens 那条网址(target=_blank rel=noreferrer,★ 与三家云同一条律:那句额度话不替 GitHub 承诺数字)。⚠️ 这两行还没在真机上看过,与第十七、十九、二十轮那几屏挂在同一条走查清单上),外加一张只读的「运行环境」表(最近那一发的传输路径 + 宿主能力位)。

它不是什么

  • 不是 GitHub 官方工具,与 github.com 无隶属关系;榜单是趋势页页面自己排的名次。
  • 不做 AI 解读(零 ctx.llm) —— 2026-10-06 第八轮由用户拍板改判为「默认零调用 + 句柄只许一个使用者」:现译只在点开详情那一下、只在开关开着的那一档发生。 ★ 同日第九轮再改一次:现译默认不再走模型 —— 出厂档换成免密钥的翻译接口,宿主模型降为设置页分段器里的一档(上面「现译引擎五档」那条;★ 第十轮那一档旁边又多了两家云,从三档变五档)。两次改判都没动这条铁律的另一半: ★ 第二十二轮(10-08)改判的是那一次的"什么时候发"(「只在点开详情那一下」→「详情那一刻 + 每轮检查后给榜面补一批」),这条铁律的另一半照旧一个字没松:句柄仍只许 lib/services/llm.js 一个使用者(新落点 lib/board-zh.js 只吃装配层给的 getTranslator(),认不到句柄),开关关着 / 引擎没就绪 ⇒ 两处都零发。 不发通知、不写会话日志、不动宿主定时器之外的任何东西照旧成立;要通知请用宿主自己的机制,本插件不代作决定。 真机口径(2026-10-05 第六轮为「描述译中文」跑过一次临时宿主 LLM 探针,跑完即撤、现已撤净):这台宿主的 ctx.llm 关不掉思考 —— 官方那两个关思考的字段被静默吞掉、reasoningEffort 看不出起作用,20 来字的译文照烧 209~318 outputTokens ⇒ 真要做现译只能默认关闭 + 从调用次数省。 10-06 01:16 那一轮把它翻案了:思考能关,走 reasoningEffort:'off' —— 同模型同题两发对照:outputTokens 260 → 12、耗时 1.9s → 0.9s、思考字符 1342 → 0(归零才算关掉,耗时和观感都不算判据); 顶层那两个官方关思考字段照旧传了不生效,因为适配器只认 reasoningEffort 这一个入口。★ 这句"还没有排期"也一并作废:10-06 同日第八轮就做了, 发的每一发固定 reasoningEffort:'off'(LLM_REASONING_EFFORT 单点在 domain)。 五发读数与两发对照、判据全在 docs/design-spec.md §9.4 / §9.4.1。

一个必须先说清的口径

数据源是 https://github.com/trending?since=daily|weekly|monthly 的页面 HTML,属于非官方接口:对方改版即失效。 (为什么不选 Search API:要 key,而且"趋势榜"是站点自己算的一张榜,API 复现不了你在 github.com 上看到的那个名次。为什么不选第三方镜像:多一层可用性风险,数据也不可追溯。)

第二个数据源只在点详情时才出现:https://api.github.com/repos/{owner}/{name}(+ /readme、必要时 /contents/)。它是官方 REST,字段稳定,但额度默认是匿名那一档:60 次/小时/IP(实测历轮每一发都回 x-ratelimit-limit: 60。★ 第二十一轮(10-07)改判那半句"硬的":设置页可以填一个 GitHub 令牌 ⇒ 详情那四发各带一条 Authorization: Bearer <token>,只进请求头(不进 URL、不回显、不进日志、不进快照,空白格等于没填、照旧匿名发), 官方文档口径带令牌是 5000 次/小时(★ 本机没有 GitHub 账号也没有令牌 ★ 10-10 只读对账改口:库里 ghToken 那一格非空(只报"非空 + 40 字",值不打印)⇒ 详情那两发带着 Bearer 在发;但那一档仍是零真回包 —— 历次真回包只见过 60,5,000 那一格从来没从 GitHub 头上落到本机,所以那一形状到现在还是合成的)⇒ 屏上那句「匿名配额 / 已认证配额 剩 N / 上限」的上限与那两个字的标签都由 GitHub 自己回的那一格决定:填了却被拒(撤销、拼错)就照旧念「匿名配额」,代理把那一格吞了就退回保守的 60 —— 宁可梦见 60,不可梦见 5000。★ 发数一发没多(一次点击仍 ≤4 发),而 github.com/trending 榜面那三发永远匿名(gh.js 连这一格的键名都不许认得)。 所以一次点击最多 4 发(元数据 1 + README 1 + 只在默认篇不是中文时补 根目录列表 1 + 中文文件 1;★ 第十五轮第二路没加这个数 —— 那一发中文文件正文照发,只是路径改从已经在手的默认 README 那行语言切换里抽,零额外请求,命中才发), ★ "隔多久才肯再问"这一格现在是三层叠起来(★ 第二十七轮 10-10 收成两层、★ 第三十一轮 10-12 用户改判回三层):① TTL(设置页那一档,出厂 24 小时) ⇒ 这一期内一发都不问,连验证器都不问;② 过档那一问走条件请求(元数据与 README 各带自家 If-None-Match,原样转发弱标 W/"…";验证器只存两格、不设长度上限,截断的钥匙永远换不回 304);③ 手动「重新取一次」裸发全量(?refresh=1,一个字都不喂 prev)。失败档 5 分钟(不进设置页),同人连点两下在途去重,界面还如实显示「这一小时还剩几次」。 ★ 出网账(第三十一轮改口的就是这一条):TTL 内点开同一个仓库 = 0 发;过档那一问若正文没变 = 2 发各回 0 字节、单发 ≈100ms、但配额照扣 1 —— 官方文档那句「304 不计入速率限制」被本机 9 发匿名探针推翻(§9.1 那张表),★ 这条实测正是"为什么不能每次点开都问"的依据(匿名档 60/小时下,每次点开都问会把一小时压成约 15~30 次点击;已认证那一档本机零样本,用户裁定「不测,边界如实登记」);⚠️ 代价也照实登记:不回源就不知道 README 改了,正文最长滞后 = 用户自己选的那一档。唯一一条 TTL 例外:库里那一行自称中文 README 那一档还没探完(zhProbed 缺或 false,第三十轮那半截结论)⇒ 过档那一问必须真出网重判,否则中文那一档要等满 24 小时才自愈、第三十轮那条修复当场白做。 两个时刻各有各的说话权:at 只在真拿到正文时推进、checkedAt 每问必推 ⇒ 那句落款念「正文取回于 3 天前 · 刚核对过」(那两截词来自 domain,客户端不造缺位符、相对时间仍由浏览器算,§8.10);★ 第三十一轮把「刚核对过」收窄成只在真核对过那一问才念(cached === true 时恒 false ⇒ TTL 命中那一屏只有第一截,屏上不许出现"第三截"那种东西)。⚠️ TTL 判的是 checkedAt(缺这格的老行回退 at)—— 判 at 会让"最省额度"那一类行(304 后 at 是刻意冻住的)每次都出网,那正好把用户要的东西反着做。★ 第十一轮的 zh_section 那一档不在这个数里加东西:默认篇是外文时,先在已经在手的那份整篇 README 里找中文小节(零额外请求,那条路实测 3 发封顶),找到了就不再往现译那一路派活;「仓库自己写的描述本身就是中文」(descSelfZh)同理;★ 第十九轮的第三道闸门同样不在这个数里加东西 —— 它吃的是要派出去的那段节选(/readme 那一发已经回来的字),既不许多打一发去猜路径,也不新增载荷键或存储字段 ⇒ 三闸门省的都是翻译那本账,GitHub 这本账一克没动。详情读的是仓库自己写的话(description 两路中文都没有时那句原样标「原文,未翻译」—— 开关关着、那一档发不出去、或接口答错了都落在这档),命中内置离线词表时多一句人工预译的中文(带来源与时间戳,原文照给,见上面「描述列中文」那条与 docs/design-spec.md §8.2),现译命中时同理(落款是「<这一行当初是谁译的> · <时刻>」,原文同样照给,§8.3 / §8.4)。 ★ 第二十二轮(10-08)起这本账有两处:详情那一路仍是「一次点击最多两发 = 描述 + 摘要」,榜面那一路新增「一轮检查后最多 12 发、同时在途 2 发、只补描述那一档」(用户裁定的额度闸门)。 ★ 10-10 起榜面那一路分成两组,但 12 发仍是共享的那一份:全站高星 那一档开着(prefs.allStarsEnabled === true)时它那一批行也进补译的参与集合,排序上榜面先吃饱、全站那批排在后面(两个 rank 不同轴:榜内名次 vs 全站名次)。真机口径(脚本回算,不是估的):库里那一批发 30 行,其中 2 行本来就在三榜可见切片上(所以旧版那两行有中文)⇒ 本轮新并入的参与行是 28 行,ceil(28 / 12) = 3 轮才补齐,按生效的 intervalMin = 60 ≈ 180 分钟。★ 这笔支出花的是翻译那本账(host_llm 那一路连 HTTP 都不打),GitHub 的 REST 与 search 两本账一克没动;关掉那一档 ⇒ 已攒下的译文仍躺在 trans 表里,只是不在参与集合里所以不上屏,重开立刻上屏且不重烧额度(那是这一档"开关"的真实代价形状)。 ★ 读路径恒零发 —— 打开面板、重开面板、SSE 首帧都只读库不算活 ⇒ "面板开合"这个动作一发都不花钱,配额严格按检查节拍花(出厂 60 分钟一轮,手动「重新取一次」也算一轮)。 ★ 第二十八轮(10-10)起,那两本账之外多出第三本,而且它是用户按下去才开的:详情弹框 self 段段名那一行右侧那三枚常驻按钮 —— 展开全文 = 1 发 GitHub(整篇裸取,一个字都不带验证器、不落库、也不受详情那一档 TTL 挡:那一发要的是正文,不是"问一次有没有变");译整篇 = 1 发 GitHub + 最多 40 发翻译/模型(段落边界分块、同时在途 2 发、到 MANUAL_LEG_MAX 闸就停手并把已跑的拼回去);整篇摘要 = 同一本账,但预算先扣 1 发留给末尾那一发汇总 ⇒ 块最多 39、汇总恒轮得到、总发数 40 封顶。★ 这三枚不受设置页那两个开关管(用户原话「不受参数设置控制」),但照吃就绪态与能力位:没选引擎 / 那家云凭据没填 / 宿主没给句柄 / 这一档不会摘要 ⇒ 置灰并说一句各自的话(四形四句,不许互相冒充)。⚠️ 上面那句「读路径恒零发」一字未动 —— 手动这一路是写(POST /api/repo/readme),只有按下去才出发,渲染期一个字节都不派。 闸门的闭嘴形状各有名字、各有判据:那一路没接(no_engine)/本地库不在(no_store)/开关关着(off)/引擎没就绪(unavailable)/账本读不出来(read_failed ⇒ 整轮作废,不是当新行重烧 12 发)/屏上全命中(nothing)。 ★ 第三十二轮(10-13)多出第四个写入口(POST /api/fav,那枚 ☆),而它是这本账上唯一一本"零出网"的:收藏那一刻的五格读数(显示名 / 描述 / 语言 / 语言色 / 星数)全部由宿主从本地四张表派生(favSeedOf 的查找序 = 屏上那几屏的顺序:三榜切片行 →「全站高星」那一批 → 榜史 seen → 详情缓存 repo 表),★ 第四路刻意读表而不是读 repoService.load() —— 后者会在 TTL 之外真问 GitHub 一发,而这一趟的出网账钉的是 0。四路都没有 ⇒ 那一行照落库,出处念「详情」、四格在屏上是 —("本机一个读数都没见过它"的实话,不是缺格)。这一路同时不派现译(★ 第三十三轮改口:那一屏的描述格摆的是本机已有的那一份中文 —— 内置预译或库里已付过额度的现译,命中判据吃榜面那同一个函数;「不派」这一半一个字没动,读它不花一分钱,也永远不欠一次请求)、不写 events(流水的判据是"榜变了什么")。 ★ 10-06 之后这里多出第二个出网账:现译开关开着且内置表没命中时,那一句会交给设置页选中的那一档(一次点击最多两发 = 描述 + 摘要;★ 第十五轮曾把翻译四档砍成只剩描述那一发,第十七轮(10-07)用户改判放回 ⇒ 五档又都吃满这个上限,那道能力声明 kinds() 与源侧闸门都还在(★ 第十九轮又补一道,见上面那条))。五档里只有 宿主模型 那一发不打 HTTP(走宿主自己的模型连接与额度); 免费接口 / 百度 / 腾讯 / 阿里 那四发是插件自己经同一份 net.js 出的网(代理仲裁与 15s 超时都不另建一套),打的却是另四个域名(translate.googleapis.com / fanyi-api.baidu.com / tmt.tencentcloudapi.com / mt.aliyuncs.com,白名单由 TRANSLATE_ENDPOINTS 派生成 TRANSLATE_HOSTS,判据不手抄清单) ⇒ GitHub 那一域的配额五档都不占(★ 第二十一轮之前那句写的是「那 60 次/小时」;现在那一域是"匿名 60 那一档,填了令牌则是按账号那一档",但翻译那四发一格都不占这件事没变),运行环境 与页脚那句配额说的还是 GitHub 那一头,跟翻译成没成是两条独立的线(别在文案里混成"配额用完了所以没译出")。判据与口径见 §8.3 / §8.4。 ★ 全程只读 GET 这条铁律一个字没松:腾讯云与阿里云那两路接进来用的是它们官方签名里能走 GET 的那一档(腾讯 v1 签名把参数放查询串、阿里 RPC V2 是查询串签名), 所以改判的是"翻译域的查询参数里允许出现厂商标识符"那一格,不是 method。★ 后半那句「也不是 GitHub 那一域的零凭据」第二十一轮就地改判(原句留着当历史):现在写的是「默认零凭据 —— 库里 ghToken 空着(出厂态)时那一域一发凭据头都没有,与旧版逐字节一致;填了才带一条 Authorization,只进请求头、绝不进 URL,且只给 api.github.com 的详情那一路」;cookie / client_secret / access_token 三类头全域仍然一律禁(判据 hc-7 按域收窄成三道硬界,逐条证伪见 §9.2 第二十一轮)。

探针实测的三件事决定了解析器的形状(完整读数见 docs/design-spec.md §9.1):

  • 每个数值 span 前内嵌约 700 字符的 <svg> ⇒ 锚点必须跨 </svg> 取文本,定长窗口会静默取空。
  • 未登录页每行都带 /login?return_to=… 的 star 按钮 ⇒ 仓库名必须从 <h2 起找,不然每个仓库都解析成 login。
  • ?since=bogus 不报错,逐字节返回日榜;语言 slug 不存在也只给 200 + 0 条 ⇒ 白名单与「空榜 / 无效语言」的判据(<title> 念没念语言名)只能守在宿主侧。

因此:

情况面板表现
某一榜本轮抓不到 / 解析失败该榜卡就地写「故障 · <原因>(显示 <多久> 前的上次成功数据)· 已连续 N 轮」,行数据冻结在最后一次成功轮,其他两榜照常
连不上 / 超时(传输类)先补发(同榜最多 3 发),仍不通则卡上多一条来源提示,按最近那一发的实际路线说:经代理 http://127.0.0.1:7897 未通 / 直连未通 / 配置坏到根本没出网(三种情况绝不并成一句「网络不通」);同时写明「下次自动检查 X 后」
代理地址填错 / 解析不出来记为配置错误(不补发、不静默回落直连),榜面冻结在最后一次成功轮,运行环境 · 传输路径 一行红点写明原因
语言 slug 站点不认记为配置错误(不是源故障),但仍然冻结该榜并写清原因;保存时直接 400 拒收
语言合法但这一档今天没榜合法空榜:ok=true + 「这一档今天没有上榜仓库」,不冒红点
条件请求拿到 304只推「最近取回」时间,榜面数据时间不动(304 只证明整页字节没变,"今日新增"是累计值)
点详情时 api.github.com 给 404 / 限额用尽 / 传输失败 / 配置坏四种各给一句话(REPO_ERROR_LABELS + 接口原话),榜面照常;失败行 5 分钟内复读同一仓库不再出网,免得把坏名字刷爆额度
详情在设置页那一档 TTL 内再点同一个仓库(★ 第三十一轮:那一档摆回来,第二十七轮的固定 60 秒窗口 DETAIL_RECHECK_MS 整键删掉;⚠️ 第三十轮那句落款第三截「· 60 秒内没再问 GitHub」跟着撤,词表回两格)载荷标 cached: true + ageMs,连验证器都不问、这一问 0 发出网 ⇒ 底部那句配额读数不往下走;落款只念第一截「正文取回于 <多久> 前」,revalidated 恒 false(这一问压根没核对过,念「刚核对过」就是谎);★ 唯一不受这一挡的成功行是 zhProbed 不是 true 那一类(见下一行的例外);重取走 ?refresh=1 —— 它绕过缓存且一个字都不带验证器(带着旧 ETag 去问就大概率换回 304 的老正文,那颗按钮写着「不走缓存」就会说谎)
点开详情、已过档且仓库一个字没改(★ 形状 B 自第二十七轮起在,★ 第三十一轮起这一支只在"过档那一问"才走到)照样出网 2 发、各回 0 字节(≈100ms,配额照扣 1),载荷 revalidated:true ⇒ 底部那句念「正文取回于 <上一刻> · 刚核对过」,正文沿用本地那一份、一个字没换;README 变了才走满 2~4 发;★ 没带钥匙却回了 304(中间代理 / 接口改版)⇒ 当场裸发重问一发,绝不把空正文端给界面;⚠️ ★ 第三十轮那道例外在第三十一轮升格成 TTL 的例外:库里那一行若自称中文 README 那一档还没探完(zhProbed 缺或 false —— 上一版把探测那一发超时/5xx 留下的半截结论连同整行一起冻住,用户每问一次都命中同一个「没有中文版」),freshEnough() 直接判假 ⇒ 这一问一个字都不喂验证器、裸发四发重判一次,探完才写回 true ⇒ 代价是一次性的,三问内回到 0 发(TTL 命中);⚠️ 那一格的口径不许写成"来过 probeReadme 一趟就算探完"(那是把同一个冻结换个地方继续冻),八形逐形钉(六 true 两 false)
三榜连坏节拍按 2^N 翻倍退避,指数封顶 4 轮、绝对封顶 4 小时;任何一榜成功即归零。(2026-10-05 真机改造前:启动抖动连坏三轮,未封顶的指数退避把下一轮推到 24 小时,面板一整天空着。改造后同一场景实测 backoffExp:1 → effectiveMs 顶到 4 小时,第三轮自愈)
宿主没有 ctx.storageDomain / 存储域 open 失败榜面照看,能力位与状态卡如实写「变化史留不下来」。绝不谎报存储在位

安装

⚠️ 当前状态:页签化 + 传输补发 + 插件内代理隧道 + 仓库详情(数据源与详情对话框)+ 描述列内置离线预译 + 模型现译(C)+ 现译引擎五档(D,第九轮三档、第十轮扩到五档并接上腾讯 / 阿里云)+ 自带中文探测与结构化段表(A,第十一轮)+ 详情屏撤废话与详情缓存时长可配置(第十二轮)+ 名次徽章分档(第十四轮)+ 节选与判据窗口分家 / 句子边界收口 / 摘要能力跟着那一路 / 语言切换行找中文 README(第十五轮,★ 其中「摘要能力跟着那一路」已被第十七轮用户改判放回)+ 回执带上厂商请求号 / 同屏一条失败句只念一次(第十六轮)+ 摘要现译放回来(第十七轮)+ README 有中文就不派摘要(第十八轮,闸门本就在)+ 屏上那段节选里已有中文也不派摘要(第十九轮,★ 同一轮"库里那条旧译文行删"那一件没做成** —— 删掉后被在跑的宿主写回,要等宿主关掉重删)+ 多份中文篇并存时挑简体那一份(第二十轮)+ 设置页 GitHub 令牌那一行 / 详情配额那句跟着 GitHub 自己回的那一格(第二十一轮,★ 这轮动的是文首那条铁律的"不带 key":改判为默认零凭据 + 填了只进请求头)+ 榜面描述列接上现译(第二十二轮,★ 这一列从此是「内置预译 + 每轮检查后补的现译」两种来源并存)+ 明星这一屏(第二十三轮:第七个页签 + 形状 B 薄快照 + 那一发的闸门与落库)+ 点「开」的那一刻默认拉一次(第二十四轮)+ 检查间隔之内已经成功取回过就不重发(第二十五轮)+ 全站高星那一档接上描述列现译(第二十六轮,★ 与榜面共享每轮那 12 发、榜面先吃饱)+ 详情改条件请求 / 固定 60 秒防连点 / 撤掉「详情缓存」那一档(第二十七轮,★ 本轮把「隔多久才肯再问」从"按设置页那一档"改成"每次点开都问、只问验证器";⚠️ 第二十七轮那两件事已被第三十一轮用户亲手改判:条件请求留下、"每次都问"换成"过档才问"、60 秒窗口整键删除)+ 详情弹框那三枚手动按钮:展开整篇 / 译整篇 / 整篇摘要(第二十八轮,★ 第一条由浏览器发起、当场花模型额度的写,也是「不受参数设置控制」那半句的落地)+ 面板选中态落盘:切走再回来还在原页签、原档位(第二十九轮,★ 只动浏览器半边 client.js —— 宿主 main 那个 keyed 席位切走就是整棵树重建,而选择态里躺着的东西不该进库、更不该进快照)+ 中文 README 那一档不再被 304 冻住 / 摘要那一发不再被"推测有中文"挡掉 / 60 秒防连点窗口命中那一屏有可见结果(★ 第三十轮,你那两问「1.我开了摘要现译,这个点开没有翻译;2.截图里写着有中文,为什么没有拉取到中文版」—— 修法是让库里那一行说自己"探完了没有":repo 表追加 zhProbed 那一格(口径 = 判定输入齐了才算探完),缺或 false ⇒ 下一问一个字都不喂验证器、裸发重判一次,探完写回 true ⇒ 代价是一次性的;另两处是闸门只认屏上真中文,与那句落款补第三截「60 秒内没再问 GitHub」;⚠️ 那第三截已被第三十一轮撤掉)+ 详情缓存那一档摆回来(默认 24 小时 / 四档可调)· 固定 60 秒防连点整键删除 · TTL 之内连点 0 发 · zhProbed 那半截结论不受 TTL 挡(★ 第三十一轮,你那句「我说还是改成以前那种模式,默认缓存24小时,可以配置,听不懂吗,不要用60秒这种」—— 这是你亲手撤销自己 10-10 那次撤档裁定的改判,不是新功能;落款第三截跟着撤、词表回两格,「刚核对过」收窄成只在真核对过那一问才念)+ 项目收藏:那枚 ☆ 三处入口 + 第八个页签「收藏」+ 第八张表 fav(★ 第三十二轮,你那句「增加一个项目收藏功能」—— 三条形状是这一屏的骨架:存的是收藏那一刻的快照而不是引用(星数与描述不随榜面刷新,所以表头念「那一刻」、卡脚那句 note 把这件事说白)⇒ 打开那一签与点那枚 ☆ 都恒零出网;「这一轮」那一格是宿主本地比出来的成品句(三榜 → 明星的优先级、单值、比键时把 renamedFrom 一起铺进去 ⇒ 改名后不把"在榜"念成"未上榜") ★ 第三十五轮整条作废(用户裁定「去掉这个」⇒ 那一列连同 domain 那四个名字、favView 的三档原料入参一起撤,屏上七列;这三条形状只剩两条,另立新立的那四读与判据出处见上面第三十五轮当前读数与本节第 419 行那条);那一行的五格读数由宿主派生(favSeedOf 四路读本地表,浏览器只递 {repo, action});收藏不裁行、不设上限、不参与 LRU)+ 收藏那一屏接上本机已有的那一份中文(★ 第三十三轮,你那句「为什么收藏过来的项目描述没有翻译的」+ 回「按 A 开工」:零出网被动上屏,★ 「这句中文该不该上屏」从此只有一处判据 descZhHits)+ 详情缓存那把尺只留一处(★ 第三十四轮:repo 表裁行键换成「最后一次问过 GitHub」的 repoAskedAt,TTL / 裁行 / list() 三处读同一个函数;同轮把内置表那个批取函数改名 builtinDescZhMap 消歧)+ 收藏那一屏撤掉「这一轮」那一列(★ 第三十五轮,你划界「只删那一列、右侧那枚 ★ 留着」⇒ 八列变七列,domain 那四个名字与 favView 的三档原料入参一并撤干净、不留死码)+ 全站项目检索那一屏(★ 第三十六轮,你那句「加一个全站项目检索功能」:第九个签「检索」+ 第十条路由 POST /api/search,★ 形状是零入库 —— 一次性载荷、切页签或重启就没了、不 broadcast,那一屏的中文只念本机已有的那一份;行尾那枚 ☆ 把「那一刻的三格」seed 随收藏一起存下(你的 B 案),而出处那一格从此与读数解耦),这几件已过 671 项用例(★ 口径:含那两条要真出网的;SKIP_LOCAL=1 下是 669 过 / 0 挂 / 2 跳;套件 16 → 17(★ 第三十二轮到 16,第三十六轮到 17 —— 中间那三轮都是"条数变、套件数不变"))(★ 第十三轮把基线从 356 推到 357(差的那一条是事故补的回归判据)、第十四轮推到 358、第十五轮推到 368、第十六轮推到 371、第十七轮推到 372、第十九轮推到 376、第二十轮推到 378、第二十一轮推到 391、第二十二轮推到 415、★ 第二十三轮推到 494、第二十四轮推到 504、第二十五轮推到 514、第二十六轮推到 521、第二十七轮推到 530、★ 第二十八轮推到 565(套件 14 → 15)、★ 第二十九轮推到 568(套件仍 15,差额 +3 全在 client 66→69)、★ 第三十轮推到 573(套件仍 15,差额 +5 分两套:repo 101→105 / client 69→70)、★ 第三十一轮推到 574(套件仍 15,差额 +1 只落 repo 105→106)、★ 第三十二轮推到 626(套件 15 → 16,差额 +52 分五套:store 47→57 / api 89→99 / client 70→77 / host-compat 21→22 / 新开 favs 24))(★ 口径更正:跑测器 test/_helpers.mjs 数的是用例(check)条数**,不是 assert 条数,旧文档写"项断言"是把这两件事混成一件了;10-07 10:0x 本机复跑:SKIP_LOCAL=1 下 354 过 / 0 挂 / 2 跳,那两条跳的是要真出网的口径(hc-17 与 wt-27);不带 SKIP_LOCAL 那一份是 355 过 / 1 挂 / 0 跳,挂的是 wt-27 免费接口真出网那一发回 HTTP 429;那是外部限流的读数,离线 354 不受影响,细节与归因见下面「测试」那节与 docs/design-spec.md §9.2)(★ 第十三轮(10-07,修完第十二轮那格 requiredInt 之后):基线推到 357 项、SKIP_LOCAL=1 下 355 过 / 0 挂 / 2 跳,逐套差值只在 store 39→40; 而第十二轮落地当天界面上是三榜全红「故障 · 存储不可用」——离线那一份满绿测不到那一发(假设施 open() 不跑 schema),见下面第十三轮那条与 §9.3 那条病历) (★ 第十四轮(10-07,名次徽章分档:前三名金/银/铜、第 4 名起中性,色值与兄弟插件 modelwatch 对表):基线推到 358 项、SKIP_LOCAL=1 下 356 过 / 0 挂 / 2 跳,逐套差值只在 client 53→54; 这一件只动浏览器半边** client.js(宿主半边 / 载荷 / schema 一字未动),界面上要等宿主重新加载那份 client 源(重载面板,不行就重启 dsh desktop);无头量了逐档计算样式与徽标 rect(tmp/probe-rank.mjs),但活宿主那一屏仍未截图) (★ 第十五轮(10-07,四件合并:节选与判据窗口分家 / 句子边界收口 / 摘要能力跟着那一路 / 语言切换行找中文 README):基线推到 368 项、SKIP_LOCAL=1 下 366 过 / 0 挂 / 2 跳(直跑 368 / 0 / 0),差值在 repo +7 / api +1 / llm +1 / web-translate +1,另两套(client / host-compat)条数不变、内容改判;这一件过真机(图 6870 + 第二路真回包 + 配额 55→51 那一屏四发),逐条读数见下面第十二件那条与 §9.3 第十五轮;★ 第十四轮欠的那张活宿主名次徽章屏仍未截 ⇒ 还挂在那条清单上) (★ 第十六轮(10-07,两件旧账收尾:vendorErr 把厂商请求号排在回执最前 / 详情同屏一条失败句只念一次):基线推到 371 项、SKIP_LOCAL=1 下 369 过 / 0 挂 / 2 跳(直跑 371 / 0 / 0),差值 repo 63→64、client 54→55、web-translate 28→29;证伪电池 tmp/r16-falsify.mjs 11 条 / 未抓到红 0 条;★ 这一轮没有真机截图,也不是"过了真机" —— 那两屏各要一个现场:请求号那一屏要一次真的厂商失败(要么用你库里的真凭据发坏签名,要么等你自己撞上),去重那一屏要 host_llm 档两路同时挂(本机模型是就绪的,我不动它)。逐条读数与边界见下面第十三件那条) (★ 第十七轮(10-07,用户改判第十五轮③「摘要现译放回来」):基线推到 372 项、SKIP_LOCAL=1 下 370 过 / 0 挂 / 2 跳(直跑 371 过 / 1 挂 / 0 跳,挂的仍是 wt-27 免费档真出网那发回 HTTP 429 —— 与本轮改动无关的外部限流),差值 api 56→57(新那条钉的是"说明句跟着档位走"),repo / client / host-compat / web-translate 条数不变、内容改判;证伪电池 tmp/r17-falsify.mjs 12 条 / 未抓到红 0 条,末行 [还原 ok],读数 tmp/r17-falsify-out.txt。★ 这一轮没有真机截图:那一屏要重启 dsh desktop 宿主才看得到(改的是宿主半边 lib/**,link: 挂载下浏览器半边重载不算),两屏(设置页两行开关 + 详情弹框「中文节译」那一段)挂在 §9.3 那条走查清单上,等你重启后截给我) (★ 第十八轮(10-07,你那条「README 有中文就不许译」):行为一字未改(那道闸 readmeSource === 'en_default' 自第十一轮就在,本轮把 zh_default / zh_file / zh_section 三档各自钉上能承重的现场 —— 旧形状摆在只开描述档的桩下等于没钉,被电池判出一条假绿);基线仍 372 项、SKIP_LOCAL=1 下 370 过 / 0 挂 / 2 跳(逐套与上一份同数,api 那条就地改判);电池 tmp/r18-falsify.mjs 7 条 / 未抓到红 0 条;真库存对账 tmp/probe-readme-zh-rows.txt 抓到一条旧行残留(alibaba/open-code-review 库里有一条 12:24 的 readme:keyless 译文,而它现在记 readmeSource=zh_file —— 那是第二路落地前那一版判成"英文篇"时发的;★ 闸门排在 translate() 之前,这种旧行读不出来也不会显示,我没动你那行库存)) (★ 第十九轮(10-07,你改判「这两种也算有中文,旧译文行删」):这是真行为改动 —— 新立第三道源侧闸门 readmeZhOnScreen(节选)(节选 CJK ≥ 8 ⇒ 中英混排篇;出现「中文」两字 ⇒ 中文篇在子目录没抓到、只剩那行语言切换字样),★ 而 README_ZH_MIN_CJK = 20 那条档名律一字未动(两条律分家:8 管"别派",20 管"档名敢不敢说");反面三条钉死(「日本語」不算中文、国名「中国 / 中國」不算声明、英文 Chinese 不认 —— 误挡一类就是删了你在用的那一屏)。基线 372 → 376 项、SKIP_LOCAL=1 下 374 过 / 0 挂 / 2 跳(差值 api 57→59 / repo 64→66);电池 tmp/r19-falsify.mjs 8 条 / 未抓到红 0 条(★ 首跑第 ③ 条挂在别人先炸的断言上 ⇒ 把反例拆成独立 check 才算验成,同族第八次)。旧行删过一次、又被在跑的宿主写回来了(★ 详见下面第十六件那圈 ④ 与「假读数」那两条):tables.trans["readme:alibaba/open-code-review"] 19:24 摘掉(回执 trans 9 → 8|其余各格逐字一致 ok、那一刻对账 readme:* 5 条全 en_default),19:26:37 宿主那一写把内存态整份落回文件 ⇒ 现在仍是 9 行 / 6 条,这一件没做成,要等你关掉 dsh desktop 再删。★ 我自己的假读数一并登记:动手前用 tasklist 过滤 dsh / electron 判"宿主没在跑",而它的进程名是 DeepSeek Harness.exe(镜像名里两个词都没有)⇒ 那个条件结构上抓不到它,判"宿主在不在跑"要按 CommandLine 匹配。本轮零额外出网(闸门吃已在手的那段节选),也没新增载荷键 / 存储字段(repo schema 未动)。⚠️ 没有真机截图:又是宿主半边 ⇒ 要重启 dsh desktop,两屏(那两类不再多出摘要段 + 日文篇照旧给摘要)与第十七轮那两屏一起挂在 §9.3 等你重启后截给我) (★ 第二十轮(10-07,你裁定「只做屏上有中文/那行写着有中文版,不猜路径」+「使用 README.zh.md 这种」):第一条 = 零改动(那种形状没法零请求识别,猜路径要加一发、撞 60 次/小时那条红线 ⇒ 保持不做);第二条 = 真行为改动(多份中文篇并存时旧写法两路各自 .sort() 取首个,'-'(0x2d) 排在 '.'(0x2e) 前 ⇒ 真机 thedotmack/claude-mem 挑中了 README.zh-tw.md 那份繁体,读数 tmp/probe-zh-link-shape.txt)。落地形状是一份优先档、两路共用:zhVariantRank(文件名) 出 0 明写简体 / 1 不带变体 / 2 明写繁体,比较器只此一处,pickZhReadme 与 pickZhReadmeLink 都挂它;三条边界各有反向用例(只排序不过滤(只有繁体时繁体照旧上屏)/切文件名词元不切路径不按子串/同档内仍按字面)。基线 376 → 378 条、SKIP_LOCAL=1 下 376 过 / 0 挂 / 2 跳,差额只在 repo 66→68(★ pickZhReadmeLink 那一圈条数不变、内容改判:旧断言把繁体钉成了规矩);电池 tmp/r20-falsify.mjs 9 条 / 未抓到红 0 条 + [还原 ok](★ 首跑第 ⑥ 条的植入顺手把大小写归一也丢了 = 一发变异动两维 ⇒ 改成单因再跑)。本轮出网 0 发、载荷与 schema 零增量。⚠️ 仍然没有真机截图:又是宿主半边 ⇒ 要重启 dsh desktop;那一屏是点开 thedotmack/claude-mem 后 self 段的路径念 docs/i18n/README.zh.md(★ 库里它那行 at=10-06 08:42 早于第二路,所以不能拿旧库存当"验过"),与第十七、十九轮那几屏挂在同一条清单上;第十九轮那件"旧行删"这一轮复跑对账照旧 6 条(宿主还在跑)) (★ 第二十一轮(10-07,你问「匿名 60/h ⇒ 一小时最多 15 个仓库,能不能提升?比如设置页加一个 GitHub token」+ 对方案点头「可以」):这一轮动的是文首那条铁律的一半 —— 「对 github.com / api.github.com 全程只读 GET:不带 key」改判为「默认零凭据;填了才带一条 Authorization: Bearer,只进请求头、绝不进 URL;只给 api.github.com 的详情那一路,榜面那一路恒匿名」。只读 GET / 不 POST / 不下载 zip / 不 clone 一个字没松,发数一发没多(仍 ≤4 发)。配额那一格的上限与「匿名 / 已认证」那两个字的标签一起跟着 GitHub 自己回的 x-ratelimit-limit 走:填了却被撤销 ⇒ 照旧念「匿名配额」;代理吞了那一格 ⇒ 退回保守的 60(宁可梦见 60,不可梦见 5000);客户端旧那句 || '匿名配额' 的兜底整段删掉(同一屏不许有第二个真相)。★ 它同时是"第四把密钥":ghToken 并进 PREF_CRED_FIELDS 那张派生表 ⇒ schema / clampPrefs / publicPrefs / POST 白名单 / hc-19 五处一处手抄就红(store 那条"新增键必须 optional"的第十三轮律照守,域 version 仍 1、零迁移)。基线 378 → 391 条、SKIP_LOCAL=1 下 389 过 / 0 挂 / 2 跳(差值 repo 68→76 / api 59→61 / client 55→57 / host-compat 20→21,store 条数不变、两条内容改判);电池 tmp/r21-falsify.mjs 16 条 / 未抓到红 0 条 + [还原 ok](去向 6 / 读数 4 / 派生 4 / 接线与界面 2;★ 同一个"令牌进 URL"的植入钉了两次 —— 行为侧 + 静态侧各红一次)。★ 诚实两条:① 5000 那一形状本机零真回包(没有 GitHub 账号,历轮每一发都是 60)⇒ 它是官方文档口径、夹具里标注为合成,真机上要读的是那两个字的标签换没换而不是那个数;可验的那半是"填一个坏令牌 ⇒ 那句必须仍念『匿名配额』"。② 本轮零真出网、没截屏,且没动你的 prefs、没替你填令牌;那两屏(设置页新增那两行 + 详情弹框那句配额)与第十七、十九、二十轮一起挂在 §9.3 等你重启 dsh desktop 后截给我) (★ 第二十二轮(10-08,你那张截图 +「我开了翻译,为什么这些没有翻译」+「按C来」):现场是设置页「现译引擎=宿主模型 / 描述现译=开」,而日榜那一列全是英文、卡头还念着「描述中译为内置离线预译 · 2026-10-06」—— 因为旧口径把现译只派给"点开详情那一刻",榜面永远零现译。★ 这一轮把那一列改成两种来源并存,三条口径按你的裁定原话落地:「检查轮次后补(推荐)」(补译只挂在检查服务那一次 update 之后 ⇒ 读路径零发:GET /api/snapshot 与 SSE 首帧一发不派,面板不会因为翻译而变慢;补成真了才推第二帧)、「每轮 12 发 · 并发 2(推荐)」(常数只在 lib/domain.js,同仓库三榜同现只烧一发额度)、「复用「描述现译」这一档(推荐)」(设置页一行都不加,开关关着 ⇒ 榜面这一路零发)。B(内置离线预译)优先级一个字没松;界面逐行念它自己的落款(两种来源说的不是一件事,不许拿卡头那句套每一行),卡头念宿主按这一张榜算好的整句,另加一句只在四格同时成立才非空的「现译这一路这会儿发不出去」;失败冷却只在进程内存、runner 一个字不写库(落库归 translate() 自己)。基线 391 → 415 条、SKIP_LOCAL=1 下 413 过 / 0 挂 / 2 跳(差值新开 board-zh 19 + api 61→65 + client 57→58,另两圈条数不变、内容改判:api 那条 hits 形状、client-47 的行内落款;★ 设置页那句 TRANSLATE_COMMON_NOTE 改了文案而判据是从 domain import 的 ⇒ 测试面零改动,这就是"不许手抄句子"那条律在兑现);电池 tmp/r22-boardzh-falsify.mjs 25 条 / 未抓到红 0 条 + [还原 ok]。★ 首跑有两条没红,两条都登记:拆掉单闸那发让 busy 用例挂在没释放的 gate 上(顶层 await 不结算 ⇒ 套件不打印 ⇒ 电池拿不到失败信号,判据自己补了 200ms 竞速才响),另一发把分隔符改成无条件摆(只是多一个「 · 」,没有任何断言在乎 ⇒ 换成"界面自己数条数"这种真变异)。⇒ "漏网"有两种:没判据,和判据在但拿不到失败信号。 载荷只把 descZh.hits 的值从「一句译文」升成 {zh,via,label,note,src} 并新增 heads/liveNote,version 仍 1、零迁移。本轮出网 0 发(所有补译形状吃假 translator),⚠️ 没截真机屏:动的还是宿主半边 + client.js,而本插件在宿主里是 github: 复制副本(改源码不即时生效)⇒ 本机已把六个文件覆盖进那份副本(覆盖前的原文件备份在 tmp/host-copy/r22-before/),剩下的只有重启 dsh desktop + 硬刷新面板;那两屏(榜面出现带「现译」落款的那几行 + 现译发不出去时榜面上那一句)与第十七、十九、二十、二十一轮一起挂在 §9.3 等你重启后截给我。你的 prefs 与库存行一个字没动) (★ 第二十三二十七轮(10-0810-10):四件功能 + 一次撤档 = 明星这一屏(形状 B)/点「开」的那一刻默认拉一次/检查间隔之内已经成功取回过就不重发/「全站高星」那一档接上描述列现译/★ 第二十七轮详情改条件请求(用户那句「只有有变更时才重新获取,没有变更还是用本地缓存的」+「按你推荐的 B」)并把「详情缓存」那一档整个撤掉(裁定原文「撤掉这一行,改成固定 60 秒防连点」)。逐轮读数、差值、证伪电池与病历都在下面「测试」那节(基线 415 → 494 → 504 → 514 → 521 → 530 项;电池 8 + 14 / 9 / 9 / 9 / 13 条各拿到全部失败信号),这里只记三条口径级的账: ① ★ GitHub 文档那句「304 不计入速率限制」被本机 9 发匿名探针推翻(tmp/probe-detail-304.txt,零凭据、零落库)⇒ "每次点开都问"的真实代价按次数计而不是按字节计,匿名那一档一小时约 1530 次点击到顶;已认证那一档(5,000/小时)本机零样本,按第三条裁定原文「不测,边界如实登记」,不写成"验过"; ② ★ 那两个时刻不合并成一格:at = 上一次真拿到正文(两发都 304 就沿用库里那刻)、checkedAt = 上一次问过(每问必推,含 304)⇒ 界面那句「正文取回于 3 天前 · 刚核对过」两截各有出处(先例是 state 表的 at / lastFetchAt,§8.10 那张表逐格写了"能说什么 / 反例"); ③ ★ 撤一格偏好要沿一条链撤五个点(domain 那三个名字 + DEFAULT_PREFS + prefsRecord 声明 + clampPrefs 名单 + index.js 的接线与 prefsView 初始格 + api.js 的 400 校验 + hc-11 键表 + 设置页那一行与 hc-20 那条正则)⇒ hc-20 当时扫的是"代码位一处都不许认得那个撤掉的键",留一条"读得到但摆不出来"的库存就是第二份真相;删格方向由 tmp/probe-schema-drop.txt 实测安全(未声明的多余键被 schema 静默丢弃)⇒ 零迁移、域 version 仍钉 1。⚠️ 第三十一轮把这一条验成了双向:摆回来走的是同一条链、五个点反向,一处不落(hc-20 那条正则因此从"认不得那个键"翻成"认得那条 TTL 链 + 认不得 DETAIL_RECHECK_MS")—— 链是同一把,方向不挑人。 ★ 10-10 用户重启 dsh desktop 后走完第二十六轮那四步并回报「全部符合预期」(⚠️ 口头读数、无截图;ceil(28/12)=3 轮 ≈180 分钟那个完整读数没等满)⇒ 那一屏逐轮变中文的形状、关掉退回原文而 trans 表不删、只有全站那一档欠账时榜面不念那句故障话,三条各对上一条活宿主读数;⚠️ 第二十三二十五轮那三屏 + 本轮那一屏四读(设置页那一行没了 / 那句「正文取回于 …· 刚核对过」/ 60 秒内连点 0 发 / 那颗按钮真的重新出网)仍挂 §9.3 —— 本轮动的是宿主半边 index.js + lib/** 与浏览器半边 client.js ⇒ 要你再重启一次才看得见;我不替你重启、没动你的 prefs、没动库存行、也没替你点过详情弹框。⚠️ 那四读里的第一读(「设置页那一行没了」)与第三读(「60 秒内连点 0 发」)已被第三十一轮改判 ⇒ 那两读从此作废,改读「那一行摆回来且能改」+「TTL 内连点 0 发、配额读数不动」,见本轮那条。 (★ 第二十八轮(10-10,你那条「1.加一个按需展开,下次点开支持重新加载README,最好是加个按钮;2.加几个按钮,英文文档支持点击翻译和对整篇文档生成摘要,……不受参数设置控制」,附 cathrynlavery/diagram-design 那张详情截图):详情弹框 self 段段名那一行右侧多了三枚常驻按钮(展开全文 / 译整篇 / 整篇摘要),三条裁定落地成 「分块跑完整篇 + 熔断」+「存结果 + 原文指纹」+「常驻,不该点时置灰并说明」。 ★ 立论前提是整篇早就下载完了(1,492 字是在落库之前砍的)⇒ "全量加载"在出网侧零增量,代价全在存储与载荷,所以整篇正文一个字都不入库、每次动作自己裸发那一发(★ 一个字都不带验证器:带了就大概率换回 304,而 304 的正文是 0 字节,那一屏展不开 —— 与第二十七轮那颗「不走缓存」的按钮同一个坑)。 ★ 手动绕的是设置页那两个开关,不绕就绪态与能力位:lib/services/llm.js 的 enabled() 因此从两行改成三行(第一行 MANUAL_KINDS.includes(kind) ⇒ true),少了那一行 readmeFullZh 就会被 llmDesc 那个设置页上根本不存在的开关管住;免费四档 SERVED_KINDS 补 readmeFullZh 但不声明摘要 ⇒ 那枚在免费档置灰,那句是「这一档只会翻译,不会摘要」而不是「开关没开」。 ★ 一趟只落 trans 一行:分块那几发恒 persist:false(27 行分块会把榜面那两路的复用行挤出 TRANS_MAX=200),src 存的是整篇指纹(sha256 前 16 位 + ':' + 字数)而命中判据「主键 + src 逐字相同」一个字没改 ⇒ README 换版本、旧译文自动作废;整篇译文超 MANUAL_FULL_ZH_MAX = 30,000 字整份不存(截一半的"已存"是假话)、schema 与域 version 照旧 1、零迁移。 ★ 新增 POST /api/repo/readme 是第八条路由、第四条被回环闸门拦下的,也是第一条由浏览器发起、当场花模型额度的写(最多 40 发出网 ⇒ 它自己在路由上标 loopback:true,不许只靠"是 POST 就闸"那条顺带规则);结果走载荷那一整格 manual({section, runNote, actions, sections},命名统一吃 kind)不走客户端 state ⇒ 关掉弹框不丢。 基线 530 → 565 项(口径沿用从前:含那两条要真出网的,=563 过 + 2 跳)、套件 14 → 15、SKIP_LOCAL=1 下 563 过 / 0 挂 / 2 跳(过的那一边净 +35:新开 full-readme 19 + repo 96→101 + api 83→89 + client 63→66 + llm 19→20 + web-translate 28→29,store 47 条数不变、就地补断言;两个来源回算同值,逐套与全文 ^ok 各数一遍); 电池 tmp/r28-manual-falsify.mjs 15 条 / 未抓到红 0 条 + [还原 ok] 4 个文件跑完逐字节等于进来时。★ 首跑两条"全绿 = 判据空跑"都登记(同 r22 那条律:漏网有两种):指纹那条的第二趟换了新库 ⇒ old 恒为 null、变异体与原判据走同一条路(改成同一副替身改正文 + 复用同一副库);展开覆盖两块那一条的夹具恰好与段表同序 ⇒ "按下标"与"按 kind"等价(夹具改反序 + 补一条段内位置断言)。 ★ 本轮抓出的不是回归、是一处隐式耦合:full-readme.js 里 runOnce 落库前自己小写、readRows 却把保留大小写的键交给表,靠 lib/stores.js 内部再归一一次 ⇒ 生产没坏,但同一张表的键形状有两处出处;是冒烟那颗不做归一的替身表把它照出来的(tmp/r28-smoke.txt)。⚠️ 它没进电池:真表会归一 ⇒ 两种写法在真设施上逐字等价,拿它做变异只会得到假绿,如实登记为等价改动。 ⚠️ 收尾那一遍另修三处台账自身与文案的不实(都在盘上回算过,不是顺手改字):① 那三条新写的详情判据短号撞了既有的三条(client-56/57/58 各出现两次;全名不重 ⇒ 跑测器与 pass 66 都看不出,但本仓指判据认的是短号)⇒ 改号 client-64/65/66、电池四发期望串跟着换、整把十五发重跑(红数逐发与撞号前相同、实名变了:⑮ 那九条是 client-41/43/45/50/51/53/55/57/64,其中 client-57 是第二十一轮那条配额句 ⇒ 三枚按钮的形状与段表直通是同一块地基);撞号前那份留在 tmp/r28-falsify-out-before-rename.txt。② 详情载荷出边界那格 README 一直写着第十一轮的 21 键 ⇒ node -e 现算钉回 23(挂上 manual 那一整格是 24,且只在 ok:true 那一支)。③ GH_TOKEN_REGISTER.quota 那句里「本机没有 GitHub 账号可验」是把本机状态摆进通用 UI,且已被 10-10 盘上读数证伪一次 ⇒ 撤掉那半句(判据吃的是常量不是手抄句子 ⇒ 零用例改;改完全量重跑同数:15 套 pass 563 / fail 0 / skip 2,第二来源 ^ok 563 同值,读数 tmp/rerun-r28-postfix.txt)。 ⚠️ 本轮零真出网、零截图:19 条编排用例吃的都是合成正文与替身翻译,真机欠账两条挂在 §9.3(① 展开那一发真的不带验证器 —— 活宿主上看一次 GitHub 回 200 而不是 304;② 免费档那枚「整篇摘要」置灰的话在屏上念得出来)。你的 prefs、库存行、dsh desktop 一个字都没动、没替你重启) (★ 第二十九轮(10-12,你那条「切换了tab后,右侧面板选择的东西就没了」):面板选中态落 localStorage(三枚 id:tab / starsView / starsSort)。 ★ 定性靠宿主安装包的盘上行号,不靠猜(tmp/host-asar.mjs 从 app.asar 只读抽出三个包到 tmp/host-asar/)⇒ 这是两条独立的根因:路 1 = 插件内切签,client.js 那一片条件渲染换签即卸载旧卡片,而全插件只有 StarsCard 带内层选择态 ⇒ 切一次签,明星那一屏的视图档与排序档回第一档;路 2 = 切宿主面板再切回,dsh-client-ui-layout/lib/client.js:118 把 main 做成 keyed 席位(entryKey = activePanelId)、dsh-client-ui-renderer/lib/client.js:1153-1156 只渲染 options.key === entryKey 的那一条 ⇒ 整棵 GhTrendingPage 重建,而 keepMounted 那条保活(dsh-client-ui-sidebar-right/lib/client.js:5522)只给右侧栏 tab 席位,本插件走的 sidebar.panellist + main 不在其上 —— 不是宿主疏漏,是分席位。 ★ 形状:只落 id、生效档在渲染期现推。读回走单点 pickOption(名单, 存的 id, 出厂档):认「在册且未禁用」(关掉那一档时库里那份旧 id 自动回落名单第一档,与「关掉把人送回第一档」共用同一处判据,不另立一条);不在挂载时一次定(首帧没有载荷 ⇒ 那一刻会把存的那一份判成"不在册",载荷到位也回不去,电池第 ⑧ 发钉的就是这一形);读写各包一层 try/catch(隐私模式 / 配额写满 ⇒ 界面照旧在内存里用,与宿主 README 自己那句「存储失败时,当前布局仍可在内存中使用」同口径);键名 ${PANEL_ID}.ui.v1 跟着载荷的 panelId 走(不手抄,client-68 ⓪ 两条断言)。 ★ 明确不落盘的三样:设置页那份草稿(proxyUrl 是草稿态、点「保存」才发,落盘等于把"未确认的输入"变成"下次自动用它")、详情弹框那一份(重开白发一发出网)、四把密钥(client-68 ⑤ 用 domain 派生的 PREF_SECRET_KEYS 钉「存串里一个密钥键名都不许出现」,其余偏好键也一律不进)。 基线 565 → 568 项(套件仍 15、SKIP_LOCAL=1 下 566 过 / 0 挂 / 2 跳,过的那一边净 +3 且全部落在 client 66→69,其余十四套逐套同数;两个来源各数一遍又对上:全文 ^ok 566 / ^FAIL 0 / ^SKIP 2,另 git diff -U0 -- test/ | grep -c '^+check(' = 3 = 净差值); 电池 tmp/r29-ui-state-falsify.mjs 10 条 / 未抓到红 0 条(红总数 12:④ 与 ⑧ 各红 2、其余各 1)+ [还原 ok] client.js 跑完逐字节等于进来时。★ ⑨ 首跑「全绿 = 判据空跑」并登记:那一发改的是 UI_KEY 字面量,而用例读的 UI_KEY 来自同一份导出 ⇒ 两侧一起动、判据看不见(漏网第一种:判据吃被测常量本身),补 client-68 ⓪「键名跟着载荷 panelId」两条后才有失败信号。★ 等价变异 1 条如实登记:pickOption 里 arr[0]?.id ?? fallbackId 改成直接 fallbackId —— 三个调用点的出厂值与名单第一档逐字相同,抓不到红。 ★ 一处既有判据改判(不是回退源码):client-62 ③″ 旧写法是硬塞 view='allStars' 去验「开关关着却停在那一档 ⇒ 退回原文」,而落盘之后这一形成了每次重挂都会遇到的输入、被名单校验挡掉 ⇒ 改判为「关掉 ⇒ 回落名单第一档、列数跟着回落、那一枚照旧灰着摆着」;「客户端不许自己拿 transRows 补中文」那半仍由同条的 ②③③′ 三头钉着。 ⚠️ 本轮零真出网、零截图,且只动浏览器半边 client.js(index.js 与 lib/** 一字未动)⇒ junction 挂载下不用重启 dsh desktop,刷新面板即生效(本机对账:宿主五个 DeepSeek Harness 进程同为 10-12 08:50:10 起、client.js 09:21:29 落盘 ⇒ 现在跑着的那一份还是旧的,刷一次就是新的);真机欠账一条挂在 §9.3(切走宿主面板 / 切签再回来还在原页签与原档位 + 禁用存储时界面照旧)。你的 prefs、库存行、dsh desktop 一个字都没动、没替你重启) (★ 第三十轮(10-12,你那两问「1.我开了摘要现译,这个点开没有翻译;2.截图里写着有中文,为什么没有拉取到中文版」+ 追问「多点几次详情会重新去 GitHub 拉取,并没有缓存 24 小时」):这是第一轮"修 bug"而不是"加功能",三处落点与三条定性(全文取证在 spec §8.13): ★ 定性一(缺陷):中文 README 那一档被 304 冻住 —— 第二十七轮抽 probeReadme 时那句注释写的是"判定输入就是 README 正文,正文没变 ⇒ 结论不会变",这句漏了前提:结论还依赖插件自己的探测走到哪一步。真机 debpalash/VoiceStudio 的现场是「中文篇那一发超时 ⇒ 库里落下 en_default 这半截结论 + 两把验证器齐着 ⇒ 此后每一问都 304、整条探测跳过 ⇒ 永远翻不出中文」(tmp/r30-probe-zh-file.mjs 走产品函数两趟复现:第一趟 4 发裸取能翻对,第二趟 2 发全 304 就冻住了)。修法只有一条形状:让库里那一行说自己"探完了没有" ⇒ repo 表追加 zhProbed: optionalBool(追加键一律 optional、域 version 恒钉 1、缺格的老行与 false 同义 ⇒ 零迁移),load() 的 prev 闸门多一条 ⇒ 代价是一次性的(多两发),三问内收敛,不是"从此每问四发"。⚠️ 口径不许写成"来过 probeReadme 一趟就算探完"(那是把同一个冻结换个地方继续冻)⇒ 八形逐形钉(六 true 两 false),电池 ② 打掉这一条时两条判据一起红,是本轮最重的一发牙。 ★ 定性二(缺陷):摘要那一发被一个推测挡掉 —— 第十九轮那道闸门认的是 cjk(节选里真躺着中文)∪ lang(那行写着有中文版)。lang 那一支在派活这一侧从不起作用(推测兑现的仓库档名会落在 zh_file / zh_section,上面那道档名闸已经把它挡在那儿了),它唯一生效的现场恰恰是推测没兑现那一种 ⇒ 挡下来就是"屏上既没中文、也没摘要",而用户开了开关、点了详情、什么也没拿到(真读数:那 1,600 字节选里 CJK 只有 7 个)。⇒ 收窄成 .via !== 'cjk';⚠️ 段名后缀那两支照旧都给(那半句说的是关于这篇 README 的事实,与派不派活是两件事 —— 这一轮第一次把同一个 via 的两种用途分列,电池 ⑦ 钉的就是"顺手把段名也收窄"那一发)。 ★ 定性三(不是缺陷,是没有可见结果):「为什么不缓存 24 小时」那一档是用户 10-10 亲手裁定撤掉的(4a80fd3,裁定原文「撤掉这一行,改成固定 60 秒防连点(推荐)」),且 60 秒内实测 0 发 —— 那一屏旧落款只念「正文取回于 刚刚 · 刚核对过」,被读成"又拉了一遍"。⇒ 补第三截「60 秒内没再问 GitHub」,只认载荷 cached;那个秒数在 domain 按 DETAIL_RECHECK_MS / 1000 现拼(hc-20 两头钉:domain 必须现算、client.js 代码位不许出现那个数)。⚠️ 这一条的定性已被第三十一轮推翻:10-12 那一问不是"缺一句可见话",而是用户不要那个 60 秒形状 ⇒ 第三截整截撤掉、DETAIL_RECHECK_MS 整键删;定性一与定性二(zhProbed 那一格与摘要那道闸门)照旧成立,且 zhProbed 在第三十一轮从"304 复用的例外"升格成"TTL 的例外"。 基线 568 → 573 项(套件仍 15、SKIP_LOCAL=1 下 571 过 / 0 挂 / 2 跳,过的那一边净 +5 分两套:repo 101→105 / client 69→70,另四处(api 那条整条替换、hc-11 词表、hc-20 的 prev 字面、repo 那条落库判据补一句)条数不变、就地改判;三个来源各数一遍又对上:逐套加总 571 = 全文 ^ok 571,另 git diff -U0 -- test/ 数 check( = 新增 6 删 1 ⇒ 净 +5;⚠️ "净差值 5"与"新增 6"是两个口径、不许混用); 电池 tmp/r30-zh-probed-falsify.mjs(圈 四个源:lib/services/repo.js / lib/api.js / client.js / lib/domain.js)11 发 / 未抓到红 0 / 等价变异 1 + 末行 [还原 ok] 4 个源文件跑完逐字节等于进来时(③「白名单漏那一格」一下红五条 = 那一格的四条律共用同一个存储出口)。★ 两条病历登记:① ⑪ 首跑红 3 条而不含目标那条(那条落库判据只钉 etag 与 checkedAt,schema 漏格在它眼里不可见)⇒ 补一句断言后整把 11 发重跑、红数逐发核对(③ 4→5、⑪ 3→4);② ⑤ 全绿 = 等价变异(readmeFieldsFromPrev 写死 true 与照原样带在盘上不可分辨,因为 load() 只把探完的行递进来)⇒ 不新增判据也不放宽电池。⚠️ 踩到跑测器自己的口径:SKIP_LOCAL=1 是按用例名含「真机」二字跳的 ⇒ 新那条最初叫「★★ 真机形状回归」被静默跳过(pass 104 / skip 1,全绿而不报错),改名「★★ 冻结那一形自愈(10-12 那两个读数)」后才真跑(它吃真夹具 + 合成档,零出网)。 ⚠️ 本轮产品侧零真出网、零截图(取证 10 发全匿名、走系统代理,没吃用户令牌:curl 抓那三件 + 重放 4 发,r30-probe-zh-file.mjs 走产品函数两趟 6 发),且动的是宿主半边 lib/domain.js / lib/services/repo.js / lib/api.js 三份 ⇒ junction 挂载下要重启 dsh desktop 才装得上(client.js 刷新面板即可,但它只是第三截的显示层);四条判定性走查挂在 spec §9.3(⚠️ 走查前别清库、也别改偏好 —— 那两个 bug 的现场就在库里那一行)。另登记一处本轮没修、也没有判据的真隐患:lib/stores.js:213-214 按 at 裁 REPO_CACHE_MAX=120 行,而 304 命中时刻意冻住 at ⇒ 越省额度的行越先被删、删了退化成裸发全文(本机库里 13 行,量不到、拿不到失败信号)⇒ ★ 第三十四轮已修(裁行键换成「最后一次问过 GitHub」并复用 TTL 那把尺 domain.repoAskedAt,两条行为牙落进 test/store.test.mjs,形状与判据分层见 spec §8.17;⚠️ 第三十一轮那句"改回 TTL 后更难咬到"随之作废 —— 现在有牙,不再依赖真机现场)。你的 prefs、库存行、dsh desktop 一个字都没动、没替你重启) (★ 第三十一轮(10-12,你那句「我说还是改成以前那种模式,默认缓存24小时,可以配置,听不懂吗,不要用60秒这种」):这一轮不是加功能、也不是修 bug,是用户亲手撤销自己 10-10 那次撤档裁定的改判回退(4a80fd3 删前那份是尺子:档位 / 接线 / 校验 / 界面四处逐字落回,不凭印象重写)。⚠️ 归因先记在自己账上:10-12 那两问(「为什么不缓存 24 小时」)我按"缺一句可见落款"处理成第三十轮定性三 ⇒ 判错了性质,他要的是行为回退,不是话术。三处新旧语义冲突各有裁定(D1 / D2 / D3,全文取证在 spec §8.14): ★ D1(TTL 判 checkedAt,缺这格的老行回退 at):304 命中时刻意冻住 at(正文没变就不该改取回时刻)⇒ 拿 at 判 TTL 会让"最省额度"那一类行每次都出网、而本机 9 发实测 304 照扣 1 次配额,那正好把用户要的东西反着做;freshEnough() 里那一句 const base = num(row.checkedAt) ?? row.at; 是这一条的落点。 ★ D2(zhProbed !== true 的成功行不受 TTL 挡):第三十轮那一格从"304 复用的例外"升格成 TTL 的例外 —— 否则库里那半截结论要等满 24 小时才自愈、上一轮那条修复当场白做 ⇒ 代价仍是一次性的(过档那一问多两发,探完写回 true)。⚠️ 这一条例外不进设置页,屏上也不许多出一句专门解释它的话。 ★ D3(落款回两截):第三十轮那第三截「60 秒内没再问 GitHub」整截撤,DETAIL_STAMP_LABELS 回到 {body, revalidated} 两格;「刚核对过」收窄成 ok===true && cached!==true && checkedAt>at ⇒ TTL 命中那一屏恒 false(没问过 GitHub 就不能说核对过)。 ★ 形状两条:① TTL 之内一发都不问(连验证器都不问,配额读数当场不动)—— 这正是那句「不要用60秒这种」的正面落地;② 过档那一问仍走条件请求(第二十七轮那半件没撤:If-None-Match / 304 复用 / revalidated 全在),手动「重新取一次」照旧裸发全量、一个字不喂 prev。代价如实登记:不回源就不知道 README 改了,正文最长滞后 = 用户自己选的那一档。 ★ 接线两条律照守:getTtlMs() 调用时现取现算(第十二轮那笔账:装配时锁死 ⇒ 界面已显示新档、真跑的窗口还停在旧值);DETAIL_RECHECK_MS 整键删掉,hc-20 从"代码位一处都不许认得那个撤掉的键"翻成"认得那条 TTL 链 + 认不得 DETAIL_RECHECK_MS"(同一条链反向走一遍,五个点一处不落 ⇒ 那条律验成了双向)。库里那格 repoCacheHours 从头到尾没真正消失过(第二十七轮只是让 open() 静默丢弃)⇒ 本轮改回 optionalInt 声明把它收住、POST 脏档照旧 400 拒收(它现在决定"这一问出不出网",不像那版走白名单丢弃),域 version 恒 1、零迁移(10-07 那条 requiredInt 血案律照守,电池 ⑦ 打掉它时红 2 条)。⚠️ 有意没恢复旧的 REPO_CACHE_TTL_MS 那个导出 —— 盘上没有消费者 ⇒ 恢复它就是第二真相。 基线 573 → 574 项(套件仍 15、SKIP_LOCAL=1 下 572 过 / 0 挂 / 2 跳,过的那一边净 +1 且只落在 repo 105→106(新那条钉"装配后改档、下一发就按新档判,不用重启宿主"),client 70 / host-compat 22 / store 47 / api 89 条数不变、就地改判;三个来源各数一遍又对上:逐套 pass 加总 572 = 逐套全文 ^ok 572(另 ^FAIL 0 / ^SKIP 2)= 源码 ^check( 574,读数 tmp/rerun-r31.txt + tmp/suites-r31/;⚠️ 含跳口径 = 过 + 跳,与"净差值"是两个数、不许混用); 电池 tmp/r31-ttl-falsify.mjs(圈 六个源:lib/domain.js / lib/services/repo.js / index.js / lib/stores.js / lib/api.js / client.js)10 发 / 未抓到红 0 / 等价变异 0 + 末行 [还原 ok] 6 个源文件跑完逐字节等于进来时(红共 11 条:⑦ 那一发红 2 条 = store 那圈把"schema 的 open 校验"一起照住了)。★ 首跑三发指向错套件、补完重跑:③ 那发(装配时锁死出厂档)最初圈 test/repo.test.mjs ⇒ 那套件不 import index.js,结构上不可能有失败信号(漏网第二种:判据在但拿不到红)⇒ 改指 host-compat(hc-20 那条静态接线)才算验成;另两发同族(client / store 各一处)跟着挪正后整把十发重跑。⚠️ 三处台账文案本轮一并改口:文首「一个必须先说清的口径」那三行、口径表里「60 秒」那两行、第二十八轮那句「不进 60 秒防连点那个窗口」⇒ 现在念「不受详情那一档 TTL 挡」。 ⚠️ 本轮产品侧零真出网、零截图,动的是宿主半边 lib/domain.js / lib/services/repo.js / lib/api.js / lib/stores.js / index.js 五份 + 浏览器半边 client.js ⇒ junction 挂载下要重启 dsh desktop 才装得上;四条判定性走查挂在 spec §9.3(那一档能改 / 改档立刻生效 / TTL 内连点 0 发且底部配额读数不往下走 / 过档那一问走条件请求并回 304)。另:第三十轮那四条走查里「60 秒内连点 0 发」那一读判据文字已被本轮改写作废,改读上面第三条。你的 prefs、库存行、dsh desktop 一个字都没动、没替你重启) (★ 第三十二轮(10-13,你那句「增加一个项目收藏功能」+ 原型那三条推荐全选、「可以」):第八个页签、那枚 ☆ 三处入口、第八张表 fav(形态取证全文在 spec §8.15,本轮落地与那八步的差口全记在 §8.15 末尾那张改口表里)。四条骨架,逐条都有判据: ★ 存的是收藏那一刻的快照,不是引用 ⇒ 星数与描述不随榜面刷新(表头因此念「累计 ★(那一刻)」、卡脚那句 note 把这件事说白,要新值点仓库名走详情那条链);由此推出本轮最硬的一条出网账裁定:打开那一签与点那枚 ☆ 都恒零出网(不为了补快照去问 GitHub),且不派现译、不写 events —— ★ 三件"不做的事"由 api 那一条用例上的四本计数器一起钉(出网 / 现译作业 / repoService.load 调用次数 / 流水条数),移出那一路同理。 ★ 那一行的五格读数由宿主派生(favSeedOf 四路读本地表:三榜切片行 →「全站高星」那一批 → 榜史 seen → 详情缓存 repo 表;★ 第四路刻意读表不读 repoService.load() —— 后者会在 TTL 之外真问一发出去),浏览器只递 {repo, action} ⇒ stars / desc / lang 递不进来;四路全空照落库,出处念「详情」、缺的格在屏上是 —("本机一个读数都没见过它"的实话,不是缺格)。 ★ 「这一轮」那一格是宿主本地比出来的成品句(拿收藏键与同一帧那几批行比,按 日榜 → 周榜 → 月榜 → 明星 的优先级出单值,没命中念「未上榜」),★ 比键时把榜行的 renamedFrom 一起铺进去 —— 不铺就会在仓库改名后把"明明在榜"念成"未上榜"(你那条默认裁定:误念比缺念更糟)。⚠️ 本条已被第三十五轮整条作废(用户指着屏上那一列说「去掉这个」⇒ 那一格连同派生、那几个 domain 常数与判据一并撤干净;当时那八列于是变七列)。历史原文留在这里不改写,当前口径看文首「项目收藏」那一条与 spec §8.15 本轮改口表。 ★ 界面上的代价:那枚按钮落在宿主表尾原本 width:0 的占位列上,改成 36px ⇒ 描述列少的就是那 36px(你收下这条代价,所以没有新增 <col>/<th>);收藏不裁行、不设上限、不参与 LRU。 ⚠️ 取证抓出两处真缺陷、都在"三档说话"那一格上(§8.15 落地改口 ⑦):① 屏上那一侧:存储位不真时空态那句话照摆 ⇒ 「读不到那张表」与「还没有收藏」两句同屏拆台 ⇒ 加 f.available === true 那道闸(client-74 ②);② 宿主那一侧:lib/api.js 只看 favStore.available 那一位门面(它说的只是"有设施且没关",不代表 open() 成功、更不代表这一帧读得出来)⇒ readFavRows 回报 {rows, unreadable}、storageAvailable 两道都问。★ ②是一条分形律:以后任何一张表的"读得到没有"都不许只看门面(判据 hc-22 ③、电池 ①⑭ —— ⑭ 那一发撤掉 unreadable 之后 hc-22 当场红,说明补上的判据有牙)。 基线 574 → 626 项、套件 15 → 16(★ 逐套读数、+52 那五套的分摊、四来源对账、22 发证伪电池与那一发等价变异病历全在本文「测试」那节的 当前读数(10-13 第三十二轮),此处不重抄一遍数、免得起第二真相); ⚠️ 本轮产品侧零真出网、零截图,动的是宿主半边五份(lib/domain.js / lib/stores.js / lib/api.js / lib/favs.js 新 / index.js)+ 浏览器半边 client.js ⇒ junction 挂载下要重启 dsh desktop 才装得上,同时还要刷新面板;七条判定性走查挂在 spec §9.3(★ 走查前别清库 —— 收藏那几行的出处全靠库里已有的榜史与详情缓存行)。你的 prefs、库存行、四把密钥、dsh desktop 一个字都没动、没替你重启) (★ 第三十三轮(10-13,你那句「为什么收藏过来的项目描述没有翻译的」+ 回「按 A 开工」):收藏那一屏接上本机已有的那一份中文,形态取证全文在 spec §8.16,落地与那八步的差口记在 §8.16 末尾那张改口表里。三条骨架,逐条都有判据: ★ 命中判据只有一个出处:把 descZhView 里那一圈"内置优先 → 与库里那行原文逐字比对"抽成导出的纯函数 descZhHits(rows, transRows) ⇒ {hits, counts}(★ 返回只有这两键 —— 把 todo 也带出来,收藏那一屏就变成会花钱的屏),descZhView 内部首行改调它 ⇒ 榜面那三项逐字不变;在 lib/favs.js / client.js 再写一遍 stored.src === transSrcKey(desc) 就是第二份判据,两侧漂移的结果正是你截图里那种"半屏假话"。 ★ 一帧一处读:transStore.entries() 每一帧只读一次,榜面那份 hits 与收藏那份 hits 吃同一个值(读两遍 = 中间落库一次就是两个答案);中文放载荷第 11 格 descZh(⚠️ 第三十五轮撤掉末尾的「这一轮」那一列之后那一行只剩十格,这个序号名作废 ⇒ 现在只叫「descZh 那一格」)、desc 仍是收藏那一刻的原文(覆盖之后屏上与库里同名不同值,"快照不刷新"就只剩注释能证明);渲染侧三屏(榜面 / 明星 / 收藏)收进一个 descCell(那条"客户端只搬字不判档"的规则此前已有两份逐字拷贝,收藏是第三个用户)。 ★ 出网账 0 发 + 0 新增额度(本轮最重要的一本):两根钉子 —— 收藏那批行不进 descZhRows 的参与集合(那个函数一个字没改),descZhHits 是纯函数(派活只发生在轮次之后的批次)⇒ 收藏里躺着一个从没译过的仓库也一发不派;那一格中文是被动上屏的,屏上永远不欠一次请求。⚠️ 被否掉的两案已登记:B(为收藏新派现译)多花额度且把"这一屏不刷新"变成"这一屏会花钱",C(只补一句解释)是没改行为 —— 你回的是「按 A 开工」,两案不许在实现期偷偷改回来。 基线 626 → 637 项(★ 逐套读数、+11 那五套的分摊、四来源对账、19 发证伪电池与那两发等价变异病历全在本文「测试」那节的 上一份读数(10-13 第三十三轮),此处不重抄一遍数;⚠️ 那一轮末尾登记的"同一族命名账(两个同名 descZhHits)"已由第三十四轮改名消歧,见 §8.17 与下面第三十四轮当前读数); ⚠️ 本轮产品侧零真出网、零截图,动的是宿主半边四份(lib/board-zh.js / lib/api.js / lib/favs.js / lib/domain.js)+ 浏览器半边 client.js ⇒ junction 挂载下既要重启 dsh desktop 也要刷新面板;三条判定性走查挂在 spec §9.3(★ 走查前别清库、别改偏好 —— 清了 trans 表就只剩英文原文,这一形再也读不到)。你的 prefs、库存行、四把密钥、dsh desktop 一个字都没动、没替你重启) (末尾另修了六条你递过来的真机问题:定时器崩溃、榜单表列宽、页头字号、页签条那条没意义的滚动条、注册链接被推到行尾、★ 以及 10-07 那张「存储不可用」截图); 前面那四件在真机(挂 web profile + 无头浏览器逐签截图)走过三轮,其后又有第四第七轮(第四轮定时器崩溃、第五轮列宽、第六轮内置离线预译、第七轮模型现译,下面几段各记一件),逐轮记账都在 §9.3。第一轮含一次真故障往返:三榜连坏三轮时界面读到 (共尝试 3 次) / 已连续 N 轮 / 传输提示 / 下次自动检查 4 小时后,退避 effectiveMs 实测顶到 4 小时封顶。 第二轮(2026-10-05 12:17)验的是隧道本身:宿主的 dsh 进程里 reg query 读得到系统代理,三档(跟随系统 / 自定义 / 直连)各查一轮, 运行环境 · 传输路径 逐档改口,三榜 16 / 19 / 23 条真数据经隧道取回。截图又抓出一个断言全绿看不见的问题(外链吃浏览器默认蓝 + 下划线),逐条记账见 docs/design-spec.md §9.3。 详情这一层数据源与弹框都过了真机:tmp/probe-repo-service.mjs 经隧道跑通 vite(英文篇,3 发)、ant-design(另有中文 README,4 发)、ruanyf/weekly(默认篇本身就是中文,2 发); 第三轮走查(tmp/shot-detail.mjs + tmp/shot-detail2.mjs,图 tmp/shots/18~26-*.png)在挂出来的面板里点仓库名逐档核对: 遮罩盖住整视口且压过 sticky 页签条(顶栏 hit-test 落在遮罩上)、底色是 color(srgb … / .26) 不是黑块、900×800 下对话框完整在视口内、横向溢出 0; 中文篇那一屏读到「这个仓库的 README 本身就是中文写的,下面是节选。」+ 中文正文;Esc / × / 点空白关得掉、点框内不关; 缓存命中 14ms 落地(GitHub 侧 0 发)、「重新取一次」实测改发 &refresh=1 且配额 60→57(英文篇三发); ok:false 与 HTTP 503 两档各给一句话、不给元数据也不给中文叙述。截图另抓出一个断言全绿看不见的问题(落款把整篇原文长度念成节选字数),逐条记账见 docs/design-spec.md §9.3。 另有一条真机崩溃已修(2026-10-05 14:54,desktop host 被拖崩,IDE 弹「应用无法启动或已意外停止」):定时器回调里调的是裸 run(),而 run 当时只是 return {…} 上的一个方法 ⇒ 挂上定时器不报错、响的那一刻必抛,ReferenceError 从 Timeout.tick 落进宿主的 uncaughtException。闸门提成闭包里的具名函数,另加三条"把回调摘下来真的调一遍"的回归用例(两档后端各一条 + 撞忙时一条); 病历与复现读数见 docs/design-spec.md §9.3 第四轮。桌面 profile 是以 link:F:/dsh-plugins/dsh-plugin-gh-trending 挂的这同一份目录 ⇒ 修复已在原地生效,重启宿主即可(不用重挂载,也不必走"禁用第三方插件"那条按钮); 诚实一句:这一版没有在 desktop 里活满一个节拍再观察过(那要等一整个档位,且得由你决定何时重启)。 另有一条你截图递过来的列宽问题已修(同日第五轮):日榜表前三列被截成 100px、今日新增 整列不见、余量全灌进最后一列 —— 根因不是宽度数值,是 <col class="gt-repo"> 与格子里的 <a class="gt-repo"> 撞名,单元格那条 display:block 把 col 踢出了列布局,后面每列拿到的宽度整体左移两格。 列宽类改为带前缀的 gt-col-repo / gt-col-desc,数值按"尽量显示全"重配(# 46 / 仓库 268 / 描述吃余量 / 语言 112 / 累计★ 64 / 今日新增 72 / 较上轮 56,≤1000px 反过来), 四档视口的量宽读数与截图见 tmp/probe-cols.mjs / tmp/shots/27-cols-*.png,病历见 §9.3 第五轮。同样一句诚实话:这一版只在离板夹具(真 CSS + 真榜面解析结果)上量过,没在挂出来的宿主面板里重走。 (同日第六轮补了一半:真宿主面板的截图里八列各有值、今日新增 不再是 0 宽 —— 那是肉眼看过、没量过,逐列 px 仍然只有离板读数。) 第五件(描述列内置离线预译,2026-10-06):离线 266 项 + 真机截图都走过了。 lib/desc-zh.js(73 条,死数据)+ snap.descZh + 弹框那句「中文描述(内置离线预译 · <日期>,不是现译)」, 离线 266 项全绿、十一条证伪各挂各的现场(台账与证伪读数 §9.2,功能口径 §8.2),另用 10 发 GET /repos/{owner}/{name} 对账过 api 的 description 与表里 src 逐字相同(命中 10/10)。 真机那一遍(同日 08:4908:51,你重启 desktop 宿主后先读了它的 snapshot,再把同一份目录挂进 web profile 起实例、无头浏览器截图):卡头「描述中译为内置离线预译 · 2026-10-06」在日 / 周 / 月三张卡上各出现一次, 日榜 13 行里 11 行中译 / 1 行无描述 / 1 行未命中照给原文,周榜与月榜各 15 行里 14 行中译;弹框命中档与未命中档两屏都在(§9.3 第六轮,图 tmp/shots/30~32-*.png)。 第六件(模型现译 C,2026-10-06):离线 305 项 + 真机截图都走过了。 lib/services/llm.js 是宿主模型句柄的唯一使用者(改判后的 hc-8:那个文件由 index.js 的 createLlmTranslator 接线派生,不是手抄清单), 你四条裁定落在实现上就是「点开详情只译当前这一条 / 描述出厂开、README 摘要另开关 / 落 trans 表按「仓库键 + 原文逐字」判复用 / B 命中绝不重发」。 离线 305 过 / 0 挂(SKIP_LOCAL=1 下 304 / 0 / 1 跳),六发证伪各挂各的现场(F4 分两味,所以是七发读数:F1 重拼吃 base ⇒ repo 46/1 + api 46/1、F2 provider:undefined ⇒ llm 17/1、F3 模型闸门提到缓存前 ⇒ llm 17/1、 F4a 回执被洗成 errText ⇒ llm 17/1、F4b 回执整个丢掉 ⇒ llm 16/2、F5 descErr 不给 ⇒ repo/api 各 46/1、F6 客户端不渲染「回执:」⇒ client 50/1),台账见 §9.2。 真机那一遍(同日 10:1910:4x,脚本 tmp/shot-llm.mjs、读数全文 tmp/walk-llm3.txt、图 tmp/shots/40~46-llm-*.png + 42-detail-{②,③,④,⑤}*.png,§9.3 第七轮)抓出三条断言全绿、真机一跑才现形的毛病并都修了: ① 点了「开」而高亮还停在「关」(保存偏好不推 update 帧);② 每一次现译都失败在 NO_ADAPTER no adapter registered for provider "undefined"(旧的离线用例还把 provider 缺省钉成了规矩); ③ 模型命中那一档的叙述头一句塌成「这是一个 GitHub 仓库。」(重拼吃了错的源对象)。修好后的屏上原文:m-abozaid/esp32-c3-adblock 那一屏头一句是 这是一个用 C++ 写、MIT 许可证、累计 1,342 星的项目。最近一次推送在 2026-10-04,建档 2026-06-19。,译文与原文两句并排(中文描述(模型现译 · 10-06 10:25):… / 仓库自己写的描述(原文):…), 摘要段段名 中文摘要 · 模型现译 · 10-06 10:29;复用那一次是按你裁的"逐字"来核的 —— 两次点同一条,两个落款逐字相同、trans 表之后没有新增行; 两档一起关那一屏读到「模型」字样 = false、摘要段 = false、仓库自己写的描述(原文,未翻译):… 照在 ⇒ 关掉的那一档不是"翻译失败",是压根没派活; 900px 窄视口 + 出厂态是描述段中文照在而摘要段不在(各开各的),横向溢出 {"over":0}。 本轮出网账:api.github.com 0 发(三屏页脚都是「缓存于 1 小时前」),模型 2 发(描述 92 字 / 摘要 189 字)—— 花的是宿主的模型额度,不占 GitHub 那 60 次/小时。 走查后环境已拆净(实例关掉、web profile 里那个 junction 用 cmd rmdir 摘掉、package.json 与 cordis.patch.yml 从备份还原并 cmp 逐字节一致、偏好回出厂态)。 诚实一句:C 的失败四档(no_model / unavailable / timeout / store)在真机一格样本都没有,那四句文案目前只有离线判据;「两档全关 ⇒ 句柄零调用」在宿主上也只有屏上层证据。 另有一条你截图递过来的页头字号问题已修(同日第八轮):红框圈住「GitHub 热榜」那句「这个字感觉太小了点,比其他插件的小」—— 先对表不猜:同一台 desktop 里 modelwatch / stock-analysis / sysops / it-tools 四家的 -title 规则都是 font-size:17px;font-weight:600,只有 api-catalog 与旧的我们是 16px(卡头 13px、页签与 .X-sub 都跟 modelwatch 逐字同源 ⇒ 偏的就页头那一格)。 .gt-title 改 17px,墨迹读数 17px ⇒ ink 17 / 宽 97 / 盒 98.8×25.5、16px ⇒ ink 16 / 宽 91.3(zoom:1、transform:none,缩放那条解释排除了),脚本 tmp/probe-title.mjs、并排图 tmp/shots/47-title-parity.png,判据就地挂在 client-31(掉回 16px 当场红,证伪读数 [client] pass 50 / fail 1)。 同样一句诚实话:这一条没在挂出来的宿主面板里重截(离板夹具量的是真 CSS 与各家真规则);client.js 是浏览器半边,刷新页面即生效、不必重启宿主,最后一屏还得你自己看。 第七件(现译引擎三档 D,2026-10-06 第九轮):330 项离线断言 + 真机截图都走过了。 你两条裁定落在实现上就是「两条都做,设置页选」+「与宿主模型并存、二选一、默认落免费接口」: lib/services/web-translate.js(免密钥那一路 + 百度那一路,同形换体)与 lib/services/llm.js(第八轮那一路)并存,选路只有一处(pickTranslator 读 prefs.translateEngine), 没选中的那两路连"你开着吗"都不问。trans 表行内多一个 engine ⇒ 落款跟着那一行自己的来源,换引擎不作废旧译文(也不冒充新引擎)。 离线 330 过 / 0 挂 / 2 跳(SKIP_LOCAL=1,跳 hc-17 与 wt-19),新套件 web-translate 19 条 + api 6 条 + client-52 + hc-7 改判 + hc-19 新增; 十六发证伪各挂各的现场(十发在免费/官方那两路:去 dt=t / 把密钥当参数发 / 不遮 sign / 复用不看原文 / 开关闸门漏 / 引擎闸门漏 / 超时不响 / 没汉字也算成功 / 落款不看行引擎 / 库里存截断原文; 六发在凭据与只读 GET 那两条铁律上:三个出口不再摘密钥 ×3 / 翻译那一路改调用名从派生名单溜走 / 带 cookie 头 / 发 POST),台账与逐发读数见 §9.2。 ★ 这一轮把 hc-7 的出网名单从手抄两个文件名改成由"谁真的调用 fetchFn("派生 —— 手抄那一版对新增的 web-translate.js 零覆盖还照样全绿,和 §0 第七轮那个洞同一个形状、换了个位置复发。 真机那一遍(同日 12:0513:2x,脚本 tmp/probe-sbar.mjs / tmp/probe-engine.mjs / tmp/probe-detail-keyless.mjs,读数 tmp/probe-*.out|txt,图 tmp/shots/48-sbar-live-1440.png + 50~57-*.png,§9.3 第八轮): 出厂屏高亮在「免费接口(免密钥)」且没有凭据行;点官方档 ⇒ 真发 {translateEngine:'official'}、凭据行出现、说明换成「官方接口还没填 AppID 与密钥…(零出网)」; 存过凭据后 placeholder 念「库里已存(留空不改动)」并出现「清除」,切回宿主模型 ⇒ 凭据行整行撤掉,清除那一发是 {baiduAppid:'',baiduKey:''}; 渲染完的那一屏全文搜密钥 ⇒ found:false(hc-19 的真机对照);详情弹框第 3 行 michael-denyer/pstack-claude 读到 中文描述(免费接口 · 10-06 13:21):…,同屏前两行是「内置离线预译」⇒ B 优先在真机上仍然排在新档前面。 本轮抓出的那条只有截图看得见:密钥框 placeholder 第一版太长被裁掉半句 ⇒ 缩短 SECRET_SAVED_HINT 并重启宿主复拍(⚠️ "改前"那张被同名复拍覆盖了、没留档,下次换文件名)。 诚实一句:官方那一档真机零样本(本机没 AppID,那一发从没发出去过;test/fixtures/trans-official.json 里 "synthesized": true 登记的就是这件事,签名靠 wt-7 在用例里独立复算对账。★ 那一份第十轮已按厂商拆成三份,登记方式改成逐条 provenance,见下面「第八件」末尾); transport / http / bad_json / empty / too_long / store 六档失败文案在真机也一格样本都没有;而「免费接口」那一路是网页接口、不是官方授权接口(ToS 不覆盖程序化调用,对方随时可能改形状)—— 把它做成默认档是你的裁定,风险登记在 §9.3。 另有一条你截图递过来的滚动条问题已修(同日第九轮):「这个滚动条没有意义」—— 真宿主上量到 .gt-tabs 的 scrollWidth 1088 === clientWidth 1088(没有横向溢出可防)而 scrollHeight 34 > clientHeight 33(溢出的是当前签那条 :after{bottom:-1px}), ⇒ 撤掉那句 overflow-x:auto(flex:none 留着:第一轮那条 column flex 收缩压力还作数,不许顺手一起删),判据就地改强挂在 client-38(那条规则里出现任何 overflow 即红)。 第八件(现译引擎五档:接上腾讯与阿里云 + 切换时显示注册地址,2026-10-06 第十轮):342 项断言 + 真机 13 张截图都走过了。 你那句原话是「腾讯,阿里都接上,切换官方接口时,下面显示去哪个网址注册key」,两条落点是「改判铁律,两家都接」+「分段器并排五档」: 免费接口 / 百度 / 腾讯 / 阿里 / 宿主模型 五枚按钮并排(短名,谁译的、要不要注册、离不离得开代理由下面那句当前档的话说), 选中三家云任何一家 ⇒ 下面出现那一家的两格(标识符 + 密钥)与那一家的注册地址(百度 1 条、腾讯 2 条、阿里 2 条,target=_blank rel=noreferrer;额度那句不念数字 —— 这一轮没复核到官网的可引用读数,一律"以官网计费页为准")。 ★ 只读 GET 那条铁律一个字没松:两家云用的都是官方签名里能走 GET 的那一档(腾讯 v1 把参数放查询串、阿里 RPC V2 是查询串签名), 改判的只是"翻译域的查询参数里允许出现厂商标识符";密钥本体仍然只进摘要,不进 URL、不出网、不回显、不进日志,GitHub 那一域仍然零凭据(★ 第二十一轮改判的就是这半句:现在念作「GitHub 那一域默认零凭据;设置页填了令牌才带一条 Authorization: Bearer,只进请求头、绝不进 URL」—— 本条第十轮其余口径原样留着当历史,见文首那条铁律与 §8.6)。 旧档名 official(第九轮只有百度那一档时存的)在读的那一刻先搬家成 baidu 再判脏,库里那批 engine:'official' 的旧译文继续读得出来、不改写(TRANS_ROW_ENGINES)。 离线 340 过 / 0 挂 / 2 跳(SKIP_LOCAL=1,跳的还是 hc-17 与那条真发,编号已从 wt-19 漂到 wt-27),直跑 342 / 0 / 0;本轮 +10:web-translate 18→26(两路签名各一条 + 一次性数 + 非 2xx 先读回包 + 旧档名行 + 命中缓存不组 URL + 档名归一 + 夹具逐家口径),store 36→38(搬家顺序 + 旧行继续读); client / api / host-compat 条数不变、内容改判(client-52 整条重写成五档 + 逐家凭据 + 注册行 + CSS 那七段判据,hc-19 从扫一把密钥改成扫三把)。 十四发证伪全红到位(tmp/r10-falsify.mjs,逐发还原并逐字节比对,读数 tmp/r10-falsify-out.txt):出口少摘一把 / 干脆不摘 / 视图带出 value / 字段表不看档名 / 搬家排在判脏之后 / 腾讯改成编码后再签 / 阿里出网改用 URLSearchParams / 阿里一次性数写死 / 日志不遮签名 / 密钥框退成明文 / 没存也念"库里已存" / 留空密钥进 patch / 注册行不摆 / 草稿收口拆掉。 ★ 首跑抓出一条假绿:「阿里一次性数写死」当场全绿 —— wt-11 当时只钉腾讯那个 Nonce 键名,判据没跟着新覆盖面走;扩成两家各发两发再比之后重跑才 14/14。 真机那一遍(同日 19:2x,web profile + 无头 Chrome,脚本 tmp/probe-engine10.mjs / tmp/probe-regrow.mjs,读数 tmp/probe-engine10.txt / tmp/probe-regrow.txt,图 13 张 tmp/shots/60~66-engine10-*.png,§9.3 第十轮): 逐档走查每一发真 POST 的 body 都记了档(切档只发 {translateEngine:'…'}、保存只发当前档两格、清除只发当前档两格空串,带 body 的共 9 发); 免费接口 与 宿主模型 两档两行都不摆(连输入框都不给);三家空凭据时屏上多一句新写的 no_credential(原话点名"AppID 与密钥",那两家的字段名不是这个);存过之后标识符明文回填、密钥框空白 + 「库里已存(留空不改动)」+ 出现「清除」; 渲染完那一屏搜三把密钥 ⇒ found:[](收尾那一屏再搜仍是空)。本轮抓出的那条还是只有截图看得见:注册链接被 .gt-link 那条 margin-left:auto(卡头「完整榜单 →」用的)推到行尾 ⇒ 加一条例外 .gt-setrow .gt-link{margin-left:0}, 活宿主上复量标签到第一枚链接的间距 10px(改前那一大片空是几百 px),前后两张图这次都留着(62-engine10-03-腾讯-已存.png / 66-engine10-07-注册行贴标签-腾讯.png)。 诚实三句:两家云的签名本机零真机样本(无凭据那一发只走到"查标识符"那一步:腾讯 AuthFailure.SecretIdNotFound、阿里 HTTP 404 + InvalidAccessKeyId.NotFound ⇒ 服务端先查标识符后验签名,签名对不对这台机器测不出来,只有离线独立复算那一条腿); 额度数字没复核到出处,所以界面不念(第三方转述的数字含第九轮那句"百度 5 万字符/月",本轮从文档与界面一起撤了); 腾讯取的是 v1 签名,有第三方转述说部分新账号会被要求改 POST + TC3 —— 官方文档这轮没复核到这条明文,真撞上时要按规矩另开一次改判,不在实现里偷偷 POST。 第九件(自带中文探测 + 结构化段表 A,2026-10-06 第十一轮):350 项离线断言走过了,真机截图这一件还没走。 你那句原话是「自带中文探测 + 结构化摘要,换引擎后旧译文照样复用,按这个做」,三条落点是「只做零额外请求那两处」+「宿主模板分段,不新增调用」+「拆进段里,整段撤掉」⇒ 这一轮没改判任何铁律、出网预算增量为零(详情那一层编排仍是最多 3 发,读数 tmp/probe-zh-readings.txt),动的是"详情那一屏由谁拼、拼成什么形状": ① readmeSource 多出第五档 zh_section —— 默认篇是外文时,在已经在手的那份整篇 README 里找中文小节(splitReadmeSections + pickZhSection,判据吃 CJK 个数、与默认篇那一档同一条律 README_ZH_SECTION_MIN_CJK=20;围栏代码块里的 # 行不算语义标题,这条状态机的真形取自榜上那篇 token_ids… 代码注释);找不到就保持 en_default,不硬凑一段; ② 两道源侧闸门(都排在派活之前,不是译完再挑):descSelfZh(仓库自己写的描述本身就是中文,DESC_SELF_ZH_MIN_CJK=8)⇒ 不派描述那一发;命中 zh_section ⇒ 不派摘要那一发; ③ 详情载荷从"一整句 narrative"换成结构化段表 sections[](四段 what/heat/self/summary,块只有 p/sub/num/excerpt 四种 kind,段序只认 REPO_SECTION_KEYS、数字只进 heat.facts 各一次)—— 旧那五格 narrative / facts / flags / readmeLabel / readmeMeta 连同 repoNarrative() 整段撤掉,narrativeFields 改名 sectionFields 且只在宿主内部、api 一进来就解构删掉 ⇒ 载荷 26 键 → 21 键(repoView 21 含 sectionFields、出边界 21 含 zh 不含它);段表与 sectionFields 都不落库,缓存命中与刚取回两条路同走 repoView→applyZh,逐字同形; ④ 「换引擎旧译文照样复用」钉成裁定 = 保持现状,所以这一条零代码改动,只补判据与文档(落款署的是那一行当初的来源,命中只比原文不比引擎,§8.4)。 离线 350 过 / 0 挂 / 2 跳(SKIP_LOCAL=1,跳的还是 hc-17 与 wt-27),10-06 当晚直跑 352 / 0 / 0;本轮 +10(repo 47→56:围栏状态机、pickZhSection 两条、两个阈值两侧余量、zh_section 那一路仍三发封顶、descSelfZh 入库行、段序只认常量、数字只出现一次、描述五种来源的字面分档、summary 段成功带落款/失败给 note 与回执;api 53→54:第一道闸门那条), client / store / check / host-compat 条数不变、内容改判(client-41 整条改吃段表:四种 kind 各自类名逐字、p ⊂ sub ⊂ num 逐级加重、一张 gt-modal-facts、旗标句落 heat 段的 sub 块;client-51 改判:摘要失败照摆段、段名说「没取到」)。 十三发证伪全红到位(tmp/r11-falsify.mjs,四个源文件逐发还原并逐字节比对,读数 tmp/r11-falsify-out.txt):围栏失效 / 小节阈值放宽到 1 / zh_section 编排整块撤 / 那句落款删 / descSelfZh 阈值失效 / 段序改手写表 / 数字并回 what 段 / applyZh 不删 sectionFields / 两道闸门各拆 / B 优先拆 / num 退成 sub / excerpt 与正文同形。 ★ 首跑又抓出一条假绿:「B 优先拆除」当场全绿 —— 那条用例把 enabled 写成只开 readme,"描述那一发没派"是开关挡的、不是 B 优先挡的;改成两档都开并在派活矩阵补一行「B 命中 + 只开描述档 ⇒ 零调用」后才是 [api] 52 / fail 2(同一条律第二次抓到"断言没承重",§9.2)。 ★ 本轮还第一次抓到用例名把用例杀掉:那条围栏用例原名带「真机」二字,而 test/_helpers.mjs:12 的机制是用例名含「真机」⇒ SKIP_LOCAL=1 时整条静默跳过 ⇒ 离线那 350 里压根没有它;改名「(榜单上真出过的形状)」才进覆盖面(同一条律第三次撞,判据是复跑时盯 skip 那一位)。 诚实两句:这一件没有真机截图 —— 详情弹框重排改的是"一屏四段、句子分主次"的形状,按验收口径该在活宿主上逐段量 getBoundingClientRect(每段吃多高、sub/num 墨迹深浅差、excerpt 的边框与内边距),只数 DOM 节点或断言 CSS 字符串都算没验过; 那要把这份目录重挂进 web profile 并重启 dsh desktop 宿主,本轮没做(要你点头),所以 §9.3 未验证清单第十一轮那条还挂着。 zh_section 命中侧零真机样本:榜上仓库里唯一候选 QwenLM/Qwen,按"认围栏"口径重跑后那三段 CJK≥8 的"中文小节"全是代码注释 ⇒ 退回零样本;全链路吃的是合成夹具 test/fixtures/repo-zh-section.json(标 synthetic、逐条 shapeSources),真回包那一路没吃过(探针与出网账见 §9.1,其中 probe-zh-fixture.mjs 的发数没留档,是本轮唯一的读数缺口)。 第十件(详情屏撤掉废话 + 详情缓存时长进设置页,2026-10-07 第十二轮):356 项离线用例走过了(★ 同轮事故修复后基线是 357 项、第十四轮起 358 项,见下面第十三轮那条),真机截图这一件还没走。 你那句原话是「1.把这个页面上的废话都去掉,2.缓存时长可以配置吗,调整为默认24小时」,两条落点是「四段来源落款全撤」+「进设置页,默认 24 小时」: ① 段对象从五格缩成四格(key/label/blocks/facts)—— 四句 source 落款("这一段读的是 api.github.com 的 description / language / license / topics 字段"、"这些数字与日期是元数据字段,不是本插件算的"、"下面是仓库自己写的 README 正文…不是译文"、"这一段是现译给的,不是仓库自己写的中文")整格撤, REPO_SECTION_SOURCE_NOTES 那张表连带删掉;「是谁写的 / 是谁译的」改由段名说(仓库自己怎么介绍它 · 默认 README 是英文、中文摘要 · 免费接口 · 10-07 09:5x),self 段那两句(README 五档说明句 + zh_section 的小节名)并进段名,readmeNote() 整函数删除; ② 撤的是解释,不是事实:保留「不是现译」那个标签、仓库原文那一句(译文永不替换原文)、页脚那行 GitHub 配额; ③ README 那行落款压成一行短字面 节选 54 / 整篇 4,235 字 · 已去标记 · README(两个口径的数都留着,差在哪由那道斜杠交代,不另起一句解释;两个数相等时写「整篇就这么多」,不许把同一个数念两遍); ④ 详情缓存 TTL 从常量 REPO_CACHE_TTL_MS(12 小时)改成封闭四档 REPO_CACHE_HOURS=[6,12,24,72] + repoCacheTtlMs() 单点换算,出厂 REPO_CACHE_DEFAULT_HOURS=24;设置页多一行分段器(与检查频率同形状、话术全吃载荷), POST /api/prefs 档位外直接 400(★ 不许悄悄回落 24 —— 那等于库里一个值、分段器上另一个值,同 translateEngine 那条理由),clampPrefs 只认名单(缺这格的旧库由出厂值补回 24); ★ 服务侧吃的是 getTtlMs() 调用时现取现算:装配时把毫秒锁死会让"改档"到宿主重启才认,而屏上分段器已经显示成新档(两份真相,hc-20 同时钉这条接线与"装配处不许出现 ttlMs:");失败档那 5 分钟不进设置页(那是故障保护,不是给用户调的配置)。 ★ 第二十七轮(10-10)撤掉了这一档 —— 上面那四档与那条接线是当时的口径,历史叙述原样留着不改写;撤档的理由不是"那套接线写坏了",而是详情改成条件请求之后那一档没有可判的对象("多久算新鲜"被"问一次验证器、没变就 0 字节"取代,窗口只剩 60 秒防连点与失败 5 分钟两格,都在 domain、都不进设置页)。撤干净的一条链五个点与零迁移实测见上面第 44 行那条与 spec §8.9。⚠️ ★ 第三十一轮(10-12)用户再次亲手改判,那一档摆回来了(裁定原文「还是改成以前那种模式,默认缓存24小时,可以配置,听不懂吗,不要用60秒这种」)⇒ 上面那四档与那条接线又是当前口径,只多两条新语义(TTL 判 checkedAt + zhProbed 那条例外);那条链验成了双向,逐点读数见上面第三十一轮那段与 spec §8.14。 离线 354 过 / 0 挂 / 2 跳(SKIP_LOCAL=1,跳的还是 hc-17 与 wt-27),同轮直跑 355 过 / 1 挂 / 0 跳(挂的仍是 wt-27 那一发真出网回 HTTP 429);本轮 +4(api 54→55:档位封闭与越界 400;client 52→53:那一行分段器 / 选中读库里那份 / 旧载荷整行不摆;store 38→39:越界回落 + 旧库补格;host-compat 20→21:hc-20 TTL 接线), repo 56 条条数不变、内容改判(段对象只四格、self/summary 段名、readmeMeta 新字面、'note' in zh.summary === false、TTL 那两条从 12 小时口径改口到 24 小时 + 现取现算)。 十九发证伪全红到位(tmp/r12-falsify.mjs,六个源文件逐发还原并逐字节比对,末行 [还原 ok]):source 格加回 / self 段名不带档名 / summary 段名不带引擎 / note 塞回载荷 / 落款压回旧长句 / 两数相等仍报整篇 / 客户端把撤掉的落款摆回屏上 / 装配时锁死 TTL / 服务侧抄毫秒常量 / prefsView 初值漏格 / 出厂档不是 24 / 档位多出第 5 档 / 话术表少一档 / clampPrefs 不认档 / 入口载荷不发档位 / api 闸门拆除 / 设置页那行撤掉 / 旧载荷仍摆空行 / 选中项读出厂值。 ★ 首跑有一条不算证伪过(电池自己的缺陷,不是判据漏洞):那条把 self 段名的跨行模板串只吃了上半句 ⇒ 植入后源文件直接 SyntaxError,跑挂了却没有一条红用例。补全锚点后 19/19,并给电池加一档显式读数「植入改坏源文件(判据没跑到)」—— 免得下次把脚手架的坏消息读成判据的红(同一条律第四次:判据要在自己的现场上挂)。 诚实两句:这一件没有真机截图 —— 撤废话改的是那一屏的句子密度、加的那一行是设置页的分段器,按验收口径要在活宿主上截两屏并逐段量 getBoundingClientRect,而 index.js 动了装配半边 ⇒ 得重启 dsh desktop 宿主;第十一轮那条未验证清单还挂着,本轮把"详情弹框 + 设置页缓存行"并成一次走查。 「改小到 6 小时那一档之后,库里那批 12 小时时代存的行怎么办」真机零样本(只有离线那两条:24h 档下 7 小时的行仍算新鲜,切到 6h 档同一行当场过期重取)。

★ 第十件落地当天就撞出一发真机事故(10-07 第十三轮,用户递截图问「怎么回事」):desktop 上三榜全红「故障 · 存储不可用」、每榜 0 条。 根因就在这件的第四个落点里:新偏好键 repoCacheHours 当时写成 requiredInt('详情缓存时长(小时)'),注释理由是"与邻居 intervalMin 同形状"—— 可 intervalMin 是首建就存在的必填键、对它自己的老库合法;追加的必填键对第十二轮之前写下的那一行就是坏行。 而宿主只在 open() 读存量时跑这套 schema,一条坏行被 kv-records-base.js 包成 UNAVAILABLE ⇒ 一整域不可用(榜面走降级路径所以还看得见,但状态与榜史全读不出来)。 修法两处,零新键 / 零迁移 / 域 version 仍钉 1:那一格改回 optionalInt(缺格由 clampPrefs 补出厂 24 小时,语义不丢), 并往 test/store.test.mjs 末尾加一条跑真宿主生效那一步的回归判据(拿 GHT_DOMAIN.tables[t].valueSchema.parse 吃上一版库存里真实存在的行形状;两头钉 —— 不抛 = 域还开得上,不凭空造格 = 补默认只许 clampPrefs 一处)。 ⚠️ 为什么"离线 354/0/2 全绿"跟"界面上全线红"能同时成立:test/_helpers.mjs 的假设施 open() 不跑 schema、seed() 明写"未经 schema 校验" ⇒ 那套假设施结构上碰不到这一发。★ 同一条律第九轮的 engine 与第十一轮的 readmeSection / descSelfZh / zhCjk 都守住了(全部 optional*,注释里写着同样的理由),第十二轮这一格是自己破的。 读数(10-07 11:0x 复跑,tmp/rerun-r12-fix.txt):store 39→40、离线全量 355 过 / 0 挂 / 2 跳(基线从 356 项推到 357 项);同一块证伪电池扩到 20 条 / 未抓到红 0 条(新那一发"把这格写成 required"当场 [store] pass 39 / fail 1,tmp/r12-falsify-out3.txt); 真库存只读探针 tmp/probe-storage-open.mjs 报六表 239 行、读不出 0 行,并自证真缺那一格(prefs 缺 repoCacheHours / repo 缺 readmeSection / trans 缺 engine)—— 它只报行数与缺哪一格,绝不打印行值(prefs 那一行躺着你的真凭据)。 ⚠️ 界面上什么时候退红,取决于你什么时候重启 dsh desktop 宿主(link: 挂载下宿主半边在进程启动时加载;修复在树里,但那个进程还拿着旧 schema)。我没替你重启。 ★ 顺手补的第三处:lib/stores.js 里 */export function createPrefsStore 那个被第十二轮吃掉的换行(全树只有这一处,改的只有这一行)。 ★ 第十一件(名次徽章分档,2026-10-07 第十四轮):你递了一张 modelwatch「本周前三」的截图(红框圈住 1/2/3 三枚圆徽),口径「榜单前三名也加上这种徽标和颜色,好区分一点」。 落法:.gt-rank 退成纯底座(22×22 / 圆角 8 / 11px·700 / tabular-nums),底色一律由档类给 —— 金 #e8b530 / 银 #c3c9d2 / 铜 #cf9a63(字色 #3d2c00 / #2f353c / #3a2410),第 4 名起 .gt-rank-n 走宿主令牌; 三档色值与 modelwatch 的 .mw-rank-1/2/3 逐字相同(观感口径跟兄弟插件对表)⇒ 改一处要连着改另一处,这条对表关系由 client-54 的色值正则钉着。榜页 8 列表格与总览速览共用同一个 RankBadge,两处渲染点各自验(只钉组件不算:调用点自己拼类名就把档吃掉了)。 读数(10-07 11:2x–11:3x,tmp/rerun-r14.txt):client 53→54、离线全量 356 过 / 0 挂 / 2 跳(基线 357→358 项,差额只有那一条新用例 ⇒ 数据面 / 载荷 / schema 一字未动);新电池 tmp/r14-falsify.mjs(只圈 client.js)7 条 / 未抓到红 0 条,末行 [还原 ok]。 无头那一遍(tmp/probe-rank.mjs → tmp/shots/67-rank-medals.png)量到:三档计算样式 rgb(232,181,48) / rgb(195,201,210) / rgb(207,154,99)、第 4 名与第 15 名 rgb(250,250,251) + 1px 边框,五枚徽标恒 22×22(中性档那 1px 边框没把它撑大,靠 .gt-root *{box-sizing:border-box})、46px 首列内右缘留 8px、nowrap 没触发折行、两位名次不撑列。 ★ 这一轮踩到两条自己的律:① CSS 是模板串 —— 在 const CSS = \…` 里写的注释带了反引号 ⇒ 整份 CSS 当场截断,报的是「rank is not defined」这种八竿子打不着的错([client] pass 4 / fail 50);**② 断言钉前提** —— client-54 首跑挂在它自己的前提上(夹具的日榜只到第 3 名 ⇒ "第 4 名走中性"空跑),补成 5 行才落到位。另剔掉一条**自等价植入**(Number(rank)换parseInt(rank,10)||rank抓不到任何红)。 ⚠️ 诚实一句:**这一件同样没有活宿主截图** —— 上面那一遍量的是**从client.js 逐字抠出来的那份 CSS + 复刻的表**(宿主真令牌与深色外观没覆盖,表体其余七列是占位文本),而本轮只动浏览器半边 ⇒ 界面上要等宿主重新加载那份 client 源(重载面板,不行就重启 dsh desktop)。我没替你重启,也没挂 web profile 走查;这一屏并进上面那条欠着的走查清单(详情弹框 + 设置页缓存行 + 名次徽章)。 ★ **第十二件(节选与判据窗口分家 + 句子边界收口 + 摘要能力跟着那一路 + 第二路找中文 README,2026-10-07 第十五轮):368 项离线用例 + 真机三张截图都走过了。** 你递的是两屏现场:alibaba/open-code-review「**这种项目有中文文档,为什么没有获取到**」(那份中文 README 在 docs/i18n/README.zh-CN.md,根目录压根没有),和详情屏那句断在 Install Ask your a 的硬切节选;裁定「**照你说的,把这几处修复合并在一轮里完成**」⇒ 四件并成一轮: ① **分家**:readmeZhVerdict交两样东西 ——head(去标记后**前 600 字**,只用来数 CJK 判那五档)与 clean(去标记后的**整篇**);旧版拿 head 当节选交出去 ⇒ **README_EXCERPT_MAX=1600那道预算从来没生效**(入库、上屏、喂摘要三者都恒 ≤600)。现在节选吃clean、bodyChars 钉的是**节选出自的那一篇**的整篇长度(命中中文篇时指那一篇,zh_section那一档仍指默认篇)。★ schema 那一格的maxLength一字未动、域version 仍钉 1 ⇒ **零迁移**(库里旧的 600 字行读回来还是 600 字,下一发按新档重取才变长)。 ② **收口**:excerptOf()切到 1,600 后往回退到窗口内**最后一个句子收尾**(回退上限EXCERPT_SENT_BACK_MAX=200,窗口里一个句末都没有就宁可硬切),EXCERPT_SENT_END_RE**中西文两支各写各的**(中文那句没有空格可依赖);硬切与回切都退掉半个代理对(1,398 个x+ end. + 200 枚 emoji ⇒ 长度恰为 **1,599**,切在半枚 emoji 上就红)。 ③ **能力下沉**:lib/services/web-translate.js的SERVED_KINDS=['desc']+kinds()(enabled(kind)第一行就查这张表)⇄lib/services/llm.js的kinds() => [...LLM_KINDS](两路都 serve)⇒「整理成一段简体中文摘要」那一路**只派给 宿主模型**;设置页那几行开关跟着变成载荷 switchRows[](每行 {key,kind,row,label,on} 五格,客户端只念四格),**当前那一路做不了摘要 ⇒ 那一行压根不摆**,不再留一个点了没用的控件。 ★ **第十七轮(10-07)这一条被用户改判**(原话「我前面是有摘要现译的,你在哪一次改坏了,给我放出来」):SERVED_KINDS现在报['desc','readme'] ⇒ 五档都派摘要那一发、设置页那行开关五档都摆;本段**原样留着**当第十五轮当时的口径与读数(图 68/69 是那一版的屏,不是现状),保留的只有"不挂假名"那半:那四档给的是节选的**节译**,段名与说明句跟着档位走(domain.summarySectionLabel/switchRowLabel)。 ④ **第二路**:pickZhReadmeLink(默认篇 raw 原文)吃那行语言切换,**markdown文字与 HTMLhref="路径" 两种写法都认**(真机那一行用的是后一种,只写前一种等于没做),多条命中按名排序(★ **这一条已被第二十轮改判**:现在先按"明写简体 / 不带变体 / 明写繁体"三档、**同档内**才按名 —— 见下面第十七件);zhReadmeRelPath的闸门**全排在造 URL 之前**(scheme / 站内绝对//#/ 反斜杠 / 空段与. ../ 非.md/ 超README_ZH_LINK_MAX=200 一律不放行),返回**原始路径**(encodeURIComponent只在出网那一发逐段做,界面上readmePath念的也是原始那份),那一发 404 就回落en_default 不炸。★ **编排没加发数**:那一发中文正文本来就是第 4 发,只是路径换了来源。 读数(10-07 12:5x,tmp/rerun-r15.txt):SKIP_LOCAL=1 下 **366 过 / 0 挂 / 2 跳**,基线 358 → **368 项**(逐套过数:repo 56→63、api 55→56、llm 18→19、web-translate26→27(跳的还是wt-27,所以项数 27→28)、client54 与host-compat20 **条数不变、内容改判** —— 前者现译那一屏的夹具改成吃translatorView现造的switchRows,后者 hc-18从读translator.descOn改成遍历switchRows;只报条数就会把这两套的改判漏记账)。 **十二发证伪**全红到位(tmp/r15-falsify.mjs,圈 repo.js/domain.js/web-translate.js/api.js/llm.js五个文件,逐条还原并逐字节比对,读数tmp/r15-falsify-out.txt):**[证伪] 12 条 / 未抓到红 0 条**,末行 [还原 ok]。★ 首跑抓出**两条自己的假绿**:「绝对 URL 闸门撤掉」当场全绿 —— //那种被"空段"那一支**冗余挡住**了,补上无//的mailto:/http:坏形状才让这一支成为唯一防线;「宿主模型谎报只 serve desc」那一发**指错了套件**(植在llm.js却跑api)—— 判据在另一套件里,等于没验。逐条归因表在 §9.2。 真机那一遍(10-07 12:5x~13:2x,tmp/shot-r15.mjs,读数全文 tmp/r15-walkthrough.txt,图 3 张 tmp/shots/68~70-r15-.png,宿主日志 tmp/r15-host.log,第二路真回包两份 tmp/r15-ocr-live{,2}.json):出厂「免费接口」那一屏**只有「描述现译」一行**(图 68)、点「宿主模型」当场多出一行 摘要现译 关/开[on]且引擎行提示同步换话(图 69)、切回免费接口 又恢复成一行(★ **这一读数是第十五轮那一版的现状,第十七轮已改判**:现在五档都摆两行,那一屏待重启宿主后重拍);详情弹框(tester-army/e2e,图 70)节选 textLen:1,594、endsAtSentence:true、尾巴逐字 …report them to security@tester.army.,框 650×319/maxHeight:400.8px/ownScroll:false/dialogScrollable:false;第二路真回包 readmeSource:zh_file/readmePath:docs/i18n/README.zh-CN.md/整篇 8,869/zhCjk 330/ 节选 **1,586 且落在「。」上**,两次相邻refresh=1之间配额 **55 → 51** ⇒ 那一屏真发四发,与「4 发封顶」对上。本轮出网账api.github.com**10 发匿名 GET**、翻译那四个域名 **0 发**。 ⚠️ 诚实三句:**中途差点读错一次** —— 13:09 那一屏回的是cached:true + 节选 600 字,那行是 **12:24 旧进程写进库的**(cacheAgeMs 2,716,250),不是新代码产的;"库里那行旧"和"代码没生效"在两屏读数里长得一模一样,分清它俩的是 cached+cacheAgeMs + 进程创建时间三个数(tmp/r15-ocr.json就是那份**旧**读数,原样留着别当本轮证据)。★ 第二路这一发补的是**"详情载荷那一屏的zh_file 真回包"那一格**(zh_file此前只在 §9.1 的**数据源探针**里过过 —— ant-design 那份README-zh_CN.md走的是**根目录列表命中**那一版,本轮第一次是**第二路**命中的),**它补的不是zh_section**(后者本机仍 0 命中)。而 **第二路那两发吃的是合成档**(语言切换行按真机形状手写,只有"根目录没命中"那一头用 vitejs/vite的真清单,那一发 404 态真接口压根触发不了)⇒alibaba/open-code-review的真回包只留在tmp/,**没落进 test/fixtures/**。逐段 getBoundingClientRect仍欠(上面界面那节那条)。走查后环境已拆净(探针宿主 PID 12144 连同四枚无头 chrome 关掉、junction 先验ReparsePoint/Junction再[System.IO.Directory]::Delete 摘掉、package.json从tmp/bak/web-package.json.r15-before还原并cmp逐字节一致、prefs 只读回translateEngine:keyless、一次性 DOM 探针与浏览器目录删掉);**desktop 那台宿主我没替你重启**。 ★ **第十三件(回执带上厂商请求号 + 同屏一条失败句只念一次,2026-10-07 第十六轮):371 项离线用例走过,真机那一屏没造。** 这两件都是我自己上一轮递给你的旧账,你回的是「**按你推荐的来**」⇒ 按下面这两条落地;★ 顺带认一条:**我上一轮那句"request id 常正好被 .slice(0,200)切掉"说得不准** —— 旧vendorErr只拼code + msg,那串号**压根没进过回执**(三家还各放在不同格:腾讯 Response.RequestId、阿里顶层 RequestId、百度叫 log_id),所以本轮的修法不是放宽那 200,而是**把号认出来并排在最前**。 ① **请求号进回执且砍不掉**:vendorErr现在拼请求号 <号> ,号先截 VENDOR_ID_MAX=64再排最前 —— 调用点那句${statusNote}${errText}的slice(0, 200)砍的是尾巴,号排在HTTP 403 +请求号 + 64 = 77 字之内,**错误体再长也砍不到它**;没有号(百度那条真回包就没有log_id)时那三个字一个都不摆,不许拼出「请求号 」那种半截话。屏上那一行是 回执:HTTP 403 请求号 …,用户找客服时报得出号。 ② **同屏只念一次**:repoSections里摘要段的sub(失败句)与 num(回执:…)两块**按字面跟着描述段去重** —— 两路现译走的是**同一个**当前档(pickTranslator只选一个服务),它挂掉时两处逐字相同,那句话讲的是那一档的事实不是这一路各自的事实。★ 去重只按"已在屏上的字面"逐格判:原因不同(描述挂在传输、摘要too_long)时各说各的;两块都撤了**段仍摆**,段名「中文摘要 · 没取到」本身是新信息(撤成整段不摆就是把一次失败说成没失败;★ **第十七轮**那一句段名跟着档位走,失败行没有引擎 ⇒ 现在念「**中文现译** · 没取到」,成功行才分「中文摘要 / 中文节译」)。载荷键一格没撤(summaryNote/summaryErr 照给,只是不再重复上屏)。 读数(10-07 15:4x,tmp/rerun-r16.txt):SKIP_LOCAL=1 下 **369 过 / 0 挂 / 2 跳**,基线 368 → **371 项**(repo 63→64、client 54→55、web-translate项数 29(过数 28,跳的仍是wt-27);api/host-compat/llm一字未动);★ 不带SKIP_LOCAL 的直跑(tmp/rerun-r16-full.txt):**371 过 / 0 挂 / 0 跳**(hc-17、wt-27 这一次都通,满绿不保证复现)。 **十一发证伪**全红到位(tmp/r16-falsify.mjs,只圈 lib/services/web-translate.js与lib/services/repo.js,读数 tmp/r16-falsify-out.txt):**[证伪] 11 条 / 未抓到红 0 条**,末行 [还原 ok]。★ 这一轮的电池专门做了**两头**:repo.js那五条改动先在repo套件里红,其中两条**另在client套件各跑一遍**(同一条屏上的话由宿主拼、由客户端摆,第十五轮踩过"植入的文件与跑的套件对不上 ⇒ 判据等于没验");「号排回正文尾巴」那一发当场红在wt-29的**顺序**那一头(三家夹具各断一句startsWith('请求号 …')),而同一用例的**第二头**钉的是预算 —— 最坏那一发(403 + 64 字顶满的号 + 约 700 字错误体真走假 net)断言回执 ≤200且^HTTP 403 请求号 R{64} :只写头一头会漏另一头。 ⚠️ 诚实两句:**这一轮没有真机截图,也不能写成"过了真机"** —— ①那一屏要一次**真的厂商失败**,本机发得出它的只有你家库里那三把真凭据(我不会拿它去发坏签名);②那一屏要 host_llm档**两路同时挂**,而你这台宿主的模型是就绪的,我不会为了造现场把它弄成不可用。两屏都并进那条欠着的走查清单(详情逐段 rect + 深色外观 +6/72小时档 + 第十四轮那张名次徽章活宿主屏):**哪天你自己撞上"翻译接口回了错误",那一行开头就该是回执:HTTP xxx 请求号 …** —— 那串号能直接报给厂商客服,截图给我我就把这格划掉。代码本轮只动这两个文件,载荷形状、schema、出网账一字未动。 ★ **第十四件(摘要现译放回来,2026-10-07 第十七轮):372 项离线用例走过,真机那一屏没截。** 你递的是设置页那一屏:切到腾讯、阿里、百度、免费接口任何一档,**「摘要现译」那一行都不在**(那张聊天截图没落进 tmp/shots/,本轮没编号 —— 它是**这轮要修的现场**,不是本轮的验收读数),原话「**我前面是有摘要现译的,你在哪一次改坏了,给我放出来**」+「**前面我使用免费接口都翻译了摘要,什么做不了**」⇒ 这一轮是把第十五轮③那道**档侧能力闸**撤掉,不是加新功能: ① **放回那一发**:lib/services/web-translate.js的SERVED_KINDS从['desc']改回['desc','readme']⇒kinds() 两路都报,enabled('readme')仍只看llmReadme 开关(放回不等于自动派活,额度还是用户点开的);api.js那道want('readme') 与**两道源侧闸门**(descSelfZh、readmeSource === 'en_default')一字未动 ⇒ 中文篇 README 依旧不白花那一发。 ② **不挂假名(本轮唯一保留的口径)**:翻译四档给的是节选的**逐字节译**,不是「整理成一段」的摘要 ⇒ 段名 summarySectionLabel(engine)(host_llm念「中文摘要」,其余四档念「**中文节译**」,失败行没有引擎、切不出档 ⇒ 念「**中文现译** · 没取到」),设置页那句说明switchRowLabel(key, engine)跟着档位走(行名**仍是**「摘要现译」,那正是你要放回来的那一行)。落款engine 吃的是**那一行自己的**(applyZh里?? 'host_llm' 只兜第八轮那批没这格的旧行),换档不会把旧的免费档译文署成模型口吻。 读数(10-07 16:0x,tmp/rerun-r17.txt/tmp/rerun-r17-full.txt):SKIP_LOCAL=1下 **370 过 / 0 挂 / 2 跳**,基线 371 → **372 项**(差值只在api 56→57:新那条钉的是"说明句跟着档位走、行名不跟着变";repo64 /client55 /web-translate28 /host-compat 21 **条数不变、内容改判** —— 前两套改成吃三档段名与两行开关,hc-18 从"翻译档只有一行"改成"两行",wt-28整条重写为"这一档 serve 两路");★ 不带SKIP_LOCAL的直跑:**371 过 / 1 挂 / 0 跳**,挂的仍是wt-27免费档**真出网**那一发回HTTP 429(外部限流,与本轮无关;上一轮同一条是通的 ⇒ 满绿不保证复现)。 **十二发证伪**全红到位(tmp/r17-falsify.mjs,圈 domain.js/web-translate.js/repo.js/api.js/client.js五个文件,读数tmp/r17-falsify-out.txt):**[证伪] 12 条 / 未抓到红 0 条**,末行 [还原 ok]。★ 首跑**没验成**一条:客户端那条锚点缩进抄错 ⇒ 报「锚点失效」而不是假绿(这条如实登记,改正后 12 条全红);③④那两组刻意做了**两头**(宿主拼段名跑 repo、客户端摆段名跑 client;服务的能力声明跑 web-translate与api两套)。 ⚠️ 诚实一句:**这一轮没有真机截图** —— 本轮动的是**宿主半边**lib/**,link:挂载下重载面板不算,要**重启 dsh desktop** 才看得见那两行开关与「中文节译」那一段(我不会替你重启,也不动你库里的 prefs 与缓存行)。两屏(设置页五档各两行开关 + 详情弹框那一段的段名与落款)并进那条欠着的走查清单(详情逐段 rect + 深色外观 +6/72 小时档 + 第十四轮那张名次徽章屏 + 第十六轮那两屏):**你重启后截给我,我就把这格划掉。** ★ **第十五件(README 有中文就不许译 —— 判据覆盖面补齐,2026-10-07 第十八轮):零行为改动,372 项复跑同数,抓出一条我自己的假绿。** 你的原话「**如果项目 readme 有中文,即使开摘要现译也不要翻译,只有英文的才翻译**」。核对结果是:**这条口径代码里已经在**(lib/api.js:356那道闸view.readmeSource === 'en_default' ⇒ 三档"已经有中文"的都不派:zh_default整篇中文 /zh_file抓到仓库另写的那份中文篇 /zh_section 整篇里嵌一段达标中文小节),所以本轮**没改行为**,改的是**判据与文档**三处: ① **判据覆盖面**:api那圈派活矩阵原先只在「**只开描述档**」的桩下摆中文形状 ⇒want('readme')恒假,那种行**测不到摘要闸门**(我第一版就往里加了一行zh_file,电池当场报它**假绿** —— 同族第七次:断言钉住了文本、没钉住前提)。改成在「**只开摘要档**」那一圈里**三档中文各钉一发**「jobs 必须为空」+ 各钉一发 self 段的档名,en_default 那一发仍派且喂的是节选。 ② **真库存对账**(tmp/probe-readme-zh-rows.mjs,只读、零出网、只打键与枚举不打行值,读数 tmp/probe-readme-zh-rows.txt):trans表 6 条readme:里**有一条对不上档** ——alibaba/open-code-review有engine:keyless的摘要译文行,而它repo行现在记的是readmeSource=zh_file(zhCjk=330)。**对得上的解释**:那行 src 是 600 字(第十五轮"节选与判据窗口分家"之前的旧上限),行时刻 12:24、repo行时刻 18:26 ⇒ 它是**第二路还没落地那一版判成"英文篇"时留下的旧行**。★ 关键是它**现在不会被读出来**:闸门排在translate() 之前,不派活就连查表都不查 ⇒ 我不去删你那行库存(旧行留着还是"曾经谁译的"的账,删它得你点头)。 ③ **口径落档**:lib/api.js那段注释原先只点名zh_section,现在三档都点名并写清"只有默认篇是英文才译"。 读数:全量复跑与第十七轮**逐套同数**(SKIP_LOCAL=1 下 **370 过 / 0 挂 / 2 跳**,api仍 57 —— ★ **条数不变、内容改判**的那一套:矩阵那一圈从 1 档中文扩到 3 档,加进去的行不增check()数,只报条数就会把这次改判漏记账)。证伪电池tmp/r18-falsify.mjs(圈 lib/api.js+lib/services/repo.js,读数 tmp/r18-falsify-out.txt)**7 条 / 未抓到红 0 条**,末行 [还原 ok]:闸门给 zh_file/zh_default/zh_section **各单独开侧门**(三发,验三档各自都真有现场、不是只有一条承重)、放宽成"有来源就派"(一发)、readmeZhVerdict 永说不是中文(repo 6 红)、pickZhSection 阈值抬死(repo 4 红)、第二路整条断掉(repo2 红)全被抓回。 ⚠️ 两条**没动的边界**(要动得先有真样本,别凭我判):一是阈值README_ZH_MIN_CJK = 20—— 整篇里汉字不足 20 且没有一段达标小节的**中英混排篇**仍算en_default(会译),当初定 20 的真读数是英文侧 ant-design2 / 中文侧 30、195、297;二是中文篇名字状README_ZH_NAME_RE与语言切换行 —— 仓库把中文篇放在子目录**又**没在默认篇里写链接时找不到(仍算只有英文 ⇒ 会译)。~~你说"这两种也要算有中文"我就去收窄,否则我留着这两个口径不动。~~ ★ **下一轮(第十九轮)你就说了**,这两条边界当场作废,见下面第十六件。本轮**行为一字未改 ⇒ 没有新真机现场**,第十七轮那两屏照旧欠着(要重启宿主)。 ★ **第十六件("这两种也算有中文" + 旧译文行删,2026-10-07 第十九轮):这次是真行为改动,376 项离线用例走过,同样没真机屏。★ 两件事里只做成了第一件 —— 旧行删掉后被在跑的宿主用内存态写回(④b/④c 记的是这一笔)。** 你的原话「**这两种也算有中文,旧译文行删**」⇒ 上一轮那两条"没动的边界"由你裁定作废,本轮做了两件事: ① **第三道源侧闸门readmeZhOnScreen(节选)**(判据在 lib/services/repo.js,常量在 domain.js,api.js 派活前调用)。两条来路各管你说的那一种:via='cjk'(节选里中日韩字符 ≥ **8** ⇒ 中英混排那档,真机 thedotmack/claude-mem 节选 9 字)/via='lang'(节选里出现「**中文**」两字 ⇒ 中文篇在子目录、第二路没抓到、手上只剩那行语言切换字样,真机 ant-design 英文篇整篇才 2 个 CJK)。★ **零额外请求**:吃的还是默认 README 那一发已经拿回来的那段节选,不猜路径、不许多打一发(60 次/小时那本账本轮没动);★ **零新增载荷键、零新增存储字段、repo 表 schema 一字未动**(第十轮那条「存储不可用」事故的律)。 ② **★ 档名律与闸门律分家(本轮最要紧的一条裁定)**:README_ZH_MIN_CJK = 20 **一个字没动** —— 那 20 管的是「默认 README 本身就是中文」**这句档名敢不敢说**;新的 8 只管「这段节选里已有中文 ⇒ 别派」。拿 8 去改 20 的后果是真读数:ant-design 英文篇整篇 2 个 CJK、claude-mem 那 9 个字**全是语言切换行的标签**(tmp/probe-zh-link-shape.txt)⇒ 那样改名等于档名说谎。两条律问的不是同一件事,阈值就该分开。 ③ **反面三条钉死(误挡一类就是删了你在用的那一屏)**:「**日本語**」不算中文(CJK 计数含假名,那 3 个字够不着 8 也不含「中文」⇒ 真机 m-abozaid/esp32-c3-adblock照旧派摘要);国名「中国 / 中國」不算声明;英文Chinese不认(Chinese tea 一大把)。命中时self 段名补那半句实话,两档各有字面(「(节选里已有中文)」/「(这行写着有中文版)」,宿主单点拼、客户端不重拼,client 那套黑名单盯着),★ 且**不许写成「所以没译」**—— 开关关着时同样不译,那句会把"没开"说成"不该译";zh_三档不补(中文由档名自己说)。 ④ **旧译文行删了一次,被在跑的宿主写回来了**(你点头的那一件,**这一件没做成**):库里trans表那条readme:alibaba/open-code-review(engine:keyless,而该仓现在记的是 zh_file/zhCjk=330)。做法两道闸都守住了:整文件备份 tmp/gh_trending.json.bak-20261007-192307(sha256 逐字节一致)+ 只有「JSON.parse再stringify(按库存自己的缩进档)与原文**逐字节相同**」才落盘,否则一字不改地退出(脚本 tmp/delete-stale-readme-row.mjs,默认干跑,只打键与枚举、不打行值)。19:24 的回执 trans 9 → 8|repo 16 行未动|其余各格逐字一致 ok,那一刻对账 readme:**5 条全部**en_default。 ④b ★★ **但 19:26:37 宿主那一写把整份内存态落回文件**(同批新增 37 条 events、state 三行刷新、seen+4 —— 它就在那儿跑着),19:33 复跑对账回落到trans 9 行 / readme:* 6 条,那一行原样在 ⇒ **文件层删一格而内存里那格还在,下一次落盘就还原。删它必须先把 dsh desktop 关掉**(我没替你关,也不动你的进程)。 ④c ★ **本轮最该记的一条是我自己的假读数**:动手前我用 tasklist过滤dsh/electron 判"宿主不在跑",据此把"可能被内存态覆盖"那句风险划掉了 —— 而宿主的进程名是 **DeepSeek Harness.exe**(PID 9500,10-07 18:25:01 创建),镜像名里 dsh与electron两个词都没有 ⇒ 那个过滤条件**结构上抓不到它**,判"宿主在不在跑 / 哪一版在应答"要按Get-CimInstance Win32_Process 的 **CommandLine** 匹配。★ 而「闸门排在 translate() 之前 ⇒ 旧行不查、不读、不上屏」那句仍然成立,所以它躺在库里不影响本轮行为。 ⑤ 读数(19:24 本机,tmp/rerun-r19.txt):SKIP_LOCAL=1 下 **374 过 / 0 挂 / 2 跳**,基线 372 → **376 项**。差额四条按圈记:api 57→**59**、repo64→**66**。★ 本套**第 8 次**撞自己立的坑:新那条 repo 用例名字里带「真机」⇒SKIP_LOCAL=1下**静默跳过并打 skip 1**,我一度以为它在跑 ⇒ 改名「两侧各用一条本机真读数钉边界」后才真进矩阵(要真出网的口径仍只归hc-17/wt-27)。 ⑤b **本轮出网账**:api.github.com **4 发**(tmp/probe-zh-link-shape.mjs:thedotmack/claude-mem与m-abozaid/esp32-c3-adblock各两发 =/contents/+/readme,只读、只打路径形状与 CJK 计数,不打正文也不打凭据),★ 另有 **2 次失败尝试**没打出可用读数(探针接线错,如实报差额不藏);**闸门与删行那两件事各 0 发**(闸门吃已在手的那段节选、删行是本地读写)。60 次/小时那本账本轮花 4。 ⑥ **八发证伪**(tmp/r19-falsify.mjs,圈 api.js/domain.js/services/repo.js,读数 tmp/r19-falsify-out.txt):**[证伪] 8 条 / 未抓到红 0 条**,末行 [还原 ok]:闸门撤除/阈值抬死/阈值降到 1/「中文」字样认法失效/放宽到 Chinese·中国/段名不补/那半句不分档乱补/闸门改吃库存 zhCjk全被抓回。★ **首跑第 ③ 条挂在别人的现场上**(阈值降到 1 时,同一个check()里lang 那条断言先炸 ⇒ "误挡日文"这个现场永远轮不到报红)⇒ 按「**证伪要在自己的现场上挂**」把反例**拆成独立用例**(api/repo 各一圈),拆完复跑才有那两行"红在自己的用例上";★ 拆圈的代价是条数上涨(api 58→59、repo 65→66),只报"新增一条用例"会漏记这一笔。 ⑦ ★ **一条能力边界如实登记(本轮没做)**:「中文篇在子目录、**默认篇里连那行都没写**」这种形状**没法零请求识别** ⇒ 猜路径就要多加一发,撞的是 60 次/小时匿名配额那条红线 ⇒ 只做「屏上那段有中文/那行写着有中文版」,不猜路径。~~另登记一条**没动的发现**(你裁定范围外):pickZhReadmeLink按名字排序取第一个 ⇒ claude-mem 那种形状会挑中docs/i18n/README.zh-tw.md(繁体)而不是 README.zh.md('-'(0x2d) 排在 '.'(0x2e) 前面)。~~ ★ **第十七件(第二十轮)把这条发现接住了**:你裁定「**使用 README.zh.md 这种**」⇒ 已落地,见下面那件;「不猜路径」那一条你也裁定了 **保持不做**。 ⚠️ 诚实一句:**这一轮没有真机截图** —— 本轮动的又是**宿主半边** lib/,link:挂载下重载面板不算,要**重启 dsh desktop** 才看得见(我不替你重启,除了④那一格是你点头才动的库)。要看的两屏是「混排篇/只剩切换行那两类仓库**不再多出**摘要段,且self` 段名尾巴上有那半句」+「日文篇那一屏照旧**给摘要」,与第十七轮那两屏一起并进欠着的走查清单:你重启后截给我,我就把这格划掉。

★ 第十七件(多份中文篇并存时挑简体那份 + 「不猜路径」保持不做,2026-10-07 第二十轮):一条真行为改动、一条零改动,378 项离线用例走过,同样没真机屏。 你上一轮那两条"没动的"这轮都有了答复(原话「只做"屏上有中文/那行写着有中文版",不猜路径」+「使用 README.zh.md 这种」): ① 零改动那一条:那种「中文篇在子目录、默认篇里连那行都没写」的形状不做路径猜测 —— 猜就要多加一发 contents,撞 60 次/小时匿名配额那条红线 ⇒ 第十九轮那道闸门的两条来路(节选 CJK ≥ 8/出现「中文」字样)就是最终覆盖面,能力边界继续如实登记(界面上永远不会为那种形状凭空多出一段中文)。 ② 真行为改动那一条:两条路命中多份中文篇时,旧写法都是 .sort() 取第一个,而 '-'(0x2d) 排在 '.'(0x2e) 前面 ⇒ 真读数 tmp/probe-zh-link-shape.txt 第 8~9、40 行:thedotmack/claude-mem 那行语言切换同时写着 docs/i18n/README.zh.md 与 docs/i18n/README.zh-tw.md,繁体那份被挑中了。 ③ 形状 = 一份优先档、两路共用:domain.js 两份封闭词元名单(简体 ['hans','cn','chn']/繁体 ['hant','tw','hk'])→ zhVariantRank(文件名) 出 0 明写简体 / 1 只写 zh、chinese / 2 明写繁体,比较器 byZhPreference 只此一处,pickZhReadme(根目录列表)与 pickZhReadmeLink(语言切换行)都挂它。★ 单点不是洁癖:第十五轮那条发现就是"两处各写一次排序"里第二处单独露出来的;电池第 ①② 条分两条钉,就是为了"只接一路时另一路那条必须还红得起来"。 ④ 三条边界各有反向用例:只排序不过滤(只有繁体时那份繁体照旧上屏 —— 把它过滤掉等于撤掉你在用的那一屏,同第十七轮"不许对任何一档说做不到"那条律;两档同时出现在一个名字里 ⇒ 保守按繁体算)/切文件名的词元,目录名不参与(docs/tw/README.zh.md 还是"不带变体"那份)、不按子串(拼错的 README.zh-cnother.md 不许冒充简体)/同档内仍按字面排序("稳定比聪明重要"没改判 —— 丢掉 tie-break 的话,GitHub 目录序一变你看到的那一份就换一份)。 ⑤ 出网账 0 发 / schema 账零增量:挑到哪一份都是原来那一发正文(详情编排仍 ≤4 发),载荷键、repo 表字段与域 version 一字未动。判据吃的是第十九轮那 4 发留下的读数+本地库存两行(只读)。 ⑥ 读数(20:1x 本机,tmp/rerun-r20.txt):SKIP_LOCAL=1 下 376 过 / 0 挂 / 2 跳,基线 376 → 378 条,差额只在一套:repo 66→68(zhVariantRank 一圈 + 「两路共用同一条优先档」一圈);★ pickZhReadmeLink 那一圈条数不变、内容改判 —— 旧断言「多条命中按名排序」把"繁体那份赢"钉成了规矩,本轮当场翻案(同第八轮 provider:undefined 那一族:离线断言把坏行为钉成规矩)。 ⑦ 九发证伪(tmp/r20-falsify.mjs,圈 domain.js / services/repo.js,读数 tmp/r20-falsify-out.txt):[证伪] 9 条 / 未抓到红 0 条,末行 [还原 ok]:两路各退回字面排序/两路各把排序做成过滤/词元从整条路径切/词元换子串/简繁先后调换/丢掉 tie-break/两份名单撞车,各红在自己的断言上。★ 一条自我 correction:首跑第 ⑥ 条的植入写成 /tw|hant|hk/.test(base) —— 顺手把大小写归一也丢了,一发变异同时动了两维(连带把 pickZhReadmeLink 那一圈也炸了)⇒ 改成 base.toLowerCase() 只动"词元还是子串"这一维再跑。变异也要单因,否则读数在同时说两件不同的事。 ⑧ ★ 对照读数(只读、零出网):库里 thedotmack/claude-mem 那行 repo 记的是 readmeSource=en_default / readmePath=README / zhCjk=9 / at=2026-10-06 08:42:21 ⇒ 那发早于第十五轮第二路,它身上第二路从来没跑过。所以"改完挑简体那份"这一条不是验证过,是重启后要点开它看的那一屏。 ⚠️ 诚实一句:这一轮也没有真机截图(又是宿主半边 lib/** ⇒ 要重启 dsh desktop,我不替你重启)。要看的那一屏只有一处:点开 thedotmack/claude-mem,self 段元数据里的路径念 docs/i18n/README.zh.md;顺带 alibaba/open-code-review 应仍是 docs/i18n/README.zh-CN.md(它只有一个候选 ⇒ 若它变了,就是我把排序做成了过滤)。★ 第十九轮那件"旧译文行删"这一轮照旧没做成:20:0x 复跑对账仍是 trans 9 行 / readme:* 6 条(宿主 5 个 DeepSeek Harness.exe 进程在跑,18:25 起)⇒ 等你关掉 dsh desktop 我再删一次,脚本与逐字节备份都在 tmp/。 ★ 同一轮 21:3x 再对一次账(只读、零出网),有两处要把旧读数划掉:宿主在 21:10:33 被重启过(5 个 DeepSeek Harness.exe 全为新进程,库存文件 21:12:15 落过一盘)⇒ 上面那句「18:25 起」只对那一遍成立;而那一版加载的是 client.js(16:43)/ lib/api.js(19:26)/ 第十九轮那两份 lib/** ⇒ 第十七、十九轮那几屏现在就在应答,不必再重启就能截;本轮 21:20:06-07 落地的 lib/domain.js / lib/services/repo.js 晚于那次重启 ⇒ 只有第二十轮那一屏还欠一次重启。同一遍对账:readme:* 仍 6 条(含那条 zh_file 的旧摘要行)⇒「旧译文行删」照旧挂着。

下面的挂载步骤是给你确认用的。

方式 A:官方 CLI

dsh plugin --profile desktop add github:gh-gongjin/dsh-plugin-gh-trending

CLI 内部走 pnpm,需要 pnpm 在 PATH 里。本地目录同样可装:dsh plugin --profile desktop add <本仓库的绝对路径>。

方式 B:手工两步(不需要 pnpm)

  1. 编辑 profile 的 package.json(桌面版是 ~/.dsh/profiles/desktop/package.json,Windows 为 %USERPROFILE%\.dsh\profiles\desktop\package.json):

    • dependencies 增加:"dsh-plugin-gh-trending": "link:<本仓库的绝对路径>"
    • dsh.profile.bundles 数组末尾追加 "dsh-plugin-gh-trending"
  2. 在 profile 的 node_modules 下建目录联接:

    New-Item -ItemType Junction `
      -Path "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-plugin-gh-trending" `
      -Target "<本仓库的绝对路径>"
    
  3. 重启 dsh(宿主半边在启动时加载)。只改 client.js 的话刷新页面即可。

停用 / 卸载

临时停用:在 ~/.dsh/profiles/desktop/cordis.patch.yml 里加

- id: gh-trending
  disabled: true

界面

S2 起是页签制(交互照 modelwatch 的同源实现):页头(三榜状态胶囊 + 「立即检查」+ 该操作的回执)与页签条包成一块 sticky 常驻,滚到榜底也切得动签;六个签 ⇒ 第二十三轮(10-09)起七个签 ⇒ 第三十二轮(10-13)起八个签 ⇒ 第三十六轮(10-14)起九个签 总览 / 日榜 / 周榜 / 月榜 / 明星仓库 / 收藏 / 检索 / 变化记录 / 设置(「明星仓库」插在月榜之后、「收藏」插在明星仓库之后、★「检索」插在收藏之后、「变化记录」之前 —— 用户裁定的形状甲,否掉「并进明星那一屏」),签上带该榜条数徽标(0 条、总览与设置不带徽标 —— 拿 0 冒充有数最坏;★ 「明星仓库」的徽标 = 载荷 stars.rows.length、「收藏」的徽标 = fav.rows.length,同一律;★ 「检索」这一枚不带徽标 —— 那一屏零入库,快照 search.rows 恒空,摆一枚 0 就是把"没库存"演成"这一档坏了")。⚠️ 第七枚插进来之后页签条的宽度与折行在活宿主上还没量过(旧那份"六个签在 1088px 栏里 scrollWidth === clientWidth"是第九轮的读数,判据在 client-38,七签要重看 —— 挂在 §9.3);★ 第三十二轮又多一枚 ⇒ 那一遍要量的是八签,本轮零截图、读数挂在 §9.3 那条;★ 第三十六轮再加一枚 ⇒ 现要量的是九签(同一遍走查补一次读数即可,判据面新立的是 client-17/client-30 那两个就地改判:labels 表九键、clicked 九键)。

  • 总览:三榜状态 → 每榜前 3 名速览(名次徽章 + 仓库 + +新增)→ 跨榜同现,一屏看完「要不要点进某一榜」;卡头的「完整榜单 →」就是切页签。总览原先收尾在一张「最近变化」小结(前 4 条 + 「全部 →」),2026-10-05 用户口径去掉——流水就归「变化记录」那一签管,总览不重复养一份影子。
  • 日 / 周 / 月榜:各自一张 8 列大表(table-layout:fixed + <colgroup>:# 46 / 仓库 268 / 描述吃余量 / 语言 112 / 累计★ 64 / 本轮新增 72 / 位次变化 56 / 兜底 0,≤1000px 时仓库吃余量、描述定 160),卡头一行给「榜面数据 · 最近取回 」(坏榜改口「最近尝试」)与 显示 / 榜面 计数,这一张榜真有命中的描述时再追一句「· 描述中译为内置离线预译 · <日期>」(没命中就整段不出现,载荷的 label 换成别的界面就跟着变 —— 那句话读的是 snap.descZh.label,客户端不许自己编日期)。描述列:命中的行显示译文、悬停看得见原文(译文是预译的,读的人有权核对它翻的是哪一句),没命中的行仍是原文。 ★ 第二十二轮(10-08)这一列与卡头跟着改判(§8.7):卡头那一句现在读 snap.descZh.heads[board](按这一张榜算好的整句,宿主给什么念什么:描述中译为内置离线预译 · <日期> / 描述中文为现译 M 条 / 描述中文:内置预译 N 条 · 现译 M 条,都没命中给空串 ⇒ 整段不出现;client-48 两头钉死"界面不数条数、不拼句子、不拿别榜的句子挂本卡")。 描述列从此一列两种来源并存 ⇒ 落款跟着每一行走:descZh.hits[repo] 是 {zh, via, label, note, src} 五格,悬停给「原文 + 这一行自己的来源 + 注」(拿卡头那一句套每一行就串了 —— 内置预译与每轮补的现译说的不是一件事); 再加一句 descZh.liveNote(只在「有欠着的行 + 库存得下 + 开关开着 + 这一路此刻给不出」四格同时成立时非空:「榜面这一列只显内置预译:现译这一路这会儿发不出去…下一轮检查会自动再试」),榜面一行都没空榜也不唠叨(client-58)。
  • 明星仓库(★ 第二十三轮(10-09)新增,形状 = 用户裁定的那份 B):这一屏答「哪些仓库反复上榜、谁在往上走」,原料全在本地(最近一轮三榜的行 + 观测史 seen)⇒ 打开这一签零请求,与榜面同一条"出网只在点仓库名那一下"。七列 # / 仓库 / 描述 / 语言 / 累计 ★(今日新增)/ 在榜(轮数 · 峰值)/ 兜底(★ 「今日新增」只吃日榜那一条,不在日榜给 — 而不是 0;周/月榜的"新增"是另一个周期,混进同一列就是把两件事演成一件);卡头只摆三件(标题 + 视图分段器 + 那一档的开关),排序分段器与统计那句下沉到卡体首行 .gt-bar,滚动权在卡内的 .gt-scroll(整页一张卡,卡是 .gt-root 的直接子)。 ★ 「一份真相」在这一屏钉得最死,因为这里每个数字看着都像"界面自己数一下就有":档位归属、排序、行数、置灰判据、缺位符、那三句话全在宿主(载荷 stars 那一格),界面只做"筛与不筛、搬与不搬"(判据 client-59~client-63,承重由 tmp/r23-stars-falsify.mjs 那八发验过)。 全站高星那一档出厂关着(§1 那份清单里唯一新增的一路,prefs.allStarsEnabled 出厂 false):关着 ⇒ 分段器那一枚照摆但 disabled、签上写「全站高星 · 未开启」、卡体念那句 note(点「开」的那一刻当场发那一发、之后每轮最多一发、结果进缓存、关掉不删已攒的那些行);★ 10-09 改判(用户裁定「开启的时候默认拉取一次」):把那一档从关拨到开 ⇒ 宿主在 POST /api/prefs 的回执里当场发那一发(认的是库里的转换,已经开着再存一次 true 不派;发完才回回执,所以按钮"保存中…"散去的那一刻那一批已经在库里),之后每轮 1 发、不补发、不重试,失败时上一批照常显示并挂一句故障(★ 连"点开的当口就坏了"也是当场追帧,不藏到下一轮),三榜一个字不动;★ 同日第二条裁定给那一趟又加一道新鲜度闸:库里最后一次成功取回还在一份检查间隔(prefs.intervalMin,出厂 60 分)之内 ⇒ 这一趟 0 发、也不追第二帧(那一批本来就在库里,开关位随同一次回执上屏)——"当场"指的是当场决定发不发,不是必发;⚠️ 上一发是坏的那一档不算"拉过",点开照旧重试;这一道只挂在开启那一趟,检查轮那一路不受影响;★ 开启 ≠ 跳档(点的是数据源的开关不是切屏),只有关掉时把人送回名单第一档(那一枚这时已 disabled,不送就困在这一屏)。 ★ 10-10 第三条裁定(用户看了真机截图问「这些为什么没有翻译过来」,裁定「按 A 执行,条件判定加上 allStarsEnabled」):这一档开着时,它那一批行也进描述列的现译集合 ⇒ 那一屏的「原文,未翻译」不再是固定形状。判据的出处只有一处(lib/board-zh.js 的 descZhRows({ boards, allStarsRows, allStarsEnabled })),快照视图与每轮检查后的补译批次都调它 —— 分成两处各判一次就会造出"hits 里有它而排队里没有"那种半截屏(第二十三轮把这一档排除在现译之外的那句裁定已作废,见 §8.8 落地改口 10 与新增的第 17 条)。每轮那 12 发是两组共享的同一份预算、榜面先吃饱(两个 rank 不同轴:榜内名次 vs 全站名次);界面上那句「榜面这一列只显内置预译」的欠账只数榜面那一组(boardMissing),只有全站那一档欠着时榜面不许念它。关着 ⇒ 一行都不进参与集合(库里已攒的译文不删也不上屏,重开立刻上屏、不重烧额度);真机补齐那一屏需要 ceil(28/12) = 3 轮 ≈ 180 分钟(§1 出网账),且满屏之后仍不发(逐字复用那把判据照旧)。 ⚠️ 两处与榜面的可见差异,都是律逼出来的不是漏做:语言那一枚点是灰的(这一屏的行不带 langColor,补齐它要么在宿主再造一份色表出口、要么让客户端定义枚举 ⇒ 走 CSS 那一份灰);卡脚没有 .gt-note 那句(原型上有,那是界面自己拼的话)。
  • 收藏(★ 第三十二轮(10-13)新增,第八个签,用户诉求原文「增加一个项目收藏功能」):三处入口那枚 ☆ 都画在宿主给的那一行上(三榜行尾 / 明星行尾 / 详情弹框标题行,同一个组件 FavStar,亮灭只看一个 on 位),点它只改收藏 ⇒ 不跳转、不开弹框、不滚动,榜面那一枚还必须 stopPropagation(client-71)。 这一屏七列 # / 仓库 / 描述 / 语言 / 累计 ★(那一刻)/ 收藏于 / ★(★ 第三十五轮:用户指着屏上「这一轮」那一列说「去掉这个」⇒ 八列变七列,右侧那一枚 ★(取消收藏的入口)照旧留着、还是最后一格),★ 星数列表头那个「(那一刻)」和卡脚那句 note 是同一件事的两句说法(星数与描述是收藏那一刻的快照,不随榜面刷新),要新值点仓库名走详情那条链 ⇒ 打开这一签零请求。三档排序分段器 收藏时间 / 累计 ★ / 名称(默认档「收藏时间」)与页签一样落 localStorage(favSort,第二十九轮那套 pickOption 复用);名单只有一份出处(snap.fav.sorts),客户端一个字不排表(client-75)。 「这一轮」那一格念的是成品句(在日榜 / 在周榜 / 在月榜 / 在明星 / 未上榜,优先级与那两句汉字只在 domain,FAV_ON_BOARD_PRIORITY),★ 单值 —— 一个仓库同时在两榜只念优先级最高的那一个;没命中那一档跟着置灰(gt-flat),与明星屏同一条读法。 ★ 第三十五轮(10-13)这一整段作废:那一列连同宿主侧的派生、载荷里那一格、domain 那四个名字(FAV_ON_BOARD_LABELS / FAV_OFF_BOARD_CELL / FAV_ON_BOARD_PRIORITY / FAV_COL_ON_BOARD)一起撤干净,不留死码 —— 判据是 favs 那条「撤一列连入参一起撤:旧的三档原料照喂,行与载荷也长不出「这一轮」那一格」+ hc-24(那四个名字零出处、favView 的调用点只喂三格、客户端连「未上榜」那三个字都不认)+ 电池 tmp/r35-onboard-cell-falsify.mjs 十一发。仓库名旁边那枚「来自 日榜」照旧吃宿主拼好的整句 fromCell(客户端把 from 和「来自」接起来就是第二份榜名,client-72)—— 撤掉那一列之后,这一屏与榜面的关系只从那一枚出处牌读。 ⚠️ 三档说话分开:available !== true ⇒ 卡体念 noStoreNote(存储不可用,☆ 按下去不落库);available === true 且零行 ⇒ 念 emptyNote(还没有收藏);★ 两者不许同时出现在屏上(那两句互相拆台)—— 这道闸门正是本轮取证出来的两处真缺陷之一,判据 client-74。
  • 检索(★ 第三十六轮(10-14)新增,第九个签,用户诉求「加一个全站项目检索功能」+ 裁定形状甲):这一屏答「我问 GitHub 一个词」,与「明星仓库」(本机攒下的那批)和「收藏」(我挑过的)都不同源。六列 # / 仓库 / 描述 / 语言 / 累计 ★ / 收藏(★ 表头那两枚列名吃载荷 search.cols,前四格是界面结构名、与明星屏同名同序;⚠️ 没有第七列 —— 那一屏不摆「这一轮」也不摆「在榜」,它跟榜面没有库存关系)。五件事的形状各有判据(client-79 / client-80 / client-81): ① 触发只有两处:回车(且 !e.isComposing,输入法选词期间回车不发)或点「搜一下」⇒ 敲进去的字不会自己变成请求(无防抖、无输入即发,那形状会在一个词里烧掉整池匿名额度);在问的那一会儿输入框与按钮一起 disabled。 ② ★ 零入库 + 不广播:这一趟八张表一张都不碰、也不 hub.broadcast('update') ⇒ 结果是"这一次提问"的一次性载荷,切页签、刷新面板、重启宿主就没了,同机的另一块面板也看不见它(这是零入库的定义,不是缺陷。⚠️ 卡脚原本那一句长说明已由用户 10-14 当场划掉,见第三十六轮 ⑫ 追加改判 —— 这件事现在只由上面 ③ 那六句状态话来说,卡脚只剩额度那一行)。⚠️ 界面因此不许读 snap.search.rows(快照那一格恒空,它只是文案格),也不许把输入的词落进 localStorage(那是草稿,第二十九轮那条律继续生效)。 ③ 六态各说各的话:还没问 / 正在问 / 有结果 / 没回仓库 / 额度用尽 / 那一发没成(★ 六句成品与六枚短词只在 domain,SEARCH_STATES / SEARCH_STATE_LABELS / searchStateLine();empty 是答案、error 是没答案,两态都不摆空表 ⇒ 只有 ok 那一态摆表;判据 client-79 ⑦ 两头钉:屏上那一句逐字等于载荷那一句 + 六句互异 + 喂空串时屏上必须画空)。 ④ ★ 唯一拿不到回执的那一会儿(asking,POST 还没回)念的是快照预带的那两句(snap.search.stateLabels.asking / askingNote)⇒ 快照因此多一枚 search 文案格(恒零行、纯文案,state 恒 idle);这是「界面不许自己抄文案」与「那一会儿屏上必须念得出话」两条律唯一合规的交点。 ⑤ 描述那一格是被动上屏(第三十三轮那条律的第四次复用):descCell(r.desc, r.descZh, missing),中文只多开一格、desc 恒是原文;★ 这一屏不派现译、不进补译集合(出网账由用户那一次点击决定,不由这一格偷偷加一发),命中的判据仍只在 descZhHits 一处。语言那一格只有名字、没有色点(search 回包压根不给 langColor,插件里不许另立第二份语言色表 ⇒ 走 CSS 那一份灰)。 ⑥ 行尾那枚 ☆ 递三样:屏 id search + 屏上那一刻的三格 seed{desc, lang, stars} ⇒ 收藏那一屏「来自」那一格念成**「来自 检索」(第五档出处,FAV_FROM_SEARCH)。⚠️ 用户裁定的 B 案(原话「点击收藏的时候,同步存储这些数据」)在宿主侧有四道边界**:只在 add 且 from==='search' 那一支看、★ 四路 first-hit 优先(库里任一有读数 ⇒ seed 整格忽略)、脏值整格丢掉(不截断、不把 "9000" 圆成 9000)而收藏照旧成功、langColor 这一路压根拿不到 ⇒ 那一行色点恒缺位。
  • 变化记录:全量流水。设置:偏好 + 只读「运行环境」表(环境跟在设置里,不占一个签)。偏好里 出网方式 那行下面是现译引擎五档分段器(免费接口 / 百度 / 腾讯 / 阿里 / 宿主模型,★ 档名、顺序、当前档、这一档那句 engineHint、以及「这一档现在发不出去」那句 notReadyHint 全从 snap.translator 读,点一下即存,客户端不排表);只在选中有凭据那三家之一时多摆一行凭据(每档恰好两格、由 credFields[] 给出:AppID+密钥 / SecretId+SecretKey / AccessKeyId+AccessKeySecret。标识符那格是普通框、value 等于库里那份,密钥那格 type=password 且 value 恒空、从不回显 —— placeholder 说「库里已存(留空不改动)」而不是给你看那几个字;旁边那个「清除」只在库里这一档真有凭据时才出现(credStored),点了只发当前档那两格的空串,没凭据时它压根不摆;留空的密钥框不进 patch,进了就等于清除,那是旁边那个按钮的语义);凭据行下面紧跟注册那一行(百度 1 个链接、腾讯/阿里各 2 个 —— 开通入口与密钥管理分开,全部 target=_blank rel=noreferrer,★ 只跟当前选中的那一家,别家的 URL 出现在这一屏即红;那句额度话不念具体数字,只指向官网计费页);再下面才是现译开关行(★ 第十五轮:行清单是载荷给的 —— snap.translator.switchRows[],每行 {key,kind,row,label,on} 五格,客户端只念 key/row/label/on 四格,一行代码都不排表;当前那一路 kinds() 报什么 ⇒ 屏上就摆什么(★ 第十五轮那四档只报 desc、只有 描述现译 一行;第十七轮用户改判放回 ⇒ 五档的 kinds() 都报 desc+readme,两行开关五档都在,行名 摘要现译 不跟着档位变,只有那句 label 跟着变:翻译四档念「README 英文节选译成中文(这一档只做翻译,这一段是节译不是摘要)」,宿主模型 念「README 英文节选另给一段中文摘要」)。同一套分段器类名 .gt-seg,点一下即存,没有草稿态;这些行只管「要不要」,「能不能」只在上面引擎那一行说一次;「这一路压根没有摘要能力」这件事由那一行不出现来说(★ 第十五轮那句作废:现在由那一行的说明句来说 —— 撤掉一行等于删了用户在用的那一屏;仍然不许客户端自己补行:载荷没给 switchRows 的旧宿主整段不摆,点了没用的控件比没有更糟 —— 那说的是载荷里没这一格,与档位无关)。出网方式 是三档分段器 + 一个地址框(草稿,点「保存」才发),切到 自定义地址 时模式与地址一起发——只发模式会拿旧地址出网,只发地址则可能压根没在用自定义。详情缓存那一行(★ 第十二轮立起)与检查频率同形状:四档分段器 6 小时 / 12 小时 / 24 小时 / 3 天、出厂 24 小时,档位与话术都从入口载荷读(cacheHours / cacheHourLabels,客户端一个字不写)、点一下即存;★ TTL 在服务侧调用时现取现算 ⇒ 改档后下一发详情就按新档判新鲜,不必重启宿主;档位外的值 POST /api/prefs 直接 400(不许悄悄回落 24 —— 那等于库里一个值、分段器上另一个值);失败档那 5 分钟不进设置页(故障保护不是给用户调的配置)。 ★ 第二十七轮(10-10)那一行整行撤掉(用户裁定原文「撤掉这一行,改成固定 60 秒防连点(推荐)」),★ 第三十一轮(10-12 用户再次亲手改判)按原来那形状摆回来(裁定原文「还是改成以前那种模式,默认缓存24小时,可以配置,听不懂吗,不要用60秒这种」)⇒ 上面那段划掉的描述逐字又是当前口径,只补三条本轮新增的语义:① TTL 之内一发都不问(连验证器都不问,不是"只问验证器");② 那一档多一条例外:库里 zhProbed 不是 true 的成功行不受 TTL 挡(第三十轮那半截结论必须过档就真出网重判,否则要等满 24 小时才自愈);③ 撤档期间换进去的那格 60 秒防连点(DETAIL_RECHECK_MS)整键删掉,snap 里那两格(cacheHours / cacheHourLabels)回来,detailStampLabels 那格留着但只剩两个词(第三十轮补的第三截跟着撤,见下面「详情弹框底部那句落款」那条);库里那一格从头到尾没真正消失过(第二十七轮只是让 open() 静默丢弃它)⇒ 本轮改回 optionalInt 声明收住、POST 脏档照旧 400(它现在又决定"这一问出不出网"了)。失败档那 5 分钟照旧不进设置页(故障保护不是给用户调的配置)。运行环境第一行是 传输路径:最近那一发到底走了哪条路(代理隧道 · Windows 系统代理 · http://127.0.0.1:7897 / 直连 · 设置页选了直连 / 没能出网 · <原因>),整句由宿主拼好,客户端只搬字;没出过网之前这一行干脆不出现。
  • 没有自动弹出的提示层(toast / 通知):所有错误、降级、保存反馈一律就地落在那张卡上;「立即检查」的回执落在页头,因为按钮在页头 —— 页签化之后若回执仍只活在某一签里,点完按钮的人当场看不到下文。唯一的浮层是点仓库名才出现的详情对话框:它不自己冒现。★ 对话框的内容从第十一轮起是段表直通:宿主把 sections[] 一次拼死(四段 项目是什么 / 热度与元数据 / 仓库自己怎么介绍它 / 中文摘要,每段一组带 kind 的块 p/sub/num/excerpt),客户端只按 kind 挑类名摆(.gt-modal-sec 装段、.gt-modal-h2 是段名、.gt-modal-p / gt-sub / gt-num 逐级加重、excerpt 走带框那条 .gt-modal-readme),不重拼句子、不自己排段序、数字只从 heat 段那一张 gt-modal-facts 出来(同屏一个数只出现一次);现译那两句(中文描述 / 中文摘要)也落在段里,不另立一套视觉语言。 ★ 第十二轮(用户裁定「把这个页面上的废话都去掉」)把四段各自的"来源落款"整句撤了:段对象只剩 key/label/blocks/facts 四格(source 那一格连同 REPO_SECTION_SOURCE_NOTES 那张表一起删), "这一份是谁写的 / 那一句是谁译的"并进段名说(仓库自己怎么介绍它 · 默认 README 是英文、仓库自己怎么介绍它 · 默认 README 里有一段中文说明(小节「…」)、中文摘要 · 免费接口 · 10-07 09:5x ★ 这一个是第十五轮之前的真读数,那时段名不分档;第十七轮(10-07)起段名跟着那一行自己的引擎走:宿主模型 才念「中文摘要」,翻译四档念「中文节译 · 免费接口 · …」,失败行念「中文现译 · 没取到」),README 那行落款压成一行短字面 节选 54 / 整篇 4,235 字 · 已去标记 · README。 ★ 第十五轮:那一行短字面没改形状,改的是节选本身 —— 旧版拿"数中文的那 600 字窗口"当节选交出去,README_EXCERPT_MAX=1600 那道预算从来没生效;现在窗口只服务判据,节选吃去标记后的整篇,并且在句子边界收口(真机那屏断在 Install Ask your a)。真读数:节选 1,594 / 整篇 4,802 字 · 已去标记 · README(tmp/shots/70-r15-detail-excerpt.png)与 节选 1,586 / 整篇 8,869 字 · 已去标记 · docs/i18n/README.zh-CN.md(第二路真回包 tmp/r15-ocr-live.json)。 撤的是解释,不是事实:「不是现译」那个标签、仓库原文那一句(译文永不替换原文)、页脚那行 GitHub 配额,三件都照旧在屏上。 ⚠️ 诚实一句:「四段摆出来好不好读」的判据这一件(类名逐字 + 块序 + facts 归属 + 段对象只四格 + 那四句旧落款一句都不在屏上)在第十一、十二轮只有离线判据,旧那三张 tmp/shots/42-detail-*.png 是第八轮「一整句叙述」那一版的图、别拿它们当第十一轮的读数;★ 第十五轮(10-07)补上了活宿主那一屏的截图与弹框几何(tmp/shots/68~70-r15-*.png:设置页两档各有几行开关、详情弹框 650×319 / maxHeight 400.8px / 弹框自身不滚),但"逐段 getBoundingClientRect"仍然欠着 —— 每一段吃多高、sub/num 墨迹深浅差、excerpt 的边框与内边距,那一遍没量 ⇒ 挂在 §9.3 未验证清单第十一轮那条。 ★ 第二十八轮(10-10):self 段段名那一行右侧多了三枚常驻按钮(展开全文 / 译整篇 / 整篇摘要,用户原话「加几个按钮……不受参数设置控制」)。形状上四件事各有一条判据(client-64 / 65 / 66): ① 常驻 ≠ 恒能点 —— 三枚恒在,不该点的那一枚 disabled 并把原因写进 title;置灰有四种各说各的话(no_readme 这一屏没有可展的原文 / already_zh 仓库自己写的就是中文 / no_sum_capability 这一档只会翻译不会摘要 / not_ready 现译这一路此刻发不出去),★ 而且**"根本没装配现译"那一支排在能力位之前**(少了它那种屏会念成"这一档不会摘要",是把没接上的东西说成不支持); ② 点下去当场 await 跑完再回执 ⇒ 没有进度条(浏览器拿不到中间态;硬做要再引一张 job 表 + SSE 推进度,本轮撤掉)、也没有"停手"按钮:关掉弹框不打断那一趟,结果照样落库、下次点开秒出 —— 这是"取消"最省的形状,真取消要让 AbortController 贯穿分块循环(第二套生命周期); ③ 那两段中文只从载荷 manual.sections 摆(段名连落款原样念,库里没有那一行就整段不摆;回执那份读不到库也照样顶上一屏,因为那一趟不能白跑;失败回执不顶替那一段),展开那一下只按 kind 覆盖已有的两块(节选 + 那句元数据),客户端不判"这一段该显示什么"; ④ 按钮名单回执那一份优先于点开那一刻的详情载荷(档位换了置灰口径跟着换),且 disabled 同时认 can 与"正在跑" —— 同一趟额度只有一份,跑着的时候连另一枚也不许点。 ⚠️ 这三枚是第一条由界面发起、当场花模型额度的动作 ⇒ 真机那一屏(点了真等 20 秒那一趟)到现在一次都没走过:活的宿主半边要重启 dsh desktop 才装得上新的 lib/**,挂在 §9.3 本轮那两条欠账里。
  • ★ 第二十九轮(10-12):页签与明星那一屏的档位落 localStorage(你那句「切换了tab后,右侧面板选择的东西就没了」)。屏上只多了一件事 —— "它记得你上次在哪",四条形状各有判据(client-67~client-69 + 改判的 client-62 ③″): ① 存的只有三枚 id(tab / starsView / starsSort,键 ${panelId}.ui.v1 跟着载荷的 panelId 走)⇒ 设置页那份草稿、详情弹框那一份、四把密钥一律不落(半截密钥进浏览器存储是新增的泄露面;草稿落盘等于把"未确认的输入"变成"下次自动用它",而 proxyUrl 那格点「保存」才生效); ② 读回只认名单(在册且未禁用才生效)⇒ 档位撤掉、库里那点脏值、载荷换了一批都不认,界面上就是一次正常的出厂;「关掉那一档把人送回名单第一档」与这条回落共用 pickOption 一处判据,不另立第二份真相; ③ 生效档在渲染期现推,不在挂载时定死 ⇒ 首帧还没有载荷时,不许把存着的那一份判成"不在册"(否则载荷到位也回不去,用户看到的仍是"记不住"); ④ 存储坏了不带走界面:读写各包一层 try/catch,读不到当没存过、写不进就在内存里用完这一份(宿主自己的 README 就写着「存储失败时,当前布局仍可在内存中使用」,插件同口径)。 ⚠️ 为什么这件事必须由插件做:宿主的 main 是 keyed 席位(entryKey = activePanelId,renderer 只渲染命中那一条),切走面板就是整棵树重建;那条 keepMounted 保活只给右侧栏 tab 席位,本插件走的 sidebar.panellist + main 不在其上 ⇒ 「切回来还在」这个席位上从来没有保活可依赖(宿主侧行号取证见 spec §8.12)。
  • ★ 第三十轮(10-12):详情那一屏的两笔真机 bug + 60 秒窗口命中那一屏的可见结果(你那两条「我开了摘要现译,这个点开没有翻译」与「截图里写着有中文,为什么没有拉取到中文版」,判据与病历见 spec §8.13)。三件事的形状: ① 中文 README 那一档不再被 304 冻住:repo 表追加一格 zhProbed(optionalBool、域 version 恒钉 1),口径是判定输入齐了才算探完 —— 八形里六形算探完(zh_default / zh_file / zh_section / README 404 那个 none / 中文篇坏链接的 404 / 清单 200 且两条路都无线索的 en_default),只有"探测那一发自己没答上来"两形留 false(清单 5xx、中文篇超时 ⇒ 同一个 en_default 档名,探没探完差在这一格);库里那一格缺或 false ⇒ 下一问一个字都不喂验证器(裸发重判一次),探完才写回 true ⇒ 代价是一次、三问内收敛,不是每问四发。★ 这一格填的正是第二十七轮那道「304 就沿用库里那一行」的洞:上一版把半截探测结论(默认篇是英文、中文篇那一发没探成)连同整行一起冻结,用户每问一次都命中同一个 en_default,永远翻不出中文。 ② 摘要那一发不再被"推测有中文"挡掉:源侧第三道闸门从「屏上有中文 或 那行写着有中文版」收窄成只认屏上真中文(readmeZhOnScreen(节选).via !== 'cjk' 才派活)—— 第二路那份「语言切换那一行」是线索不是正文,拿它挡摘要等于替用户断定"中文的已经在屏上了"。段名后缀那两支照旧都给(README_ZH_GATE_SUFFIXES 认 cjk 与 lang 两种来源,说的是"段名为什么这么念",与"要不要派活"是两件事)。 ③ 窗口命中那一屏有可见结果:详情底部那句落款补第三截「60 秒内没再问 GitHub」,只在 cached:true 那一支出现(DETAIL_STAMP_LABELS.windowHit,秒数由 domain 现拼,client.js 一个字不写那个数)⇒ 第二十七轮那条「60 秒内再点同一仓库,这一发请求都不发」从此在屏上看得见,不再是只有账本知道。⚠️ 这一条不是缺陷修复:「为什么不缓存 24 小时」的 24 小时档是用户 10-10 自己裁定撤掉的(裁定原文「撤掉这一行,改成固定 60 秒防连点」),本机 60 秒内实测 0 发 —— 补的是可见结果,不是把档位加回来。⚠️ ★ 第三十一轮(10-12)这一条整条作废:用户当场改判「听不懂吗,不要用60秒这种」⇒ 那一档加回来了、第三截与 windowHit 那个词整撤,DETAIL_STAMP_LABELS 回两格;这一句当时把性质判错了(当成"缺一句可见话",实际要的是行为回退),登记在此不改写历史。 ⚠️ 本轮动的是宿主半边 lib/** ⇒ 要重启 dsh desktop 才看得见(client.js 那半刷新面板即生效);四条判定性走查挂在 spec §9.3,本轮零真出网、零截图,你的 prefs 与库存行一个字没动(走查前别清库、也别改偏好,那两条 bug 的现场就在库里那一行)。
  • ★ 第三十一轮(10-12):设置页「详情缓存」那一行按原形状摆回来 + 落款回两截(用户裁定原文「我说还是改成以前那种模式,默认缓存24小时,可以配置,听不懂吗,不要用60秒这种」)。界面上只有两处: ① 设置页那一行:四档分段器 6 小时 / 12 小时 / 24 小时 / 3 天、出厂 24 小时,档名与顺序仍从载荷 cacheHours / cacheHourLabels 读(客户端一个字都不排表,client-53 钉这一条时打的是"客户端写死那四个数"⇒ 电池第 ⑧ 发);点一下即存,改档下一发详情就按新档判(getTtlMs() 现取现算,不必重启宿主);旧宿主没推 cacheHours ⇒ 整行不摆(摆出来点了没用的控件比没有更糟,与现译那两行同一条律)。 ② 详情底部那句落款:从三截回两截 —— 正文取回于 <多久> 前 · 刚核对过,且第二截收窄成只在真核对过那一问才念(cached === true 那一支恒 false ⇒ TTL 命中那一屏只剩第一截,因为那一问压根没问过 GitHub)。那两个词仍只在 domain(DETAIL_STAMP_LABELS),第三个词 windowHit 整格删(hc-20 与 client-70 两头钉:词表键集 = {body, revalidated}、client.js 代码位不许出现「秒内没再问」那半句)。 ⚠️ 形状上没有新增:撤档那两轮没删过库里那一格(只是让 open() 静默丢弃),所以摆回来零迁移;⚠️ 本轮动的是宿主半边五份 + client.js ⇒ 要重启 dsh desktop 才装得上,四条走查挂 spec §9.3。
  • ★ 第三十二轮(10-13):那枚 ☆ 三处入口 + 第 8 页签「收藏」(用户诉求原文「增加一个项目收藏功能」,原型三条推荐全选 + 那条默认裁定「这一轮跟着 renamedFrom 归一 —— 误念比缺念更糟」⚠️ 那条裁定连同「这一轮」那一格已被第三十五轮整条作废(用户指着那一列说「去掉这个」)见 spec §8.15)。界面上多出来的东西全在这几条: ① 三处入口共用一个组件(FavStar,.gt-fav 一枚 28×22 的方框,亮灭只看 on)⇒ 样式只有一份、行为只有一份;榜面那张 8 列表与明星那张表末尾那列原本是 width:0 的纯占位(.gt-tail),本轮把它改成 36px 摆那枚按钮 ⇒ 代价是描述列少那 36px(用户收下这条代价,所以没有新增 <col>/<th>;§8.15 落地改口 ① 把规格原文那句「约 34px」收窄成实读的 36px),列宽那三条账(td 有 overflow:hidden、按钮走 border-box 28px、左右内距 8 ⇒ 36−8=28 刚好)写在 client.js 那条 CSS 的注释里; ② 点它只改收藏:不跳转、不开弹框、不滚动,榜面那一枚还 stopPropagation(client-71 的判据是"整行那条链接一次都不许被触发");收藏那一发零出网、不派现译、不写 events(三件"不做的事"由 api 那条用例上的四本计数器一起钉,流水的判据是"榜变了什么"); ③ 收藏屏是三档说话(available / rows.length / 那两句成品),★「读不到那张表」与「一行都还没收藏」不许同时念 —— 本轮取证出的两处真缺陷就在这一格与词表那一格上(详见 spec §8.15 落地改口); ④ 排序分段器与页签选中态一同落 localStorage(第二十九轮那套 readUi/writeUi 直接复用,多一枚 favSort id)。 ⚠️ 本轮动的是宿主半边五份(lib/domain.js / lib/stores.js / lib/api.js / lib/favs.js 新 / index.js)+ 浏览器半边 client.js ⇒ junction 挂载下要重启 dsh desktop 才装得上,同时还要刷新面板;七条判定性走查挂 spec §9.3,本轮产品侧零真出网、零截图,你的 prefs、库存行、四把密钥一个字没动(★ 走查前别清库 —— 收藏那几行的出处就靠库里已有的榜史与详情缓存行)。
  • 名次徽章、新面孔 标签(本机首次上榜)、原 owner/name 标签(改名)、无描述显示 —;数值列走 tabular-nums 并用 fixed 表模板定宽(余量给描述列,不是给末尾空列 —— modelwatch 的真机大空隙事故)。 ★ 第十四轮起徽章分四档(用户口径「榜单前三名也加上这种徽标和颜色,好区分一点」,附 modelwatch 截图):.gt-rank 只做底座(22×22 / 圆角 8 / 11px·700 / tabular-nums),底色一律由档类给—— .gt-rank-1/2/3 金 #e8b530 / 银 #c3c9d2 / 铜 #cf9a63(三档色值与 modelwatch 的 .mw-rank-1/2/3 逐字相同,改一处要连着改另一处),.gt-rank-n(第 4 名起)走宿主令牌 --gt-soft/--gt-faint/--gt-line; 选档单点在 RankBadge(Number.isFinite(n) && n>=1 && n<=3,坏名次一律落中性档,不许把 NaN 拼进类名),榜页 8 列表格与总览速览两处渲染点共用它(判据 client-54 三头:单点类名 / 两处渲染点各带档类 / CSS 规则逐字)。
  • 「榜面数据 」与「最近取回 」分两条写:拿到 304 时只有后者在动,混成一条就会把陈旧数据念成新数据。反过来,取回失败那一轮 lastFetchAt 也照推(它是发起时刻),所以坏榜上这条改口念「最近尝试」,不然就把没取到的东西念成了刚取到。
  • 当前签靠字重 + 近黑下划线(--gt-fg)分主次,不拿招牌色表意(蓝色留给链接、红/黄留给状态);页签条不留横向滚动(第九轮撤掉了那句 overflow-x:auto —— 六个签在 1088px 的栏里 scrollWidth === clientWidth,那条竖 scrollbar 是纯噪声,判据挂在 client-38),三榜速览靠 auto-fit 收列,不新增断点。页头的回执同样走中性档:跑完一轮是告知不是状态,三榜全红时再抹一道绿就是两头打脸。

节拍与存储

默认 1 小时一轮,档位封闭集合 [60, 180, 720, 1440];启动 5 秒后自动跑第一轮(autoCheckOnStart 可关)。 连坏时节拍按 2^N 翻倍,指数封顶 4 轮、绝对封顶 4 小时:封顶只算绝对毫秒,不改用户的档位语义(选 24 小时的就真是 24 小时起)。 传输类失败(连不上/超时)在同一次检查内先补发(单榜最多 3 发,间隔 1 秒,成功即停),补发次数拼进故障文案,界面照读。 配置类失败(代理地址解析不出来)一律不补发:同一份坏配置补发三次只是把三发变九发。 出网前每一发先仲裁一次路线(设置页自定义 > 环境变量 > Windows 注册表 > 直连):注册表读一次缓存 60 秒,改偏好即作废; 读不到注册表如实写「读不到系统代理」并按直连走 —— 读注册表失败不是网络故障,别把两件事混成一条红。 宿主 ctx.timer.interval 优先,缺了退 setInterval(unref + dispose 显式清 —— 宿主给的是 disposer 函数,对它调 clearInterval 是静默 no-op)。 本机口径(2026-10-05 19:12:41 从运行中的 desktop 宿主拉的 snapshot):实测走的是宿主那一档(caps.timer:true)⇒ setInterval 兜底档在本机没有真机样本, 而修复版已在真机上活满了一个节拍:20:05:37 那一拍响,20:06:35 读到 nextCheckAt 前移到 21:05:37(整 +60 分钟)、events 70→71(新那条 board_exit 带 20:05:40.839),崩溃日志目录 19:05 之后无新文件; 兜底档那半仍然没验过,两档不许说成"都验过"。原文 snapshot 留在 tmp/snapshot-desktop-20261005.json,响后那份与逐分钟读数留 tmp/tick-desktop-after.json / tmp/tick-watch.log。 ★ 挂进定时器的那个回调只能调闭包里的具名函数:真机 desktop host 上它响了一次,回调里的裸 run() 找不到(那时 run 只是 return {…} 里的一个方法)⇒ ReferenceError 从 Timeout.tick 直接落进宿主的 uncaughtException,整个 IDE 弹「应用无法启动或已意外停止」。 闸门的忙时分支仍是 rejected promise,被回调自己的 .catch 接走 ⇒ 定时轮撞上手動轮只留一行告警。诊断与三条回归用例见 docs/design-spec.md §9.3 第四轮。

存储走 ctx.storageDomain,域 gh_trending,六张表 ⇒ 第二十三轮起七张表 ⇒ 第三十二轮起八张表同域:state(按榜分行)/ events(只追加 + 裁老)/ prefs / seen(观测史,★ 本轮加两格 roundsTotal「累计在榜轮数,一轮同现三榜只 +1」与 bestRank「历史最好名次,同轮跨榜取最小、只降不升」,两格都走 optionalInt)/ repo(仓库详情缓存,LRU 裁到 REPO_CACHE_MAX 行;★ 第三十一轮起那一行还多背一件事:TTL 判的是 checkedAt(缺这格的老行回退 at),而 zhProbed 不是 true 的成功行不受 TTL 挡 —— 那一格是第三十轮追加的 optionalBool,缺格与 false 同义 ⇒ 老库零迁移)/ trans(现译译文,键 kind:小写 owner/name,LRU 裁到 TRANS_MAX 行)/ search(★ 本轮新加:全站高星那一批,键恒为单值 'batch',行 = {at, lastFetchAt, ok, error, transport, rows[六格], rateLeft, rateLimit, rateResetAt, rateAuthed},只有一个写者 = lib/services/all-stars.js 那个 runner,坏轮冻结与三榜同一条读法、关掉不删行)/ fav(★ 第三十二轮新加:项目收藏,键 = 小写 owner/name,行 8 格(repo / name / desc / lang / langColor / stars / addedAt / from,★ 那是收藏那一刻的快照、不随榜面刷新,且 desc 恒是原文 —— 中文不落库);唯一写者 = POST /api/fav,不裁行 / 不设上限 / 不参与 LRU(用户自己挑过的东西,按 at 裁那种读法摆在这儿等于"收藏久了被系统悄悄删掉"))。⚠️ 域 version 恒钉 1、零迁移(新表 = 空表起步)—— 加表不是抬版本的时机,理由见下面那条。★ 第三十六轮(检索那一屏)没有新增任何一张表:那一屏八张一张都不碰,这是「零入库」的定义而不是省事(§8.18 ④),别的面板因此看不见谁的提问;search 那张表是第二十三轮「全站高星」那一批的库存,与手动检索同名不同用,⚠️ 别把那一屏的结果写进去 —— 判据是 api 那套的「★ 成功一趟之后八张表逐张没多一行、SSE 一帧不追(零入库是这一屏的定义而不是缺陷)」,电池 tmp/r36-search-falsify.mjs 第 ② 发(往路由里塞一句 deps.searchStore?.write?.(…))打的就是它。 域名排他(同名重复 open 报 already-open),所以 open 收口成 WeakMap + refcount 登记表,最后一个持有者放手才真关域。 ★ 域 version 保持 1:加一张表不是抬版本的时机。宿主整档布局按 stored !== descriptor.version 直接抛 version-mismatch(@deepseek-ai/dsh-storage-json 的实现,实测口径),compatibleVersions 只管 per-record 布局 —— 抬到 2 会让本机已经攒下的榜史与偏好整个打不开,而库里少一张表本来就是空表起步。

API 面

GET /gh-trending/api/snapshot、GET /api/stream(SSE,首帧 snapshot、检查完 update = 全量快照)、POST /api/check、 GET /api/events?limit=&board=、GET|POST /api/prefs、GET /api/repo?name=owner/name[&refresh=1]、★ 第二十八轮新增 POST /api/repo/readme(详情弹框那三枚手动按钮的唯一出口,体是 {name, action, path},action 只认 expand | translate | summarize)、★ 第三十二轮新增 POST /api/fav(那枚 ☆ 的唯一写入口,体只认 {repo, action, from, seed} 四格,action 只认 add | remove,越界 400 并把合法值念回来;from 是封闭屏 id 名单 FAV_SCREEN_IDS(三榜 + stars + ★ 第三十六轮的 search + detail),认不出的值 400 且一行不落库;seed 只在 add 且 from==='search' 那一支被读且只认白名单三格 desc/lang/stars(favSeedClean,脏值整格丢、收藏照旧成功);repo 走详情那一路的同一把闸门 normalizeRepoKey,其余字段一律不看 ⇒ stars / desc / lang 浏览器只有走这一支才递得进来,别的屏递了也不看) ★ 改判登记:第三十二轮那句「体只认 {repo, action} 两格」与「四路全空 ⇒ 落 FAV_FROM_DETAIL」那两支已作废(第三十六轮 ① 出处与读数解耦:from 由界面点名;② 用户裁定 B「点击收藏的时候,同步存储这些数据」:seed 是第四路本地读数的替代料),⇒ 路由表十条(5 GET + 5 POST),★ 第十条是 第三十六轮新增 POST /api/search(那屏唯一的出口,体只认 {query} 一格:trim 后为空 400、超过 SEARCH_QUERY_MAX = 256 同样 400 并念出本插件自己的边界(★ 那不是 GitHub 的口径,本机零真凭据 ⇒ 一个字都不写进代码去冒充它);闸门只有一把:一发在飞 ⇒ 409 GHT_SEARCH_IN_FLIGHT 且那一发压根没出发,★ 不自建一小时计数账本(额度恒吃回包响应头);服务没装配回 501;★ 零入库 + 不广播 —— 八张表一张不碰、hub.broadcast('update') 一次不发)。 ★ 第二十三轮(明星那一屏)没有新增任何一条路由(那是红线改判不是顺手加发):它的一切骑在 GET /api/snapshot 与 SSE update 帧上,出口是快照里 stars 那一格(headline / minRounds / roundsAvailable / thin / thinNote / views / sorts / 三个列名 / missingCell / rows / allStars{note, statLine, hasData, ok, error, transport, rows}),★ 没数据给空数组与空串而不是缺键;那一档开关的读数只有 prefs.allStarsEnabled 一处出口(stars 那一格里恒不重复给一位同样的布尔 —— 一个值不许有两处出口)。多开一条 GET /api/all-stars 就等于把出网时机交给浏览器(点一下发一发),每轮预算那条口径当场作废。 写操作只接受本机回环(连 x-forwarded-for 链每一跳都要是回环),纯读面板的 GET 不闸以便排障; 唯一一条闸的 GET 是 /api/repo —— 它读的是本地缓存,但缓存过期那一发要打 api.github.com,花的是匿名按 IP 计的额度,让局域网邻居点你的面板刷额度不合理。 ★ 第二十八轮起被闸的是四条、第三十二轮起五条、第三十六轮起六条(POST /api/prefs / POST /api/check / GET /api/repo / POST /api/repo/readme / POST /api/fav / ★ POST /api/search):第二十八轮新增那一条是第一条由浏览器发起、当场花模型额度的写(一趟最多 40 发),所以它自己在路由表上标 loopback:true —— 不许靠"是 POST 就顺带闸"那条隐式规则,那样哪天加一条不花钱的 POST 就会被顺带闸掉,而这条该闸的理由(额度按这台机器/这个账号计)也就没人负责了。★ 第三十二轮那一条的理由是另一件事(写在路由表那条注释上):这一路不花上游配额,它改的是本机库存 ⇒ 放给邻居点等于让别人替我收藏,闸的理由不同但同样要自己标;那句 403 文案也不穷举方法名(第二十八轮就为这个改过一次口)。★ 第三十六轮那一条的理由比 POST /api/fav 更硬:这一路花的是本机那个匿名 search 池(实测 10 次/小时,与「全站高星」同一口池子),放给局域网邻居就等于让别人替我烧额度 ⇒ 路由表上同样自己标 loopback: true,判据在 api 那三条「从别机来是 403」与 hc 的路由表扫描那一族(★ 那一族的名单是从路由表自身派生的,手写名单会在加路由那天漂)。 ★ 第三十二轮 POST /api/fav 的回执形状:{ok, action, repo, fav} —— fav 那一格就是整份新视图(与快照里那一格同一个 favView 产物),⇒ 点的那一块不必等 SSE 那一帧就到齐;★ 且写完恒追一帧(hub.broadcast('update', snap),与 POST /api/prefs 那一路同一条读法,但这里没有"库里一个字没变所以不追帧"那一支 —— add 幂等时 already 为真,可那枚 ★ 的样式与页签计数本来就该跟着这一按走)。仓储没装配回 501 GHT_RECORDS_UNAVAILABLE(不是 500,也不是"假装收藏成功了"),action 越界与 repo 不是 owner/name 一律 400 且一行都不落库。 ★ 第三十二轮(收藏那一屏)同样没有为它单开一条读路由:它的出口是快照里 fav 那一格 = favView() 的整个输出(★ 脚本回算 11 键:available / rows / count / sorts / sortIds / defaultSort / cols{stars,column,saved} / missingCell / note / emptyNote / noStoreNote;⚠️ 旧台账写的是 12 键、cols 里多一格 onBoard、外面多一格 offBoardCell —— 那两格随第三十五轮撤掉「这一轮」那一列一起删,键表由 favs 那套的 deepEqual(v.cols, …) 与「行与载荷也长不出那一格」两条钉住),★ 键恒在,一条都没收藏也给空 rows 与那两句人话;rows 里每行 10 格(同一把脚本回算:repo / name / desc / descZh / lang / langColor / stars / addedAt / from / fromCell,★ descZh 是第三十三轮加的那一格 = {zh, via, label, note, src} 或 null,而 desc 恒是那一刻的原文、不被中文覆盖;余下缺位的读数给 null ⇒ 界面摆 missingCell 那个 —),★ 「来自 …」那一格 fromCell 是宿主现算的成品句、不是零件(客户端把 from 和「来自」接起来就是第二份榜名);⚠️ 旧台账里那句「onBoard 与 fromCell 都是成品句」的前半随那一列一起作废;装配不再吃榜面那三行与明星那两批行(撤列之前它排在这些之后、因为要比键 ⇒ 第三十五轮之后与 stars 的装配先后没有依赖,hc-24 钉的就是那个调用点只喂三格)。 ★ 第三十六轮(检索那一屏)的出口有两份同一个 searchView() 产物,两份的键表逐字相同(★ ⑫ 追加改判之后脚本回算 15 键:query / state / stateLabel / stateNote / stateLabels / askingNote / rows / count / cols{stars,fav} / missingCell / statLine / ok / errKey / errText / transport;⚠️ 落地那一版是 16 键,多的那枚 note 随用户 10-14 那句「这个东西删掉」一起撤):① 快照里 search 那一格 = searchView({}) ⇒ 恒 state:'idle' + rows:[],装的是两枚列名 / 缺位符 / 六枚短词 / 那两句静态句子(idle 与 asking)—— ⚠️ 这一格原先还装一句 note(卡脚那句长说明),随 ⑫ 一起撤 ⇒ 快照与回执两头同时变 15 键,api 那条「POST 回执键表 == 快照那一格键表」的判据自动同数;⚠️ 这一格不是检索结果的库存,只是「asking 那一会儿拿不到 POST 回执而屏上必须念得出话」的唯一合规通道(界面不许抄文案);② POST /api/search 的回执 = 同一个 searchView,只是喂了 result / query / descHits / favRows 四样。rows 里每行 8 格(同一把脚本回算:rank / repo / name / desc / descZh / lang / stars / favSaved,★ 与 SEARCH_ROW_SHAPE 那六格不是同一张表 —— 库里那一行是"回包长什么样",这里是"屏上那一行要吃什么",多出来的两格 descZh(本机已有的那一句中文,descHits 喂进来、视图自己一个字不判命中)与 favSaved(那一行是否已在 fav 表里)都是装配时现算的视图格;缺位的读数给 null 而不是 0 ⇒ 界面摆 missingCell,★「真是 0 星」与「那一刻没有这一格」在屏上分得开)。⚠️ 这一屏没有读路由:结果不落在本机 ⇒ 没有任何"再取一次上一次那批"的出口可做,GET /api/search 那一天开出来就是假路由;额度那三个数(statLine)恒吃回包响应头,插件不自己记小时账(★ SEARCH_MAX_PER_ROUND = 1 那把预算挂在检查轮 runner(lib/services/all-stars.js)上,不许复用到这一路 —— 判据在 test/search.test.mjs 那一圈:在飞锁挡住时替身调用次数恒 1(不是"发完再丢掉"),而第一发结算后连着第二问照旧出发(calls.length === 2 ⇒ 本轮若自己记了一本小时账,那一发就发不出去),额度那三个数因此恒吃回包)。 /api/repo 的载荷是 applyZh 出边界的那 23 键(★ 这一格旧文档一直写着第十一轮的 21,第二十七轮多 checkedAt + revalidated 两格之后没跟着改口,收尾这一遍补上:21 → 23 → ★ 第二十八轮 24;整句中文与段落形状由宿主拼:sections(四段段表,唯一句子出口)/ error,旧的 narrative / facts / flags / readmeLabel / readmeMeta 五格已整段撤掉,客户端不补判定); ★ 第二十八轮那一整格 manual({section, runNote, actions[], sections[]})由 api 边界的 attachManual 挂上,且只在 ok:true 那一支 —— ok:false 不挂(按钮不许摆在一段错误上面),所以这份载荷的键数是条件数:坏名字那一屏回的还是 23 键。 zh 那七格恒在(开关关着、B 命中、模型没回都给齐七键,空的是 '' / null,不是缺键),而 repoView 自己那一格 sectionFields(宿主重拼段表唯一能吃的口径)在 applyZh 一进来就被解构删掉、不出边界(缓存命中与刚取回两条路在 builder 里同形、sectionFields 两边都留着,那一刀只在 api 边界切); 坏名字(不是 owner/name 形状)在造 URL 之前就被拦下,回 ok:false + errKey:'bad_key',一个字节都不出网(也不去喂模型)。

GET /api/snapshot 是界面的唯一一份真相:每榜带 transport(本轮失败是不是传输类)、顶层带 transportHint(那句话的宿主单点文案)、 net = {via, viaLabel, source, sourceLabel, proxy, reason, targetHost, at, status, text}(最近一发仲裁出来的路线,整句 text 由宿主拼好)与 cadence = {intervalMin, effectiveMs, backoffExp, nextCheckAt, fetchAttempts}(检查服务缺位则给 null)。客户端只渲染这些字段,不自己补判定。 net.status 是 ok|err|idle 三档圆点:判的是"这条路通没通"(有榜且坏榜都属传输类才算红),不是"这一榜有没有数据"——transportHint 仍只在坏榜 transport===true 时才念那句来源。


测试

零依赖:node:assert/strict + 自研 check(name, fn),node test/<x>.test.mjs 直跑,无测试框架、无 npm script。

for f in test/*.test.mjs; do node "$f"; done          # 672 项用例(十七套;含两条要真出网的口径。★ ⑬ 之后现值,落地那一版 671)—— ★ 直跑那两份通与不通都出现过,见下面读数
SKIP_LOCAL=1 node test/host-compat.test.mjs           # 跳 hc-17(声明真机口径)
SKIP_LOCAL=1 node test/web-translate.test.mjs         # 跳 wt-27(真发一发免费档)

当前读数(2026-10-09 本机复跑,第二十三轮「增加一个 tab,主要收集 github 明星项目和高星项目」⇒ 明星仓库那一屏(形状 B)那一遍,全文 tmp/rerun-r23.txt):SKIP_LOCAL=1 下 492 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 47 / repo 87 / check 39 / api 73 / client 63 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳)/ board-zh 19 / stars 28(★ 新开一套)/ all-stars 20(★ 新开一套)⇒ 基线 415 → 494 条。 当前读数(同日就地改判「开启的时候默认拉取一次」那一遍,全文 tmp/rerun-r24.txt):SKIP_LOCAL=1 下 502 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 47 / repo 87 / check 39 / api 78 / client 63 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳)/ board-zh 19 / stars 29 / all-stars 24 ⇒ 基线 494 → 504 条。★ 差额 +10 分三套:api 73→78(转换判据认库里旧值 · 取值须在写入之前 · 那一发不等回执就不回响应(延迟桩 + "库里已经有那一批"才分得开)· 发过追帧且坏轮也追 · 关掉与没碰那一档一律不派)/all-stars 20→24(2b 那一圈:闸序一条没少 · 当场落库且 round.at 记发起时刻 · 同刻连触被挡 · 两个入口互不侵占)/stars 28→29(那两句成品必须自己念出「点「开」的那一刻」与「每轮检查后」)。★ 电池 tmp/r24-enable-falsify.mjs 9 条 / 未抓到红 0 条 + [还原 ok] 三个文件逐字节等于进来时(九发各打掉一条新律:删转换判据 / 判据挪到写入之后 / 丢掉 await / 丢掉追帧 / 丢掉 onPrefsChanged(视图不刷 ⇒ off 闸吃掉那一发)/ runOnEnable 传 run(0) / 每次抹平预算 / 说明句丢「点「开」的那一刻」/ 等待句丢「每轮检查后」);★ 上一轮那两把一并复跑仍是全绿(r23-stars-falsify.mjs 8 条 / mutate-client-6.mjs 14 条,两边 [还原 ok] ⇒ 改文案与加入口没有把形状 B 那一圈的判据磨钝)。⚠️ 真机那两屏(点「开」之后立刻出现的那一批 + 那一发失败时屏上那句故障)等你重启宿主后截给我,继续挂 §9.3。 当前读数(同日第二条裁定「开启的时候,如果上次间隔时间范围内已经拉取过就不要拉取了」那一遍,全文 tmp/rerun-r25.txt):SKIP_LOCAL=1 下 512 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 47 / repo 87 / check 39 / api 80 / client 63 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳)/ board-zh 19 / stars 29 / all-stars 32 ⇒ 基线 504 → 514 条。★ 差额 +10 分两套:all-stars 24→32(2c 那一圈七条:窗口内 ⇒ skipped:'fresh'、sent:0、返回体键表恒那五格、库里一字未变 · ★ 窗口就是 prefs.intervalMin 那一格(61 分钟前的库在 60 档发、在 1440 档不发,两档各用独立库)· ★ 上一发是坏的 ⇒ 照发(判据吃 ok)· 脏时刻(at 在未来)不算新鲜 · 缺 intervalMin ⇒ 照发 · ★ fresh 只挂在 runOnEnable,run(轮次) 那一路不受影响 · 关着/无设施那一趟一次库都不读;再加一条 2d:窗口量的是 at 而不是 lastFetchAt(ok:true 而两格分开的库里行,两个方向各钉一次)/api 78→80(间隔内已取回 ⇒ 点「开」0 发、不追帧、库里 at 没被推进、而屏上那一批照旧在载荷里 · 窗口吃的是生效偏好那一格,装配层不自己数分钟)。stars 条数不变、prose pin 扩一条(那两句必须自己念得出「检查间隔之内已经成功取回过时不重发」)。★ 电池 tmp/r25-fresh-falsify.mjs 9 发 / 未抓到红 0、末行 [还原 ok] 三个文件跑完逐字节等于进来时(逐发红数:as 3 / 3 / 1 / 1 / 3 / 1 / 1,api 1,stars 1)—— ★ 首跑第 ② 发(吃 lastFetchAt)没抓到指定那条:坏轮同时把 ok 写成 false,ok === true 那一格先把闸关掉 ⇒ 字段选谁在那条用例里根本不可见,那是等价变异(真判据是 ok,第 ③ 发有牙);补了 2d 那条两格分开的库里行才拿到失败信号,过程写在 tmp/r25-falsify-out.txt 与 spec §9.2。★ 上一轮那三把一并复跑:r23-stars-falsify 8/0、mutate-client-6 14/0、r24-enable-falsify 首跑三发报「锚点在源码里找不到」(本轮把 runOnEnable 从一行箭头函数长成带 fresh 闸的 async 块、说明句里也插了半句 ⇒ 旧锚点跟丢源码,不是判据变钝)——重扫锚点后 9/0、末行 [还原 ok](三把还原均干净)。⚠️ 真机那一屏(间隔内已取回过时点开不再出网,只能从"上次取回"时刻那一格读出来)同样等你重启宿主后走查,挂 §9.3。 当前读数(10-10 第三条裁定「按 A 执行:那一档接上现译,条件判定加上 allStarsEnabled」那一遍,全文 tmp/rerun-r26.txt):SKIP_LOCAL=1 下 519 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 47 / repo 87 / check 39 / api 83 / client 63 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 ⇒ 基线 514 → 521 条(口径 = 逐套 pass + skip 之和,与上面几段同一个算法)。★ 差额 +7 分两套:board-zh 19→23(descZhRows 四面:条件两个方向(开着才并入;false / 缺位 / 0 / 'true' 一律不并)· ★ 不许污染载荷(打组标记必须拷一份 —— snap.stars.allStars.rows 就是载荷本身)· dedupe 只作用在榜面那一段 · 组序(每轮那点预算先给榜面吃饱,全站的 rank 不许插到榜面行前面)· boardMissing 与 missing 分家/api 80→83(快照那一列吃同一份集合:开着 ⇒ 库里已译的那句上屏,关掉 ⇒ 译文躺在库里也不给、而载荷 desc 一字未动 / 轮次后补译吃同一份集合:开着进 jobs、关掉只补榜面 / liveNote 的欠账只数榜面那一组:正向 + 对照各钉一次)。★ client.js 本轮零改动(那一屏读的一直是 hit?.zh || r.desc 那份取值),改的是测试夹具:snapFixture 的取行集合换成同一个 descZhRows,并把 stars 提到 zhView 之前算(对齐宿主"先有那一档的行,才有那一档开着时的屏上那些行"那份顺序)⇒ 夹具不再自己 allVisibleRows(boards) 一遍(那是第二份真相)。★ 电池 tmp/r26-starszh-falsify.mjs 9 发 / 未抓到红 0、末行 [还原 ok] 两个文件跑完逐字节等于进来时(逐发红数按脚本顺序:bz ① 1 / ② 4 / ⑤ 1 / ⑦ 1 / ⑧ 1 / ⑨ 1(六发),api ③ 1 / ④ 1 / ⑥ 1(三发)—— ② 那发一下红四条,是因为条件反过来同时打掉 dedupe、组序、boardMissing 三条吃集合归属的判据)—— ★ 首跑第 ③ 发报"没抓到",而套件里红的正是目标那条:期望串抄成了『它那一批进 hits』而用例标题写的是『它那一批里库里已译的行上屏』⇒ 判据有牙,是电池的期望串对不上名字,改期望串不动判据(过程留 tmp/r26-falsify-out.txt)。⚠️ 有一处结构约束没有可见判据、所以没进电池:api.js 里 search 那一批「读一次、两处用」—— 改成读两次,两次读之间没有写入时值完全一样 ⇒ 离线抓不到红(等价变异),只由注释与那条律守着,在这里如实登记而不是假装验过。★ 上一轮那四把一并复跑:r23-stars-falsify 8/0、r24-enable-falsify 9/0、r25-fresh-falsify 9/0、mutate-client-6 14/0,四把末行均 [还原 ok] ⇒ 本轮动的那两处 api 接线没让它们的锚点跟丢源码。⚠️ 一次回算脚本自相矛盾(记下来免得下次信错):第一次回算打印 pass 515,而同一条命令打印的合计是 521(= 519 + 2 跳)—— 用逐条数值与全文 ^ok 行数(519)交叉核对后确认 519 是真读数,515 不可复现(同一脚本复跑两次都给 519)⇒ 结论:单脚本的加总也要有独立来源交叉核对,台账数字只认核对过的那一个。★ 真机走查(10-10,用户重启 dsh desktop 后按 §9.3 那四步走完):回报「全部符合预期」 ⇒ 那一屏的描述列确实逐轮变中文、第一轮只有部分行属预期、关掉那一档退回原文而 trans 表不删、重开立刻上屏不再出网,且只有全站那一档欠账时榜面不念那句故障话。⚠️ 三条边界如实登记(详 §9.3 本轮读数那条):(a) 这一屏是口头读数、没有截图;(b) 第二十三二十五轮那三屏(七签页签条折行 / 形状 B 薄快照置灰 / 间隔内已取回不再出网的「上次取回」时刻)未逐条回报,照旧挂在 §9.3;(c) ceil(28/12)=3 轮 ≈ 180 分钟那个完整读数没等满 —— 只证到"第一轮部分变中文"这一形状,没证到"三轮后全齐"。 ★ 差额 +79 分六套,按 docs/design-spec.md §8.8 那七步一步一测记:步骤 1 store 40→47(seen 两格 roundsTotal / bestRank 走 optional + 第七张表 search + 「新增键不许 required」那一圈)、步骤 2 stars 0→28(候选窗口按时间不按轮 / "取名次最好那条"复用同一个函数 / added 只吃日榜(不在日榜给 null 且排序垫底,与「今天没涨」的 0 分家)/ 三档判据各一条 / 截断在宿主 / 三句话全来自 domain,用例里不出现手抄句子)、步骤 3 repo 76→87(q 里 >= 必须编成 %3E%3D 那条 URL 形状判据 + 回包→SEARCH_ROW_SHAPE 六格 + x-ratelimit-* 三格 + 令牌只进请求头那一圈)、步骤 4 all-stars 0→20(四道闸各返回一次且一发不派 + off 排在 no_store 之前单独钉一次(与补译那一档故意相反)+ 同一轮第二发被 round_already_sent 挡 + 坏轮 rows 不动)、步骤 5 api 65→73(stars 装配进快照且读路径零发 + 不带 at 的 update 一发不派、一帧不追 + 没落库时 allStars.rows 给空数组而不是 undefined)、步骤 6 client 58→63(client-59 七列 / 六列 col·th·td 逐列同数 + 整页一张卡那四条几何 CSS 原文 / client-60 名单、列名、句子三处全吃载荷(换哨兵值屏上必须跟着换)/ client-61 缺位与置灰(0 与「没有这一格」分得开、整列置灰不藏列)/ client-62 故障·没取回·空表·没存储四种"没内容"各说各的 / client-63 那条不对称:开启不跳档、关掉才把人送回名单第一档)。 ★ 另三圈条数不变、内容改判:client-17 与 client-30(六签变七签:labels 表、clicked 七键、首帧前那一屏)、client-32(全文件禁串扫描加三条书面豁免:累计 ★、回落 / 全部 / 全站高星、—,每条配"前提断言 + 指向承重判据的去处",免得下一个人在子串扫描上二次误伤)。 ★ 证伪电池两张(步骤 6 与步骤 15 的判据分属两侧):① tmp/mutate-client-6.mjs(只圈 client.js,14 发)14 / 未拿到失败信号 0、末行 还原逐字相同:是;② tmp/r23-stars-falsify.mjs(圈 lib/domain.js / lib/stores.js / lib/services/all-stars.js / lib/stars.js / client.js,8 发,读数 tmp/r23-falsify-out.txt)8 / 未抓到红 0、末行 [还原 ok] —— schema 追加键写成 requiredInt / 一轮同现三榜从 +1 变 +3 / off 挪到 no_store 之后 / added 拿三榜相加 / 界面按 boards 自己数轮数(屏上念成 '3 轮#2')/ 统计句换成界面自拼的额度句('search 额度剩 1' ≠ 宿主那句 '… 剩 8 / 10(匿名)')/ 缺位符界面自造 '—' / 界面自己判薄快照。 ★ 两发首跑没红,都登记:mutate-client-6 的 M6「开启时也跳档」—— 那趟的 view 停在第一档,条件本来就不成立 ⇒ 断言空跑,把 view 挪到 'allStars' 才打中;r23-stars-falsify 的 ⑧「界面自己判 roundsAvailable < 3」—— 默认夹具里 thin 与 roundsAvailable 同源,界面复算与宿主判处处相等 ⇒ 那是等价变异,补两份故意矛盾的载荷(thin=true 而 roundsAvailable=99,与反向那份)才拿到失败信号。⇒ 第二十二轮那条"漏网有两种"补上第三态:判据在、变异在,但两份真相当时恰好相等(要失败信号就得亲手让它们不相等)。 ★ 本轮出网 1 发:步骤 3 落夹具时经同一份 lib/services/net.js 直连抓的 /search/repositories(匿名 x-ratelimit-limit: 10,落盘 test/fixtures/repo-search.json,读数 §9.1 末尾);产品代码那一路在套件里零真出网,SKIP_LOCAL=1 下 search 吃那份夹具。⚠️ 没截真机屏:宿主半边 lib/** 要重启 dsh desktop 才进内存,浏览器半边 client.js 硬刷新面板即可。★ 10-09 走查当天取证改口:%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-plugin-gh-trending 现在是指向 F:\dsh-plugins\dsh-plugin-gh-trending 的 junction(package.json 里那格已从 github: 复制副本改成 link:),所以磁盘上宿主看到的就是仓库本身(六个文件 cmp 过逐字节一致)⇒ 旧那句"本轮连副本都没刷"不准,准确说法是宿主进程没重启:那一屏落进 client.js:623 的空态(载荷里没有 stars 那一格),而库存里 45 条 seen 行零条带本轮那两格、prefs 里也没有 allStarsEnabled(文件 mtime 就在走查那一刻,说明跑着的仍是旧那一份代码)。七签页签条与形状 B 首屏那两屏仍挂在 §9.3。我不替你重启、没动你的 prefs、没替你打开那一档的开关、也没动库存行(读库存只打印键名与条数)。

当前读数(10-14 第三十六轮「加一个全站项目检索功能」⇒ 第九个签「检索」+ 第十条路由 POST /api/search + ★ 零入库(八张表一张不碰、一帧不广播)+ POST /api/fav 两处改判(from 点名出处 / seed 补读数)那一遍 + ★ 同日两次追加改判:⑫「这个东西删掉」(卡脚那句长说明整条撤,载荷 16 键变 15)与 ⑬「这个框框有点丑,优化一下」(检索那一格换成一条盒子 + 条内胶囊按钮,★ 只动 client.js 一份),逐套摘要 tmp/r36-count-sources.txt、逐套全文 tmp/r36-suites/、逐发原文 tmp/r36-falsify-out.txt、电池摘要 tmp/r36-falsify-summary.txt):SKIP_LOCAL=1 下 670 过 / 0 挂 / 2 跳(★ 这是 ⑬ 之后的现值;⑫ 那一份读数 669 过 / 含跳 671 另存 tmp/r36-full-rerun-669.txt 供对账。跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 59 / repo 106 / check 39 / api 113 / client 82 / host-compat 25(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 24 / stars 29 / all-stars 32 / full-readme 19 / favs 22 / search 23(★ 新开一套)⇒ 基线 634 → 672 项、套件 16 → 17(口径沿用从前:含那两条要真出网的;过的那一边 632 → 670。★ 落地那一版是 671 / 669,⑬ 追加改判补那一条 client-82 ⇒ 净 +1)。 ★ 差额 +38 分四套(★ 现值是 ⑬ 之后:落地那一版净 +37 = search 23 + api 10 + client 3 + hc 1,⑬ 追加改判再补那一条 client-82 ⇒ client 那一套净 4):新开 search 23(★ 那一发只有一发的形状:searchRepoUrl({query}) 无 sort、无 order、无 ★ 门槛且用户自己写的比较符照原样编码 · 同一颗闭包两个入口(无参 = 全站高星那一串逐字不变,带词 = 手动那一串)· 令牌只进请求头而 URL 一个字不沾 · ★ 在飞锁两形(并发第二问替身调用次数恒 1 / 结算后连问照旧出发 ⇒ 不自建小时账本)· 空词不发 · 那一发抛错不 rethrow 且锁释放 · ★ runner 入参名单里没有仓储与广播(零入库是结构事实不是注释)· searchView 函数体里 fetch/await/Store/hub/Date.now 一概不许出现 · 行只带 8 格(多余键就是第二份真相)· 视图逐格折形(repo 小写而 name 保留 GitHub 写法)· ★ 星数缺位落 null 不演成 0 · 六态各一句且逐字等于 domain · ★ empty 与 error 三处可区分(两条判据不互为影子)· 认不出的失败键念故障不念成功 · asking 优先于回包 · ★ 快照那一格恒 idle 恒零行而带着 asking 那一句 · 额度行复用 starsQuotaLine · ★ 中文那一格命中上屏/没命中念原文而 desc 恒是原文 · ☆ 点亮态只看「这一行收过没有」 · ★ 载荷键表封闭 15 格(★ ⑫ 之后:search 那条同时钉 'note' in base === false,屏上不念的那句不许留在载荷里))/api 103→113(★ 新 15 条 − 就地改写 5 条:POST /api/search 两把参数闸(空白 400 且那一发压根没出发 / 超 SEARCH_QUERY_MAX 400 并念出本插件自己的边界)· 501 与 403 · ★ 路由上那把在飞锁有牙(409,数调用次数不数返回值)· ★ 成功一趟之后八张表逐张没多一行、SSE 一帧不追 · 那一发坏了不是 5xx(limited/error/empty 三支都回 200 而 state 各说各的)· 检索那一路不派现译、不进补译集合 · POST /api/fav 的 action/from 各是封闭枚举且越界把合法值念出来 · body 认四格而多递的 stars/desc/lang/name/addedAt 一个字进不了库 · ★ 出处与读数解耦(改判一)· favSeedOf 四路派生与切片 topN · ★ 四路全空 ⇒ 吃 seed 且出处仍念「检索」 · ★ 四路任一命中就赢过 seed · ★ 脏值整格丢而收藏仍成功)/client 78→82(★ 落地三条 client-79/80/81 + ★ ⑬ 追加改判那条形状判据 client-82:一条盒子一道边框、环画在外层、420 封顶不许复辟、哑态靠状态类不靠淡出/client-79 六列逐列同数 + 那六句与卡脚逐字吃载荷 + 六态互异 + ★ 喂空串时屏上必须画空(值驱动,不许客户端兜第七句)/client-80 那一发只有两处触发(回车 + !e.isComposing)+ 在问期间输入框与按钮一起哑掉 + 检索词不落 localStorage/client-81 行尾那枚 ☆ 递 {repo, action, from:"search", seed:{desc,lang,stars}} 而 remove 两格都不递)/host-compat 24→25(hc-25:编排那一路不认令牌、不拼 URL、不碰表、不广播 —— 扫源码形状 ⇒ 连字符串字面量都拦得住,且 ghToken 的读者名单恒 index.js / lib/domain.js / lib/services/repo.js 三处)。★ 另四处条数不变、就地改判:client-17/client-30(八签→九签)、client-77(那一发从两格改成三格 {repo, action, from})、client-78(「三屏共用 descCell」→「四处渲染点共用」)、repo 那条 searchRepoUrl 默认串(★ 参数化后的反面夹具:无参那一串逐字不变)、favs 与 store 那两条(from 封闭名单五档→六档)。 ★ 四个来源各数一遍又对上(tmp/r36-count-sources.mjs 现跑现数,全文留 tmp/r36-count-sources.txt):① 逐套 pass 加总 670(另 fail 0 / skip 2 ⇒ 含跳 672;★ ⑬ 之后重跑,落地那一版是 669/671);② 逐套全文 ^ok 670 / ^FAIL 0 / ^SKIP 2(数的是 tmp/r36-suites/*.txt 那十七份原文,不是逐套摘要);③ 工作树源码静态 ^check( 672(逐套 32+113+24+39+82+7+22+19+19+26+20+22+106+23+29+59+30,其中 host-compat 26 = 25 过 + 1 跳、web-translate 30 = 29 过 + 1 跳);④ 上一份含跳 634 + 本轮差值 38(search 23 + api 10 + client 4 + hc 1:落地那一版 client 净 3,★ ⑬ 补的那条 client-82 是第 4 条)= 672 ⇒ 四数互洽。⚠️ 口径分清楚:672 是含跳用例数,670 是 SKIP_LOCAL=1 下真跑过的条数;★ 「净 +37」与「git diff -U0 -- test/ 里 +check( 行数」是两个数:前者 = 新套 23 + 工作树那侧净 14(+check( 26 行 − -check( 12 行,那 12 行是就地改写后重打的同名用例)⇒ 23 + 14 = 37 与套间差值同数;后者单独看没有意义,第三十轮那一句"两个数都留"的口径照旧。★ 载荷形状独立回算(不是抄测试里的数):searchView({}) 顶层 15 键、有行那一支同样 15 键且 rows[0] 8 格(★ ⑫ 追加改判之后重跑 tmp/r36-count-sources.mjs:那一份留档现在写的是 15,落地那一版是 16 —— 多的那枚是卡脚 note)(rank/repo/name/desc/descZh/lang/stars/favSaved)、favView 顶层 11 键 / cols 3 格 / 行 10 格(第三十五轮那三个数未被本轮改动,复算只为确认没漂)。★ 短号自查(client-NN 到 82、hc-NN 到 25,search 那套按描述名编号)第十一次复跑(★ 落地那一版是第十次,读到 81):tmp/r28-label-dups.mjs ⇒ 17 套无撞号(本轮四个新短号 client-79/80/81/82 与 hc-25 均先做前缀重复自查;client.test.mjs checks=82 / 前缀重号=无)。 ★ 证伪电池 tmp/r36-search-falsify.mjs(圈 lib/services/repo.js / lib/services/search-run.js / lib/api.js / lib/domain.js / client.js 五个源,支持 node tmp/r36-search-falsify.mjs N… 只重跑指定那发;⚠️ 前四份盘上是 CRLF 而 search-run.js 是 LF ⇒ 多行锚点必须按各文件自己的 EOL 拼)34 发 / 未抓到红 0 / 全绿(等价或无牙)2(★ 发数三次改口:落地那一版 24,⑫ 追加改判补三发 ⇒ 27,⑬ 再补七发 ⇒ 34;★ 每补一次都按规矩整把重跑,不是只跑新增那几发;那两发 EQ 固定在 26/27,新七发排在 2834 ⇒ 序号 127 的权威序没动)、末行 [还原 ok] 5 个源文件跑完逐字节等于进来时(★ 植入前先数锚点在该源里出现几次:本轮 22 个锚点预检里有 1 个不唯一 —— favRows: favRead.rows, 在 api.js 里 favView 与 searchView 各一处 ⇒ 那发改用组合锚,这是第三十二轮那道预检第二次挡下打错地方;★ ⑫ 补的三发另用 client.js 两处锚,逐发 grep -c = 1,电池运行时那道唯一性预检 27 发全过;★ ⑬ 补的七发全圈 client.js、五处新锚(.gt-q{ 那一行的前半 / :focus-within 那一行 / .gt-search.off{ 那一行 / className: asking === true ? … 那一行 / ::placeholder 那一行)逐发 grep -c = 1,整把 34 发预检同样全过)。逐发红数(FAIL 条数,按脚本序号 1~34,序号与 node tmp/r36-search-falsify.mjs N 的 N 同轴):1 repo.js ① sort 复辟 2/2 repo.js ① 高星门槛复辟 3/3 search-run.js ④ 拆在飞锁 1/4 search-run.js ④ 锁不放 2/5 search-run.js ⑦ 插令牌字面(→ hc-25)1/6 api.js ③ 成功之后追一帧 1/7 api.js ③ 写 search 表 1/8 api.js ③ 快照那一格带行 1/9 api.js ⑥ seed 那道支路不限屏 1/10 search-run.js ⑥″ 星数缺位圆成 0 1/11 search-run.js ⑥″ 中文覆盖进 desc 1/12 search-run.js ⑥″ 载荷多塞一格 1/13 search-run.js ⑥″ ☆ 点亮态恒 true 1/14 domain.js ⑥″ 脏值圆整 1/15 client.js ② 卡脚兜第七句 1/16 client.js ② 表头复辟第七列 1/17 client.js ② 尾列列名写死 1/18 client.js ② 去 !e.isComposing 1/19 client.js ② 在问期间不置灰 1/20 client.js ② 检索词落 localStorage 1/21 client.js ⑥″ 出去时删 body.seed 1/22 client.js ⑥′ from 写死 detail 2(带走 client-77)/★ 23 client.js ⑫ 少撤:那句长说明摆回卡脚 1/★ 24 client.js ⑫ 多撤:连额度那一行一起删 1/★ 25 client.js ⑫ 抄字面:那句不摆上屏、只把字面抄进源码当一个没人读的常量 1/★ 26 EQ api.js 装配点那两格换书写先后 0(预期等价)/★ 27 EQ domain.js 出处回落 || FAV_FROM_DETAIL 0(预期等价)/★ 28 client.js ⑬ 420 封顶复辟 1/★ 29 client.js ⑬ 框中框复辟(输入框自己画回 1px)1/★ 30 client.js ⑬ 环画错地方(focus-within→:focus)1/★ 31 client.js ⑬ 哑态改回 :has() 1/★ 32 client.js ⑬ 哑态拿 opacity 冒充 1/★ 33 client.js ⑬ 在问期间不挂 .off 1/★ 34 client.js ⑬ placeholder 塞字面量色值 1 ⇒ 32 发有牙、红共 37 条(grep -c "^FAIL" tmp/r36-falsify-out.txt = 37,与逐发加总同数:落地那一版 24 发红 27,⑫ 三发各加 1 ⇒ 30,⑬ 七发各加 1 ⇒ 37;★ 序号 68 那三发同一条判据,见下面那句分账)。★ 三发打在同一个判据上(③广播 / ③写表 / ③快照带行):成功一趟之后八张表逐张没多一行、SSE 一帧不追 那一条同时数三处(八张表行数 + SSE 帧数 + 快照 search.rows)⇒ 三个变异各红一条不是判据重复,是"零入库"这一句本来就三件事。★ 两发 EQ 文末如实登记:键表锚读的是集合不是顺序;|| FAV_FROM_DETAIL 那一支没有红可拿(路由已在 favFromOf 之前用 FAV_SCREEN_IDS 挡成 400)⇒ 这正是改判一作废掉的那一支,不为它立判据。★ ⑫ 那三发打在 client-79 一条用例的三个不同段落上:23(少撤)与 24(多撤)红在 ⑥ 那句"卡脚只许一行、那一行念 statLine"(行数变 2 / 变 0),25(抄字面)红在 ⑩ 那道源码字面扫描 —— 把那句画上屏不等于抄字面进源码,抄字面也不画上屏 ⇒ 少一发就是少一颗牙;⚠️ 一条用例只报一次红,所以"⑥ 与 ⑩ 各红一次"那种说法不成立,如实记成三条各红一次。 ★ 电池/判据首跑的病历三条(§0 那条律第十二次兑现,三处都在判据/电池自身写法而不是产品代码):① 「拆在飞锁」那一发全绿 —— 不是判据钝,而是用例挂在未结算 await 上静默退出(闸一拆,第二问不再当场回 busy 而是挂在那条没释放的 gate 上 ⇒ 进程带着 Detected unsettled top-level await 退出、一条 FAIL 都不打,电池拿不到红)⇒ 给 test/search.test.mjs 那条并发用例补 200ms 限时竞速(与 test/board-zh.test.mjs 那条单闸用例同一条写法),复跑 search 23/0 确认判据不自红后整把重跑;② 「卡脚兜底句」那一发全绿 —— client-79 ⑩ 那份源码字面扫描只拦"抄 domain 那六句",拦不住客户端自己圆第七句 ⇒ 补 ⑦′ 值驱动(六态各喂 stateNote: '' ⇒ 屏上必须画空),复跑 client 81/0 后整把重跑;③ 「星数那道写侧闸」那一发报锚点找不到 —— 电池把 lib/domain.js 里 2 空格缩进的行写成 4 空格 ⇒ 改锚(判据一字未动)。三处修完整把 24 发重跑(★ 那是落地那一版),红数逐发与上面那份对齐。⚠️ ⑫ 补电池时的另一发病例(同一条律的第十四次兑现,也在电池自身写法):「抄字面」那一发首跑红 77 条 —— 不是判据钝,是我把 const legacyNote = '…' 插进了 h('p', …) 的参数位(锚用的那一行正好是表达式)⇒ client.js 当场语法崩、整套连不相关用例一起红,那种红不算失败信号(它证的是电池会写坏源码)。改锚到 SearchCard 函数体的语句位(const base = snap?.search || null;,grep -c = 1)⇒ 单跑只红 client-79 1 条,随后整把 27 发重跑。⚠️ 与第三十五轮那次"缩进抄错"同族:语句位与表达式位不能混用。⚠️ 历史电池本轮未复跑的如实说明:r32/r33/r35 三把圈的源本轮都动过(client.js / lib/api.js / lib/domain.js),按第三十五轮那一条规矩应当复跑 ⇒ 已复跑并把读数记在下面那条。 ★ 历史三把一并复跑(本轮动的正是它们圈的源;三把的旧脚本一个字未改,跑完源逐字节还原):第三十五轮那把 tmp/r36-rerun-r35.txt = 11 发 / 未抓到红 0 / 等价全绿 1 / [还原 ok] 4 个源文件(与它自己那轮一字不差);第三十三轮那把 tmp/r36-rerun-r33.txt = 19 发 / 未抓到红 5 / 等价 0 / [还原 ok] 5 个源(上一轮复跑是 3/1,多出的 2 发是本轮造成);第三十二轮那把 tmp/r36-rerun-r32.txt = 22 发 / 未抓到红 3 / 等价 1 / [还原 ok] 6 个源(上一轮复跑是 2/1,多出的 1 发是本轮造成)。52 发里「未抓到」那 8 发逐发归因,三桶: · 判据对象随第三十五轮一起消失(4 发,与本轮无关):r33 ② 那两发吃 test/favs.test.mjs 的「★ 第 11 格」,r32 ⑧/⑪ 吃同文件的「★ 改名归一」与「★ 命中优先级」—— 三个短名在今天盘上都是 0 处(那一列连同入参一起撤掉了);r33 ①′ 那条 EQ 的组合锚里写着 boards / starsRows / allStarsRows 三行入参,同样随那一次撤列没影 ⇒ 这一发算假失败(锚跟丢源码),不算判据消失。 · 本轮改动让旧字面锚跟丢(3 发):r33 ④/④′ 的锚是 18 空格那一整行 descCell(r.desc, r.descZh, missing),,而本轮检索那一屏又添了一处同形同缩进的调用(client.js:899 收藏 / client.js:993 检索)⇒ 该字面在源里命中 2 次,电池的唯一性预检直接拒打(④′ 因此压根没打上,那把的等价计数才从 1 掉到 0);r32 ⑰ 的锚 if (seenHit) return { name: seenHit.name, from: FAV_FROM_STARS }; 已被改判二引入的 hit() helper 换成 if (seenHit) return hit({ name: seenHit.name });(lib/api.js:496)。 · 真判据变钝:0 发 —— 但这一桶不许靠嘴说 ⇒ 另起一把只补验这三发(tmp/r36-rerun-drift-check.mjs,读数 tmp/r36-rerun-drift-check.txt,同样只收组合锚、历史脚本不改):收藏那一格改传 null ⇒ client-78 当场红(红 4 行)、同一处 missing 换成恒同值的另一读法 ⇒ 全绿(等价)、榜史那一路硬填 7777 星 ⇒ ★ favSeedOf 当场红(红 4 行)、favZh 改名 favHits ⇒ 全绿(等价) ⇒ 三发的牙一颗都没掉,跟丢的只是锚的字面。按第三十四轮那条 D1 字面锚的同规矩只登记不改写历史脚本。 ★ 出网账:本轮产品侧 0 发、取证侧 0 发(search 那一发在套件里全吃 test/fixtures/repo-search.json 那份第二十三轮的夹具;本轮新增的 tmp/r36-desc-len-probe.mjs 只读本机库存并只打印长度,全程没打印过任何行值 ⇒ 那四把密钥、你的 prefs、库存行、dsh desktop 一个字都没动)、零截图;⚠️ 与从前每一轮不同的一点:这一屏的正常用法本身就是要出网的(用户每点一次「搜一下」= 一发匿名 search 请求,10 次/小时的池子、与「全站高星」同一口),所以"本轮出网 0"说的是离线判据与取证,不是屏上那一条链。⚠️ 真机欠账四读挂 spec §9.3(★ 本轮既要重启 dsh desktop 也要刷新面板:宿主半边 lib/domain.js / lib/api.js / lib/services/repo.js + 新落点 lib/services/search-run.js + index.js,浏览器半边 client.js):① 回车只发一发且在问期间输入框与按钮确实哑掉(连点不多发);② 切走那一签再回来,屏上念的是「还没问过 GitHub」那句而不是上一批行(★ 这就是零入库在屏上的样子,别当缺陷报);③ ★ 检索屏点那枚 ☆ 之后,收藏那一屏那一行念「来自 检索」且 ★/描述/语言三格按本机有没有读数而定(本轮两处改判唯一肉眼可见的证据);④ 详情弹框与明星屏那两枚仍分别念「来自 详情」「来自 明星仓库」(改判一不许把它们一起带跑)。走查前别清库(那一行念什么取决于库里有没有那四路读数)。 上一份读数(10-13 第三十五轮「去掉这个」(用户截图红框圈住收藏那一屏「这一轮」那一列)+ 澄清后裁定「只删「这一轮」那一列,右侧那枚 ★ 照旧留着;宿主侧那一格派生、载荷格、相关判据与台账一并撤干净,不留死码」⇒ 收藏那一屏八列变七列 那一遍,逐套摘要 tmp/rerun-r35.txt、逐条原文 tmp/rerun-r35-full.txt,逐发原文 tmp/r35-falsify-out.txt):SKIP_LOCAL=1 下 632 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 59 / repo 106 / check 39 / api 103 / client 78 / host-compat 24(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 24 / stars 29 / all-stars 32 / full-readme 19 / favs 22 ⇒ 基线 639 → 634 项(口径沿用从前:含那两条要真出网的;过的那一边 637 → 632;套件仍 16 个)。★ 这是本台账第一次净撤(−5):判据面缩了,因为撤的不是判据而是一整个屏上的读数。 ★ 差额 −5 分两套:favs 28→22(★ 撤掉「这一轮」那一族七条:命中优先级单值 / 按档退 / 明星那两批都算命中 / renamedFrom 归一 / 未命中那句成品 + 置灰档 / 只看切片后的行 / onBoard 绝不写回输入行;就地改判一条(旧「第 11 格 descZh」→「descZh 那一格」,键数断言从 11 格换 10 格);★ 新立一条「撤一列连入参一起撤:旧的三档原料(boards / starsRows / allStarsRows)照喂,行与载荷也长不出「这一轮」那一格 —— 留入参就是死接口」,那一发的反面同时扫 onBoard / ON_BOARD / OFF_BOARD / keysOf 四个标识符)/host-compat 23→24(★ hc-24:那四个名字(FAV_ON_BOARD_LABELS / FAV_OFF_BOARD_CELL / FAV_ON_BOARD_PRIORITY / FAV_COL_ON_BOARD)在 lib/domain.js 零出处 + lib/favs.js 与 client.js 连 onBoard / offBoardCell / 「未上榜」三形都不认,每一形先在合成样本上自证扫得到再断真源码为 false;★ 另钉 lib/api.js 那个 favView({ 调用点只喂三格(descHits / favRows / storageAvailable 键表 deepEqual)且 boards / starsRows / allStarsRows 三个死料词一个都不出现,调用点恒恰一处)。其余条数不变、就地改判:client-73 改名「收藏那一屏七列逐列同数:后两列列名…」并新增两枚尾列断言(缺位那一行的尾列照样摆那一枚 ⇒ 撤一列不许把取消收藏的入口带走)+ 禁串扫描换成「client.js 里 onBoard 与「未上榜」一个都不许出现」/api 撤掉 favSeedOf 切片吃 prefs.topN 那两条里读快照比 onBoard 的末两行断言(判据对象已不在盘上)+ 三条用例名与消息里「第 11 格」改口成「descZh 那一格」。 ★ 四个来源各数一遍又对上:① 逐套 pass 加总 632(另 fail 0 / skip 2,tmp/rerun-r35.txt 逐行打印);② 逐套全文 ^ok 632 / ^FAIL 0 / ^SKIP 2(tmp/rerun-r35-full.txt,682 行 —— 第二个来源数的是它,不是那份逐套摘要);③ 工作树源码静态 ^check( 634(逐套 19+22+59+106+39+103+78+25+7+20+30+24+29+32+19+22,其中 host-compat 25 = 24 过 + 1 跳、web-translate 30 = 29 过 + 1 跳);④ 上一份含跳 639 − 撤掉那一族 7 + 新立 2(favs 1 + hc 1)= 634 ⇒ 四数互洽。⚠️ 口径分清楚:634 是含跳用例数,632 是 SKIP_LOCAL=1 下真跑过的条数。★ 载荷形状独立回算(不是抄测试里的数,留档 tmp/r35-shape-read.txt):favView 顶层 11 键、cols 3 格(stars / column / saved)、rows 每行 10 格 —— 三条都由 node -e 现调现数,与 favs 那两条 deepEqual 对上。⚠️ 序号名「第 11 格」随本轮作废(撤掉末尾那一格之后行只剩 10 格、descZh 一直在第 4 位)⇒ 台账、用例名与那两句源码注释(client.js / lib/favs.js)统一改口,盘上产品码与测试再没有一处叫它"第 11 格"。★ 短号自查(client-NN 到 78、hc-NN 到 24,favs 那套按描述名编号)第七次复跑:tmp/r28-label-dups.mjs ⇒ 16 套无撞号(本轮零新短号,client-73 就地改名不占新号)。 ★ 证伪电池 tmp/r35-onboard-cell-falsify.mjs(圈 client.js / lib/favs.js / lib/api.js / lib/domain.js 四个源,支持 node tmp/r35-onboard-cell-falsify.mjs N… 只重跑指定那发)11 发 / 未抓到红 0 / 全绿(等价)1、末行 [还原 ok] 4 个源文件跑完逐字节等于进来时(⚠️ 那两行摘要与分账打在 stdout、不进逐发 LOG ⇒ LOG 是 tmp/r35-falsify-out.txt(579 行 / 11 节)、摘要与分账另存 tmp/r35-falsify-stdout.txt;★ 本轮跑完还另把四份源码与跑前 cp 的备份 cmp 过一遍逐字节相同才删备份 ⇒ "还原干净"有两个来源)。逐发红数(FAIL 条数,按脚本序):①client 表头复辟 1/①行里那一格复辟(表头不动、行多摆一个 td ⇒ 整表错位、★ 被挤走)1/①撤列撤过头(把右侧那枚 ★ 一起删)2/②favView 行复辟那一格 2/②载荷复辟 offBoardCell 1/③装配点复辟喂料(boards: v 形)1/③同一发简写形(boards, ⇒ 键表只认 k: 那一形,抓它的是那条死料词兜底)1/③同一发顺序面(那三格交换书写先后)0(预期等价)/④domain 复辟 FAV_OFF_BOARD_CELL 1/④domain 复辟 FAV_COL_ON_BOARD 1/④客户端自己造「未上榜」1。★ 第 3 发是本轮用户那条划界的牙:撤列撤过头就是把 ★ 一起删 ⇒ 电池里"少撤"(复辟)与"多撤"(带走 ★)两个方向都有失败信号。 ★ 电池/判据首跑的病历(§0 那条律第十一次兑现,本轮红在三处判据自身写法而不是产品代码):hc-24 首跑连红三遍,产品源码一字未改 —— ① 切 favView({ 调用体那段正则 favView\(\{([\s\S]*?)\n\s*\}\) 在嵌套的 descZhHits(…) 那个 }) 处提前截断 ⇒ 入参名单少报一格,改用 indexOf('favView({') + indexOf('})', at) 切片并补一条"读全了没"的前置断言(判据不许红在读半截);② 合成样本 SYNTHETIC_ON_BOARD_CELL 里没有任何 ^\s*word: 行 ⇒ 反面自证空转,补一段 favView({ … }) 对象字面量;③ 样本用的是简写 boards, ⇒ 键表正则扫不到 ⇒ 新增死料词循环 for (const dead of ['boards','starsRows','allStarsRows']) 那一支才抓到。三次修完 host-compat 25/0/1,整把 11 发重跑。⚠️ 第 8 发(顺序面)如实登记为等价变异:那三格谁先写都不影响值与键表 ⇒ 全绿是对的,不许为它立判据。 ★ 历史两把一并复跑(本轮动的那四份正是它们圈的源 ⇒ 不复跑就不知道有没有把旧判据磨钝;读数 tmp/r35-rerun-r33-battery.txt / tmp/r35-rerun-r32-battery.txt,两把末行各自 [还原 ok]):tmp/r33-desc-zh-falsify.mjs 19 发 / ✅ 15 / ❌ 3 / ℹ 等价 1、tmp/r32-fav-falsify.mjs 22 发 / ✅ 19 / ❌ 2 / ℹ 等价 1。★ 那五处"未抓到"没有一处是判据变钝:r33 两发是假失败(期望串吃旧用例名「★ 第 11 格」,红的正是就地改名后的那条「descZh 那一格」);r33 一发 + r32 两发是判据对象随本轮消失 ⇒ 锚点在该源里找不到(r32 ⑧ renamedFrom 铺集合 / ⑪ 命中优先级,r33 ①′ 那个 favZh 局部名的等价变异锚盖着本轮删掉的那三格死料)。⚠️ 两把旧电池一个字不改、只在这里登记(与第三十四轮那条 D1 字面锚同规矩),也没有为消掉任何一发去放宽判据或改期望串。逐发归因表在 spec §9.2 本轮那条。 ★ 出网账:本轮产品侧 0 发、取证侧 0 发(撤的是一格本地比出来的读数,与出网本来无关;本轮三把电池与全量复跑全离线)、零截图;没碰你的 prefs、没碰库存行、没读那四把密钥。⚠️ 真机欠账一条挂 spec §9.3(★ 本轮既要重启 dsh desktop 也要刷新面板:宿主半边 lib/domain.js / lib/favs.js / lib/api.js 三份 + 浏览器半边 client.js;走查判据四读:那一屏变成七列且「这一轮」那一整列没了 / 右侧那枚 ★ 还在最后一格、点它仍能移出 / 描述那一格中文照旧(第三十三轮那一条不受本轮影响)/ 底部配额读数与打开那一屏之前一致 ⇒ 出网账仍是 0)。★ 顺带清掉一条旧欠账:第三十二轮那七条走查里「『这一轮』单值与改名归一」那条判据对象已不在盘上 ⇒ 作废(其余六条照旧挂着)。你的 prefs、库存行、四把密钥、dsh desktop 一个字都没动、没替你重启。 上一份读数(10-13 第三十四轮「按你推荐的来」⇒ 详情缓存那把尺抽成 lib/domain.js 的 repoAskedAt 三处共用 + lib/desc-zh.js 那个同名导出改名 那一遍,全文 tmp/rerun-r34.txt,逐发原文 tmp/r34-falsify-out.txt(1,125 行 / 18 节),套件的完整逐条输出 tmp/rerun-r34-full.txt(671 行)):SKIP_LOCAL=1 下 637 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 59 / repo 106 / check 39 / api 103 / client 78 / host-compat 23(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 24 / stars 29 / all-stars 32 / full-readme 19 / favs 28 ⇒ 基线 637 → 639 项(口径沿用从前:含那两条要真出网的;过的那一边 635 → 637;套件仍 16 个)。 ★ 本轮三件事(都是上一轮末尾列的待裁定,用户回「按你推荐的来」):① 收藏那一屏「来自」那一格保持现状并落为裁定 —— 改成"你点星那一屏"要破「浏览器只递 {repo, action}」那条承重律,为一句文案不值;② repo 表的裁行键从 at 换成「最后一次问过 GitHub」并复用 TTL 那把尺(repoAskedAt(row):checkedAt 优先 → 缺格回退 at → 脏值当缺位给 0),消掉 §8.13 末尾登记的"304 反复命中的那一行 at 冻在从前 ⇒ 越省额度越先被 LRU 删掉"那处真隐患;③ lib/desc-zh.js(内置表)那个与判据单点同名不同义的 descZhHits 改名 builtinDescZhMap,lib/board-zh.js 那个判据保持原名 ⇒ 盘上只剩一个 descZhHits。 ★ 差额 +2 全落 store(57→59):①「★ repo 裁行吃 checkedAt 而不是 at:304 反复命中的那一行不能被删」(§8.13 那处隐患的行为牙),②「★ 那把尺不吃脏时刻:库里躺着 checkedAt: Infinity / "9000"(手改 json、换机搬库)⇒ 按「没有这一格」回退 at」—— ★ 这一条是证伪电池第一跑抓到"判据空跑"之后补的(脏行必须绕开 schema 用 facility.seed 塞,checkedAt 走 optionalNumber 在 put 那关就抛)。其余全是就地改判、条数不增减:store 那条 499(裁行口径 + list() 交出去的 askedAt 与裁行同格)、desc-zh 的 dz-7(改名 + 两种导出写法都扫 + 反面自证那条"只剩一个"不是假话)、host-compat 的 hc-20(D1 那一支拆成"两个调用点 + 尺子在 domain");另 lib/stores.js 函数头注释改口(本轮换尺子这件事写在表头上,不留在注释里的旧口径)。 ★ 四个来源各数一遍又对上:① 逐套 pass 加总 637(另 fail 0 / skip 2);② 逐套全文 ^ok 637 / ^FAIL 0 / ^SKIP 2(tmp/rerun-r34-full.txt);③ 工作树源码静态 ^check( 639(逐套 32+103+24+39+78+7+28+19+19+24+20+22+106+29+59+30,其中 host-compat 24 = 23 过 + 1 跳、web-translate 30 = 29 过 + 1 跳);④ 上一份含跳 637 + 本轮新增 2 = 639 ⇒ 四数互洽。⚠️ 口径分清楚:639 是含跳用例数,637 是 SKIP_LOCAL=1 下真跑过的条数。★ 短号自查(client-NN 到 78、hc-NN 到 23,favs 那套按描述名编号)第六次复跑:16 套无撞号(本轮零新短号)。 ★ 证伪电池 tmp/r34-cache-ruler-falsify.mjs(圈 lib/domain.js / lib/stores.js / lib/services/repo.js / lib/desc-zh.js / lib/board-zh.js 五个源,支持 node tmp/r34-cache-ruler-falsify.mjs N… 只重跑指定那发;⚠️ 盘上是 CRLF,多行锚点必须按文件自己的 EOL 拼,否则电池自己空跑)18 发 / 未抓到红 0 / 全绿(等价)3、末行 [还原 ok] 5 个源文件跑完逐字节等于进来时。逐发红数(FAIL 条数,按脚本序):①裁行回退旧尺子 1/①接线面(两处调用点少一处)1/②list() 自己数 at 2/②接线面 1/②尺子撤 at 回退 2(store)/②同发打 TTL 1/②接线面(domain 不再有 numOf(row?.at))1/②两格顺序反过来 1/②同发打裁行 2/③TTL 绕开尺子 1/③行为面 0(预期等价)/③裁行绕开尺子 1/③行为面 0(预期等价)/④脏值闸撤一半 1/④脏值闸换写法("9000" 被折成 9000 插最前)1/④撤 Math.trunc 0(等价变异)/④给内置表再挂同名别名 1/④反面自证(判据那个改名)1。★ 本轮新立的形状律(锚的分层):行为层钉语义、接线层钉"两处共用" —— hc-20 用调用点 + 计数(stores.js 里 repoAskedAt( 恒 2 处)锚,不再钉整句字面;那两对"内联等价写法 ⇒ 行为全绿 / 接线锚红"的电池发就是这条律的自证,旧 D1 那种 /const base = num\(row\.checkedAt\) \?\? row\.at;/ 字面锚在"搬家"时判不出是漂了还是搬家了。⚠️ tmp/r31-ttl-falsify.mjs 里那条 D1 字面锚已随本轮搬家失效(历史脚本,不改写、在此登记)。 ★ 电池首跑的病历两条(§0 那条律第十次兑现):① ④ 那道脏值闸首跑三发全绿 = 判据空跑(注释里"字符串/Infinity 不许参与比较"当时没有任何用例喂脏 checkedAt)⇒ 补 store 那条「★ 那把尺不吃脏时刻」+ 整把 18 发重跑,重跑后该发现有牙(两发各红 1 条);② 另两发"没抓到"是电池自己期望写错(list() 那一发的行为用例是 514 那条(r-old 的 checkedAt 参与排序)而非 499 那条(那批行全没 checkedAt,两把尺在那儿同值);domain 撤 at 回退打在 repo 套咬的是「库里躺着外部改过的脏行」)⇒ 只改电池的期望,不改判据,脚本末尾分账如实打印。另有两发不为它立判据:撤 Math.trunc 等价(写入侧恒是 Date.now() 整数,小数那一形走不到)、stores.js 的 at: v?.at ?? 0 没做变异(list() 仍交正文时刻那一格,它不是本轮判据对象)。 ★ 出网账:本轮产品侧 0 发、取证侧 0 发(改的是库内裁行的尺子与一个导出名,零新增探针)、零截图;没碰你的 prefs、没碰库存行、没读那四把密钥。⚠️ 真机欠账一条挂 spec §9.3(判据就是"重启之后一切照旧":详情缓存窗口与旧库能对上、屏上读数不漂;⚠️ 不要为了验它去刷库,本轮改的是裁行顺序不是行内容)。★ 本轮动的三份全在宿主半边(lib/domain.js / lib/stores.js / lib/services/repo.js / lib/desc-zh.js / lib/board-zh.js 里除注释外无界面侧文件,client.js 一字未动)⇒ 只需重启 dsh desktop,刷新面板与否都不影响本轮判据。你的 prefs、库存行、四把密钥、dsh desktop 一个字都没动、没替你重启。 上一份读数(10-13 第三十三轮「为什么收藏过来的项目描述没有翻译的」+「按 A 开工」⇒ 命中判据抽成单点 + 收藏那一屏第 11 格 descZh 那一遍,全文 tmp/rerun-r33.txt,逐发原文 tmp/r33-falsify-out.txt,电池摘要 tmp/r33-falsify-battery.txt):SKIP_LOCAL=1 下 635 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 57 / repo 106 / check 39 / api 103 / client 78 / host-compat 23(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 24 / stars 29 / all-stars 32 / full-readme 19 / favs 28 ⇒ 基线 626 → 637 项(口径沿用从前:含那两条要真出网的;过的那一边 624 → 635;套件仍 16 个)。 ★ 差额 +11 分五套:board-zh 23→24(★「descZhHits 是命中判据的唯一出处」那条 —— 与 descZhView 的 hits/counts 逐字同 + 返回形状恒 {hits, counts} 两键(把 todo 带出来收藏屏就变成会花钱的屏)+ 内置优先在抽出来的这一层同样成立 + 脏输入(kind 认错 / zh 空串 / repo 缺位 / null 行)不给半个对象 + 空表也给满形状)/favs 24→28(第 11 格逐字搬而不覆盖 desc / 比键吃同一把归一(视图再归一遍就是第二把尺)/ 脏 descHits 一律 null(屏上分得开"没中文"与"一只有字的空泡")/ 卡脚那句本轮要能说清"屏上的中文从哪来",四件事缺一条就是假话)/api 99→103(★ 一帧只读译文表一次(读两遍就是两个答案,计数包装套在真仓储门面上、数的是产品侧信号)/ 内置与现译两路各自让榜面 hits 与收藏第 11 格逐字同且 desc 仍是原文 / 收藏里那个从没译过的仓库一发都不多派(补译集合只认屏上那些行)+ 序列化之后的键表判据 / ★ 收藏里那一行不在榜面上也照样上屏(把 descHits 换成榜面那一份就漏这一形))/client 77→78(client-78:收藏那一格摆本机已有的那一份中文、悬停三行齐(原文 + 那一行自己的落款 + 注)、没命中摆原文,★ 且三屏共用同一个 descCell —— 静态计数钉 className:'gt-desc' ×1 与 descCell( ×4)/host-compat 22→23(hc-23:lib/favs.js 与 client.js 连比对的口径都不认 —— 四类判据字面各扫两文件 + 合成正样本自证那四条正则不是扫空气 + lib/favs.js 的 import 名单恒 ['./domain.js'] + 客户端 .src === 那种"比原文"整类禁见)。 ★ 四个来源各数一遍又对上:① 逐套 pass 加总 635(另 fail 0 / skip 2);② 逐套全文 ^ok 635 / ^FAIL 0 / ^SKIP 2;③ 工作树源码 ^check( 637(= 过 + 跳的含跳口径);④ 本轮新增用例逐条点数 +11(board-zh 1 / favs 4 / api 4 / client 1 / hc 1)⇒ 626 + 11 = 637,与逐套差值分毫不差(tmp/rerun-r33.txt 末尾四行是这几个数的原始打印)。⚠️ 口径分清楚:637 是含跳用例数,635 是 SKIP_LOCAL=1 下真跑过的条数。★ 短号自查(client-NN 到 78、hc-NN 到 23,favs 那套按描述名编号)第五次复跑:16 套无撞号。 ★ 证伪电池 tmp/r33-desc-zh-falsify.mjs(圈 lib/board-zh.js / lib/api.js / lib/favs.js / lib/domain.js / client.js 五个源,逐发原文 tmp/r33-falsify-out.txt、摘要 tmp/r33-falsify-battery.txt,支持 node tmp/r33-desc-zh-falsify.mjs N… 只重跑指定那发)19 发 / 未抓到红 0 / 等价变异 2、末行 [还原 ok] 5 个源文件跑完逐字节等于进来时。逐发红数(FAIL 条数,按脚本序):①逐字闸 1/①内置撤 7(一下红七条:视图与收藏两侧共用那一个出口)/①行侧归一 1/①落款 label 1/②覆盖 desc 1/②整格不写 3/②写 undefined(跑 api)1/②脏 hits 的 ?? 1/②kind==='desc'(hc-23)1/③读两遍 1/③喂空 2/⑥复用榜面 hits 1/⑤并进补译 1/④传 null 1/④内联第四份 1/④少「原文:」3/⑦卡脚改回 1 + 两发等价变异 0。★ 电池首跑抓到一处判据空跑(§0 那条律第九次兑现):第 3 发「行侧撤小写归一」在旧夹具里全绿 —— 旁边那条小写 m/one 把命中兜住了 ⇒ 补一行 Up/One(屏上只有大写形、库里存小写键)+ 两条键表断言,整把 19 发重跑,重跑后该发现有牙(红 1 条)。⚠️ 另有两处写电池前自查出来的假绿(不是电池抓的,分账登记):assert.equal(…, null) 的 loose 相等放过 undefined(→ strictEqual);只断值不断序列化之后的键表(descZh: undefined 在内存对象里键还在,过一遍 JSON 才掉键 —— 客户端读的正是那一份)。★ 四条等价变异文末如实登记(脚本自己打印):descZhHits 那两个默认参数撤掉抓不到红/favZh 与 zhView 的装配先后对调抓不到红("一帧一处读"的牙在电池 ⑩ 那一发,不靠顺序)/lib/favs.js 加一层 descHits && 存在性判断与 ?. 逐字等价/descCell 里 hit?.zh || desc || missing 换三目写法同形。 ★ harness 侧连带改动(判据面扩了,被测源码一字不因它们而变):test/client.test.mjs 的 snapFixture 里 fav.descHits 改成现算(与 lib/api.js 的装配同形 —— 夹具另造一份 hits 就是测夹具编的形状);test/host-compat.test.mjs 加 SYNTHETIC_SECOND_JUDGMENT 合成样本。★ 同一族命名账(第三十三轮登记、★ 第三十四轮已修):lib/desc-zh.js(内置表)那个同名 descZhHits(rows)(只吃内置表、dz-7 管着,生产侧零消费者)与 lib/board-zh.js 的判据 descZhHits(rows, transRows) 同名不同义 ⇒ 第三十四轮把内置表那一个改名 builtinDescZhMap,盘上只剩 lib/board-zh.js 一个 descZhHits(dz-7 一正一反两条钉住:正面扫两种导出写法、反面把判据那个改名该红 —— 否则"只剩一个"是假话)。改名重扫了电池锚点并整把重跑(见上一段)。 ★ 出网账:本轮产品侧 0 发、取证侧 0 发(电池与全量复跑全离线,没造新探针 —— 那一句中文的来源是读盘上已有的 trans 表,不需要再造一份证据)、零截图;没碰你的 prefs、没碰库存行、没读那四把密钥。⚠️ 真机欠账三条挂 spec §9.3(同一行两屏逐字同 / 打开那一屏前后底部配额读数不动 / 卡脚与悬停那两句念得通且与屏上一致),★ 本轮既要重启 dsh desktop 也要刷新面板(宿主半边四份 + client.js),走查前别清库、别改偏好。你的 prefs、库存行、四把密钥、dsh desktop 一个字都没动、没替你重启。 上一份读数(10-13 第三十二轮「增加一个项目收藏功能」⇒ 那枚 ☆ 三处入口 + 第 8 页签「收藏」+ 第八张表 fav 那一遍,全文 tmp/rerun-r32-step8.txt,电池读数 tmp/r32-falsify-out.txt,探针读数 tmp/r32-probe-out.txt):SKIP_LOCAL=1 下 624 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 57 / repo 106 / check 39 / api 99 / client 77 / host-compat 22(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 / full-readme 19 / favs 24(★ 新开一套)⇒ 基线 574 → 626 项、套件 15 → 16(口径沿用从前:含那两条要真出网的;过的那一边 572 → 624)。 ★ 差额 +52 分五套:新开 favs 24(lib/favs.js 纯视图那一屏:行序与同刻收尾 / 键归一 / 脏行不进视图 / 命中优先级单值与按档退 / 明星那两批都算命中 / renamedFrom 归一 / onBoard 绝不写回输入行 / fromCell 是宿主拼的整句 / 缺位给 null 不是 0 / available 只看传进来的存储位 / 视图不吃时钟 / ★ 源码里没有任何 IO 形状)/store 47→57(第八张表的 schema 挡脏行、add 幂等且沿用库里那一行的 addedAt、remove 的 removed 位、键归一到小写、名单里多那张表)/api 89→99(快照 fav 那一格恒在、POST /api/fav 那两档闸门 400 且一行不落库、仓储没装配 501、从别机来 403、favSeedOf 四路派生那几形、写完恒追一帧、★ 出网计数器恒 0)/client 70→77(client-71client-77 + client-17 就地改判:那枚 ☆ 三处都在且点它零副作用 / 「来自」那一句整份吃载荷 / 缺 cols.saved 整枚不摆 / 排序名单只有一份出处 / 空态与故障话分得开 / 那一屏不跟着榜面刷新)/host-compat 21→22(hc-22:真装配点那一枚落得进真表、快照读得回来、teardown 把域真关、存储域坏时那一屏念的是那句故障话)。 ★ 四个来源各数一遍又对上:① 逐套 pass 加总 624(另 fail 0 / skip 2);② 逐套全文 ^ok 624 / ^FAIL 0 / ^SKIP 2;③ 工作树源码 ^check( 626(= 过 + 跳的含跳口径);④ git show HEAD 侧源码 ^check( 574 ⇒ 574 → 626 = +52,与逐套差值分毫不差。⚠️ 口径分清楚:626 是含跳用例数,624 是 SKIP_LOCAL=1 下真跑过的条数(本轮没有"就地改判不增条数"那几套之外的第三数)。★ 短号自查(client-NN 到 77、hc-NN 到 22,favs 那套按描述名编号)第四次复跑:无撞号。 ★ 证伪电池 tmp/r32-fav-falsify.mjs(圈 client.js / lib/favs.js / lib/domain.js / lib/api.js / lib/stores.js / index.js 六个源,读数 tmp/r32-falsify-out.txt,支持 node tmp/r32-fav-falsify.mjs N… 只跑指定发)22 发 / 未抓到红 0 / 等价变异 1 发、末行 [还原 ok] 6 个源文件跑完逐字节等于进来时(★ 本轮新加的锚点唯一性预检:植入前先数那个锚点在该源里出现几次,多于一次直接标「锚点不唯一(replace 会打错地方)」—— 免得打错地方那一形被当成"判据没牙")。两发一下红多条:⑫ favFromCell 抹掉那一句 ⇒ favs 3 红(整句/空串/五档出处三判据共用那个出口);⑤ chooseSort 不落盘 ⇒ client 2 红(client-75+client-76)。 ★ 病历一条(首跑那一发的等价变异,§0 那条律第八次兑现):⑰ 第一版写成「给榜史那一路补一个 stars: seenHit.stars」⇒ 全绿:seenRecord(lib/domain.js:1225-1240)根本没有 stars 那一格,永远是 undefined,而 parseOrInvalid 不收 undefined ⇒ 写与不写在盘上不可分辨。撤下那发换成两发拿得到失败信号的(⑰ 硬塞 stars: 7777 打掉「不许从别处补一个用户没看见过的星数」;⑱ 把 [...BOARDS].reverse() 打掉命中优先级),MUTS 尾段重新编号、文档头与文末登记同步改,然后整把 22 发重跑,红数逐发核对与台账一致。★ 另有三处等价变异如实登记(文末):reading(null) 那一形库里存不出、favMapOf/favOf 的小写归一(与 store 那一路同值,改一处不可分辨)、FAV_ACTIONS 加第三档(⑳ 那发,屏上没有第五枚按钮 ⇒ 绿得如实)。 ★ 探针标签错一次(登记在这儿免得下轮当真读数引):tmp/r32-api-probe.mjs 那条标着「切片外的日榜行」的用例最初写 topN: 2,而 clampPrefs 认 TOP_N_MIN=5 ⇒ 2 被兜回出厂 15,那一行其实在切片内(打印回来的是 from=日榜、stars=1003)。改成 topN: 5 + 七行日榜、把「切片外」那一形挪到 a/seven 才验到「出处落详情、读数一格都不带」。⚠️ 产品判断从没因此错过:test/api.test.mjs 那条判据用的是范围内 topN。 ★ 出网账:本轮产品侧 0 发(favs / store / api / client 四套全离线,hc-22 那一族吃假设施;SKIP_LOCAL=1 下跳的仍是 hc-17 / wt-27 那两条),接线白名单的独立来源 tmp/scan-cache-keys.mjs(抹注释扫代码位)零出网;零截图。⚠️ 真机欠账七条挂 spec §9.3(那枚 ☆ 三处都在且点它无副作用 + 36px 那列的描述可读性 / 第 8 签位置与计数同源 / 那一屏不随榜面刷新 / 「这一轮」单值与改名归一 / 三档分段器与落盘 / 空态与故障话分得开 / 出网账 0 的读法)—— ⚠️ 第三十五轮改口:第三那条(「这一轮」单值与改名归一)的判据对象已不在盘上 ⇒ 整条作废,本条七读变六读;本轮新立的那四读记在上面的第三十五轮当前读数里,不在这里改写本段历史原文。★ 本轮既要重启 dsh desktop 也要刷新面板(宿主半边五份 + client.js),走查前别清库(收藏那几行的出处靠库里已有的榜史与详情缓存行)。你的 prefs、库存行、四把密钥一个字没动,我没替你重启。 上一份读数(10-12 第三十一轮「我说还是改成以前那种模式,默认缓存24小时,可以配置,不要用60秒这种」⇒ 详情缓存那一档摆回来 + 60 秒防连点整键删 + 落款回两截 那一遍,全文 tmp/rerun-r31.txt,逐套全文 tmp/suites-r31/):SKIP_LOCAL=1 下 572 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 47 / repo 106 / check 39 / api 89 / client 70 / host-compat 21(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 / full-readme 19 ⇒ 基线 573 → 574 项(口径沿用从前:含那两条要真出网的;过的那一边 571 → 572)。 ★ 差额 +1 只落在 repo 那一套(105→106:新那条钉「★ 过期那一问再按用户改的那一档现算:装配后改档,下一发就按新档判,不用重启宿主」⇒ 打的就是 getTtlMs() 调用时现取现算 那一行);★ 另四处条数不变、就地改判:repo 那条 TTL 判据换成"量 checkedAt,缺格回退 at"两支 + zhProbed 那一形不受挡(D1/D2)、client 那两条(client-53 四档回来、client-70 落款两截 + revalidated 收窄,D3)、host-compat 那两条(hc-11 键表补回 cacheHours / cacheHourLabels、hc-20 整条重指向 TTL 那条链并反过来钉 DETAIL_RECHECK_MS 不在 domain)、store 那条 clampPrefs 判据与 api 那条 400 校验各自翻回"这一档有效"那一面。 ★ 三个来源各数一遍又对上:① 逐套 pass 加总 572(另 fail 0 / skip 2);② 逐套全文 ^ok 572 / ^FAIL 0 / ^SKIP 2;③ 源码 ^check( 574(= 过 + 跳的含跳口径)⇒ 与本轮台账那句「573 → 574」同一个数。⚠️ 口径分清楚:574 是含跳用例数,572 是 SKIP_LOCAL=1 下真跑过的条数,"净差值 +1"数的是含跳那一边(本轮没有净增删用例,只在 repo 净 +1 条)。 ★ 证伪电池 tmp/r31-ttl-falsify.mjs(圈 lib/domain.js / lib/services/repo.js / index.js / lib/stores.js / lib/api.js / client.js 六个源,读数 tmp/r31-falsify-out.txt)10 发 / 未抓到红 0 / 等价变异 0、末行 [还原 ok] 6 个源文件跑完逐字节等于进来时(全文共 11 条 FAIL:只有 ⑦ 那一发红 2 条 = optionalInt→requiredInt 同时把 store 那圈"新增键不许 required"与"schema 的 open 校验"两条照住)。十发逐条打的律:① D2 撤(没探完的成功行也受 TTL 挡)② "来过一趟就算探完"那一口径 ③ index.js 装配时锁死出厂档 ④ clampPrefs 那道档外回落 ⑤ api.js 那一档的 400 校验 ⑥ D3 撤(revalidated 不看 cached)⑦ schema 写成 requiredInt ⑧ 客户端写死 [6,12,24,72] ⑨ 词表加回 windowHit ⑩ repo.js 里现写 24 * 60 * 60 * 1000。 ★ 病历一条(首跑三发指向错套件,都不是判据变钝):③ 那发(装配锁死出厂档)最初圈 test/repo.test.mjs —— 那套件不 import index.js,那处变异结构上不可能有失败信号(第二十二轮那条律的第三种形态:判据在、变异在,电池却拿不到红)⇒ 改指 host-compat(hc-20 那条静态接线)才算验成;同族另两发(④ 圈 store、⑤ 圈 api)跟着逐发核对锚点后整把十发重跑,重跑后红数与首跑一致。 ★ 出网账:本轮产品侧 0 发(套件全离线,TTL 与条件请求那些形状都吃假 fetch 与手写库里行)、零截图;没有新增探针(304 照扣 1 那次配额那件事 10-10 已由 tmp/probe-detail-304.txt 那 9 发匿名 GET 证过,本轮只是把它从"反驳文档"变成"支撑裁定")。⚠️ 真机欠账四条挂 spec §9.3:设置页那一档能改并留得住 / 改档不发任何请求而下一发按新档判 / TTL 内连点同一仓库 0 发且底部配额读数不往下走 / 过档那一问真的走条件请求(GitHub 回 304、at 不动而 checkedAt 推进)。⚠️ 本轮动的是宿主半边五份 ⇒ 要重启 dsh desktop 才装得上,你的 prefs、库存行、dsh desktop 一个字都没动、没替你重启。 上一份读数(10-12 第三十轮「1.我开了摘要现译,这个点开没有翻译;2.截图里写着有中文,为什么没有拉取到中文版」⇒ 中文那一档不再被 304 冻住 + 摘要闸门收窄 + 落款第三截 那一遍,全文 tmp/rerun-r30.txt):SKIP_LOCAL=1 下 571 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 47 / repo 105 / check 39 / api 89 / client 70 / host-compat 21(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 / full-readme 19 ⇒ 基线 568 → 573 项(口径沿用从前:含那两条要真出网的;过的那一边 566 → 571)。 ★ 差额 +5 分两套:repo 101→105(① 库里缺那一格的老行 ⇒ 两把钥匙齐着也不喂、裸发四发并把 true 写回 ② 那一格是 true 才照旧复用(2 发带钥匙、at 不动、revalidated 为真)③ ★★ 冻结那一形自愈:第一问中文篇超时 ⇒ en_default + false 落库;第二问裸发 ⇒ 翻成 zh_file;第三问回到 2 发 —— 一次性代价必须收敛 ④ 八形口径表驱动逐形钉(zhProbed 与 readmeSource 两头都断言))/client 69→70(client-70 三头:三截齐全(cached:true)/第三截不出现(cached:false)/旧宿主只推两格时第三截整截不摆而前两截照旧)。★ 另四处就地改判、不新增条数:api 那条第三道闸门整条替换成三支表(cjk ⇒ 不派、lang ⇒ 照派、真机那形「…简体中文 · 日本語…」7 个 CJK ⇒ 照派,净 0)/hc-11 那枚词表两词改三词/hc-20 的 prev 字面改判 + 同一条 check 内新增「domain 那句必须现拼」与「client.js 代码位不许出现那个秒数」/repo 那条既有的落库判据补一句 row.zhProbed === true(schema 或白名单漏格当场红)。 ★ 三个来源各数一遍又对上:① 逐套 pass 加总 571;② 全文 ^ok 571 / ^FAIL 0 / ^SKIP 2;③ git diff -U0 -- test/ 数 check( 行 = 新增 6、删除 1 ⇒ 净 +5 与套间差值同数。⚠️ 「净差值 5」与「新增行 6」是两个口径、两个数都留(差在那条 api 判据的整条替换,第二十八轮"净 +35 对新增 38"同族),不许混用。★ 短号自查 node tmp/r28-label-dups.mjs(本轮第三次复跑)15 套全部无重号,client.test.mjs checks=70、repo.test.mjs checks=105 均与跑测器同数。 ★ 证伪电池 tmp/r30-zh-probed-falsify.mjs(圈 lib/services/repo.js / lib/api.js / client.js / lib/domain.js 四个源,读数 tmp/r30-falsify-out.txt,支持 node … 7 只重跑指定那发;多行锚点按各文件自己的 EOL 拼)11 发 / 未抓到红 0 条 / 等价变异 1 条、末行 [还原 ok] 4 个源文件跑完逐字节等于进来时(逐发红数 1/2/5/1/0/1/1/1/1/1/4 —— ③「白名单漏那一格」一下红五条:写回 true / 复用 / 自愈 / 收敛 / 那条补了牙的落库判据 ⇒ 那一格的四条律共用同一个存储出口;②「来过 probeReadme 一趟就算探完」红两条 = 八形口径 + ★★ 自愈 ⇒ 本轮最重的一发牙)。 ⚠️ 首跑两处的病历(修法都不是放宽电池):① ⑪ 首跑红 3 条而不含目标那条 —— 旧那条「200 那一问把验证器原样落库」只钉 etag 与 checkedAt,schema 漏格在它眼里不可见(红到的是别的新判据)⇒ 给它补一句 row.zhProbed === true 后整把 11 发重跑(③ 由 4 变 5、⑪ 由 3 变 4,其余逐发同数);② ⑤ 全绿 = 等价变异:readmeFieldsFromPrev 写死 true 与照原样带 prev.zhProbed === true 在盘上不可分辨(load() 只把探完的行递进来)⇒ 不新增判据,真挡住"把 false 洗成 true"的是 load() 那道闸与「false 也进库」那一条。 ⚠️ 一处跑测器自己的口径,记下来免得下一个人再踩:SKIP_LOCAL=1 是按用例名里含「真机」二字跳的 —— 新写那条最初叫「★★ 真机形状回归」,首跑被静默跳过(pass 104 / skip 1:全绿里少了一条而不报错),而它吃真夹具 + 合成档、零出网 ⇒ 改名「★★ 冻结那一形自愈(10-12 那两个读数)」之后才真跑。 ★ 出网账:产品侧 0 发(套件全离线);取证只读且全走匿名 curl -x http://127.0.0.1:7897 + 一路重放共 4 发(debpalash/VoiceStudio 的默认 README / README_CN.md / 根目录 contents 清单,落 tmp/r30-vs-*.md、tmp/r30-branches.mjs),另 tmp/r30-probe-zh-file.mjs 走产品函数两趟 6 发(第一趟 4 发裸取、第二趟 2 发条件请求全 304 ⇒ 那就是病历里"半截结论被冻住"的现场复现)。⚠️ 没动你的 prefs、没动库存行(读库存只打印键名与条数),本轮也不替你重启宿主;四条判定性走查挂在 §9.3,零截图。 上一份读数(10-12 第二十九轮「切换了tab后,右侧面板选择的东西就没了」⇒ 面板选中态落 localStorage 那一遍,全文 tmp/rerun-r29.txt):SKIP_LOCAL=1 下 566 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 47 / repo 101 / check 39 / api 89 / client 69 / host-compat 21(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 / full-readme 19 ⇒ 基线 565 → 568 项(口径沿用从前:含那两条要真出网的;过的那一边 563 → 566)。 ★ 差额 +3 全部落在 client 那一套(66→69,其余十四套逐套同数 —— 本轮一个字的宿主半边都没动):client-67 落盘读回只认名单(pickOption 四种输入各一回 + 组件层用载荷里真实的 group 验高亮落位,再用 <colgroup> 的列数验"真回落而不是假装在原档")/client-68 整页重挂不丢选择(⓪ 键名跟着载荷 panelId 走 · ① 出厂总览 · ② 点明星签即落盘 · ③ 新实例同一份存储 ⇒ 标题回到「明星仓库」· ④ 两个分段器各点一档 ⇒ 第三个实例高亮仍在原档 · ⑤ 存的只有那三枚 id,PREF_SECRET_KEYS ∪ 偏好那六个键名一个都不许出现在存串里)/client-69 存储坏了不带走界面(读写各自抛 ⇒ 回落总览且 storageWrites.length === 0;六种坏值 '{'; '[]'; '7'; 'null'; '"stars"'; '{"tab":{}}' 逐个喂 ⇒ 一律回落而不是抛)。 ★ 另有一条既有判据就地改判(client-62 的 ③″ 那一头,改判而不是回退源码):旧写法硬塞 view='allStars' 去验「开关关着却停在那一档 ⇒ 退回原文」,而落盘之后这一形成了每次重挂都会遇到的输入、被新那道名单校验挡掉 ⇒ 现钉的是「关掉 ⇒ 回落名单第一档、列数跟着回落、那一枚照旧 disabled 摆着」;「客户端不许自己拿 transRows 补中文」那半仍由同条的 ②③③′ 三头钉着。 ★ 三个来源各数一遍又对上:全文 ^ok 566 / ^FAIL 0 / ^SKIP 2,与逐套 pass 加总同值;第三个来源 git diff -U0 -- test/ | grep -c '^+check(' = 3 = 与套间差值同数(本轮两个数相等是因为三条全是新增、没有"就地改写"那一类,与第二十八轮"净 +35 对新增 38"那种分叉不同)。★ 短号自查 tmp/r28-label-dups.mjs 复跑 15 套全部无重号(client 那一套读出 69 条,与跑测器同数)。 ★ 证伪电池 tmp/r29-ui-state-falsify.mjs(只圈 client.js 一个源,读数 tmp/r29-falsify-out.txt)10 条 / 未抓到红 0 条、末行 [还原 ok] client.js 跑完逐字节等于进来时(逐发红数 1/1/1/2/1/1/1/2/1/1 —— ④「读回只认在册不认能不能点」与 ⑧「生效档在挂载时一次定」各红两条 = client-62 + client-67 ⇒ 改判过的那条与新增那条共用同一道名单校验,这块地基是一处)。★ ⑨ 首跑「全绿 = 判据空跑」并登记(第二十二轮那条律的第四次):那一发改的是 UI_KEY 的字面量,而用例读的 UI_KEY 来自同一份导出 ⇒ 两侧一起动、判据结构上看不见 ⇒ 在 client-68 ⓪ 补「键名跟着载荷 panelId」两条之后才拿到失败信号。★ 等价变异 1 条如实登记(不跑电池):pickOption 里 arr[0]?.id ?? fallbackId 改成直接 fallbackId —— 三个调用点的出厂值与名单第一档逐字相同,真设施上抓不到红。 ★ 本轮产品侧出网账:0 发;取证全程只读(tmp/host-asar.mjs 从宿主的 app.asar 抽出三个包到 tmp/host-asar/,一个字节都没写宿主目录)。 ⚠️ 真机欠账一条(本轮只动浏览器半边 ⇒ 结论是刷新面板,不是重启):① 切走宿主右侧面板 / 切到别的页签再回来,还在原页签与原档位;② 站点存储被禁用(或隐私模式)时界面照旧可用、回落出厂档。⚠️ "要不要重启宿主"这一条本轮重新判过而不是沿用:client.js 落盘 10-12 09:21:29 晚于宿主五个 DeepSeek Harness 进程的 08:50:10,而 junction 挂载下面板重载吃的就是盘上那一份 ⇒ 要刷的是面板;index.js / lib/** 的 mtime 都停在 10-10,那一侧没有新东西要装。第二十三二十五轮那三屏、第二十七轮那一屏四读、第二十八轮那两条照旧挂着,本轮没有顺手划掉。我不替你重启、没动你的 prefs、没动库存行、也没替你点过面板。 上一份读数(10-10 第二十八轮「1.加一个按需展开,下次点开支持重新加载README,最好是加个按钮;2.加几个按钮,英文文档支持点击翻译和对整篇文档生成摘要,……不受参数设置控制」⇒ 详情那三枚手动按钮 + 第八条路由 POST /api/repo/readme 那一遍,逐套 tmp/r28-suites-3.txt、全文 tmp/rerun-r28.txt):SKIP_LOCAL=1 下 563 过 / 0 挂 / 2 跳(跳的仍是 hc-17 与 wt-27),逐套 gh 19 / net 22 / store 47 / repo 101 / check 39 / api 89 / client 66 / host-compat 21(+1 跳)/ desc-zh 7 / llm 20 / web-translate 29(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 / full-readme 19(★ 新开一套,套件 14 → 15) ⇒ 基线 530 → 565 项(沿用从前口径:含那两条要真出网的;过的那一边 528 → 563,净 +35)。 ★ 两个来源各数一遍又对上:全文 ^ok 行数 563 / ^FAIL 0 / ^SKIP 2,与逐套 pass 加总同值。 ★ 净 +35 与"新增 check( 行 38"是两个数,都登记(口径不同:前者是套间差值,后者是 git diff -U0 -- test/ | grep -c '^+check('):差值 = 新套 19 + repo 96→101 + api 83→89 + client 63→66 + llm 19→20(新增 3 − 就地改写 2)+ web-translate 28→29(新增 2 − 就地改写 1);那三条"就地改写"是 kinds() 那两条从"两路都 serve"改钉"四路 / 三路全 serve",和 ★两档显式全关 改口成 ★受开关管的两档显式全关(★ 手动那两路恒不受开关管 ⇒ 旧那句里的"两档"已经不是全部档位,那句话在新盘上是假话,改它才是守律);store 47 条数不变、就地补断言(kind 封闭名单四路、旧两路行照读)。 ★ 本轮抓出的不是回归、是一处隐式耦合:full-readme.js 里 runOnce 落库前自己小写、readRows 却把保留大小写的键交给表 —— 靠 lib/stores.js 内部 keyOf() 再归一一次 ⇒ 生产没坏(真表确实小写),但同一张表的键形状有了两处出处;照出它的是冒烟那颗不做归一的替身表(tmp/r28-smoke.txt 第 32/35 行读回 null)。⚠️ 它没进电池:真表会归一 ⇒ 两种写法在真设施上逐字等价,拿它做变异只会得到"全绿 = 判据空跑",按第二十三轮那条"第三态"如实登记为等价改动。 ★ 另四处是改源码而不是加判据迁就(取证时才露出来的形状):删 if (!deps.fullReadme) return 501 那支死分支(同函数内无条件装配);失败回执从 notes: [] 改成给 manualFailNote 那句成品("按下按钮屏幕毫无反应"就是那一格空数组);fetchFull 装配不再兜"详情服务没装配"(路由已在派活之前 501);POST 的 403 那句不再穷举方法名(那串列举每加一条写路由就旧一次 ⇒「写操作(花上游配额或写本机库的那几枚都在内)只接受来自本机回环的请求」)。 ★ 证伪电池 tmp/r28-manual-falsify.mjs(圈 lib/services/full-readme.js / lib/services/repo.js / lib/api.js / client.js 四个源,读数 tmp/r28-falsify-out.txt,支持 node … 2 14 只重跑指定那两发)15 条 / 未抓到红 0 条、末行 [还原 ok] 4 个文件跑完逐字节等于进来时(逐套发红数:⑥ 与 ④ 各红 2、⑮ 红 9 —— 载荷没给 manual 时客户端自兜那一排,把详情弹框那一族全炸了;★ 那是撤默认兜底的必然后果,判据钉的正是"三枚按钮的出处只有一处")。★ 收尾那一遍因短号撞号整把重跑过:新写那三条落地时错填 client-56 / 57 / 58,与第二十一、二十二轮那三条撞短号(全名不重 ⇒ 跑测器与 pass 66 都看不出来)⇒ 改号 client-64 / 65 / 66 后十五发全重跑,红数逐发不变、实名变了(⑮ 那九条是 client-41 / 43 / 45 / 50 / 51 / 53 / 55 / 57 / 64,其中 client-57 是第二十一轮那条配额句 ⇒ 那一段的形状是共同地基);撞号前的读数留在 tmp/r28-falsify-out-before-rename.txt,自查脚本 tmp/r28-label-dups.mjs 回算 15 套全部无重号。★ 首跑两条"全绿 = 判据空跑",都按补判据处理而不是放宽电池(第二十二轮那条律的第 三次 + 第二十三轮"第三态"的第 二次兑现):① 指纹那条的第二趟换了新库 ⇒ old 恒 null、变异体与原判据同路 ⇒ 改成同一副替身改正文 + 复用同一副库(顺手抓出一处误写:第一趟命中库里那一行时翻译发数是 0,用例写了 6);② 展开覆盖两块那一条的夹具恰好与段表同序 ⇒ "按下标"与"按 kind"在那个夹具上等价 ⇒ 改反序夹具 + 补一条段内位置断言。★ 等价变异 1 条如实登记(joinBlocks 的 stopAt 写成恒 -1):游标取号让未跑块本来就是连续尾巴,parts[i] == null 那条 continue 已把同一段裁掉。 ★ 本轮产品侧出网账:0 发 —— 19 条编排用例吃的是合成正文(分块只认长度与段落数)与替身翻译服务,repo 那一发的 200/304/404 吃假 fetch;没有新探针、没有真回包。 ⚠️ 真机欠账两条(动的是宿主半边 lib/** + 浏览器半边 client.js ⇒ junction 挂载下要重启 dsh desktop 才进内存):① 展开那一发真的不带验证器 —— 活宿主上点「展开全文」,Network 里那一发 /readme 的请求头没有 If-None-Match、回的是 200 带整篇正文而不是 304(这一条只有活宿主能证:库里那一行确实躺着 etagReadme,代码写歪了本地一片绿);② 免费档那枚「整篇摘要」置灰的话在屏上念得出来 —— title 那句是「这一档只会翻译,不会摘要」,不是「开关没开」,也不是「这一路现在发不出去」(三种原因是三句话)。第二十三二十五轮那三屏 + 第二十七轮那一屏四读照旧挂着,本轮没有顺手划掉。我不替你重启、没动你的 prefs、没动库存行、也没替你点过详情弹框。

上一份读数(10-10 第二十七轮「能做到每次重新拉取时,只有有变更时才重新获取吗,没有变更还是用本地缓存的」⇒ 详情改条件请求(形状 B)+ 固定 60 秒防连点 + 撤掉第十二轮那四档 那一遍,全文 tmp/rerun-r27.txt):SKIP_LOCAL=1 下 528 过 / 0 挂 / 2 跳(跳的还是 hc-17 与 wt-27 那两条要真出网的),逐套 gh 19 / net 22 / store 47 / repo 96 / check 39 / api 83 / client 63 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳)/ board-zh 23 / stars 29 / all-stars 32 ⇒ 基线 521 → 530 项。★ 差额 +9 全部在 repo 那一套(87→96 = 新增十二条、就地撤掉旧 TTL 那三条:新十二里是 60 秒窗口三条(库里那一行第一次点击也不出网 / 窗口内第二次点击不出网、过 60 秒照问 / 那一格只有一个出处 —— DETAIL_RECHECK_MS = 60_000 且 domain 里不再有小时档那三个名字)/ 200 那一问的验证器原样落库(弱标 W/ 一个字不动)/ 两发都 304 ⇒ 只 2 发出网、at 沿用库里那刻而 checkedAt 推进 / 只有 README 变了 ⇒ 正文时刻推进且找中文篇那条分支重新走满 / 库里那一行没验证器(老行)⇒ 裸发、一个空 If-None-Match 也不发 / 不变式两形 / refresh=true 一个字都不带验证器 / 窗口量的是 checkedAt 而不是 at / 传输炸那一发不许把限额读数擦成 undefined),撤掉的三条是「出厂 24 小时内的第二次点击不发网络」「TTL 调用时现取现算:设置页改档…」与那条旧写法的「库里躺着今天那一行」(改写成 60 秒版)。另四套条数不变、就地改判:store(那条「repoCacheHours 只认封闭四档」换成「那一格既不读出来也写不进去」—— 断的是"存不下来",不是"不回显",因为 patch() 回的是 clampPrefs({...cur,...fields}),回显留、落库丢)、api(那条「越界 400 且不入库」换成「走白名单丢弃 ⇒ 不 400、不入库、不回显」)、client(client-41 那句落款两头钉 / client-53 撤行不带走邻居 + 旧载荷不摆那句 / 五处 segRows 名单去掉「详情缓存」)、host-compat(hc-11 载荷键表换成 detailStampLabels、hc-20 整条重指向本轮接线)。★ 回算两个口径对上了:全文 ^ok 行数 528 与逐套 pass 加总 528 独立同值,not ok 0、^SKIP 2 与逐套 skip 加总同值(上一轮那次"单脚本加总自相矛盾"的病历,这次一开始就用两个来源各数一遍)。 ★ 前置取证两遍(都只读、零落库):① 匿名 9 发 GET 探针(tmp/probe-detail-304.txt,用户裁定「跑这个匿名探针先看看」)⇒ 三条路(元数据 / README / contents)全支持 304、单发 ≈500ms→≈100ms、正文 5,189 / 17,079 / 35,817 字节 → 0 字节、而 x-ratelimit-remaining 照扣 1 —— ★ GitHub 文档那句「304 不计入速率限制」被本机实测推翻,那句"每次点开都问一次"的真实代价因此是按次数而不是按字节计;② schema 丢弃探针(tmp/probe-schema-drop.txt)⇒ 未声明的多余键被 record() 静默丢弃、不抛 ⇒ 「撤掉那一格」方向安全、零迁移(这是"撤档能否撤干净"的实测而不是推断)。 ★ 本轮抓出的一处真回归(是产品代码坏了,不是测试写错):重写 get() 时把 catch 分支里那格 rate 丢了 ⇒ 一次传输炸让 keep() 把限额读数覆成 undefined,界面上那句"还剩多少"被一次失败擦掉。判据当场红;"是不是本轮弄的"用磁盘证据判:git archive HEAD lib | tar -x -C tmp/head-ver 取出 HEAD 那份同形状复跑 ⇒ 旧码回的是那个对象(本轮引入,不是既有病)。 ★ 三条"先假后真"的病历(都登记,不抹):① 证伪第 ④ 发首跑全绿 = 判据真有缺口 —— 原「不变式」只把 prev 造成缺位,而 prevHasMeta(undefined) 本来就是 false ⇒ 变异与原判据走同一条路,"库里有整行正文、却没有钥匙"那一形从没被验过 ⇒ 补一条判据(不变式第二形)才拿到失败信号,修法不是承认等价了事;② 第 ⑤ 发首跑报"没抓到"而套件里红的正是真判据 ⇒ 期望串对不上名字,改期望串不动判据(同 r26 病历 ② 第二次);③ store 那条撤档判据首跑断错了对象(断 patched.repoCacheHours === undefined)⇒ 重写成"下一次 read() 没有它"。⚠️ 本轮第一次全量复跑有 5 套在 import 处 SyntaxError(218 过 / 1 跳就断)—— 那是撤掉 REPO_CACHE_HOURS 等名字后的预期 fallout,不是判据变红;先接完五套的 import 与用例改判再复跑,这 5 个红字登记在此,不当"一次通过"。 ★ 证伪电池 tmp/r27-detail304-falsify.mjs(圈 lib/services/repo.js / client.js 两个源,读数 tmp/r27-falsify-out.txt)13 条 / 未抓到红 0 条、末行 [还原 ok] 两个文件跑完逐字节等于进来时(逐发红数 2/1/1/1/2/2/4/3/5/7/4/1/1 —— ⑩「checkedAt 写成 0」一下红七条:那一格是防连点、revalidated、载荷同形四条判据的共同地基)。★ 上一轮那四把一并复跑:r26-starszh-falsify 9/0、r25-fresh-falsify 9/0、r24-enable-falsify 9/0、mutate-client-6 14/0,末行均 [还原 ok] —— 前两把锚在 lib/api.js 与 client.js 的设置页那一片,本轮正好把「详情缓存」那一行与那格的 400 校验撤了,复跑是必须的而不是礼节。 ★ 本轮产品侧出网账:0 发(13 发变异全打在假 fetch 与手写的库里行上;真出网只有上面那两遍只读探针的 9 发匿名 GET,零落库)。⚠️ 真机欠账(10-10 13:3x 对账后收窄):一屏四读 + 一条只有活宿主能证(动的是宿主半边 index.js + lib/** 与浏览器半边 client.js ⇒ junction 挂载下要重启 dsh desktop):① 设置页「详情缓存」那一行没了而别的键一个没变(★ 同时是"open() 把用户库里那格 repoCacheHours 静默丢弃"的唯一读法 —— 假设施的 open() 不跑 schema,离线 528 条测不到这一发,而第十二十三轮那起「存储不可用」血案就出在同一格位置);② 详情底部那句「正文取回于 … · 刚核对过」(第一次点开只有前半截,一分钟后再点该有后半截而前半截的时刻不动);③ 60 秒内连点同一个仓库 = 零出网;④ 那颗「重新取一次(不走缓存)」必须真的重新出网并推进正文时刻;⑤ 配额读数会往下走(匿名档一小时 ≈1530 次点击到顶)。★ 已认证那一档(5,000/小时)本机零样本 —— 第三条裁定原文是「不测,边界如实登记」,不写成"验过"。我不替你重启、没动你的 prefs、没动库存行、也没替你点过详情弹框。第二十三~二十五轮那三屏照旧挂着,本轮没有顺手划掉。 ★ 同轮 13:3x 本机对账(tmp/probe-r27-live-storage.mjs,只读、零出网、一个行值都没打印)把这份清单改窄了三处:(a) ① 的存储侧不再是欠账 —— 用宿主装的那份真库(dsh-storage-domain@0.2.0-rc.1)开用户真库存的拷贝、吃本轮删完格的 GHT_DOMAIN:prefs 原始行 14 键含 repoCacheHours(那一格真躺着),真 open() 不抛,运行时内存 13 键、那一格被 parse 丢掉;(b) 前提已经满足 —— 五个 DeepSeek Harness 进程同为 12:28:46 起,而 client.js / repo.js 11:40:34、domain.js 11:59:44、index.js 11:07 落盘 ⇒ 跑着的宿主已经是本轮那一份代码,它 13:31 写进库存的两行详情各带上了 checkedAt + 两把验证器,②③④ 现在就能走、不必再重启;(c) ② 读到一半 —— 那两行 at 与 checkedAt 逐毫秒相等 ⇒ 正是"第一次点开只有前半截"那一形,而库里 0 行 checkedAt > at ⇒ "过 60 秒再点同一个 ⇒ 0 字节 304 + 多出后半截"还没发生过。⑤ 那句按盘上读数改口:库里 ghToken 非空 ⇒ "这台机器没有令牌"作废、那两发是带 Bearer 发的,但配额那一格到底是 60 还是 5,000 仍然零读数(恒吃回包,界面上那一屏是唯一读法)。全程没动你的 prefs、没动库存行、没读过那一格的值。

上一份读数(2026-10-08 本机复跑,第二十二轮「我开了翻译,为什么这些没有翻译」⇒ 榜面描述列接上现译那一遍,原文 tmp/rerun-r22.txt):SKIP_LOCAL=1 下 413 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 40 / repo 76 / check 39 / api 65 / client 58 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳)/ board-zh 19(★ 新开一套)⇒ 基线 391 → 415 条。 ★ 差额 +24 分三套:board-zh 0→19(圈 lib/board-zh.js + domain 那几格)= 两套行集各管各的(批次吃"同仓库三榜只留名次最好那条"去重的那份,视图吃"每一行都在场"不删的那份 ⇒ 同现仓库只烧一发额度、三张卡照旧各有中文)+ B 优先压过库里的现译行(第八轮那句原样成立)+ 逐字命中才算数(原文变了 ⇒ 旧译文当场作废并重新排队)+ 空白描述与仓库自己写的中文都不算欠账 + 同仓库两榜 desc 不同时"谁对上算谁、命中过的不再排队" + 失败冷却只挡排队、不改读数(过了冷却自动放回)+ 卡头句子两路混排并报 / 都没命中给空串 / 内置那一句逐字沿用旧文案 + 条数只算这一张榜 + 四种闸门理由各返回一次且一发不派 + 闸门顺序(库不可用排在开关之前:无存储时"下一轮自动再试"是假话)+ 一轮 12 发 / 在途 2 发 + 出厂常数那一格(改它要跟着改判据)+ 单闸 busy + 读库失败整轮作废(不当新行重烧额度)+ 落库归 translate() 自己做(runner 一个字不写库)+ 落款与那句实话来自 domain(用例里不出现手抄句子)。api 61→65 = 榜面那一列吃库里的现译行(★ hits 的值从「一句译文」升成「译文 + 它是谁译的」)+ liveNote 只在三格同时成立才说、其余几种闭嘴各有各的理由 + 读路径零发(GET /api/snapshot 与 SSE 首帧一发不派,补译只挂在一次 update 之后,补成真推第二帧)+ 闸门与上限那一圈(20 行屏上只补 12 发)。client 57→58 = client-48(就地改判,整句逐字读载荷 ⇒ 钉「客户端不许自己数条数、也不许编日期」)+ client-58 新(现译发不出去时榜面一句 .gt-notice,其余三种情形一个字都不多)。 ★ 另有两圈条数不变、内容改判:api 那条「内置预译的 hits 只覆盖屏上那些行」(hits 的值从「一句译文」升成 {zh,via,label,note,src} ⇒ 断言跟着改,用例名不动)、client-47(同一列并排两种来源后,行内落款必须念它自己那一句,不许拿卡头那句盖下去)。★ 设置页那句说明 TRANSLATE_COMMON_NOTE 从"现译只发生在详情"翻成「现译发生在两处」,而判据侧是 import 那个常量、不是手抄句子 ⇒ 文案改口、测试面零改动(同族那条律第二次兑现:手抄的那份才会红)。 ★ 证伪电池 tmp/r22-boardzh-falsify.mjs(圈 lib/board-zh.js 11 / lib/api.js 8 / client.js 6)25 条 / 未抓到红 0 条、末行 [还原 ok](读数 tmp/r22-falsify.log):每轮上限、并发、五种闸门各调顺序、B 优先、逐字命中、按榜算条数、两套行集各退回另一套那半边、读路径派活、轮次后不派、不推第二帧、卡头自己拼句、topN 截断、liveNote 两个条件、界面六条"只渲染载荷"。★ 首跑有两条没红,如实登记:① 拆掉 if (running) 之后那条 busy 用例挂在没释放的 gate 上(顶层 await 不结算 ⇒ 进程静默退出、套件不打印 ⇒ 电池拿不到失败信号)⇒ 判据自己补一次 200ms 竞速才响;② 把卡头分隔符改成无条件摆,只多出一个「 · 」,没有任何断言在乎 ⇒ 换成"界面自己数条数"与"借用别榜那一句"两条真变异。⇒ "漏网"有两种:没判据,和判据在但拿不到失败信号。 ★ 工具账(本轮踩到、写下来给下一轮):lib/api.js / client.js 在盘上是 CRLF,本轮新建的 lib/board-zh.js 是 LF ⇒ 多行植入必须按各自 EOL 拼,不然静默"植入失败";还原只走内存字节副本,不走 git stash(本机 autocrlf=true,往返会把文件整体改写成 CRLF)。 ★ 本轮出网 0 发:所有"补译"形状吃假 translator 与假库。⚠️ 没截真机屏(动的是宿主半边 index.js + lib/** 加 client.js ⇒ 要重启 dsh desktop 并硬刷新才看得见;本插件在宿主里是 github: 复制副本,改源码不即时生效 ⇒ 本机已把六个文件覆盖进副本,原文件备份在 tmp/host-copy/r22-before/)。我不替你重启、也没动你的 prefs 与库存行 ⇒ 挂在 §9.3 那条清单上(第十七、十九、二十、二十一轮同列)。

上一份读数(2026-10-07 21:0x 本机复跑,第二十一轮「匿名 60/h ⇒ 一小时最多 15 个仓库,设置页加一个 GitHub 令牌抬到 5000/h」那一遍,原文 tmp/rerun-r21.txt):SKIP_LOCAL=1 下 389 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 40 / repo 76 / check 39 / api 61 / client 57 / host-compat 21(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳,项数 29)⇒ 基线 378 → 391 条。 ★ 差额 +13 分四套(按圈记,不是"新增十三条用例"这么轻):repo 68→76 = 默认零凭据那一圈(不填 ⇒ 每一发没有 authorization)+ 填了 ⇒ 四发各带一条 Bearer 且 URL 一个字节不变、域也不变 + 空格等于没填(请求头与视图两侧 trim 同口径)+ 上限吃 x-ratelimit-limit 那三种形状(回 5000 换档 / 仍回 60 照念匿名 / 代理吞头退回保守那一格)+ 门面 rate() 的 limit 与 label 跟着换档 + 令牌现取现算(改偏好不用重启,清空后下一发就不带);api 59→61 = githubView 只给 has 布尔不给 value(说明句与「去哪创建」全来自 domain)+ 快照里 github 那一格恒在(客户端没有兜底表,缺键就是白屏不是少一行);client 55→57 = client-56 令牌行三形状全吃 snap.github、密钥格永不回填、「清除」只在存过时摆 + client-57 配额那句只从宿主的 rate.label 来;host-compat 20→21 = hc-21 接线(装配处出现 const *token* = 那种抄死即红、令牌读者清单从 import 边派生、界面不许抄「匿名/已认证」那两个词)。 ★ 另两圈条数不变、内容改判:store 那两条(凭据格清单从手抄六格改成吃 PREF_CRED_FIELDS 那份派生表 + 那条新增键自查改用「上一版行形状只缺 ghToken」—— 拿第十三轮那起「存储不可用」血案当尺子);api 旧那条「密钥不回显」里的 secretKeys.length === 3 翻成 deepEqual 派生四把(★ 手抄一个数就等着漏扫新增那把)。 ★ 证伪电池 tmp/r21-falsify.mjs(圈 domain.js / lib/stores.js / lib/api.js / lib/services/repo.js / index.js / client.js)16 条 / 未抓到红 0 条、末行 [还原 ok](读数 tmp/r21-falsify-out.txt):① 无条件带头 ② 接线漏发 ③ 令牌拼进 URL(行为侧)③b 同一个植入换 hc-7 那条静态判据(★ 这一发是"那条静态判据不是摆设"的非空转证明,同族第八次兑现)④⑤ 两侧 trim 各缺一半 ⑥ 上限钉死不看头 ⑦ 把"带没带头"排在响应头之前(坏令牌报成"已认证"= 把没生效说成生效)⑧ 丢掉吞头那条退路(少报也是谎)⑨ 读不到上限不退回出厂那一格 ⑩⑪⑫ 三处清单退回手抄 ⑬ 视图多给一格 value ⑭ 装配时锁成常量 ⑮ 界面自己抄那两个字。★ ⑩ 首跑红在另一条断言上(记录校验失败:GitHub 令牌…过长(318 字,上限 256 字),不是我预期的那格)⇒ 挂反了也是挂,这一条如实登记。 ★ 本轮出网 0 发:本机没有 GitHub 账号也没有令牌(★ 10-10 只读对账改口:用户库里 ghToken 那一格是非空的 ⇒ 这句当时就不准,准的那半是"这一轮没读也没用它、一切填了令牌的形状都吃假 net.fetch"),一切"填了令牌"的形状都吃假 net.fetch。★ 5000 那个数字在本机是合成的(历次真回包只见过 60,那条 5000 的头是喂进去的)⇒ 界面上「已认证配额 / 5000」这一屏永久验不到,可验的那半是**"填一个坏令牌 ⇒ 那句必须仍念『匿名配额』"(repo 那一圈第 5 条钉的就是它)。载荷只多 github 一格、repo schema 未动、version 仍钉 1(ghToken 走 optional + clampPrefs 补默认,第十三轮那条律一个字没松)。 ⚠️ 同样没截真机屏(动的还是宿主半边 index.js + lib/** ⇒ 要重启 dsh desktop** 才看得见,我不替你重启、也没动你的 prefs 与库存行),第十七、十九、二十、二十一轮那几屏挂在 §9.3 同一条清单上。

上一份读数(2026-10-07 20:1x 本机复跑,第二十轮「使用 README.zh.md 这种」挑篇优先档那一遍,原文 tmp/rerun-r20.txt):SKIP_LOCAL=1 下 376 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 40 / repo 68 / check 39 / api 59 / client 55 / host-compat 20(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳,项数 29)⇒ 基线 376 → 378 条。 ★ 差额只在一套:repo 66→68 = zhVariantRank 那一圈(三档封闭 + 目录名不参与 + 子串不算命中 + 两份名单不许交集 + 简繁同时命中按繁体)+ 「两路挑篇共用同一条优先档」那一圈(同一件事在 pickZhReadme 与 pickZhReadmeLink 各钉一次,外加"只有繁体时照旧挑中"那两条反面)。★ 另有一圈条数不变、内容改判:pickZhReadmeLink 那条旧断言「多条命中按名排序」把"繁体那份赢"钉成了规矩 ⇒ 本轮就地翻案(同第八轮 provider:undefined、第十七轮 wt-28 那一族)。 ★ 证伪电池 tmp/r20-falsify.mjs(圈 domain.js / services/repo.js)9 条 / 未抓到红 0 条、末行 [还原 ok](读数 tmp/r20-falsify-out.txt):两路各退回字面排序 / 两路各把排序做成过滤 / 词元从整条路径切 / 词元换子串 / 简繁先后调换 / 丢掉 tie-break / 两份名单撞车。★ 一条自我 correction:首跑第 ⑥ 条(词元换子串)的植入写成 /tw|hant|hk/.test(base) —— 顺手丢了大小写归一,一发变异同时动两维、连带把 pickZhReadmeLink 那一圈也炸了 ⇒ 改成单因(base.toLowerCase())复跑后,红只落在该落的那条断言上。变异不单因,读数就在同时说两件不同的事。 ★ 同轮只读对账(零出网,吃本地库存):thedotmack/claude-mem 那行 repo 记 readmeSource=en_default / readmePath=README / zhCjk=9 / at=2026-10-06 08:42:21 ⇒ 早于第十五轮第二路,所以"改完挑简体那份"在活宿主上从来没跑过,这一条是待截图不是已验。★ 第十九轮那件"旧译文行删"这一轮 20:0x 复跑对账照旧是 trans 9 行 / readme:* 6 条(宿主 5 个 DeepSeek Harness.exe 进程 18:25 起在跑)⇒ 仍未做成,等你关掉 dsh desktop。 ★ 本轮出网 0 发(判据吃第十九轮那 4 发留下的读数 + 本地库存),载荷键与 repo schema 零增量;⚠️ 同样没截真机屏(宿主半边 ⇒ 要重启 dsh desktop,我不替你重启),第十七、十九、二十轮那几屏挂在 §9.3 同一条清单上。 ★ 顺手抓到一条旧账(如实登记,不藏):下面那张逐套表里 repo 与 api 两格的数字停在第十八轮(64 / 57),而第十九轮其实已经是 66 / 59 —— 那一轮只在正文记了差值、没补表头。本轮已按现读数补齐(68 / 59)。⇒ 台账里"正文与表格是两处真相"这种形状和代码里的同一句,判据一样:改一处必须扫另一处。

上一份读数(2026-10-07 19:24 本机复跑,第十九轮「这两种也算有中文」第三道闸门那一遍,原文 tmp/rerun-r19.txt):SKIP_LOCAL=1 下 374 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 40 / repo 66 / check 39 / api 59 / client 55 / host-compat 20(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳,项数 29)⇒ 基线 372 → 376 项。 ★ 差额四条按圈记(不是"新增两条用例"这么轻):api 57→59 = 第三道闸门命中圈(两形状各钉 jobs 为空 + 段名后缀)+ 反面独立一圈;repo 64→66 = readmeZhOnScreen 命中圈(真读数钉两侧余量:9 挡 / 3 不挡、7 不算 / 8 算)+ 反面独立一圈(日本語 / 纯英文 / 空串 / 中国·中國 / 英文 Chinese)。 ★ 本套第 8 次撞「用例名含『真机』⇒ SKIP_LOCAL=1 静默跳过」:新那条 repo 用例一度报 skip 1 而我以为它在跑 ⇒ 改名「两侧各用一条本机真读数钉边界」;要真出网的口径仍然只归 hc-17 / wt-27 两条,别的用例名里不许再出现"真机"两字。 ★ 证伪电池 tmp/r19-falsify.mjs(圈 api.js / domain.js / services/repo.js)8 条 / 未抓到红 0 条、末行 [还原 ok](读数 tmp/r19-falsify-out.txt)。★ 首跑第 ③ 条挂在别人的现场上(阈值降到 1 时同 check() 里 lang 那条先炸,"误挡日文"轮不到报红)⇒ 反例拆成独立 check 后复跑,③ 现在红在「attachZh:第三道闸门的反面 —— 「日本語」…」」、⑤ 红在「readmeZhOnScreen 的反面:…」—— 这是「**证伪要在自己的现场上挂**」那条律的第 8 次兑现。 ★ 同轮**库存对账**(tmp/probe-readme-zh-rows.mjs只读、零出网):19:24 删掉那一行后trans表 5 条readme:**全部**readmeSource=en_default([对账 ok]),★ 但 **19:26:37 被在跑的宿主用内存态写回**(19:33 复跑 ⇒ readme: 又 6 条,alibaba/open-code-review 那一条原样在)⇒ **"旧译文行删"这一件没做成,要等宿主关掉再删**(下面第十九轮那份读数与第十六件 ④b 记的是同一件事)。 ★ 本轮**没截真机屏**(动的又是宿主半边,link:` 挂载要重启 dsh desktop,我不替你重启),下面那两份读数的"欠截图"账一起挂着。

上一份读数(2026-10-07 18:3x 本机复跑,第十八轮「README 有中文就不派摘要」补判据那一遍,原文 tmp/rerun-r18.txt):SKIP_LOCAL=1 下 370 过 / 0 挂 / 2 跳,逐套 gh 19 / net 22 / store 40 / repo 64 / check 39 / api 57 / client 55 / host-compat 20(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳,项数 29)⇒ 基线仍是 372 项,与上一份逐套同数。 ★ 同数不等于同内容:api 那一套里 attachZh…摘要档只认 en_default 那条改判了 —— 三档中文(zh_default / zh_file / zh_section)原先只在「只开描述档」的桩下摆(那种形状 want('readme') 恒假,闸门坏了也测不到 ⇒ 我第一版新加的那行被电池当场判成假绿),现在各在「只开摘要档」那一圈钉「jobs 为空」+ 各自的 self 段档名。check() 条数因此不变(矩阵里的行不是新用例)。证伪电池 tmp/r18-falsify.mjs 7 条 / 未抓到红 0 条(三档各单独开侧门 + 整闸放宽 + 两处中文判据 + 第二路断掉,读数 tmp/r18-falsify-out.txt),末行 [还原 ok]。★ 本轮行为一字未改 ⇒ 没有新真机现场,第十七轮那两屏照旧欠着。

上一份读数(2026-10-07 16:0x 本机复跑,第十七轮摘要现译放回那一遍,原文 tmp/rerun-r17.txt):SKIP_LOCAL=1 下 370 过 / 0 挂 / 2 跳(hc-17 与 wt-27,逐套 gh 19 / net 22 / store 40 / repo 64 / check 39 / api 57 / client 55 / host-compat 20(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳,项数 29))⇒ 基线 371 → 372 项。 ★ 差额一条:api +1(新那条 switchRows 那句说明跟着档位走 钉的是本轮仅剩的那道口 —— 行名不变、说明句与段名跟着档位走;外加一条反向:服务没声明 kinds() 时一行都不摆,而这与档位无关)。四套条数不变、内容改判:repo(段名三档词都收:中文摘要 / 中文节译 / 中文现译 · 没取到)、client(client-49 两行开关 + 说明句跟档位、client-51/55 找段改吃 summaryAny)、host-compat(hc-18 翻译档也返回两行)、web-translate(wt-28 整条重写:这一档 serve 两路,llmReadme 开着就真译、关着连网都不碰)。 ★ 本轮电池 tmp/r17-falsify.mjs(圈 domain.js / web-translate.js / repo.js / api.js / client.js 五个文件)12 条 / 未抓到红 0 条,末行 [还原 ok],输出原文 tmp/r17-falsify-out.txt。★ 首跑有一条压根没验成:客户端那条的锚点缩进我抄错(12 空格 vs 文件里 10 空格)⇒ 电池报的是「锚点失效」而不是假绿,改正后重跑才成 12 条 —— 这一条如实登记:锚点命中数必须打出来,否则"改动没落地"和"判据没承重"在输出里长得一样。③④两组做了两头(宿主拼段名跑 repo、客户端摆段名跑 client;服务能力声明跑 web-translate 与 api 两套),其中"真服务只报 desc"那一发红在 api 的桩=真服务对齐那条上,不是我以为的选路那条。 ★ 同轮不带 SKIP_LOCAL 的直跑(原文 tmp/rerun-r17-full.txt):371 过 / 1 挂 / 0 跳 —— 挂的是 wt-27 免费档真出网那一发回 HTTP 429([web-translate] pass 28 / fail 1),与本轮改动无关,是外部限流;上一轮同一条是通的 ⇒ 口径照旧:满绿在任何一份上都不保证复现。

上一份读数(2026-10-07 15:4x 本机复跑,第十六轮两件旧账那一遍,原文 tmp/rerun-r16.txt):SKIP_LOCAL=1 下 369 过 / 0 挂 / 2 跳(hc-17 与 wt-27,逐套 gh 19 / net 22 / store 40 / repo 64 / check 39 / api 56 / client 55 / host-compat 20(+1 跳)/ desc-zh 7 / llm 19 / web-translate 28(+1 跳,项数 29))⇒ 基线 368 → 371 项。 ★ 差额三条一条一件的两头:web-translate +1(wt-29 请求号那条,含"最坏情况"那一发:403 + 64 字顶满的号 + 700 字错误体,量的是那串号在调用点 slice(0,200) 之后还活不活着)、repo +1(同屏去重那条:同字面撤、原因不同照给、只重一句时按格撤、描述没派活时一句不少)、client +1(client-55:同一句话在整屏文本里只出现一次,夹具走的是真的 applyZh + repoSections —— 手搓两份"看起来一样"的载荷就测不到宿主那份去重)。 ★ 本轮电池 tmp/r16-falsify.mjs(只圈 lib/services/web-translate.js 与 lib/services/repo.js 两个文件)11 条 / 未抓到红 0 条,末行 [还原 ok],输出原文 tmp/r16-falsify-out.txt。★ 这一轮的电池刻意一套植入跑两套:repo.js 那五条里的两条另在 client 套件里各跑一遍(同一条屏上的话,宿主拼与客户端摆是两套判据,第十五轮踩过"植入的文件与跑的套件对不上 ⇒ 判据等于没验")。两条旧口径的假绿顺带清掉:上一轮我说".slice(0,200) 正好切掉 request id"—— 实测旧 vendorErr 压根没把那串号拼进回执(三家位置还各不相同),所以「只认 RequestId 不认 log_id」这一发才是百度那一档的真防线。 ★ 同轮不带 SKIP_LOCAL 的直跑(原文 tmp/rerun-r16-full.txt):371 过 / 0 挂 / 0 跳 —— hc-17 与 wt-27 那两条真口径又通了一次(口径照旧:满绿在任何一份上都不保证复现,同一用例同一天里通与不通都出现过)。

上一份读数(2026-10-07 12:5x 本机复跑,第十五轮四件合并那一遍,原文 tmp/rerun-r15.txt):SKIP_LOCAL=1 下 366 过 / 0 挂 / 2 跳(hc-17 与 wt-27,逐套 gh 19 / net 22 / store 40 / repo 63 / check 39 / api 56 / client 54 / host-compat 20(+1 跳)/ desc-zh 7 / llm 19 / web-translate 27(+1 跳))⇒ 基线 358 → 368 项。 ★ 差额四处都在数据面与能力面上:repo +7(分家两条、句子边界一条含代理对那一发、第二路三条含 404 回落、pickZhReadmeLink 一条)、api +1(假那两路桩的能力声明 = 真服务的声明 —— 跨边界两头都要断言)、llm 与 web-translate 各 +1(两档各自的 kinds():LLM_KINDS 两路全 serve ⇄ SERVED_KINDS=['desc'] 摘要即使开关开着也不派。★ 后半那句是第十五轮当时的口径,第十七轮已改判回 ['desc','readme'],wt-28 那条判据整条重写见上面第十四件)。 ★ client / host-compat 条数不变、内容改判(test/client.test.mjs 现译那一屏那条用例的夹具改成吃 switchRows、两处桩各自声明 kinds();test/host-compat.test.mjs 的 hc-18 从读 translator.descOn 改成遍历 translator.switchRows)—— 只报条数就会把这两套的改判漏记账。(★ 这条与 §9.3 那几处旧行号一并记:行号会随用例增删漂移,指向某条判据要认用例名不认行号) ★ 本轮电池 tmp/r15-falsify.mjs(圈 repo.js / domain.js / web-translate.js / api.js / llm.js 五个文件)12 条 / 未抓到红 0 条,末行 [还原 ok],输出原文 tmp/r15-falsify-out.txt。★ 首跑抓出两条假绿:「绝对 URL 闸门撤掉」当场全绿(// 那种被"空段"那一支冗余挡住 ⇒ 补无 // 的 mailto: / http: 坏形状才承重)、「宿主模型谎报只 serve desc」那一发指错了套件(植在 llm.js 却跑 api)—— 判据在另一套件里等于没验。 ★ 同轮不带 SKIP_LOCAL 的直跑(原文 tmp/rerun-r15-full.txt,10-07 13:4x):368 过 / 0 挂 / 0 跳 —— hc-17 与 wt-27 那两条真口径这一次都通了(免费档真出网那发没撞 429)。★ 第十二轮那条口径照旧作数:满绿在任何一份上都不保证复现(同一用例同一天里通与不通都出现过),别把任何一份总数当"永远如此"。

上一份读数(2026-10-07 11:2x–11:3x 本机复跑,第十四轮名次徽章分档那一遍,原文 tmp/rerun-r14.txt):SKIP_LOCAL=1 下 356 过 / 0 挂 / 2 跳(hc-17 与 wt-27,逐套 gh 19 / net 22 / store 40 / repo 56 / check 39 / api 55 / client 54 / host-compat 20(+1 跳)/ desc-zh 7 / llm 18 / web-translate 26(+1 跳))。 ★ 与下面 11:0x 那份的唯一差额是 client 那一条 client-54(三头判据:单点类名 / 两处渲染点各带档类 / CSS 规则逐字)⇒ 这一轮改的是纯观感,数据面、载荷、schema 一字未动。 ★ 本轮新电池 tmp/r14-falsify.mjs(只圈 client.js 一个文件)7 条 / 未抓到红 0 条,末行 [还原 ok];输出 tmp/r14-falsify-out.txt,★ 第二版 tmp/r14-falsify-out2.txt 把挂掉那一条的断言消息一起打出来 —— 只报"挂了哪条用例"不够,本轮一条用例里有三头,得看得见是哪一头抓到的。 ★ 一条自等价植入当场被剔(const n = Number(rank) 换成 parseInt(rank,10) || rank 抓不到任何红 —— 坏名次仍旧落中性档),位置让给「榜页表格那一处自己拼徽标」。 ★ 这一条用例首跑挂在它自己的前提断言上:夹具的日榜只排到第 3 名 ⇒ "第 4 名走中性"那一档空跑,补成 5 行才落到位(assert.equal(boardBadges.length, 5, '前提:…'))。

上一份读数(2026-10-07 11:0x 本机复跑,第十三轮修完「存储不可用」那一遍,原文 tmp/rerun-r12-fix.txt):SKIP_LOCAL=1 下 355 过 / 0 挂 / 2 跳(hc-17 与 wt-27,逐套 gh 19 / net 22 / store 40 / repo 56 / check 39 / api 55 / client 53 / host-compat 20(+1 跳)/ desc-zh 7 / llm 18 / web-translate 26(+1 跳))。 ★ 与下面 10:0x 那份的唯一差额是 store 那一条新回归判据(跑真 valueSchema.parse 吃上一版库存行形状,见上面第十三轮那条)⇒ 这次修复没碰行为。 ★ 同一块证伪电池(tmp/r12-falsify.mjs)本轮扩到 20 条 / 未抓到红 0 条,输出原文 tmp/r12-falsify-out3.txt(前三份 r12-falsify-out.txt / -out2.txt 是第十二轮那 19 条的,原样留着)。

上一份读数(2026-10-07 10:0x 本机复跑,第十二轮收尾这一遍):SKIP_LOCAL=1 下 354 过 / 0 挂 / 2 跳(hc-17 与 wt-27,逐套 gh 19 / net 22 / store 39 / repo 56 / check 39 / api 55 / client 53 / host-compat 20(+1 跳)/ desc-zh 7 / llm 18 / web-translate 26(+1 跳)); 不带 SKIP_LOCAL 的那一份这次是 355 过 / 1 挂 / 0 跳 —— 挂的还是 wt-27(免费档那一路真出网那一发回 HTTP 429,[web-translate] pass 26 / fail 1)。 ★ 口径一句(本轮更正):这里数的是用例(check)条数,不是 assert 条数 —— 跑测器 test/_helpers.mjs 只按用例打 pass/fail/skip,没有断言计数器;旧文档写「352 项断言」是把两件事混成一件了。 ★ 上一轮的 350/0/2(第十一轮收尾,原文 tmp/rerun-r11.txt)、第十二轮收尾的 354/0/2 与本轮(第十三轮)的 355/0/2 都只说明"离线这一些绿";满绿在任何一份上都不保证复现(10-06 当晚直跑 352/0/0,10-07 三个时刻里 429 挂过两次),这正是"免费档不是授权接口、随时可能限流"那句判据的读数;别把任何一份总数当"永远如此"。 ★ ⚠️ 但"离线满绿"连界面是否亮着都不保证 —— 10-07 第十二轮落地当天就有过一发:354/0/2 全绿的那一会儿,用户 desktop 上是三榜全红「故障 · 存储不可用」(假设施 open() 不跑 schema,测不到那一发;判据与修法见上面第十三轮那条与 docs/design-spec.md §4 末尾)。 ★ 同日 13:5x 那一次(第九轮收尾)直跑是 331 过 / 1 挂:挂的是当时唯一真打免费接口的 wt-19(现编号 wt-27),translate.googleapis.com 连回两发 HTTP 429(等 20 秒再打仍 429)⇒ 那是外部限流的读数,不是代码坏了(离线那些全绿,插件侧的表现是降级:原文照给 + 一句「翻译接口回了错误状态」)。 本轮 19:5x 复跑那一发又通了 ⇒ 同一个用例在同一天里通与不通都出现过,这正是"免费档不是授权接口、随时可能限流"那句判据的读数;别把任何一份总数当"永远如此"。逐轮台账与证伪读数(每条新判据都改坏一次看它挂不挂)在 docs/design-spec.md §9.2。

文件项数覆盖
gh.test.mjs19parseCount 缩写量级返回 null(不交假数)、<h2 起找仓库名、跨 </svg> 取数值、丢行率判改版、304 分支、脏 slug 不出网、四档语言判定、代理配置错标 configError(不补发)而连不上代理仍算传输类
net.test.mjs22插件内隧道全套(全离线:假 socket / 假 runReg / 注入的 tunnelRequestFn):地址解析四类报错、凭据掩码、环境变量优先序、注册表三行只认那三行、例外命中转直连、路线仲裁四档各有记法、CONNECT 请求行字节逐个钉死、200 后同包 TLS 字节 unshift 不丢、407/502/关闭/连不上/超时各给一句话、跟满 maxRedirects 就把最后一个 3xx 交回、注册表缓存 60s 与 invalidate、坏配置绝不静默回落直连
store.test.mjs59(★ 第三十四轮 +2(§8.17 那把尺的牙):①「★ repo 裁行吃 checkedAt 而不是 at:304 反复命中的那一行不能被删」—— §8.13 那处"越省额度越先被 LRU 删掉"隐患的行为判据,②「★ 那把尺不吃脏时刻:库里躺着 checkedAt: Infinity / "9000"(手改 json、换机搬库)⇒ 按「没有这一格」回退 at」(⚠️ 脏行必须绕开 schema 用 facility.seed 塞 —— checkedAt 走 optionalNumber,put 那关就抛;★ 这一条是证伪电池首跑抓到"判据空跑"之后补的);同轮就地改判那条 499(list() 交出去的 askedAt 与裁行吃同一格,排序键与裁行键同源 ⇒ 界面/排障读的那份不许是第二把尺);★ 第三十二轮 +10:第八张表 fav 那一圈(schema 挡脏行 / add 幂等且沿用库里 addedAt / remove 的 removed 位 / 键归一小写 / list 倒序 / 不裁行不参与 LRU / 缺位五格存得进 / 无设施报 UNAVAILABLE / 动作两档封闭 / ★ 那条「新表从本轮起也进了『已有表』那一侧」的自查);★ 第三十一轮条数不变、就地改判:repoCacheHours 那一格从「既不读出来也写不进去」翻回「只认 REPO_CACHE_HOURS 四档、越界回落出厂 24」—— clampPrefs 补它、DEFAULT_PREFS 有它、patch({repoCacheHours:6}) 之后下一次 read() 带着它;第十三轮那条「每张表都得吃得下上一版库存里真实存在的那一行」照守(改回 optionalInt ⇒ 缺这格的旧档案读回 24 而不是 undefined,电池 ⑦ 打成 requiredInt 时这一圈红 2 条);★ 第二十三轮 +7:seen 两格 + 第七张表 search;★ 第二十七轮条数不变、就地改判那条撤档判据;★ 第二十八轮条数不变、就地补断言:LLM_KINDS 那份名单从两路扩到四路的逐字断言 + 那两路整篇真存得进来且各占一行不许互相盖 + zh 那一格 30,000 字长文写得进读得出(写入侧只有 MANUAL_FULL_ZH_MAX 一道闸,schema 里没有第二道长度闸))域登记表(refs 计数 / 关完才摘牌 / open 失败可重试)、写串行队列、close() 后写报 CLOSED、无设施报 UNAVAILABLE、prefs 宽容档 vs strict 档、代理模式只认封闭集合(地址能解析就原样留含凭据,坏地址清空留 warn)、seen 首见钉住 first*、六表同域且 version 钉在 1(抬版本 = 本机榜史整个打不开)、repo 表小写主键 / schema 拒脏行 / maxRows LRU 裁行、trans 表:键是 kind:小写仓库(描述与摘要两档互不覆盖)、schema 挡脏行(kind 只认封闭集合,空原文空译文进不来)、无设施时 available=false 且读写报 UNAVAILABLE(现译层据此走"只译不存")、超 TRANS_MAX 按最老裁、★第十轮两条:现译引擎旧值 official 在 clampPrefs 里先搬家再判脏**(顺序反了会把库里那份抹回出厂档,而凭据还躺着没人念)+ 六格凭据只钳长度、内容不归一化;trans 那一格吃的是 TRANS_ROW_ENGINES(现行五档 + 历史档名),旧档名那一行仍然读得出来 —— 换档名不等于把用户库里的译文全废**、★第十二轮:repoCacheHours 只认 REPO_CACHE_HOURS 那四档(5 / 0 / 100 / 'abc' / null 一律回落出厂 24),库里缺这格的旧档案读回来是 24 而不是 undefined(⚠️ 这一条当时只走到 clampPrefs,没走 schema —— 同轮那格写的是 requiredInt,真宿主 open() 读老库存行时当场抛、整域不可用 ⇒ 这条用例在假设施上绿而界面上红)、★第十三轮补的那条:★ schema 的 open 校验:每张表都必须吃得下"上一版库存里真实存在的那一行"(缺新增键 ≠ 坏行) —— 吃的正是真宿主那一步(GHT_DOMAIN.tables[t].valueSchema.parse,三份上一版行形状 prefs / repo / trans),两头钉:不抛(否则整域「存储不可用」)+ 'repoCacheHours' in parsed === false(补默认只许 clampPrefs 一处,两处都补就是两份真相);★第二十一轮 就地改判(条数不变)两条:凭据格那圈的清单从手抄六格改成吃 PREF_CRED_FIELDS 那份派生表(GitHub 令牌自动进来,且"空格等于没填"这一条与 repo.js 那条 trim 同源)、★ 那条新增键自查换成"上一版那一行 —— 出厂值齐全、只缺 ghToken"必须被 open() 吃得下(拿第十三轮那起「存储不可用」血案当尺子:写侧不校验、读侧一行坏行拖死整域)、★第二十七轮 就地改判(条数不变)那条「repoCacheHours 只认封闭四档」:判据从「越界回落出厂 24」翻成「那一格既不读出来也写不进去」—— clampPrefs 不再补它、DEFAULT_PREFS 里没有它、patch({repoCacheHours:6}) 之后下一次 read() 没有它、老库里那一格(连同任意一个未声明的脏键)经 open() 读回来时渗不进运行时(★ 首跑我把这条写成断 patched.repoCacheHours === undefined,而 patch() 回的是 clampPrefs({...cur, ...fields}) ⇒ 回显留、落库丢,断错了对象;现在钉的是"存不下来",不是"不回显"。⚠️ 这一条只走到 clampPrefs 与假设施的 schema,真宿主 open() 那一步仍然只有活宿主能证,欠账挂 §9.3 本轮那条)
repo.test.mjs106(★ 第三十一轮 +1:新那条钉「过期那一问再按用户改的那一档现算:装配后改档,下一发就按新档判,不用重启宿主」⇒ 打的就是 getTtlMs() 调用时现取现算那一行(第十二轮那笔账的回归判据);★ 同轮就地改判三处(条数不变):TTL 判 checkedAt、缺这格的老行回退 at(D1,反面钉"304 之后 at 冻住 ⇒ 判 at 会每次都出网")+ zhProbed 不是 true 的成功行不受 TTL 挡(D2,与第三十轮那条自愈共用一个出口)+ 落款 revalidated 收窄成 cached !== true 才可能真(D3);★ 第三十轮 +4:那一格 zhProbed 那一圈 —— 库里缺那一格的老行(两把钥匙齐着也不喂 ⇒ 裸发四发 + 写回 true)/ 那一格是 true 才照旧复用(2 发带钥匙、at 不动、revalidated 为真)/ ★★ 冻结那一形自愈(第一问中文篇超时 ⇒ en_default+false 落库;第二问裸发 ⇒ 翻成 zh_file;第三问回到 2 发 ⇒ 一次性代价必须收敛;★ 用例名里不许带「真机」二字,否则被 SKIP_LOCAL 静默跳过 —— 首跑就少了这一条而读数仍全绿)/ 八形口径逐形钉(zhProbed 与 readmeSource 两头都断,形状对齐 tmp/r30-branches.mjs 的读数);★ 同轮就地补一句断言(条数不变):那条「200 那一问把验证器原样落库」新增 row.zhProbed === true(schema 或白名单漏格在它旧形状里不可见 —— 电池 ⑪ 首跑就是这么红到别处去的);★ 第二十八轮 +5:那一发裸取整篇那一圈 —— 库里躺着验证器也一个字都不喂 / path 空与 README 走 /readme、其余逐段 encode 走 /contents / 零入库也不进 60 秒窗口(跑完库里那行不变、下次点开详情照旧自己问它的四发)/ 三种失败各说各的话且都不写字 / hc-21 那条「令牌只进请求头」的效果侧扩到这一发;★ 第二十三轮 +11:searchRepositories() 那一圈;★ 第二十七轮 新增十二条 / 就地撤掉旧 TTL 那三条(净 +9))仓库详情那一层全套(全离线,喂 test/fixtures/repo-api.json 的真字节):owner/name 形状闸门(坏名字零出网)、stripReadme 四种方括号写法(徽章串 / 引用链接 / 嵌套图片链 / 链接定义行)削到不留一个方括号、CJK 判据钉三档真读数(周刊 297 / antd 英文篇 2 / 中文篇 30)与 19-vs-20 边界、pickZhReadme 吃真根目录列表、2/3/4 发的请求路径与每发的 header/timeoutMs/signal、README-404 与 meta-404 分档、403 带 remaining:0 才算限额、proxy_config 与传输错分开、repoCacheRow 只落 schema 字段、readmeMeta 落款四个口径(节选字数吃屏上那段、整篇长度另说、两个数相等时不报整篇)、缓存命中与刚取回两条路键集与整句中文逐字一致、★TTL 按设置页那一档现算(repoCacheTtlMs 封闭四档 + 出厂 24h;改档后同一行的下一发就按新档判新鲜,不在装配时锁死)/ 失败档 5min、refresh 绕 TTL(★ 第二十七轮撤掉:详情改条件请求后那一档没有可判的对象,窗口只剩"60 秒防连点"与"失败 5 分钟"两格,都在 domain 里、都不进设置页)、在途去重、无存储时降级、脏行出边界时折成可用形状、内置预译命中时叙述三段(中文描述(<来源·时间戳>,不是现译):… 单独一句 + 原文另起一句),三条非命中形状仍分别说「原文,未翻译」与「仓库没有写描述。」、现译落款与 B 的字面分离(C 那一句里不许出现「内置离线预译」)、applyZh 两路并载荷 + B 命中不重拼 + 坏载荷不炸、两条旧用例的夹具改吃真的 repoView() 产物(夹具自己拼形状就测不到"少一格")、★第十一轮 +9(A):splitReadmeSections:围栏代码块里的 # 行不算语义标题(真形取自榜上那篇 token_ids…,原名带「真机」⇒ 被 SKIP_LOCAL 静默跳过、改名才进覆盖面)/ pickZhSection 两条(文档顺序取第一段、语言切换行与赞助者名单算噪声)/ descIsZh 阈值 8 的两侧余量 7 与 48 / 默认篇外文 + 整篇嵌一段中文小节 ⇒ zh_section,仍三发封顶(逐条点名请求路径 = 出网预算那条)/ descSelfZh ⇒ 入库行带 true 且这一档不靠翻译接口 / repoSections:段序只认 REPO_SECTION_KEYS / 数字只在 heat 段出现一次 / 描述那一句有五种来源,字面必须分得开 / self 段按 README 五档各给一句 + summary 段成功带落款、失败给 note 与回执两行;★同轮就地改判(条数不变):repoCacheRow(sections / sectionFields 两格一个字都不进库,先断"这格在 view 里存在"再断"库里没有"—— 反手抄)、缓存命中与刚取回两条路逐键同形(比的是 sections 整体 JSON.stringify,且两条路都留着 sectionFields 且逐字相等 ⇒ 删那一刀在 api 边界不在 builder)、库里躺着外部改过的脏行(段表只两段的期望改判);★第十五轮 +7:第十五轮分家:判据窗口 600 只用来数 CJK,节选吃去标记后的整篇(旧版拿窗口当节选 ⇒ 1,600 的预算从没生效)/ 第十五轮分家在载荷上兑现:长英文篇的节选真的到 1,600 / 节选在句子边界收口:回退到窗口内最后一个句末;中西文断句形状不同,中文那句没有空格(同一条里含代理对那一发:1,398 个 x + end. + 200 枚 emoji ⇒ 长度恰为 1,599,切在半枚 emoji 上就红)/ pickZhReadmeLink:第二路吃语言切换行 —— markdown 与 href 两种写法都认,多条命中按名排序 / 第二路的闸门在造 URL 之前:绝对 URL / 站内绝对 / 片段 / 反斜杠 / 非 .md / 穿越 / 超长一律不放行 / 第十五轮第二路:根目录那一层没有中文篇、但语言切换行写着路径 ⇒ 只在命中时补一发(共四发封顶) + 第二路那一发 404 ⇒ 回落 en_default,详情不炸 / ★第十六轮 +1:同一句失败话在一屏上说两遍 ⇒ summary 段那两块逐字撞上屏上已有的字面就不摆(四档:note+回执都与描述那一段相同 ⇒ 两块全撤但段名照摆「中文摘要 · 没取到」(★ 第十七轮那句改念「中文现译 · 没取到」—— 失败行没有引擎,切不出是哪一档);原因不同 ⇒ 各说各的不许去重;只 note 相同 ⇒ 只撤 note、回执留下;描述那一路压根没派活 ⇒ 一个都不许撤)—— 去重吃的是已上屏的字面不是"两路是否同一个引擎",后者为真时前者未必相同(note 各有各的档位话术);★第十七轮 就地改判(条数不变):段序只认 REPO_SECTION_KEYS 那条对 summary 段收三个词(中文摘要 / 中文节译 / 中文现译,按档位与成败各念一个),成功段名新增 /中文节译 · 免费接口 · / 与 /中文摘要 · 模型现译 · / 两头 —— 段名跟着那一行自己的引擎走,不跟着当前设置走;★第十九轮 +2:readmeZhOnScreen:摘要闸门的两条来路,两侧各用一条本机真读数钉边界(9 字挡 / 3 字不挡、7 不算 / 8 算)+ 反面独立一圈(日本語 / 纯英文 / 空串 / 中国·中國 / 英文 Chinese);★第二十轮 +2:zhVariantRank:三档封闭(明写简体 0/不带变体 1/明写繁体 2),两份词元名单不许有交集(含"目录名不参与"与"子串不算命中"两头)+ 两路挑篇共用同一条优先档:榜单上同时有 README.zh.md 与 README.zh-tw.md 时挑简体那份(★ 两路各钉一次 + "只有繁体时照旧挑中"那两条反面);★同轮就地改判(条数不变):pickZhReadmeLink 那条旧断言「多条命中按名排序」把繁体那份钉成了规矩 ⇒ 改成「先按简繁档再按名」;★第二十一轮 +8:默认零凭据:不填令牌时详情的每一发都没有 authorization(抬的是上限,不是把凭据撒出去)+ 填了 ⇒ 四发各带一条 Bearer,令牌只在请求头里:URL 一个字节不变、域也不变(★ 反手把"进 URL"这条路钉死)+ 令牌格只有空格 = 等于没填:不发 Bearer 空头(与 githubView 那一侧 trim 同口径,两处各一半就是两份真相)+ 上限吃 GitHub 自己回的那一格:回 5000 ⇒ 读数与屏上那句一起换档 + 填了令牌但 GitHub 仍按匿名回 60 ⇒ 那句照旧念「匿名配额」(★ 撤销/拼错的令牌不许报成"生效了"—— 本机唯一可验的那半)+ 代理把 x-ratelimit-limit 吞了 ⇒ 退回保守的出厂那一格,绝不梦见 5000 + 限额读数(门面):带令牌那一发之后 limit 与 label 跟着换档 + 令牌现取现算:改偏好不用重启宿主,清空之后下一发就不带;★第二十七轮 新增十二条(详情改条件请求,形状 B):库里躺着 60 秒内的那一行 ⇒ 第一次点击也不出网,中文段表仍由入库字段拼出来 / ★ 60 秒窗口内第二次点击一发不出网;过了 60 秒就再问一次(档位撤了,窗口只有 domain 那一格) / ★ 60 秒那一格只有一个出处:DETAIL_RECHECK_MS = 60_000,domain 里不再有小时档那三个名字(★ 反向钉撤档:那一格只有一个出处,撤就要撤干净)/ ★ 200 那一问把 GitHub 回的验证器**原样**落库(弱标 W/ 前缀一个字不动),下一问才带得出钥匙 / ★ 两发都 304 ⇒ 只 2 发出网、正文一个字没换:at 沿用库里那刻,checkedAt 推进 / ★ 只有 README 变了(元数据 304 + README 200)⇒ 正文时刻推进、那条找中文篇的分支重新走满 / ★ 库里那一行没有验证器(条件请求之前写的老行)⇒ 裸发,一条空 If-None-Match 也不发 / ★★ 不变式:没带验证器却回了 304(中间代理/接口改版)⇒ 立刻裸发重问,绝不把空正文端给界面 / ★ 不变式第二形:库里有正文但**没钥匙**(老行)而裸发回了 304 ⇒ 照样重问,"有正文"不等于"可复用"(★ 这一条是证伪第 ④ 发首跑全绿后补的 —— 原「不变式」只把 prev 造成缺位,而 prevHasMeta(undefined) 本就是 false,"整行正文却没有钥匙"那一形从没被验过)/ ★ refresh=true 一个字都不带验证器:那颗按钮写着「不走缓存」,带着旧钥匙去问就是大概率换回 304 的假刷新 / ★ 窗口量的是 checkedAt 而不是 at:304 之后 at 还是三天前,60 秒内再点照样一发不发 / ★ 传输层炸一发(fetch 抛)不许把限额读数擦成 undefined(★ 本轮那处真回归:重写 get() 时丢了 catch 分支那格 rate,判据当场红;用 git archive HEAD lib 取旧码复跑证明是本轮引入);同轮就地撤掉三条(出厂 24 小时内的第二次点击不发网络、TTL 调用时现取现算:设置页改档…、旧写法的库里躺着今天那一行——第三条改写成 60 秒版)。★ 三条判据的牙都靠假 fetch 的形状对齐真服务:按整条 URL 精确匹配、if-none-match 大小写不敏感地读、304 的 text() / json() 一律抛(那句「304 不该读正文」就是为此摆的 —— 读了要么炸、要么把 0 字节当成新正文覆盖库里那一份)
check.test.mjs39进出/位次/改名/首见判定、改名不报掉榜、三榜只记一条 first_on_board、跨榜翻转只在翻转轮记账、基线吃上轮成功 rows 而非 prevRows、坏轮冻结、304 只推 lastFetchAt、退避指数与 4 小时绝对封顶、传输类失败补发(次数 / 中途成功即停 / 非传输类不补发 / 关掉补发)、cadence 载荷与停表归零、单飞 409、传输层接线:custom 没地址时三榜各一发就收,故障里点名是配置坏了、端到端吃夹具、定时器响了:把挂进定时器的回调摘下来真的调一次(ctx.timer 档与 setInterval 兜底档各一条,真机崩的就是这一条路径),以及响了却撞上正在跑的一轮时 CHECK_BUSY 只落一行告警、绝不同步 throw
api.test.mjs113(★ 第三十六轮 +10(新增十条)+ 就地改判五处:新增那一圈 = POST /api/search 五发(两把参数闸:空白词 400 且那一发压根没出发 / 超 SEARCH_QUERY_MAX 400 并把边界念出来 / 服务没装配 501 + 从别机 403 且一发不替别人问 / ★ 路由上那把在飞锁数替身调用次数、并发第二问 409 / ★ 成功一趟之后八张表逐张没多一行、SSE 一帧不追 ⇒ 零入库是这一屏的定义不是缺陷 / 那一发坏了不是 5xx:limited·error·empty 三支都回 200 而 state 各说各的)+ seed 那一圈五发(★ body 认四格之后多递的 name/addedAt 等五格一个字进不了库 / ★ 四路全空且 seed 也没给 ⇒ 只有三格有值,屏上那个 — 是实话 / ★ 四路全空 ⇒ 吃 seed 且出处仍念「检索」,而库里没留“这串数是谁递的”那一格 / ★ 四路任一命中就赢过 seed(同一仓库在两个屏必须念同一个数)+ seed 只在 add 且 from==='search' 那一支被读 / ★ 脏值整格丢而收藏仍成功:desc 给对象与超长、stars 给 -1/1.5/Infinity/"9000"/NaN ⇒ 那一格不落而 ok:true)+ ★ 检索那一路不派现译、不进补译集合(命中与缺位两形都验);就地改判那五处 = POST /api/fav 封闭枚举(action 两档 → action 与 from 两把闸)/body 白名单 {repo, action} → {repo, action, from, seed}/favSeedOf 四路派生那句改口成「第一个命中决定那几格的值,出处另看那一屏」/切片那条/★ 「四路都没有 ⇒ 出处落『详情』」整支作废(改判一)⇒ 同一位置钉的是「四路都没有、seed 也没给 ⇒ 那一行只有 repo/addedAt/from 三格有值」;⚠️ 上面点名的比十条多是因为新增与改判混在同一圈里,净 +10 的算式 = 新增 15 行 − 换掉 5 行,两个数都登记(第三十轮那条律);★ 第三十五轮条数不变、就地改判三处:favSeedOf 切片吃 prefs.topN 那条末尾两行断言(读快照比 onBoard)随那一列一起删/两条序列化键表判据的消息「第 11 格…」改口成「descZh 那一格…」/「收藏那一格逐字同」那条用例名里的序号名一并改口 ⇒ 判据对象在盘上少了一格,用例名与消息不许再指它);★ 第三十三轮 +4:一帧只读译文表一次(计数包装套在真仓储门面上,数的是产品侧信号)/内置与现译两路各自让榜面 hits 与收藏第 11 格逐字同而 desc 仍是原文/收藏里那个从没译过的仓库一发不派(补译集合只认屏上那些行 + 序列化之后的键表判据)/★ 收藏里那一行不在榜面上也照样上屏(把 descHits 换成榜面那一份就漏这一形);★ 第三十二轮 +10:POST /api/fav 两档闸门 400 且一行不落库、从别机 403、仓储没装配 501、favSeedOf 四路派生各形、写完恒追一帧、★ 那一按的四本计数器恒 0(GitHub 发数 / 现译作业 / repoService.load 调用 / 流水条数)、快照 fav 那一格恒在、表读不出念故障话;★ 第三十一轮条数不变、就地改判:那一档的 400 校验从「走白名单丢弃」翻回「档位外的值直接 400」,/api/repo 那两行注释跟着改口(60 秒窗口 ⇒ 那一档 TTL + D2 那条例外:zhProbed 不是 true 时 load 先出网补判据,这一趟多几发是自愈的代价);★ 第三十轮条数不变、那条第三道闸门整条替换成三支表:via:'cjk'(节选里真躺着中文)⇒ jobs 为空 / via:'lang'(只剩那行语言切换字样)⇒ 摘要那一发照派 / 真机那形「…简体中文 · 日本語…」7 个 CJK ⇒ 照派(★ 旧口径把这一形判成"有中文、不派",正是用户那两问的现场)+ 段名后缀那两支各断一次 endsWith(README_ZH_GATE_SUFFIXES[via])(收窄派活闸门不许顺手改掉段名那句实话);★ 第二十八轮 +6:GET /api/repo 成功载荷多挂那一整格 manual 且打开这一屏一发 GitHub 都不派 / ok:false 不挂(三枚按钮不许摆在一段错误上面)/ POST /api/repo/readme 的 action 只认那三个、越界 400 且把合法值念回来 / 从别机来 403(第一条由浏览器发起、当场花额度的写,闸在路由表上)/ path 从 svc.load 的载荷透传(客户端不递裸串)/ 那一趟重走的 svc.load 坏了 ⇒ 200 交回 errKey + 那句成品话且整篇零调用;★ 第二十三轮 +8:stars 装配 + 那一发的轮次订阅;★ 同日改判「开启即拉」再 +5:转换认库里旧值 / 取值必须在写入之前 / 不等那一发就回回执 / 发过却不追帧 / 内存视图没刷就派活;★ 同日第二条裁定再 +2:间隔内已成功取回 ⇒ 点「开」0 发、不追帧 / 窗口吃的是生效偏好那一格而不是装配层自己数分钟;★ 10-10 第三条裁定(那一档接上现译,条件判定加 allStarsEnabled)再 +3:快照那一列吃同一份行集合(正向 + 反向,反向那条同时钉「载荷 desc 一字未动」)/轮次后补译吃同一份集合(开着进 jobs、关掉只补榜面)/liveNote 的欠账只数榜面那一组(正向 + 对照各钉一次);★ 第二十七轮条数不变、就地改判那条「repoCacheHours 越界 400」(⇒ 白名单丢弃:不 400、不入库、不回显,理由见本行末尾那一段)回环闸门与 XFF 链、闸门表逐条点名:三条闸(两个写 + 花配额的 GET /api/repo)与四条不闸、错误码→HTTP、SSE 帧与心跳摘牌、update 帧形状 = GET snapshot 形状、流式 body 自拼(宿主 handler 只给 (req,res))、坏榜的旧档照样给得出、transport/cadence/transportHint 随快照走、net 说最近那一发的实话(经代理 / 没出网 / 还没出过网)与 net.status 判的是路通没通而不是数据新不新、/api/repo 的 name 透传与 refresh 写法、缺 name 400、详情服务没装配 501、坏名字保持 200(那是用户输入不是故障)、服务抛错按 code 翻 HTTP、descZh 三键恒在(空数据也是 {hits:{},label,note}),hits 只覆盖 topN 切片之后屏上那些行、现译装配 attachZh 八条:两档全关那一屏逐字不变 / B 命中不派描述那一路 / 描述档三条件与摘要档只认 en_default / 译文进叙述时来源与时刻由宿主写死 / 现译失败只换那一格且把原因带给界面 / ok:false 不派活(坏名字不去喂模型)/ refresh=1 把 force 传下去 / 没装配现译服务时 zh 是全空七键而不是缺键、快照 translator 视图(键恒在、开关读库里那份、三句文案来自 domain;★ 第十五轮:descOn / readmeOn / switchLabels 三格整格撤,换成一张 switchRows[],行的条数由当前那一路的 kinds() 决定)、POST /api/prefs 两个开关只吃严格布尔("true" / 1 / on 一律 400 —— 表单序列化烧的是用户的模型额度)、那六条(第九轮立、第十轮改到五档):translator 视图逐档说话(免费档缺代理与某家云缺凭据是两句不同的话)/ 派活按引擎选路(没选中的那四路连 enabled 都不问)/ 老库里没 translateEngine 那一格按出厂档 / 密钥不回显(POST 回执 + GET prefs + snapshot 三处与序列化全文)/ translateEngine 只认现行五档、旧档名与脏值一律 400 且把合法值念出来 / 凭据六格非字符串与超长各 400、★第十一轮 +1(A 的第一道闸门):attachZh:仓库自己写的描述本身就是中文 ⇒ 描述那一发压根不派(反向也钉:sectionFields 缺 descSelfZh 时照常派 ['desc']);★同轮就地改判:zh_section 那一档在只开摘要档的现场下 jobs 必须为空(第二道闸门)+ secText('self') 命中那句小节落款、旧那些吃 narrative / narrativeFields 的断言整体搬到 sections / sectionFields(含 'sectionFields' in d === false 这条边界)、路由那条改成现调 repoView() 现算期望段表再 JSON.stringify 全等(夹具不许手搓形状)、★B 优先那条补判据:enabled 从「只开 readme」改成「两档都开」并在派活矩阵补一行「B 命中 + 只开描述档 ⇒ 零调用」—— 旧写法下"没派描述"是开关挡的、不是 B 优先挡的,拆掉闸门照样全绿(证伪首跑抓出的假绿,[api] 52 / fail 2 才是承重);★第十二轮 +1:POST /api/prefs 的 repoCacheHours 只认封闭四档('72' 这种字符串认,5 / 0 / 100 / '' / 'abc' / null 一律 400 且不入库 —— 不许悄悄回落 24 让库里一个值、分段器上另一个值,并验库里那份没被污染)+ 同轮改判 zh_section 那条与引擎循环那条(旧断言读的是撤掉的 readmeNote 落款句与 zh.summary.note,现在钉的是段名与 'note' in d.zh.summary === false);★第十五轮 +1:假那两路桩的能力声明 = 真服务的声明(桩的 kinds() 必须逐字等于真那一份 ⇒ 否则"非 host_llm 不派摘要"这条判据测的是我编的桩,不是那道闸门;同轮改判派活矩阵那条:两路各派各的 —— 宿主模型档两路都做、免费/三家云那四档摘要那一发压根不派,且用例不再传 enabled: () => true 把摘要放行);★第十七轮 +1:switchRows 那句说明跟着档位走:四档翻译路念「节译」,只有宿主模型那档念「摘要」(钉本轮仅剩的那道口 —— 行名 摘要现译 五档都不变,变的是那句说明;另加反向那头:服务没声明 kinds() 时一行都不摆,而这与档位无关)+同轮改判「假 = 真服务」那条与派活矩阵那条(翻译四档现在也报 readme,五档两行开关都在);★第十八轮 就地改判(条数不变):attachZh…摘要档只认 en_default 里那圈中文形状搬到能承重的现场 —— 旧形状把 zh_default(和第一版新加的 zh_file)摆在只开描述档的桩下 ⇒ want('readme') 恒假、闸门坏了照样全绿(电池第 ① 条判它假绿),现在改成在只开摘要档那一圈三档中文各钉一发 jobs 为空(zh_default / zh_file / zh_section)+ 各钉一发 self 段的档名,en_default 仍派且喂的是那段节选;反向还多三发(闸门给任一档单独开侧门都得当场红,见 tmp/r18-falsify-out.txt);★第十九轮 +2:attachZh:第三道闸门(第十九轮)(混排 9 字与只剩切换行那两种形状各钉 jobs 为空 + self 段名后缀)+ 反面独立一圈 attachZh:第三道闸门的反面 —— 「日本語」是日文不是中文 ⇒ 那一屏照常被译(不许顺手挡)(★ 首跑电池第 ③ 条挂在同一 check() 里先炸的那条断言上 ⇒ 反例必须拆成独立用例才红得到自己的现场);★第二十一轮 +2:githubView:只给 has 布尔,不给 value;说明句与「去哪创建」外链全部来自 domain(客户端不排表)(★ 键集封闭 + 'value' in f === false + JSON.stringify(视图) 全文搜不到令牌本体 + 空格那一格也算没填,与 repo.js 那条 trim 同口径)+ 快照里 github 那一格恒在(客户端没有兜底表,缺了就是白屏而不是少一行)(格数从 GH_CRED_FIELDS.length 读,用例不抄数);★同轮就地改判(条数不变):「密钥不回显」那条从 secretKeys.length === 3 翻成 deepEqual 派生的四把清单(★ 手抄一个数就等着漏扫新增那把),且新增那把不跟着翻译档走 —— 选哪一档翻译它都在,因为它发的是 api.github.com 不是厂商;★ 第二十二轮 +4(榜面补译四面各一条):读路径零发(GET /api/snapshot 与 SSE 首帧一发不派 ⇒ 补译只挂在一轮检查之后、补成真才追推第二帧)/这一轮的闸门与上限(off·unavailable·选中的那一路没接 ⇒ 零发,一轮最多 BOARD_ZH_BATCH_MAX 发)/榜面那一列也吃库里的现译行(B 优先、逐字命中才算数、卡头两路并报)/liveNote 只在「开关开着 + 库存得下 + 这一路此刻给不出」三格同时成立时说,其余几种闭嘴各有各的理由。★ 同轮就地改判(条数不变):旧那条「hits 只覆盖屏上那些行」换吃 hits 的新形状 {zh, via, label, note, src};★ 10-09 开启即拉 +5:POST /api/prefs 认出库里 false → true 那一趟当场派满预算(用延迟桩 + 断"回执回来时库里已经有那一批"把 await 与 fire-and-forget 分开,不延迟就圆掉了)/转换判据不是"带了这个键"(已经开着再存 true、连点、改别的键时顺带带上 ⇒ 一发不派)/关掉那一趟与没碰那一档的保存都不派/发过就追帧、坏轮也追(savePrefs 只并 prefs 那一格,那一批与那句故障不追帧就上不了屏)/两个入口各花各的预算(点完「开」这一轮检查照旧发得出,同一毫秒的第二次「开」被 round_already_sent 挡)。★ 同轮改判一条夹具口径:mkApi 的 onPrefsChanged 现在照装配层那样把内存视图刷成库里的值(旧夹具只计数 ⇒ getPrefs() 永远停在初始值,"把 kick 挪到刷新之前"这类接错在这儿一样绿);★ 同日第二条裁定(间隔内不重发)+2:库里五分钟前刚成功取回过 ⇒ 点「开」那一趟 0 发、一帧不追(回执仍 200、库里 at 没被推进、而屏上那一批照旧在载荷里 —— "挡下"不等于"空屏")/窗口吃的是生效偏好那一格(同一份 61 分钟前的库在默认 60 档发得出,先存 intervalMin:1440 再拨开关就不发 ⇒ 装配层不自己数分钟,第二真相当场红);★ 10-10 第三条裁定 +3(那一档接上现译,三面各一条):descZh 装配改用同一个 descZhRows({ boards, allStarsRows, allStarsEnabled }) ⇒ 开着时库里已译的那句能上到「全站高星」那一屏,关掉时译文躺在 trans 表里也不给(同一条同时钉 snap.stars.allStars.rows[0].desc 仍是 GitHub 原文 —— 现译不改写载荷)/一轮检查后的补译批次吃同一份集合(dedupe: true 只作用在榜面那一段,那一档的行照原样并入末尾):开着进 jobs、关掉只补榜面/liveNote 的欠账判据从 missing 换成 boardMissing ⇒ 只有那一档欠着而榜面不欠时,榜面不许念那句「榜面这一列只显内置预译」(★ 这一条必须给 mkApi 接 translator: mkTranslatorStub({ ready: false }) 才分得开:不接翻译服务时 pickTranslator 返回 null、四格条件永不成立 ⇒ 正反两档都给空串 = 假绿,首跑就是被这一条圆过去的);★ 第二十七轮 就地改判(条数不变):那条「POST /api/prefs 的 repoCacheHours 只认封闭四档、越界一律 400 且不入库」整条翻案成「走白名单丢弃 —— 不 400、不入库、不回显」(★ 判据换牙:'repoCacheHours' in 回执 === false + 'repoCacheHours' in 库里那份 === false,并验那份库没被污染;同轮把 intervalMin 一起发过去,证明"顺带带上"也进不去)。为什么从 400 翻成丢弃:那一格现在什么都不决定(界面上没有它、运行时不读它),而 translateEngine 那一格脏值会决定往哪个域名出网 ⇒ 那一路才必须 400 并把合法值念出来 —— 两格的区别写进注释,免得下一个人把"宽容"当成"没校验"
client.test.mjs82(★ 第三十六轮 +4(client-79~82:落地三条 + ★ ⑬ 追加改判补那一条形状判据)+ 就地改判五处(client-17/30/77/78 + ★ ⑬ 那枚按钮的类名 client-80 从 gt-btn-main 改口到 gt-go):client-79 检索那一屏六列逐列同数、那六句与缺位符和卡脚整句逐字吃载荷(客户端一个字不补,喂空串就画空 —— ⑦′ 那一头是值驱动,防的是"屏上兜出第七句");client-80 那一发只有两处触发(回车带 !e.isComposing 与「搜一下」)、在问期间输入框与按钮一起哑掉、★ 检索词不落 localStorage(第二十九轮那三枚 id 一个都不许多存);client-81 行尾那枚 ☆ 出去的是 {repo, action, from:"search", seed:{desc,lang,stars}} 而 remove 两格都不递、★ 屏上自己不改点亮态(只看载荷 favSaved);改判那四处 = client-17/client-30 从八签变九签(labels 表与 clicked 表各九键,「检索」那一枚不带徽标:零入库 ⇒ 摆一枚 0 就是把"没库存"演成"这一档坏了")/client-77 那句 {repo, action} 两格变 {repo, action, from} 三格(★ seed 只在检索那一支,而 client-81 管它)/client-78 从「三屏共用 descCell」改判成「四处渲染点共用」,静态计数 descCell\( 由 4 改 5(一处定义 + 四处渲染点,数字由判据自己数,用例不抄);★ 第三十五轮条数不变、就地改判 client-73:那一屏由八列变七列 —— colgroup / th / td 三处计数 8→7、gt-tail 那七格布尔跟着缩、表头 deepEqual 去掉 cols.onBoard,★ 另加两枚尾列断言(缺位那一行与有值那一行的尾列都照样摆那一枚 ⇒ 撤一列不许把取消收藏的入口带走),而全文件禁串扫描换成「onBoard 与『未上榜』一个都不许出现」;★ 第三十三轮 +1:client-78 收藏那一格摆本机已有的那一份中文、悬停三行齐(原文 + 那一行自己的落款 + 注)、没命中摆原文,★ 且三屏(榜面 / 明星 / 收藏)共用同一个 descCell —— 静态计数钉 className:'gt-desc' 恰一处、descCell( 恰四处,界面多复制一份判定就当场红;★ 第三十二轮 +7:client-71client-77 那一族(那枚 ☆ 三处入口且点它先拦冒泡 / 「已收藏 · 3 天前」那枚的词与时刻全吃载荷 / 收藏八列逐列同数 / "没内容"分三档说话 / 三档重排零请求零写偏好且缺星数垫底 / 分段器落盘与那三个 id 互不覆盖 / 那一发只有 POST /api/fav + 两格、回执整份换进快照)+ client-17/client-30 就地改判成八签;★ 第三十一轮条数不变、就地改判两处:client-53 那四档分段器回来(档名与顺序全吃载荷 cacheHours / cacheHourLabels、点一下即存且只发那一格、出厂档 24 从 PAYLOAD.defaults 读、检查间隔那个邻居不被顺带写、旧宿主没推 cacheHours ⇒ 整行不摆)+ client-70 从三截改判成两截(词表键集必须等于 {body, revalidated} / cached:true 那一屏不许念「刚核对过」/ cached:false 且 checkedAt>at 才念 / 代码位扫不到「秒内没再问」那半句);★ 第三十轮 +1:client-70 详情那句落款的第三截三头(cached:true 时三截齐全 / cached:false 时那一截整段不出现 / 旧宿主只推两格时那一截不摆而前两截照旧);★ 第二十九轮 +3:client-67 落盘读回只认名单、client-68 整页重挂不丢选择(⓪⑤ 六头,含「存的只有那三枚 id」那条密钥自查)、client-69 存储坏了不带走界面(读写各自抛 + 六种坏值逐个喂)(★ 上一版这张表把 client 停在 66 —— 第二十九轮那三条只登进了「测试」那节的读数,表没跟着改,本轮一并接上);★ 第二十八轮 +3:client-64 三枚按钮常驻(disabled 只认载荷的 can 与「正在跑」那两格)/ client-65 那两段只摆载荷给的(段名连落款原样念,库里没有那一行整段不摆)/ client-66 展开只按 kind 覆盖那两块 + 那句「这一趟说了什么」按 notes 分组摆;⚠️ 这三条落地时错填成 client-56 / 57 / 58 —— 与第二十一、二十二轮那三条短号重号(用例全名不重,跑测器与 pass 66 都看不出来,只有按短号指判据的台账会指错),收尾这一遍改成 64/65/66 并把电池那四发的期望串跟着换、全量重跑读数见 tmp/r28-falsify-out.txt;★ 第二十三轮 +5:client-59~client-63 那一屏;★ 第二十七轮条数不变、三条改判)vm 沙箱 + 假 React 渲染树:七页签各自成页 + 页签条常驻(★ 第二十三轮就地改判:原先那句是「六页签」,第七枚插在月榜之后)、页签计数徽标、总览速览小结(前 3 与跳转带键、不再摆流水小结)、故障口径(连续轮数 / 补发次数 / 下次自动检查 / 传输提示只在传输类出现)、设置卡的出网方式三档吃载荷、地址是草稿、切自定义得带着地址一起发、各卡分支文案、步进器到边界禁用、保存反馈看状态位、根 CSS 铁律(含外链不吃浏览器默认蓝、页头标题 .gt-title 必须是兄弟四家在用的 17px)、client 里宿主枚举字符串一个都不许出现、详情弹框:载荷由真的 repoView 造(段名 / 块 / 元数据对 / 配额行逐字照搬,客户端不数星不拼句)、三种"没内容"各说各的(还在取 / 请求坏了 / 宿主说没拿到)、Esc·×·遮罩·框内的开关语义、三个触发点各自只发一发 GET /api/repo?name=、遮罩挂在 .gt-root 之内、默认态一个浮层都不许在、描述列命中显示译文且悬停给原文与 note;「描述中译为…」只在该卡真有命中时出现,且逐字读 snap.descZh.label(换载荷文案就跟着变,客户端不许自己编日期)、设置卡现译那几段(引擎行 / 凭据行 / 注册行 / 开关那几行):状态读 snap.translator,ready:false 时那句 notReadyHint 只在「现译引擎」那一行念一次(★ 第十五轮:各行自己的行名与说明句从 switchLabels 那张表改成行内自带的 row / label,不重复念"能不能发"),宿主没给这个键时整段不摆、详情弹框的现译分段(描述段 + 摘要段 + 那句 summaryNote 落款)、回执有才念(回执:provider_error: bad response 上屏;errText 为空时那行不出现;zh 全空时详情里连「模型」两个字都不该出现)、★client-52(第十轮整条重写成七段判据):五档按钮的名字/顺序/高亮/disabled 全吃载荷(换 engineLabels 界面跟着改口,客户端不排表)+ 只念当前那一档的 hint(别档那句一个字都不许在屏上)+ 逐家凭据行的 type/maxLength/autoComplete 跟 credFields 走、标识符 value 等于库里那份而密钥 value 恒空、'value' in credFields[1]===false、keyless/host_llm 两档连输入框都不摆、留空密钥压根不进 patch、库里没凭据时不给「清除」、「清除」只发当前档两格、注册那一行只跟当前那一家(别家的 URL 出现在这一屏即红)且不念额度数字** + 源码侧三条(草稿收口那句在、三个密钥键名不许出现在 client.js、.gt-setrow .gt-link{margin-left:0} 那条 CSS 在**);★同轮 client-38 就地改强:.gt-tabs 那条规则里出现任何 overflow 即红(撤掉那条没意义的滚动条的判据,不新增用例);★第十一轮条数不变、三条改判(A 的段表侧):client-41 整条改吃段表 —— 四种 kind 各自的类名逐字(p ⊂ sub ⊂ num 逐级加重、excerpt 走带框那条 .gt-modal-readme)+ 一张 gt-modal-facts + 同屏一个数只出现一次 + 旗标句落 heat 段的 sub 块 + readmeSource:'' ⇒ self 段整段不摆;client-50 改吃 what 段第一块与 self 段的 sub 块;client-51 改判:摘要那一发失败照摆 summary 段、段名说「没取到」,回执那行是段内 num 块(旧口径「失败就不摆」撤了)。★ 踩到的假绿形状:test/client.test.mjs:229 的 findByClass 只按单个 class token 匹配,拿 'gt-modal-p gt-sub' 整串去查永远查不到;★第十二轮 +1(client-53)与两条改判:设置页多一行「详情缓存」分段器 —— 四档文案全吃载荷(6 小时 / 12 小时 / 24 小时 / 3 天)、选中项读库里那份(不是出厂值)、点击只发 {repoCacheHours:那一档}、载荷没给 cacheHours 时整行不摆(一排没有文案的按钮比没有更难解释) ★ 第二十七轮整条就地改判(条数不变):那一行撤掉(用户裁定「撤掉这一行,改成固定 60 秒防连点」)⇒ client-53 现在钉三件反方向的事:① 库里那一行真的还躺着 repoCacheHours: 12(这台机器改过那一档)时界面上不认它(那一行不在),且 `/详情缓存
desc-zh.test.mjs7内置离线预译表本身:表体形状(主键小写、src 里不许有汉字、译文≠原文、主键不重号、条数与 DESC_ZH_COUNT 一致)、命中判据 =「主键 + 原文逐字相同」(空白归一、主键大小写不敏感,原文被改或被截断 ⇒ 回 '')、★表与解析器同口径(四份真榜面夹具里「表中有此仓库」的每一行必须命中,防解析清洗口径漂移而表还指旧句)、自带中文的仓库不进表、来源与时间戳只有一份(LABEL/NOTE 都由 DESC_ZH_AT+DESC_ZH_ORIGIN 拼,NOTE 必须含「不是现译」)、这份文件是死的(去注释后零 import/fetch(/require(/ctx./readFileSync ⇒ 离线口径由源码钉住)、descZhHits 只收命中行且键为小写主键(⚠️ 旧名,第三十四轮改名 builtinDescZhMap:它是内置表那一层的批取函数、只吃 rows、生产侧零消费者、仅 dz-7 读它,从前与 lib/board-zh.js 那个"命中判据唯一出处"的 descZhHits(rows, transRows) 同名不同义 ⇒ 现在盘上只剩 board-zh 那一个 descZhHits;★ 第三十四轮 dz-7 条数不变、就地改判:① 扫两种导出写法(export function descZhHits 与 export {…descZhHits…})都不许在 lib/desc-zh.js 出现,② 反面自证(把 board-zh 那个改名该红 —— 两条若把盘上两个都清空也照样绿,那就是判据空跑)
board-zh.test.mjs24(★ 第三十三轮 +1:★「descZhHits 是命中判据的唯一出处」—— 与 descZhView 的 hits/counts 逐字同、返回恒 {hits, counts} 两键(带出 todo 收藏屏就变会花钱的屏)、内置优先在这一层同样成立、脏输入(kind 认错 / zh 空串 / repo 缺位 / null 行)不给半个对象、空表也给满形状、★ 行侧与 byRepo 侧两头都归一(Up/One 那一行是电池第 3 发抓到判据空跑后补的);★ 10-10 +4:descZhRows 那份参与行集合四面)★第二十二轮新套件(10-08):lib/board-zh.js 那份视图与批次。假 transStore / 假 translator 的形状逐格对齐真服务(entries() 回整行、translate() 回那八个键)—— 桩少一格,测的就是桩不是闸门(第十五轮那条教训)。两头:视图(两份行的分工 / B 优先压过库里那行 / 逐字命中才给现译、原文改了当场作废并重新排队 / 空描述与仓库自写中文都不算欠账 / 缺的那几行按名次排队并截到上限 / 跨榜 desc 不同 ⇒ 谁逐字对上算谁、命中过的不再排队 / 失败冷却只挡排队不改读数 / 卡头三档句子且内置那一句逐字沿用旧文案 / 卡头条数只算这一张榜且只算逐字对上的那一行 / via 名单是 domain 那一格 / 落款与 blocked 句子全来自 domain ⇒ 用例里不出现手抄句子)与批次(闸门四种理由各返回一次且一发不派 / no_store 排在 off 之前 / 屏上全命中 ⇒ nothing / 一轮最多 batchMax 且在途不超过 concurrency / 出厂常数 12·2·30min 跟着 domain 走 / 单闸 busy(★ 限时判据:不当场返回就红,见 spec §0 本轮 ⑫ —— 单闸破了用例原本会"挂住而不报红")/ 失败进冷却当轮不重派、其他行照发 / 读库失败 ⇒ 整轮不发也不崩(日志两句:先说因、再说决定)/ runner 不写库只认 translate() 回执;★ 10-10 +4(参与行集合 descZhRows 四面):① 条件两个方向(allStarsEnabled === true 才并入那一档的行;false / 缺位 / null / 0 / 'true' 五种取值循环 ⇒ 一行都不许并进来,同一条里另钉「不许污染载荷」:打组标记必须 {...r} 拷一份 —— 传进来的那批行就是 snap.stars.allStars.rows 本身,就地改会把内部标记写进用户屏幕上的载荷)② dedupe 只作用在榜面那一段(那一档的行不参与「同仓库三榜取名次最好那条」的去重)③ ★ 组序:todo 先按 zhGroup 再按 rank ⇒ 每轮那 BOARD_ZH_BATCH_MAX 发共享预算先给榜面吃饱,全站的 rank 不许插到榜面行前面(两个 rank 不同轴:榜内名次 vs 全站名次)④ boardMissing 与 missing 分家(界面上那句故障话的主语只能是榜面,只有那一档欠账时榜面不念)
favs.test.mjs22(★ 第三十二轮新开 24 条;★ 第三十三轮 +4:descZh 那一格 / 比键归一 / 脏 hits / 卡脚那一句;★ 第三十五轮 −6:撤掉「这一轮」那一族七条(命中优先级单值 / 按档退 / 明星两批都算命中 / renamedFrom 归一 / 未命中成品句 + 置灰档 / 只看切片后的行 / onBoard 绝不写回输入行)、descZh 那条就地改判(键数 11→10)、新立一条「★ 撤一列连入参一起撤」⇒ 28→22)lib/favs.js 那一屏的纯视图(22 条全离线):行序恒 addedAt 倒序 + 同刻按主键 localeCompare 收尾 / 键归一小写 / 脏行不进视图 / favRows 给 Map 也吃得下 / ★ 撤一列连入参一起撤(旧的三档原料 boards / starsRows / allStarsRows 照喂 ⇒ 行与载荷都长不出「这一轮」那一格,源码里 onBoard / ON_BOARD / OFF_BOARD / keysOf 四个标识符零出处,而 Object.keys(行) 恒 10 —— 留入参就是死接口)/ ★ descZh 那一格逐字搬调用端喂进来的那一份而 desc 不被覆盖(§8.16 ② 那条"快照在载荷上肉眼可验";缺位那一形用 strictEqual —— loose 相等把 undefined 判成 null)/ ★ 比键吃同一把归一(视图再归一遍就是第二把尺)/ 脏 descHits(缺位 / 空 map / 那一格假值)一律 null / ★ 卡脚那句要能说清"屏上的中文从哪来",四件事缺一条就是假话 / fromCell 是宿主拼的整句 / 出处空 ⇒ 空串(界面整枚不摆)/ 五档出处都能拼成句 / 读数缺位给 null 不是 0 / addedAt 非法归 0 不丢行 / name 缺位回落主键 / ★ 三档名单与三句话逐字吃 domain,cols 用 deepEqual 钉成 {stars,column,saved} 三格(用例里零手抄中文)/ available 只看传进来的存储位(没说 = false)/ available=false 与「一行都没收藏」是两件事 / 视图不吃时钟 / ★ 源码里没有任何 IO 形状(不发请求、不读库、不写库、不 await)/ 入参一个都不改判(挡脏行是 schema 的活)
stars.test.mjs29(★ 第二十三轮新开:lib/stars.js 那个纯视图;★ 同日 +1:那一档那两句成品必须自己念出「点「开」的那一刻」与「每轮检查后」两件事 —— 改文案可以,把口径改掉就红)候选集按时间窗不按轮(含 >= 边界那位整 7 天的不能被一次比较踢掉)/ 这一轮屏上的行无条件进候选(seen 那行还没写进去的新面孔必须在屏上)/ 同一仓库在两处都有 ⇒ 只有一行 / ★ 每行读数复用 visibleBoardRows(不另写一遍"取名次最好那条")/ 回落行的读数给 null 与空串,本地没有这一格就不硬造 / ★ added 只吃日榜(在周/月而不在日给 null)+「今天没涨」的 0 与「不在日榜」的 null 是两件事 / 常客·新星·回落三档判据各一条 + 每行只给一个 group(三档不必互斥,全部 兜住)/ ★ 截断在宿主(超 STARS_ROWS_MAX 先按累计轮数再按星数)/ 载荷恒按星数降序预排 + null 星数排在那批之后 / ★ 三句人话全部现算自 domain(用例里不出现任何手抄中文句子)/ thin 两种形状(够 ⇒ false + 空串,不够 ⇒ true + 那句原料现算的话)/ roundsAvailable 取候选里最深那位(不是"跑过几轮检查")/ 无存储 ⇒ rows 空数组且 headline 换成那句「本地存储不可用」/ 分段器 disabled 跟着 prefs.allStarsEnabled / 开着那句额度全吃落库那一发的 x-ratelimit-* / 坏轮冻结 + 故障那三格与三榜同形状 / search 从没落库 ⇒ 给空数组而不是 undefined / SEARCH_ROW_SHAPE 只认 domain 那几格(回包多带的字段不进载荷)/ ★ lib/stars.js 源码里没有任何 IO 形状(不发请求、不读库、不写库,同 dz-6 那一族)/ 视图不吃外部时钟(窗口只认传进来的 roundAt)
all-stars.test.mjs32(★ 第二十三轮新开:那一发的闸门与落库;★ 同日 +4:2b 那一圈 = 第二个入口;★ 同日第二条裁定 +8:2c 新鲜度闸那一圈七条 + 2d 钉字段来源那一条)闸门顺序 off 排在 no_store 之前(与补译那一档故意相反,两边各钉一次)/ 四道闸各返回一次且一发不派、返回形状恒为 {skipped,sent,ok,failed,stored} 五格全零 / no_round:轮次时刻认不出来就不发(0 / NaN / 字符串 / 负数…六路脏值,不收 Number() 那一次强转)/ 偏好那一格不是严格 true 都算没开 / 每轮预算按 SEARCH_MAX_PER_ROUND 数得住 / ★ 闸门在第一个 await 之前判完(同一轮连触两次、第一次还在途 ⇒ 第二次当场挡)/ 换轮(roundAt 变了)重新有预算 / 新实例 = 进程重启语义(预算只在进程内存里)/ 不重试、不补发、连续失败不另抬闸门(两轮都坏 ⇒ 两轮都真发)/ 成功轮走真 createSearchStore + 真设施端到端 / 坏轮冻结(上一批的 rows 与 at 原样留着,只改 ok 那几格)/ 失败原因存原样回执,不过 REPO_ERROR_LABELS / 停在上一批的不止 left(已认证那四格一起跟)/ fetchBatch 抛错折成失败轮(transport:true)/ 落库失败不影响这一轮返回(stored:false + warn)/ read() 抛错当"没有上一批" / 成功轮但 rows 不是数组 ⇒ 落空数组(脏回包不进 schema)/ ★ runner 调 fetchBatch 时实参为零个(令牌递不进这一层)+ 本文件源码不认得 ghToken、不拼 URL / stats 记 rounds/sent/ok/failed/stored / ★ 2b 那一圈(同日改判「开启的时候默认拉取一次」)四条:runOnEnable 那串闸一道没少(关着仍 off、无设施仍 no_store,且顺序与 run 同一份)/ 当场派一发并真落库,round.at 记的是发起时刻(那句"记轮次而不是本地时钟"的唯一例外,例外只开在这一趟)/ 同一时刻连触两次 ⇒ 第二次 round_already_sent(连点不叠发,预算仍是那一个实现处)/ 两个入口互不侵占(检查轮那只预算占不掉「开」这一趟,反过来也不行)/ ★ 2c 新鲜度闸那一圈七条(同日第二条裁定):窗口内刚成功取回过 ⇒ skipped:'fresh'、sent:0、返回体键表恒那五格、库里那批一字未变(挡下的一趟既不写库也不推进 lastFetchAt)/ ★ 窗口就是 prefs.intervalMin 那一格而不是第二个常数(同一份 61 分钟前的库:60 档发、1440 档不发 —— 两档各用独立的库,共用一份会被第一档真落库污染掉第二档的前提)/ ★ 上一发是坏的 ⇒ 照发(不许让用户为了重试去等下一轮检查)/ 脏时刻(库里 at 在未来)不算新鲜 ⇒ 照发(★ 这条抓出过实现漏的 age >= 0:负差值恒小于任何窗口,不补那句那一档从此再也发不出去)/ 生效偏好里缺 intervalMin ⇒ 照发(开启即拉那条裁定优先)/ ★ fresh 只挂在 runOnEnable,同一份库走 run(轮次) 那一路不受影响(挪进去就把 60 分档机器取回的数据凭空变旧一小时)/ 关着与无设施那一趟一次库都不读(带计数的 spy store ⇒ 闸序 off/no_store 仍在 fresh 之前)/ ★ 2d 一条钉字段来源:ok:true 而 at 与 lastFetchAt 故意分开的库里行 ⇒ 两个方向都按 at 判(第一档照发、第二档挡住)—— 2c 那条"坏轮照发"挡不住这一种变异(ok === true 先把闸关掉了,字段选谁在那条用例里不可见),那半句判据要靠把两格摆开才有牙)
search.test.mjs23(★ 第三十六轮新开:lib/services/search-run.js 那颗在飞锁 + lib/services/repo.js 参数化那一发 + searchView() 那一格载荷,三样都在同一套里判 —— 这一屏零入库,所以没有第四样)三圈。出网那一发(全离线假 fetchFn,按整条 URL 精确匹配):searchRepoUrl({query}) 无 sort、无 order、无 stars: 门槛且 per_page 吃常数(★ 反面钉"不许顺手把全站高星那串继承过来")/ 用户自己写的门槛与比较符照原样编码(插件不替他改写查询 —— stars:>=5 这种词原样交出去)/ 那一发只许一发(URL 现拼,本层不补发也不翻页)/ ★ 同一颗闭包两个入口:无参调用仍是全站高星那一串(⇒ 明星那一路本轮零改动在判据上可见),带词才是手动那一串 / 令牌只进请求头:没令牌时那一发压根不带 authorization,递了才进头而 URL 一个字不沾。闸门那一圈:★ 并发第二问压根没出发(数替身调用次数、两问返回值做成一模一样也不认,回执 busy:true —— 只看回执形状就测不出"其实发了两发")/ ★ 锁真的会放:第一发结算后第三问照样出发(calls.length === 2;★ 这一条是本轮首跑补的牙 —— 没有它,"锁永不放"和"每问都发"两种坏法都能全绿,而 SEARCH_MAX_PER_ROUND = 1 那本账故意没搬过来:手动这一路不自建一小时计数账本)/ 空词不发那一发(ask 收到空白直接给空结果 —— 400 是路由层的事,这里再兜一道是给裸调用兜底)/ 那一发抛错不 rethrow(折成失败形状 + 锁释放 + 日志留一句)/ ★ runner 的入参名单里没有仓储与广播(零入库是结构事实,不是注释里的一句承诺)。载荷视图那一圈(纯函数、零 IO):searchView 函数体里 fetch/await/Store/hub/Date.now 五形一概不许出现 / 行只带六格 + descZh + favSaved(GitHub 一条 item 六十多个键一个字不进)/ 逐格折形:repo 折小写而 name 保留 GitHub 写法、rank 非数落 0、缺 desc/lang 给空串 / ★ 星数缺位不演成 0(非有限数落 null,缺位符由 domain 给 —— 画 0 就是"这个仓库没有星")/ ★ 六态各一句且逐字等于 domain 那一份(客户端与视图都不许自己圆)/ ★ empty 与 error 的载荷形状可区分(三处都能拿到失败信号,两条判据不互为影子)/ 认不出的失败键念故障而不是念成功(state 名单外的形状一律 error,缺位不许演成 idle)/ asking 优先于回包(那一会儿屏上念"正在问",不许抢跑把上一发的结果摆出来)/ ★ 快照那一格(恒 idle、恒零行)带着 asking 那一句(客户端在飞的那一会儿不造文案也有话说)/ 额度那一行复用 starsQuotaLine(★ 不另立第二份句子,四个数全吃回包)/ ★ 中文那一格:命中上屏、没命中念原文(desc 恒是 GitHub 那句,缺位不给占位符)/ ☆ 点亮态只看"这一行收过没有"(主键归一,且不复制收藏那一屏的任何读数 —— 那一屏的读数是收藏那一刻的,这一屏是此刻的)/ ★ 载荷键表封闭(视图多一格就是第二个住处:六列 + 状态 + 文案 + 额度 + 失败信号)
full-readme.test.mjs19(★ 第二十八轮新开:lib/services/full-readme.js 那三枚按钮的编排)整趟全离线(替身 fetchFull + 替身翻译服务,19 条吃的都是合成正文 —— 分块只认长度与段落数):原文指纹(折叠空白取 sha256 前 16 位 + : + 字数 ⇒ 空白写法不同判同一篇、改一个字判两样)、chunkParagraphs 只在段落边界累加且块拼回不含丢字、置灰四形各说各的话(no_readme / already_zh / no_sum_capability / not_ready,★ 且 !tr 那一支排在能力位之前)、action 越界与坏名字零出网零发且那句是 domain 拼好的成品、README 那一发本身坏了把 errKey 原样交回且账上记 1 发 GitHub / 0 发翻译、展开全文 = 一发 GitHub 零发翻译(回执把要换的那两块给全,客户端按 kind 覆盖)、译整篇 = 切 3 块 / 并发 2 / 每发 persist:false ⇒ 整趟只落一行且 src 是整篇指纹、指纹对上库里那一行 ⇒ 零发翻译而 GitHub 那一发照扣(那句说的是「没有重跑」)、一块失败原位留原文并指得回第几块、熔断跑满即停且没跑的尾巴不进段(那句报的是块数)、摘要 = 各块短述 + 末尾那一发汇总(预算先扣 1 ⇒ 块最多 39、汇总恒轮得到、总发数 40 封顶)、汇总没成屏上是拼的那一份 + 那句「不是汇总过的」、超 MANUAL_FULL_ZH_MAX 整份不存、本机没有译文表 ⇒ 那一屏照样给且加一句「看完就丢」、写库自己失败是另一句(与超限是两件事)、连点同一枚按 action:仓库 去重而另一枚与另一个仓库不受影响、载荷那一整格四个子键一次给全且命名统一吃 kind、三枚按钮在宿主档全绿而免费档那枚摘要灰(★ 置灰那句与真点下去共用同一个口径函数)
llm.test.mjs20(★ 第二十八轮净 +1:新增三行 − 就地改写两行 —— 新建「手动那两路不受参数设置管(10-10 裁定)但就绪态照挡」,把旧的「★两档显式全关」改口成「★受开关管的两档显式全关」(手动那两路恒不受管,旧句子在新盘上是假话),旧的「kinds():这一档两路都 serve」改钉四路全 serve)模型现译那一发(全离线,喂假句柄 + spy stream()):闸门顺序四档各有各的话且句柄零被碰(未知路数 / 没原文 / 开关关 / 宿主没句柄)、★两档显式全关 ⇒ spy 句柄零调用(不是出厂态:描述那档出厂是开的)、发出去那一发的 reasoningEffort:'off' + temperature:0 + 两档各自 maxTokens + 原文截断,全部从交给 stream() 的那一份 opts 上读回来(不从标签反推)、transSrcKey 折叠空白 ⇒ 喂进去与存下来同口径、in-band 错误(finish 帧里坐着的 failure)判失败而不靠 throw、AbortError 与别的异常各说各的话、★超时那一发把定时器真的拨响(不许把异常圆成超时)、内容三闸(空 / 没汉字 / 超长 ⇒ 原文照给且各说各的)、分片累加与 delta.text 写法、逐字复用与"改一个字就重译"、★宿主默认模型那一档(没给 / 给空 / 读它抛 ⇒ 三句不同的话且句柄零被碰;库里已有译文时压根不取这一档)、desc 与 readme 两档各存一行不互盖、force(重新取一次)绕复用并盖掉旧行、在途去重、落库失败仍给译文并补那句"显示完就丢"、脏行按未命中重译、ready 只说宿主给没给能 stream 的句柄且 dispose 后立刻 false、判据自证(内置表那一条永远不被本套件当成"模型译过的")、★第十五轮 +1:kinds():这一档两路都 serve ⇒ 设置页那两行开关都摆(与 wt-28 那一档相对 —— ★ 第十五轮那一边只报 desc,第十七轮改判后两边都报 desc+readme ⇒ 这一条钉的不再是"谁能做摘要",而是"能力声明由那一路自己说":两路各自的 kinds() 不许被 api 或客户端写死)
web-translate.test.mjs30(+1 跳;★ 第二十八轮净 +1:wt-28 就地改口成「这一档 serve 三路:kinds() 报 desc+readme+readmeFullZh」(摘要开关开着的节选真的译,那条律一字未动),新建 wt-28b「免费四档的整篇翻译不受参数设置管,但没声明那一路(readmeFullSum)照挡」⇒ 那枚「整篇摘要」在免费档置灰的出处就在这条)★第九轮新套件(19 条)、第十轮扩到 27 条:免费 + 三家云那四路(全离线,喂假 net.fetch;假 net 按整条 URL 精确匹配)—— 闸门与档位(wt-1 开关关着零出网 / wt-2 三家各缺任一格凭据 ⇒ no_credential 且零出网 / wt-3 没传输层归 transport 而不是"翻译失败" / wt-4 路数不认与空原文 / wt-5 档名归一(official→baidu、脏值落出厂档)/ wt-14 免费档几种失败各归各档 / wt-15 连不上与超时都归 transport 且把超时定时器真拨响)、四份端点形状(wt-6 免费档按夹具里那条实测 URL 逐字发 GET / wt-7 免费档夹具是真回包(有抓取时刻与代理路径)/ wt-8 百度 MD5 / wt-9 腾讯 v1(★ 签的是原值、出网才编码)/ wt-10 阿里 RPC V2(★ 签的就是出网那一份百分号编码串,空格编 %20 不是 +)—— 三条都在用例里按官网公式独立复算并断言 URL 里没有密钥本体 / wt-11 一次性数每发都换(腾讯 Nonce 与阿里 SignatureNonce,且 Nonce 换了签名必须跟着换)/ wt-12 三家错误形状不同,认不出来就得点名 bad_json / wt-13 非 2xx 也要先读回包(阿里实测错误就是 404 + Code/Message))、复用与存储(wt-16 逐字复用且落款跟那一行自己的引擎 / wt-17 第九轮那批 engine:'official' 的旧行继续读得出、不冒充新档 / wt-18 改一个字就作废重译、库里记的是折过空白的同一份 / wt-19 force 绕表并写回 / wt-20 存储不可用仍给译文并说"显示完就丢" / wt-21 并发去重 / wt-22 命中缓存那一发不组 URL(一次性数在查库之后才算)/ wt-24 入参截断而库里存没截的那份)、边界自证(wt-23 打码:三家标识符各留头 4 位、签名/密钥/一次性数整段遮 / wt-25 五档引擎名与各张表在 domain 里各只有一份 / wt-26 三家夹具各恰好一条 provenance:'live'(无凭据真回包)且合成样本不许带 capturedAt / wt-27 真机一发,SKIP_LOCAL 跳)、★第十五轮 +1(wt-28):这一档只有翻译能力:kinds() 只报 desc,摘要那一路即使开关开着也不派(把 enabled 的第一行那道能力闸门钉住 —— 摘要提示词那句「整理成一段简体中文摘要」只派给真有摘要能力那一路;★ 第十七轮整条重写:SERVED_KINDS 改回 ['desc','readme'] ⇒ 这一档 serve 两路,llmReadme 开着就真的把那发译出来(断 engine==='keyless' 且假 net 恰一发),开关关着则 errKey:'off' 且连网都不碰 —— 能力回来了,闸门还是那道闸门)、★第十六轮 +1(wt-29):厂商请求号排最前,别被调用点那句 .slice(0, 200) 吃掉(三家位置各不同:腾讯 Response.RequestId/阿里顶层 RequestId/百度 log_id;最坏一发真走假 net —— HTTP 403 + 64 字请求号 + 约 700 字错误体,断言回执行 ≤200 且 ^HTTP 403 请求号 R{64} 那串号活着;没有请求号的真回包不许凭空拼出「请求号 」那种半截话)
host-compat.test.mjs26(★ 含跳口径,与同表其它行一致:25 过 + 1 跳(跳的是 hc-17 那要真出网的一条);★ 第三十六轮 +1:hc-25「检索那一屏的接线」四面 —— ① 新文件 lib/services/search-run.js 真在扫描面里(HOST_FILES 是 walk('lib') 动态得到的 ⇒ 改名或挪走,下面那几条当场变成给空气立的牌坊),② 五种坏形状各扫一次(ghToken/getGhToken、authorization/Bearer、api.github.com/https://、favStore/transStore/put(/broadcast(、llm/translate/fetch()且每一形先在一段合成样本里自证扫得到再断真源码为 false(同 hc-8/hc-23 那条"正则扫不到合成样本就是扫空气"的规矩),③ lib/api.js 里必须写 fetchBatch: deps.searchFetcher(那一发不吃已装配的闭包 ⇒ 令牌就得在门面现取)且 ghToken 在本文件恒 0 处,④ ★ hc-21 那份逐字名单本轮不动:readers 仍 deepEqual ['index.js','lib/domain.js','lib/services/repo.js'](新文件挤进去 = 多开一个出口,少一处 = 这一轮没接完);★ 第三十五轮 +1:hc-24「那一列撤得干净」—— 那四个 domain 名字(FAV_ON_BOARD_LABELS / FAV_OFF_BOARD_CELL / FAV_ON_BOARD_PRIORITY / FAV_COL_ON_BOARD)零出处 + lib/favs.js 与 client.js 连 onBoard / offBoardCell / 「未上榜」三形都不认(★ 每一形先在合成样本上自证扫得到、再断真源码为 false)+ lib/api.js 那个 favView({ 调用点恒恰一处且只喂三格(入参键表 deepEqual = descHits / favRows / storageAvailable,boards / starsRows / allStarsRows 三个死料词一个都不许出现,样本里那一格必须存在做反面自证);⚠️ 首跑连红三遍、三遍都是判据自身写法(① 切调用体的正则在嵌套 }) 处提前截断 ⇒ 补"读全了没"的前置断言;② 合成样本里没有 ^\s*word: 行 ⇒ 反面自证空转;③ 样本用简写 boards, ⇒ 键表扫不到 ⇒ 补死料词循环那一支)⇒ 修判据不动产品码,读数见「测试」那节本轮那段;★ 第三十四轮条数不变、hc-20 里 D1 那一支整支重写:旧字面锚 /const base = num\(row\.checkedAt\) \?\? row\.at;/ 随尺子搬进 domain 而判不出是漂了还是搬家了(真红过一次)⇒ 现在钉三处接线:lib/services/repo.js 写 const base = repoAskedAt(row);、lib/stores.js 里 repoAskedAt( 计数恒 2(裁行 + list(),少一处就是那一处自己数一遍 = §8.13 那处隐患回来)、尺子本体在 lib/domain.js(numOf(row?.checkedAt) 与 numOf(row?.at) 两格缺一不可);★ 锚的分层(spec §8.17 本轮新立的形状律):行为层钉语义(内联等价写法本来就该绿,store/repo 两套有语义牙)、接线层钉"两处共用"(调用点 + 计数,不钉整句字面)—— 电池里那两对"内联等价 ⇒ 行为全绿 / hc-20 红"的发就是这条律的自证;★ 第三十三轮 +1:hc-23「这句中文该不该上屏只有一处判据」—— 四类判据字面(transSrcKey / kind\s*[!=]==\s*['"]desc['"] / descZhFor / descZhHits)各扫 lib/favs.js 与 client.js 两文件 + ★ 合成正样本自证那四条正则不是扫空气 + lib/favs.js 的 import 名单恒 ['./domain.js'](多一条边就是它自己去读了别的模块)+ 客户端 .src === 那种"比原文"整类禁见;★ 第三十二轮 +1:hc-22 第八张表的接线(真装配点落得进真表、快照读得回来、teardown 把域真关、存储域坏时念故障话);★ 第三十一轮条数不变、两条就地改判:hc-11 载荷键表补回 cacheHours / cacheHourLabels(detailStampLabels 留下但键集钉成 {body, revalidated} 两格)、hc-20 整条重写成那条 TTL 链的九段(现取现算 / 判 checkedAt 回退 at / repo.js 不写死小时数 / 代码位六文件白名单 / 客户端不排档位话术 / 落款两词只在 domain / 'DETAIL_RECHECK_MS' in DOMAIN === false / optionalInt( 在而 requiredInt( 不在 / repoCacheTtlMs(24) === 24*60*60*1000)⇒ 那条律从"撤"验成了"撤与摆双向";★ 第二十七轮那次改判的原文留在下面)hc-0 扫描面自己先要「有东西可扫」:清单从 lib/ 目录真读派生(不是手抄文件名),且每个都真读得出 >200 字符、lib/desc-zh.js 必须在里面、零 @deepseek-ai/* / 零第三方依赖、★只读 GET 律的出网名单也改成派生(hc-7:凡真的调用 fetchFn( 的服务文件都算一路,net.js 自己除外;再按端点常量切成 GitHub 路与翻译那四路两拨,并自证两家之和等于总数、translateBound().length===1(四档共用同一份 web-translate.js,这一位就是在钉"不许哪天冒出第二个翻译出网文件而这条律扫不到它");逐文件钉无写方法、GitHub 那一路无凭据字样、不 clone 不下载、不起子进程、不许硬写 https: 字面量、地址只能从 domain 引 —— 手抄那一版对新增的 web-translate.js 零覆盖还照样全绿,见 spec §0 第九轮)、schedule/jobs/通知零调用 + 模型句柄只许一个使用者(hc-8 原为「零 ctx.llm」,10-06 第八轮改判:白名单文件由 index.js 的 createLlmTranslator 那条 import 边派生,并要求它真在扫描面里、真拿到句柄 ≥2 处;其余文件凡出现 deps.llm / snap.llm / .llm? 形状一律红,四类坏形状内置自证 —— 这条判据原先只匹配字面 ctx.llm,被 ctx.inject(['llm'], s => s.llm) 一路绿灯溜过去,见 spec §9.4)、inject=[]、index-inject 载荷 26 键齐(★ 第十二轮多 cacheHours / cacheHourLabels 两格:档位与中文话术都从 domain 走,客户端一格都不自己写 ★ 第二十七轮就地改判:那两格换成 detailStampLabels —— 键表是刻意双写的,加键/换键不同步就当场红;本轮另断 Object.keys(v.detailStampLabels).sort() 恒为 ['body','revalidated','windowHit'](★ 第三十轮那第三个词进了这份名单 ⇒ hc-11 就地改判、条数不变;那句落款的三个词只在 domain 一份,装配处只递名字,客户端读到的是这三格、不是自己造那三个字))、客户端读的每个 cfg().X 都有人推(键表从宿主实际推的那一帧反查,不手抄清单)、保存偏好后必须真推一帧 update(hc-18:挂真 SSE 长连接、真 POST、读回那一帧的 translator.switchRows 里那一行的 on 翻转(★ 第十五轮:从读 descOn 那一格改成遍历这张表**,因为那一格整格撤了)—— 走查抓到的"点了『开』高亮还在『关』")、★hc-19 密钥边界(效果侧,第十轮从一把扩到三把):boot 插件 → 逐家真 POST 一份含 KEY 的偏好 → 逐条扫 POST 回执 / GET /api/snapshot / GET /api/prefs / SSE 帧文本 / logger.warn 里既无三把密钥中的任何一把、也不出现它们的键名,并要求该档 credFields[].has===true 且 'value' in f===false 做非空转证明(★ 只摘其中一把密钥的植入就是从这里被抓出来的)、★第十二轮 hc-20(详情 TTL 的接线)——★ 第二十七轮整条重指向本轮接线(条数不变):~~装配处只许写 getTtlMs: () => repoCacheTtlMs(getPrefs().repoCacheHours)(现取现算),出现 ttlMs: 那种抄死毫秒即红;出厂那一档与出厂那个毫秒必须同源;prefsView 的初始值里就得有 repoCacheHours 那一格~~ ⇒ 现在钉的是五条新的:index.js 里不再出现** getTtlMs / repoCacheTtlMs(档位撤了还留着注入点 = 一个没有喂主的第二真相)、ttlMs: 那种装配时抄死毫秒照旧即红(第十二轮批评过的那个形状,撤档后更不该留)、载荷必须写 detailStampLabels: DETAIL_STAMP_LABELS 而 index.js 与 client.js 两处都不许出现「正文取回于 / 刚核对过」那两个词(同一句话有第二处就红)、★ 撤档要撤干净:整条链(domain / stores / api / index / client)在代码位一处都不许认得 repoCacheHours

目录结构

index.js            宿主半边装配:能力探测、八仓储(★ 第二十三轮多一张 `search`、★ **第三十二轮**多一张 `fav`)、节拍、路由、详情服务(~~★ 第十二轮:TTL 交 `getTtlMs()` 现取现算,不在装配时锁死~~ ★ **第二十七轮撤掉那个注入点**,★ **第三十一轮(10-12 用户改判)摆回来**:装配处又出现 `getTtlMs: () => repoCacheTtlMs(getPrefs().repoCacheHours)`,且**必须现取现算**(锁死 = 界面已换新档、真跑的窗口还在旧值,第十二轮那笔账);入口载荷多回两格 `cacheHours` / `cacheHourLabels`,`detailStampLabels` 那格留着但**只剩两个词**(第三十轮补的第三截 `windowHit` 跟着 60 秒窗口一起撤);`hc-20` 现在扫的是这条 TTL 链本身 + 「domain 认不得 `DETAIL_RECHECK_MS`」,代码位白名单六个文件)、入口载荷 ★ **第三十二轮(收藏 §8.15)三处接线**:第八张表 `createFavStore({ getFacility, logger, now })` 接进 `deps.favStore`;同时把 **`repoStore` 那张表**(⚠️ 刻意**不是** `repoService` —— 后者会在 TTL 之外真问 GitHub,而收藏这一趟的出网账是 0)也递进 deps,给写路径的 `favSeedOf` 当第四路本地读数;teardown 的 close 名单**从七张变八张**(漏第八张 ⇒ 域留在设施里、下次启动 already-open,判据 `hc-22` + 电池 ㉑) ★ **第三十六轮(§8.18)这个文件一字未改**,而这一条要登记的理由恰恰是"没改":那枚新屏要用的出网闭包早就在 3.9 那一节(`createSearchFetcher({ fetchFn: net.fetch, logger, now, getGhToken: () => getPrefs().ghToken })`,`index.js:227`),参数化只发生在 `lib/services/repo.js` 里面(少给一个参数就落回全站高星那串默认),`deps.searchFetcher`(`index.js:274` 那**一个**键位)从本轮起喂**两个**消费者 —— `all-stars.js` 照旧**无参**调用(那个文件本轮也一字未改)与 `lib/services/search-run.js` 的 `fetchBatch(query)` ⇒ ★ 一颗闭包两个入口是**同一趟出网的两张脸**,不是两条出网路(`hc-21` 那份「认得 `ghToken` 的只有 `index.js` / `lib/domain.js` / `lib/services/repo.js`」的逐字名单本轮不动,`hc-25` ④ 把这条当判据扫了一遍)。⚠️ 装配点不动 ≠ 没接线:路由、闸门、载荷、页签全在 `lib/api.js` 与 `client.js`,本文件唯一的职责是那颗令牌绑在哪儿,本轮它一个新键都不加
client.js           浏览器半边:侧栏图标 + 整页面板(SSE 主、手动检查兜底;★ 第十二轮:设置页多一行「详情缓存」分段器(~~★ 第二十七轮那一行撤掉~~ ⇒ ★ **第三十一轮按原形状摆回来**:两格 `cfg().cacheHours` / `cfg().cacheHourLabels`,四档分段器点一下即存,**客户端一个字都不排档位表**、旧宿主没推那两格时整行不摆),详情弹框那句落款**只搬载荷那两个词**(`detailStampLabels.body` / `.revalidated`;★ 第三十轮多的那枚 `.windowHit` 连同那个秒数在**第三十一轮一并撤**,客户端不写「正文取回于 / 刚核对过」这两句汉字,也没给词表时整句不摆)、相对时间「3 天前」仍由浏览器自己算(时钟在客户端);详情弹框只摆宿主给的段名与块;★ 第十五轮:现译那几行开关改成吃 `translator.switchRows` —— **行清单是载荷给的**,当前那一路没有摘要能力时那一行不摆,客户端不写死两行;★ **第二十三轮**:页签由六变七(「明星仓库」插在月榜之后,徽标 = `stars.rows.length`),`StarsCard` 整页一张卡且**只搬字** —— 七个列名、视图与排序那**两张档位名单**、置灰那句 `thinNote`、缺失格那个 `—`、额度那一句全部读载荷,界面不数条、不拼句、不判档(`thin`)、不自造缺位符,也**不自己列档位名单**(★ 排序比较本身是本地纯计算 `starsPick()`,载荷恒按 `stars` 降序预排 —— 见 spec §8.8 那条 10-09 收窄改口) ★ **第二十九轮**:页签与明星那一屏的**选中态落 `localStorage`**(`UI_KEY = ${panelId}.ui.v1` 跟着载荷走、只存三枚 id `tab`/`starsView`/`starsSort`;`readUi`/`writeUi` 各包一层 `try/catch` ⇒ 存储被禁或写满时界面照旧;`pickOption(名单, 存的 id, 出厂档)` 是"读回只认**在册且未禁用**"的单点,与「关掉送回第一档」共用它,生效档在**渲染期现推**而不是挂载时定死 ⇒ 见 spec §8.12) ★ **第三十轮**曾给详情底部那句落款补**第三截**(`stampWindow` 只认载荷 `cached === true`,三截 `filter(Boolean).join(' · ')`,那句整份来自 `detailStampLabels.windowHit`、秒数在 domain 按 `DETAIL_RECHECK_MS / 1000` 现拼),★ **第三十一轮整截撤掉** ⇒ 落款回**两截**、`DETAIL_STAMP_LABELS` 回两格、「刚核对过」收窄成**只在真核对过那一问才念**(TTL 命中那一屏只剩第一截,因为那一问压根没问过 GitHub);`client.js` 代码位现在扫不到「秒内没再问」那半句 ⇒ 见 spec §8.13 与 §8.14) ★ **第三十三轮(§8.16 ④)描述格收进一个 `descCell(desc, hit, missing)`**:~~榜面 / 明星 / 收藏三处渲染点共用它~~ ⇒ ★ **第三十六轮加「检索」⇒ 四处渲染点共用它**(此前那条"只搬字不判档"的规则在文件里已有**两份逐字拷贝**,收藏是第三个用户 ⇒ 再抄一份就是第四处,界面上出现"两屏同仓库、悬停不同形"是迟早的事 —— 本轮那一处**没有再抄**,直接调它)。三格判法:有命中摆 `hit.zh`、没命中摆原文、原文也空才摆 `missing`(缺位符吃载荷 `missingCell`,客户端不自造);悬停三截「原文:${desc} / ${hit.label}(那一行自己的落款)/ ${hit.note}」整份来自宿主,★ **⚠️ 判据不在屏上** —— `hit` 是宿主 `descZhHits` 喂进来的那一份,这里不出现 `transSrcKey`、不写 `kind === 'desc'`、不比 `src`(`hc-23` 扫 `client.js` 连 `.src ===` 那种"比原文"整类都禁见;`client-78` 用静态计数钉 `className:'gt-desc'` 恰一处、`descCell(` **恰五处**(★ 第三十三轮到第四处为止是"一处定义 + 三处渲染点",第三十六轮加检索那一屏 ⇒ 一处定义 + **四处**渲染点,数字由 `client-78` 那条自己数))) ★ **第三十六轮(§8.18)那一屏 `SearchCard`**(第九签):六列 `colProps` 与表头同源同数、★ **那一枚尾列 `gt-tail` 只打在最后一格**(那 36px 归 CSS);四路描述格走同一个 `descCell`;语言那一格**只有名字 + 那个不带内联色值的 `i`**(`langColor` 这一路压根没有 ⇒ 不许在浏览器里另立第二份语言色表);★ 六态各念载荷那一句、**喂空串就画空**(`client-79` ⑦′ 值驱动那一头,客户端不许兜第七句);触发只有回车(`!e.isComposing`)与「搜一下」两处、在问期间输入框与按钮一起 `disabled`、**检索词不落 `localStorage`**(`client-80`);`FavStar` 在每一行恒摆、点亮态只看载荷 `favSaved`,点它递 `{repo, action, from:'search', seed:{desc,lang,stars}}` 而 `remove` 两格都不递(★ 屏上自己不改状态,亮灭只跟载荷,`client-81`);⚠️ **不读 `snap.search.rows`**(快照那一格恒零行,只是文案格)、也**不摆第七列**。
lib/domain.js       一份真相:枚举、标签、边界、阈值、八表 schema(★ **第二十三轮**:多一张 `search` 表 + `seen` 那两格 `roundsTotal` / `bestRank`,追加的键**一律 `optional*`**、域 `version` 恒钉 1;★ **第三十二轮**多第八张表 `fav`(详见下面本条末尾);含 GitHub API 基址、★现译引擎**五档**与各家凭据字段表 `TRANSLATE_CRED_FIELDS`(三家六格:schema 键名与长度上限全部从这张表派生,手抄必漏)、`TRANS_ROW_ENGINES`(现行五档 + 历史档名 `official`,让第九轮那批旧行继续读得出)、翻译端点白名单(`TRANSLATE_HOSTS` 由 `TRANSLATE_ENDPOINTS` 派生)、注册地址表 `TRANSLATE_REGISTER`、~~★**第十二轮的详情缓存四档**:`REPO_CACHE_HOURS`(`6/12/24/72`,封闭集合)+ 话术表 `REPO_CACHE_HOUR_LABELS` + 出厂档 `REPO_CACHE_DEFAULT_HOURS=24` + 单点换算 `repoCacheTtlMs()`(越界退回出厂档),`REPO_CACHE_TTL_MS` 由出厂档**算出来**而不是写死的毫秒数~~ ★ **第二十七轮那三个名字与 `DEFAULT_PREFS.repoCacheHours` 那一格整条撤掉**(用户裁定原文「撤掉这一行,改成固定 60 秒防连点(推荐)」),★ **第三十一轮(10-12 用户再次亲手改判)那三个名字与那一格原样摆回**(裁定原文「**还是改成以前那种模式,默认缓存24小时,可以配置,听不懂吗,不要用60秒这种**」)⇒ 上面那段划掉的描述**逐字又是当前口径**;当时换进去的那三格里,`DETAIL_RECHECK_MS = 60 * 1000` **整键删掉**(`hc-20` 反过来钉 `'DETAIL_RECHECK_MS' in DOMAIN === false`),`REPO_FAIL_TTL_MS = 5 * 60 * 1000`(失败档,第十二轮起就从不进设置页)**留下**,`DETAIL_STAMP_LABELS` 回**两格** `{ body: '正文取回于', revalidated: '刚核对过' }`(界面那句落款的词**只在 domain 这一份**,装配处只递名字 ⇒ 载荷 `detailStampLabels`;★ 第三十轮那第三个词 `windowHit` 连同"秒数现拼"那条模板一起撤,`hc-20` 与 `client-70` 两头钉代码位扫不到「秒内没再问」);⚠️ **有意没恢复**旧的 `REPO_CACHE_TTL_MS` 那个导出 —— 盘上没有任何消费者,恢复它就是第二真相;`repo` 表 schema **追加三格** `checkedAt` / `etagMeta` / `etagReadme`(**全 `optional*`、域 `version` 恒钉 1**;★ 两个 etag **不设 `maxLength`** —— 截断的验证器永远换不回 304,每发退化成全文,比"没存"更糟)、★**第三十轮那一格 `zhProbed`**:`repoRecord` 再追加 `zhProbed: optionalBool(...)`(**仍 `optional*`、域 `version` 恒钉 1**,缺格的老行与 `false` 同义 ⇒ 零迁移)—— 口径是**判定输入齐了才算探完**(八形六 `true` 两 `false`,逐形钉在 `test/repo.test.mjs`),那一格的**唯一读者是 `load()` 喂不喂 prev**(见下面 `repo.js` 那条);同轮把 `README_ZH_GATE_SUFFIXES` 的注释**两条用途分列**(`cjk` 与 `lang` 两支都还给出段名后缀 ⇒ 摘要闸门收窄不影响段名那句话),★ 表本身一字未改(改的是 `api.js` 那一支读它的方式)、`tmp/r30-branches.mjs` 是那八形的取证脚本;★**第十一轮的段表与阈值**:`REPO_SECTION_KEYS`(段序唯一真相)与 `REPO_BLOCK_KINDS`(`p/sub/num/excerpt` 四种块;★ 第十二轮 `REPO_SECTION_SOURCE_NOTES` 那张来源落款表**整表删除** ⇒ 段对象只剩 `key/label/blocks/facts` 四格)、`README_ZH_SECTION_MIN_CJK`(= `README_ZH_MIN_CJK`,**同一条中文判据不另立一个数**)、`DESC_SELF_ZH_MIN_CJK=8`(描述本身就是中文 ⇒ 不派现译)、五档 `REPO_README_SOURCE_LABELS`、`repo` 表 schema 多的那两格 `readmeSection` / `descSelfZh`(★ `sections` 与 `sectionFields` **不在 schema 里** ⇒ 段表不落库,域 `version` 仍钉 1)、★**第十五轮的节选与第二路常量**:`README_HEAD_CHARS=600`(**只服务那五档的中文判据**)与 `README_EXCERPT_MAX=1600`(节选预算,本轮才真生效)**分家**、回退窗口 `EXCERPT_SENT_BACK_MAX=200` + 中西文两支 `EXCERPT_SENT_END_RE`(句子边界收口)、`README_ZH_LINK_MAX=200`(第二路那条链接的长度闸门)、`LLM_SWITCHES` 每行自带 `kind`(设置页那几行跟着当前那一路的 `kinds()` 走)、★**第二十三轮明星仓库那一屏的常数、名单与四句成品**:阈值 `STARS_MIN_ROUNDS=3`(薄快照那道门,**判档在宿主**)与**同值但不同概念**的 `STARS_REGULAR_ROUNDS` / `STARS_RISING_ROUNDS=2`、窗口 `STARS_WINDOW_MS`、行数上限 `STARS_ROWS_MAX=120`(截断在宿主做)、视图与排序名单 `STARS_VIEWS` / `STARS_SORTS`(★ 客户端**不自己列这张名单**,但排序比较在屏上做 —— 见 spec §8.8 落地改口 14)、未开启那档的灰化标签 `STARS_VIEW_DISABLED_LABELS`、七列里那三个「并进」列名 + `STARS_MISSING_CELL`、四句成品(`STARS_ALL_STARS_NOTE` / `STARS_QUOTA_WAITING_NOTE` / `STARS_QUOTA_OFF_NOTE` / `STARS_NO_STORE_NOTE`)加**只在真拿到响应时从响应头现拼**的 `starsQuotaLine()`、search 那一发的三格常数 `SEARCH_STARS_FLOOR=100000` / `SEARCH_PER_PAGE=30` / `SEARCH_RATE_ANON=10`(★ 这是 10-09 真回包读数,**不等于 REST core 的 60**:search 与 core 是两套池子,按 60 判会把「匿名还是已认证」念错)+ `SEARCH_MAX_PER_ROUND=1`、`SEARCH_ROW_SHAPE` 与 `searchRecord`) ★ **第三十二轮(收藏 §8.15)那一整叠新常数 + 第八张表**:两档动作 `FAV_ACTIONS = ['add','remove']`(封闭枚举,越界 400 并把合法值念出来,同 `MANUAL_ACTIONS` 那一条)、三档排序 `FAV_SORTS` / `FAV_SORT_LABELS` / `FAV_DEFAULT_SORT='added'` + `favSortsOf()`(★ 名单与标签**只在这里**,客户端不自列档位)、那几句成品(~~`FAV_ON_BOARD_LABELS` 四格 + `FAV_OFF_BOARD_CELL='未上榜'` + 命中优先级 `FAV_ON_BOARD_PRIORITY` + 列名 `FAV_COL_ON_BOARD='这一轮'`~~ ★ **第三十五轮这四样整簇删除**(用户裁定「只删「这一轮」那一列……一并撤干净,不留死码」)⇒ 那四个名字在盘上**零出处**,判据 `hc-24`;**留着的**是下面这几份:`FAV_STAMP_LABELS`、列名 `FAV_COL_STARS='累计 ★(那一刻)'`、`favFromCell()` 那句「来自 <榜名>」、卡脚 `FAV_NOTE`、空态 `FAV_EMPTY_NOTE`、故障 `FAV_NO_STORE_NOTE`)、`from` 那一格的封闭取值 `FAV_FROM_SOURCES`(**前三档由 `BOARDS` + `BOARD_LABELS` 派生**,手抄就会在加榜那天漂;后两档 `FAV_FROM_STARS` / `FAV_FROM_DETAIL` 单独命名是给装配侧点名的);`favRecord`(key = 小写 `owner/name`,★ **新表**所以主键与 `addedAt` 走 `required*` 是安全的 —— 10-07 那条血案律管的是"往**已有**表追加必填键",两句不许混,⚠️ 而从本轮起 `fav` 自己进了"已有表"那一侧,往后给它加必填键就是那次三榜全红的重演;五格快照 `name/desc/lang/langColor/stars` 全 `optional*`,`from` 是 `requiredEnum` ⇒ 每行必然有出处),`GHT_DOMAIN.tables.fav`(**域 `version` 恒钉 1、零迁移**:新表 = 空表起步);⚠️ ~~界面上那一句「明星仓库」在「这一轮」那一格念成「在明星」是**这一格的成品句**,不是第二份榜名(别处仍吃 `BOARD_LABELS`)~~ ★ **第三十五轮整句作废**:那一格连同 `FAV_FROM_STARS` 在「这一轮」那一列的用法一起撤,收藏屏上「明星仓库」现在只剩「来自 <榜名>」那一处出口(`favFromCell()`,`FAV_FROM_SOURCES` 五档名单未动);★ **第三十四轮(§8.17)那一把尺**:`repoAskedAt(row)` —— **详情 TTL 判据基准 + `repo` 表 LRU 裁行键 + `list()` 交出去的 `askedAt`,三处读同一个函数**(口径:`checkedAt` 优先 → 缺格回退 `at` → 脏值(非有限数)当缺位给 `0`);换它之前 TTL 与裁行是两把尺,§8.13 末尾那处"越省额度的行越先被 LRU 删掉"的真隐患就是它俩分家造成的;★ **第三十六轮(§8.18 检索那一屏)那一叠新常数 + 出处改判两格**:长度闸门 `SEARCH_QUERY_MAX = 256`(**挡在路由层**,400 那句话把这道边界念出来、那一发压根不出发;⚠️ 这不是 GitHub 的口径,是插件自己的一道闸 —— 与 `PROXY_URL_MAX=200` / `GH_TOKEN_MAX=256` 同族,挡的是「把整段正文粘进框里」那种形状,不是校准真值),六态名单 `SEARCH_STATES` 与话术表 `SEARCH_STATE_LABELS`(还没问 / 正在问 / 有结果 / 没回仓库 / 额度用尽 / 那一发没成 —— ★ 六个词只在这里,`client.js` 一个都不写)+ **那六句的唯一点** `searchStateLine({ state, query, count, reason })`(★ 客户端不数条、不拼句、不判档:`ok` 那一句里的条数、`error` 那一句里的原因都由宿主递进来;⚠️ `error` 那一句**不许**暗示屏上还留着上一批 —— 这一屏零入库,坏了就是空着,与榜面那条"坏轮冻结"**故意反向),那一屏的 note `SEARCH_NOTE`(★ 与 `STARS_ALL_STARS_NOTE` **逐字分开**:那一句讲的是"每轮检查后 1 发并落库",这一句讲的是"手动一发、不落在本机、切页签就没了",混着用就是把两种口径演成一种),列名 `SEARCH_COL_STARS`(**直接等于** `STARS_COL_STARS`,★ 同一件事不另立第二份口径)与 `SEARCH_COL_FAV = '收藏'`(★ 收藏那一屏的尾列是「移出」,两个词都由宿主给,客户端不许两边都写),★ **改判一**:出处新增一档 `FAV_FROM_SEARCH = '检索'` ⇒ `FAV_FROM_SOURCES` **五档变六档**(`fav` schema 那个 `requiredEnum` 名单同步 ⇒ 库里攒出界面念不出来的档就是 schema 的失职),并**作废** r32 那条「四路全空 ⇒ 落 `FAV_FROM_DETAIL`」—— 出处与读数从此**解耦**(`from` 只说"在哪一屏点的",那几格数仍按四路 first-hit),封闭屏 id 名单 `FAV_SCREEN_IDS = [...BOARDS, 'stars', 'search', 'detail']`(★ 宿主按这张表校验 `from`,越界 400 并把合法值念回来;客户端只递 id,「来自 X」那一句永远由 `favFromCell()` 拼 ⇒ `client.js` 源码里「来自」二字仍一处都不许出现),★ **改判二**那三格白名单 `FAV_SEED_KEYS = ['desc','lang','stars']`(`name` 与 `langColor` **恒不收**:显示名有库里与榜上那一份可比,`langColor` 这一路压根拿不到 ⇒ 检索屏收进来的行色点永远缺位、画 CSS 那份灰)+ 文本上限 `FAV_SEED_TEXT_MAX = 1000`(⚠️ **1000 是本机库的现读读数取整**:`repo` 表 desc 最长 267、`search` 表 171、`lang` 10 —— 不是 GitHub 给的口径,注释里写明了这一句,别处不许当"官方上限"抄)+ 清洗函数 `favSeedClean(seed)`(★ 脏值**整格丢掉**:`desc`/`lang` 只收**非空字符串且 ≤ 上限**(★ 这里**不做 trim** —— "全是空格"那一形在路由层已经 400 挡掉,清洗只管形状不管语义),`stars` 只收 `Number.isSafeInteger` 且 `>= 0` ⇒ 那一格不落,★ **不截断、不当 0、不把 `"9000"` 圆成 `9000`、不把小数四舍五入**,而**收藏照旧成功** —— `ok:true` 与"三格全丢"是两件事,混在一起就是把输入校验当成写入失败)
lib/kv-schema.js    最小 schema 校验(sysops / stock / modelwatch 同名文件的同源拷贝)
lib/kv-records-base.js  记录域底座:WeakMap 域登记表 + refcount + 串行写队列(同源拷贝)
lib/stores.js       state / events / prefs / seen / repo / trans / search / fav 八仓储(★ **第二十三轮**多一张 `search`:单行 key = `batch`,形状刻意与 `state` 那三行同一种读法 `{at, ok, error, transport, rows[]}` + 坏轮冻结,且**不与 `repo` 缓存同表**;★ **第二十二轮**给 `trans` 加一个出口 `entries()`:整表一次扫、回 schema 认过的**整行**、不裁字段 —— 榜面那列的中文视图在**读路径**上每帧要吃全表,按屏上行逐个 `get` 等于把开面板的成本挂在榜面行数上;★ **第三十二轮**多第八张 `createFavStore`:key 归一到**小写**(`Vitejs/Vite` 与 `vitejs/vite` 必须同一行,否则同一仓库存两份、屏上两枚 ★ 各亮各的)、`list()` 按 `addedAt` **倒序**(装配侧只做这一种序,重排交给界面)、**不裁行 / 不设上限 / 不参与 LRU**(与 `repo` / `trans` 那两张表最大的不同:收藏是用户自己挑过的东西,按 `at` 裁那种读法摆在这儿等于"收藏久了被系统悄悄删掉")、★ `add` **幂等**且幂等那一支**沿用库里那一行的 `addedAt`**(「收藏于 3 天前」说的是第一次收的那一刻,重复点那枚 ☆ 不该把它刷成「刚刚」)、`remove` 回 `removed` 位(库里本来没有那一行时是真话);⚠️ 这张表**只由 `POST /api/fav` 那一路写**,快照五格由宿主派生、不接受客户端递值)
lib/check.js        一轮检查的编排 + 变化判定纯函数
lib/stars.js        ★**第二十三轮(10-09)新落点**:明星仓库那一屏的**纯视图函数** `starsView({ seenRows, boards, roundAt, prefs, search, storageAvailable })` —— 零 IO / 零出网,原料全是本机库(三榜 `rows` + `cross` + `seen` 观测史 + `search` 那一批)。三件事在这一个文件里:① **候选集** = 窗口内的观测史**并入**这一轮屏上那些行(新面孔即使它的 `seen` 行还没写也一定在屏上);② **判档**(常客 / 新星 / 回落,以及「在榜」那一列够不够证据 —— `roundsAvailable = max(roundsTotal)` 是**盘上证据深度**而不是"本机跑过几轮",`thin` 就在这算);③ **截断**(先按累计轮数、同轮按星数,截 `STARS_ROWS_MAX`,★ 截完恒按星数降序重排 ⇒ 交给屏上的**默认序**就是星数降序;屏上换排序键时在**已到手**那批里本地重排(`starsPick()`,零请求)—— 客户端不许自己列档位名单,但排序比较本身在屏上)。★ 「今日新增」那一列**只吃日榜**:不在日榜给 `null`(界面上是 `—`),在日榜但那一格坏了给 `0`("今天没涨"是真话)
lib/favs.js         ★**第三十二轮(10-13)新落点**:「收藏」那一屏的**纯视图函数** `favView({ favRows, descHits, storageAvailable })`(★ 第三十三轮多一枚入参 `descHits` —— 由调用端喂,本文件**一个字都不判命中**;★ **第三十五轮把三档原料入参撤干净**:`boards` / `starsRows` / `allStarsRows` 三个键从签名里消失 —— 那一列都不摆了还留着喂料就是**死接口**,判据两头:`favs` 那条「★ 撤一列连入参一起撤」(旧的三档原料照喂 ⇒ 行与载荷仍长不出那一格)+ `hc-24` 钉 `lib/api.js` 那个 `favView({` 调用点**恒恰一处且键表 `deepEqual` 只回那三格**) —— 与 `lib/stars.js` 同一条律:**零 IO / 零出网**,原料全由调用端喂进来(`fav` 整表 + 同一帧读出来的那一份 `descHits`)⇒ "这一屏打开时出不出网"在结构上就是零。~~三件事~~ ★ **第三十五轮起两件事**在这一个文件里:① **快照不刷新**:`stars` / `desc` / `lang` 恒是库里那一行**收藏那一刻**的值,本函数一个字都不与榜上的新读数合并(要新值走详情那条链,那一屏出不出网由设置页那一档管着,不在这里替它决定);~~② **「这一轮」那一格是本地比出来的**:拿收藏键与屏上那些行比一次,命中按 `FAV_ON_BOARD_PRIORITY` 念第一个命中的成品句、没命中念「未上榜」⇒ **恒不发请求**,★ 比键时把榜行的 `renamedFrom` 一起铺进集合(仓库改名后收藏键与榜行键不同,不铺就会把"明明在榜"念成"未上榜" —— 用户收的默认:误念比缺念更糟),⚠️ 且**这一格不写回库里那一行**(每帧现算,写回去就是第三份星数之外的第三份榜况);~~ ★ **第三十五轮整段作废**(用户裁定「只删「这一轮」那一列」):那一格连同它吃的三份原料、`FAV_ON_BOARD_PRIORITY` / `FAV_OFF_BOARD_CELL` 两个 domain 出口、`renamedFrom` 那一圈铺集合、以及 `keysOf` 那个只为它存在的辅助函数一起撤 ⇒ 本文件里 `onBoard` / `ON_BOARD` / `OFF_BOARD` / `keysOf` 四个标识符**零出处**(判据 `hc-24` + `favs` 那一发反面);② **恒定的那一种序**:`addedAt` 倒序、★ 同刻按主键 `localeCompare` 收尾(顺序必须每帧确定,否则同一份库存渲染出两种顺序),截断与档位都不在这里(这一屏不裁行)。读数缺位给 `null` 不是 `0`(`0` 是"真的是 0",`null` 是"那一刻没有这一格"),界面按 `missingCell` 摆 `—`;⚠️ 边界登记:`reading(null)` 因 `Number(null)===0` 得 `0`(与 `lib/stars.js` 逐字同源,改一处就是两处),**库里存不出 `null` 这一形**(`parseOrInvalid` 不收 `undefined`)⇒ 不为它加防护、也不立判据,夹具改喂 `undefined`;★ `storageAvailable` **不给默认值** —— "存得下"是一句好话,说它要拿出依据,调用端没说就落 `false`;★ **第三十三轮(§8.16)四处落点**:① 行多**那一格 `descZh`** = `descHits?.[keyOf(r.repo)] || null`(⚠️ **第三十五轮改口**:从前叫「第 11 格」,那个序号吃的是「那一行共有十一格」而不是它自己的位置 —— 撤掉末尾的 `onBoard` 之后行只剩 **10 格**,序号名失去所指 ⇒ 台账与用例名统一改叫「`descZh` 那一格」,它实际一直在第 4 位;`keyOf` 是**本文件的归一函数**、与上一段撤掉的 `keysOf` 不是同一个东西)(**逐字搬**调用端喂进来的那一份 ⇒ 本文件四类判据字面一个都不许出现:`transSrcKey` / `kind==='desc'` / `descZhFor` / `descZhHits`,`hc-23` 扫的就是这个文件,连 import 名单都恒 `['./domain.js']` —— 多一条边等于它自己去读了别的模块);② ★ **`desc` 那一格恒不被中文覆盖**(覆盖之后屏上与库里同名不同值,"快照不刷新"只剩注释能证明 —— 判据在 `api` 那两条用例上比的是两屏载荷逐字同);③ 比键用**同一把** `keyOf` 归一(视图再归一遍就是第二把尺,`descHits` 的键恒是宿主归过的小写);④ 卡脚 `FAV_NOTE` 跟着改口(要说清"屏上那一句是本机已有的中文,这一屏一发都不问")。⚠️ **库里 `fav` 那一行仍是 8 格** —— 中文不落库,它是每帧现读现算的视图(spec §4 那张表因此**不改口**)
lib/services/gh.js  趋势页抓取与解析(榜面唯一"发什么请求"的地方;怎么出网它不管,交给 net.js)
lib/services/repo.js 仓库详情:api.github.com 元数据 + README + 自带中文 README 探测(★第十一轮到**五档** `zh_default` / `zh_file` / **`zh_section`** / `en_default` / `none`)+ ★**结构化段表** `repoSections`(四段 `what/heat/self/summary`、四种块 `p/sub/num/excerpt`、段序只认 `REPO_SECTION_KEYS`、数字只进 `heat.facts`;旧的整句 `repoNarrative()` 第十一轮整段撤掉)+ 两道源侧闸门用的 `descIsZh`(`DESC_SELF_ZH_MIN_CJK=8`)与围栏状态机 `splitReadmeSections`(同一份 net 传输层,编排仍 3 发封顶)+ ★**第十二轮**:`repoSections` 的段对象缩成 `key/label/blocks/facts` 四格(四句来源落款整格撤,"是谁写的/是谁译的"并进**段名**),`readmeNote()` **整函数删除**,`readmeMeta()` 压成一行短字面 `节选 N / 整篇 M 字 · 已去标记 · 文件`,详情服务的 TTL 吃 ~~`getTtlMs()` **调用时现取现算**~~(★ **第二十七轮撤掉那个注入点**、★ **第三十一轮(10-12 用户亲手改判)摆回来**:这一层又按设置页那一档判新鲜,`freshEnough()` 那句就是 `now() - base < getTtlMs()`,⚠️ **TTL 之内一发都不问、连验证器都不问**;条件请求那一半**照旧没撤** —— `get()` 多一个 `etag` 入参且**非空才发 `if-none-match`、原样转发弱标 `W/`**;**回 304 时一个字节都不读正文**(先读头再决定);`fetchRepoDetail` 收一个 `prev`,**只有成功行且非 `refresh` 才喂**;★ **没带钥匙却回了 304 ⇒ 当场裸发重问一发**,绝不把空正文端给界面(不变式,两形各一条判据);窗口判据在 `freshEnough()` 一处:`now() - base < getTtlMs()`,而那个 `base` = `num(row.checkedAt) ?? row.at`(★ **D1**:304 刻意冻住 `at`,判 `at` 会让"最省额度"那一类行**每次都出网**)+ 一条例外 `if (row.zhProbed !== true) return false;`(★ **D2**:半截结论不受 TTL 挡,否则第三十轮那条自愈要等满 24 小时);⚠️ 本文件**不许自己写小时数或毫秒数**(电池 ⑩ 打的就是这一条);失败档仍吃 `failTtlMs`(5 分钟,按裁定不进设置页、失败行也不带验证器);`at` 只在真拿到正文时推进、`checkedAt` 每问必推,`revalidated` 由那两格现算**不入库**),★**第十五轮**:`readmeZhVerdict()` 交两样东西 —— `head`(去标记后前 600 字,**只用来数 CJK 判那五档**)与 `clean`(去标记后的整篇),节选吃 `clean` 并经 `excerptOf()` 在**句子边界**收口(`README_EXCERPT_MAX=1600` + 回退窗口 `EXCERPT_SENT_BACK_MAX=200` + 中西文两支 `EXCERPT_SENT_END_RE` + 硬切与回切都退掉半个代理对),第二路 `pickZhReadmeLink()`(markdown 与 `href` 两种写法)+ `zhReadmeRelPath()`(五道闸门排在造 URL 之前,返回**原始路径**,`encodeURIComponent` 只在出网那一发逐段做)) ★ **第二十八轮新增 `fullReadme(name, { path })`**:取**整篇**正文那一发 —— `path` 空或 `README` 走 `/readme`,其余**逐段 encode** 走 `/contents`(展的必须是屏上那一篇);**不带任何验证器**(`If-None-Match` 一个字节都不喂,喂了就大概率换回 304 的 0 字节正文)、**不落 `repo` 表、也不看 60 秒那个窗口**(那一发是"再取一份正文",不是"再问一次详情");三种失败各说各的话且都不写字(404 → `not_found`、空正文 → `parse`、坏名字连网都不碰);令牌照旧**只进 `Authorization` 请求头**(`hc-21` 的效果侧判据本轮从详情那四发扩到这一发,URL 逐字节不变) ★ **第三十轮(10-12,中文那一档不再被 304 冻住)四处落点**:① `probeReadme` 的返回**多吐一格 `zhProbed`**,按"判定输入齐了才算探完"的八形写 true/false(六形探完,只有清单 5xx 与中文篇超时那一发没探成留 false);② **闸门在喂 prev 那一侧**:`load()` 的 prev 条件从「成功行且非 `refresh`」加到「**且 `stored.zhProbed === true`**」⇒ 缺那一格的老行或半截行**一个字都不喂验证器**(下一问裸发四发重判一次),★ 而不是在 `fetchRepoDetail` 里另判(探针实证:直接递 prev 仍会换回 304);③ `repoCacheRow` 的白名单**收 `zhProbed` 且 `false` 也收**(只存 true 会让"探到一半"与"从没探过"在库里同形);④ `readmeFieldsFromPrev` 原样带那一格(★ 电池 ⑤ 判这一处为**等价变异**:`load()` 只把探完的行递进来,写死 `true` 在盘上不可分辨 ⇒ 不新增判据)。自愈的代价是**一次**:探完写回 true ⇒ 第三问回到 2 发省额度那一路(★★ 判据把三问收敛钉死) ★ **第三十六轮(§8.18 ②)search 那一发参数化**(★ 是**第二个入口**,不是第二条出网路 —— 出网口仍只有本文件那条私有 `get()`,令牌只在它的 `authorization: Bearer`):`searchRepoUrl({ query = '' })` 两支,★ 给了非空词 ⇒ `{q, per_page, page}` **无 `sort`、无 `order`、无 `stars:` 门槛**(回的是 GitHub 按相关度排的那一批,插件不替他改写查询:用户自己写 `stars:>=5` 也照原样 encode 交出去),**不给或给空格串 ⇒ 落回全站高星那一路的默认常量串**(`stars:>=SEARCH_STARS_FLOOR` + 那两支排序,**逐字未动**:`all-stars.js` 的调用点仍是无参那颗闭包,本轮那个文件一个字没改,判据「同一颗闭包两个入口」钉的就是这一形);`searchRepositories({..., query })` **只透传不加工**(trim、空串 400、超长 400 全在路由层 ⇒ 本层的默认支不许自己变成第三种形状);⚠️ 那个"空格串与根本不给同形"的边界要说清:挡「用户按了按钮但框里没字」是 `POST /api/search` 的 400,这里若把空格编成 `q=%20` 发出去,GitHub 回一句它不懂的错 ⇒ 界面上就是一句假故障;★ 失败行的 `errText` 照旧是**原样回执**、不过 `REPO_ERROR_LABELS`(那张表的 `rate_limited` 写死「60 次/小时」,念到 search 这一档就是假话 —— 两套池子,`rate.authed` 拿 **search 自己**那一份匿名读数 `SEARCH_RATE_ANON=10` 判);`searchRowOf()` 那六格 `SEARCH_ROW_SHAPE` 一个多余键都不带(真回包一条 item 六十多个键:`owner` / `score` / `text_matches` / 各种 url —— 跟着进库就是把这一档当第二份 `repo` 缓存),★ `rank` 是**这一批里的位次**且坏行被丢后**留下的行仍拿自己原来的位次**(不重新编号:那一列列名叫 `#`,重编号会把"GitHub 给的顺序"改成"我数出来的顺序")
lib/services/full-readme.js ★**第二十八轮(10-10)新落点**:详情弹框那三枚手动按钮的**编排层**(`createFullReadmeRunner`),三件事都在这一个文件里:① **那一发 GitHub 是裸取** —— 调 `repo.js` 的 `fullReadme(name, {path})`,**一个字都不带验证器**(带了就大概率换回 304,而 304 的正文是 0 字节,那一屏展不开;与第二十七轮那颗「不走缓存」同一个坑),**零入库、也不受详情那一档 TTL 挡**(★ 第二十八轮当时写的是"不进 60 秒防连点那个窗口",第三十一轮那扇窗换成 TTL 那一档 ⇒ 那一发跑完库里那行一个字没变,下一次点开详情该不该出网仍由那一档与 `zhProbed` 那一格决定);② **分块跑完整篇 + 熔断**:`chunkParagraphs` 只在段落边界累加、单段超预算才切句末,`MANUAL_CONCURRENCY=2` 在飞,`MANUAL_LEG_MAX=40` 是单点在 domain 的封顶(摘要那趟**先扣 1 发**给末尾的汇总 ⇒ 块最多 39、汇总恒轮得到),到闸就停且**没跑的尾巴不进段**,那句实话报的是跑到的**块**数;单块失败**原位留原文**并指得回第几块,不整趟作废;③ **存结果 + 原文指纹**:`src` 那格存 `sha256(整篇) 前 16 位 + ':' + 折空后字数`,命中判据「主键 + `src` 逐字相同」与两路服务**同一条**(比的是整篇指纹而不是时刻);分块那几发恒 `persist:false` ⇒ **一整趟只落 `trans` 一行**;超 `MANUAL_FULL_ZH_MAX = 30_000` 字**整份不存**(截一半的"已存"是假话),回执带 `stored:false` + 那一句。另有纯函数 `manualGateOf`(置灰四形:`no_readme` / `already_zh` / `no_sum_capability` / `not_ready`,★ `!tr` 那一支排在能力位之前 —— "根本没装配现译"不许念成"这一档不会摘要")、`readmeFingerprint`、`readRows`(**库里那一行优先**,没落库的那一份从回执顶上屏,失败回执**不顶替**那一段),载荷那一整格 `manual = {section, runNote, actions[], sections[]}` **命名统一吃 kind** ⇒ 客户端把回执对上载荷不需要另建一张"动作 → 段"表。★ **落库归 `translate()` 自己**(本文件一个字不写库),★ **句子全来自 domain**(用例与界面里不出现手抄句子);⚠️ 本文件**只出现在注释位的那句 `ghToken`** 不进 `hc-21` 的语句位扫描(认得那个键名的仍然恰好三处:index.js / domain.js / lib/services/repo.js)
lib/services/all-stars.js ★**第二十三轮(10-09)新落点**:「全站高星」那一发的**闸门 + 每轮预算 + 落库**(`createAllStarsRunner`)。四道闸门一条不许换序:`off` → `no_store` → `no_round` → `round_already_sent` → 发 —— ★ `off` 排最前,与 `board-zh.js` 那一路的 `no_store` 在前**语义相反、故意相反**(这一档没开时根本不该讨论"存不存得下";补译那档是默认开着的,库坏了要说清"不是没开,是存不下"),两条判据各钉一次不许哪天合并成一个 runner;★ `no_round` 排在预算之前是因为预算挂在轮次上,且**计数在第一个 `await` 之前落定**(记在 await 之后 ⇒ 同轮第二次触发一起穿过去,"一轮 1 发"变成"两轮 2 发")。落库走**成功与失败同一个** `rowOf()`:坏轮冻结(`at` 与 `rows` 停在上一批,只有 `ok/error/transport/lastFetchAt` 跟着这一轮写),额度那四格**只在成功轮更新**;不重试、不补发、**没有失败冷却表**(每轮 1 发本身就是节流,与 board-zh 另一处故意不同)。失败行的 `error` 存**原样回执**、故意不过 `REPO_ERROR_LABELS`(那表里 `rate_limited` 写死"60 次/小时",念到 search 这一档就是假话)。★ 本文件**一个字节都不碰令牌与 URL**:出网那一是 `repo.js` 的 `createSearchFetcher()` 绑好的**无参函数**递进来的,键名 `ghToken` 在这里不许出现(`hc-21` 按键名扫文件,认得它的只有 index.js / domain.js / repo.js 三处)。★ **同日就地改判(「开启的时候默认拉取一次」)多出的第二入口**:`runOnEnable()` 与 `run(roundAt)` 走的是**同一串闸门、同一只预算**,唯一差别是它把**发起时刻**当成自己那一轮的轮次身份 ⇒ 点「开」不会被上一轮检查那只预算挡成"点了没反应";代价是「`round.at` 记的是轮次时刻而不是本地时钟」那句口径**只在这一条路上开了例外**(判据 `test/all-stars.test.mjs` 2b 那一圈四条:闸序没少、当场落库、连点被同刻的 `round_already_sent` 挡、两个入口互不侵占);★ **同日第二条裁定**再给那一趟加**第五道闸 `fresh`**(窗口 = `prefs.intervalMin` 那一格、判据 = 库里 `ok===true` 那一次的 `at`,**只挂在 `runOnEnable`** ⇒ 上面那句"四道闸一条不许换序"对 `run` 一字未动)⇒ 它是本文件**唯一在第一个 `await` 之后**才判的闸门,与"闸门全在 await 之前判完"那条律故意不同:那条防的是同轮并发穿透,而这里的原料(上次成功取回的时刻)**只在库里、没有第二来源**,穿透由调用端那道转换闸挡;判据吃 `at` 而不吃 `lastFetchAt`(上一发是坏的就该让用户重试),且**认不出合理窗口就不挡**(缺 `intervalMin`、`at` 在未来、库里没行 ⇒ 一律照发);挡下时 `skipped:'fresh'`、`sent` 仍是 `0` ⇒ 门面不追帧(判据 `test/all-stars.test.mjs` 2c 那一圈七条 + 2d 钉字段来源那一条)
lib/services/search-run.js ★**第三十六轮(10-14)新落点**:「检索」那一屏的两样 —— ① `createSearchRunService({ fetchBatch, logger, now })`:**闸门只有一把**「一发在飞」(`flight` 那枚 Promise,★ **拦与放都是主张**:并发第二问拿 `busy:true` 且 `fetchBatch` **压根没被第二次调用**,第一发结算后 `flight = null` ⇒ 连问照旧出发;⚠️ **不自建一小时计数账本** —— 额度恒吃回包响应头,`SEARCH_MAX_PER_ROUND` 那把挂在检查轮 runner 上的预算**管不到这一路**;空词在 runner 里再兜一道不发;那一发抛错**不 rethrow**,折成失败形状 + 锁释放 + 日志一句);② `searchView({ result, query, descHits, favRows, asking })`:**载荷视图,★ 零 IO**(函数体里 `fetch` / `await` / `Store` / `hub` / `Date.now` 五个形状一概不许出现 —— "这一屏出不出网"要在结构上是零而不是注释);六态在这里判(`asking` 优先于回包、认不出的态念 `error` 而不是 `idle`),六句成品调 domain 的 `searchStateLine()`,额度那一句复用 `starsQuotaLine()`(★ 不另立第二份句子),行只出 **8 格**、顶层只出 **16 键**(★ 多一格就是第二个住处,判据用 `deepEqual` 的键表钉)。⚠️ 本文件**没有仓储入参**(`favRows` 与 `descHits` 是视图料,不是写料)⇒ 零入库是签名层面的事实;★ 与 `lib/favs.js` / `lib/stars.js` 同一条律:判命中的字面(`transSrcKey` / `kind==='desc'`)在这里一个都不出现,`descZh` 逐字搬调用端喂进来的那一份。
lib/desc-zh.js  内置离线预译描述表(**生成的死数据**:`[小写主键, 原文, 中文]` × 73 + `descZhFor` / `builtinDescZhMap`(★ 第三十四轮由 `descZhHits` **改名**:这后一个是**内置表那一层的**批取函数,只吃 `rows`、生产侧零消费者、仅 `dz-7` 读它 —— 从前与 `lib/board-zh.js` 那个"命中判据唯一出处"的 `descZhHits(rows, transRows)` **同名不同义**,改名后盘上只剩 board-zh 那一个 `descZhHits`),零 import / 零出网,见 `dz-6`)
lib/board-zh.js ★**第二十二轮(10-08)新落点**:榜面描述列的**混合来源视图 + 每轮检查后的补译批次**。两条路一份判据 —— 纯函数 `descZhView(屏上行, 整张 trans 表)` 给视图(**读路径零发**),
                    `createBoardZhRunner().run()` 给批次(闸门顺序:`busy` 单闸 → `no_engine` → `no_store` → `off` → `unavailable` → `read_failed` → 逐字复用 → 失败冷却 → 每轮上限 12 发 · 并发 2);
                    另有 `visibleBoardRows`(批次吃:同仓库取名次最好那条)与 `allVisibleRows`(视图吃:三榜原样并一列、**不去重**,否则跨榜逐字命中的那一行会被别榜的旧原文抢掉)、
                    ★ **10-10 新增 `descZhRows({ boards, allStarsRows, allStarsEnabled, dedupe })` = 参与行集合的单一出处**:快照视图与轮次后批次**两处都调它**,「那一档参不参与现译」只在这一处判一次 ⇒ 挡掉"屏上 `hits` 有它、排队 `todo` 没它"那种半截状态(真机截图问的就是这个形状)。`allStarsEnabled !== true`(含缺位 / `null` / `0` / `'true'`)⇒ **一行都不并**;开着时那一档的行带内部组标记 `zhGroup: 1` 排在榜面之后,且**拷一份再打标记**(传进来的那批行**就是** `snap.stars.allStars.rows` 本身,就地改会把内部标记写进用户屏幕上的载荷)。`dedupe` 只作用在榜面那一段。
                    `descZhView` 的返回因此多了两样:`todo` **先按组再按名次**(每轮那 12 发是两组**共享**的预算,榜面先吃饱 —— 两个 `rank` 不同轴,全站名次插到榜面行前面就是抢名额),以及 `boardMissing`(**只数榜面那一组**的欠账)⇒ 界面上那句「榜面这一列只显内置预译」不会因为只有全站那一档欠着而被念出来(主语不能骗人);
                    `boardDescZhHead`(按**这一张榜**数条数)与 `boardDescHeadText`(三档句子,内置那一句逐字沿用旧文案)。★ **不碰宿主模型句柄**(只吃装配层的 `getTranslator()`),**不写库**(落库由 `translate()` 自己管);★ **第三十三轮(§8.16 ①)判据单点**:那一圈「内置优先 → 与库里那行原文逐字比对」抽成导出的 `descZhHits(rows, transRows) ⇒ {hits, counts}` = **命中判据的唯一出处**(榜面经 `descZhView` 吃它、收藏经 `lib/api.js` 直接吃它 ⇒ 复制粘贴出来的两份判据一漂移,屏上就是"榜面有中文、收藏没中文"那种半屏假话),`descZhView` 首行改成 `const { hits, counts } = descZhHits(rows, transRows);` 而 `todo` / `missing` / `boardMissing` 三样**留在原地**;★ 它的返回**恒只有那两键**(带出 `todo` 就把收藏那一屏变成会花钱的屏,这一条有判据);归一吃**两头**(库里那批行的键 + 屏上那些行的键各归一次小写,电池第 3 发抓到只钉一头时判据空跑);★ `descZhRows`(参与行集合)**本轮一个字没改** ⇒ 收藏那批行不进补译集合,那本账仍是 **0 发 + 0 新增额度**。⚠️ 本文件这个 `descZhHits` 与 `lib/desc-zh.js`(内置表)那个同名导出**不是同一回事**(后者只吃内置表、生产侧零消费者)—— 命名账登记在「测试」那节第三十三轮末尾
lib/services/net.js 传输层:CONNECT 隧道 + 路线仲裁(设置页自定义 > 环境变量 > Windows 注册表 > 直连)+ 注册表 60s 缓存
lib/services/llm.js 模型现译(★五档引擎里 `host_llm` 那一路):**宿主模型句柄的唯一使用者**(`hc-8` 的白名单文件由这一条 import 边派生)—— 闸门顺序、逐字复用、八档失败文案都在这一个文件里;★**`kinds()`(第十五轮立的机制,第十七轮仍在)**:~~这一档两路都 serve(`[...LLM_KINDS]` = `desc` + `readme`)⇒ 设置页那两行开关都摆~~ ★ **第二十八轮**这一档**四路全 serve**(`kinds()` 回 `[...LLM_KINDS]` = `desc` + `readme` + `readmeFullZh` + `readmeFullSum`,名单单点仍在 domain,判据是 `test/llm.test.mjs` 那条「这一档四路全 serve」);★ 同轮 `enabled(kind)` 从两行改成**三行**:第一行 `if (MANUAL_KINDS.includes(kind)) return true;`(用户裁定「不受参数设置控制」⇒ 手动那两路**不查那两枚开关**),第二三行才读 `prefs.llmDesc` / `llmReadme` —— 少了第一行,`readmeFullZh` 就被设置页上**并不存在**的那枚开关管住(点了没反应 yet 屏上说能点);★ 但它**不绕就绪态**:没选引擎 / 那家云凭据没填 / 宿主没给句柄,照旧挡,且挡的那句话与"开关没开"是两句不同的话
lib/services/web-translate.js ★**四路**(`keyless` 免费接口 + `baidu` / `tencent` / `aliyun` 三家云,第十轮把后两家接上):同一个形状的服务、同一条 `net.js` 传输,**全 GET**(腾讯 v1 那一路的签是「GET + host + 字典序原值」,POST/TC3 那套没走);查询串里只带各家的**标识符**(`appid` / `SecretId` / `AccessKeyId`)+ 一次性数(`salt` / `Nonce` / `SignatureNonce`)+ `sign`/`Signature`,★密钥本体只进摘要、**不进 URL**;`pickTranslator` 按 `prefs.translateEngine` 在这四路与 llm.js 之间**选一个**(没选中的那一路连 `enabled` 都不问);★**`SERVED_KINDS=['desc','readme']`(第十七轮现值)**:这四路 `enabled(kind)` 第一行查这张表、第二行才看那两枚开关(`readme` 吃 `llmReadme`、`desc` 吃 `llmDesc`)⇒ 摘要那一发照派,只是段名与那句说明按档位念「节译」(第十五轮曾把这张表缩成 `['desc']` 并撤掉那一行开关,本轮已被用户改判撤回,见上面第十四件) ★ **第二十八轮**这张表扩成 **`['desc','readme','readmeFullZh']`** —— **有意不声明 `readmeFullSum`**:免费那四路做不了整篇摘要(`summarize` 那枚在免费档置灰,那句置灰的话是「这一档只会翻译,不会摘要」而不是「开关没开」);同轮这四路的 `enabled(kind)` 也在最前面加了 `MANUAL_KINDS` 那一行 ⇒ 手动那两路**不受参数设置管**,但**没声明那一路照挡**(判据 `wt-28` / `wt-28b`))
lib/api.js          路由表 + SSE hub + 错误码翻译 + 快照装配(`netView` 在这里把路线翻成界面那句话,`translatorView` 在这里把当前档翻成那 13 键(含 `credFields[]` / `register`,★ 恒无 `value`;★ **第十五轮:`descOn` / `readmeOn` / `switchLabels` 三格并成一张 `switchRows[]` ⇒ 15 键变 13 键,行的条数吃当前那一路的 `kinds()`**),派活那一侧的第三道闸门 `want(kind)` 读的是那一路的 `enabled()`,~~`descZh.hits` 也在这里按屏上那些行算~~ ★ **第二十二轮**:`descZh` 那一格换成 `{hits,heads,liveNote}` 三格、装配全在 `lib/board-zh.js`(这里只调 `descZhView(descZhRows({ boards, allStarsRows, allStarsEnabled }), await transStore.entries())`,**纯读、一发不派**;★ **10-10**:那份行集合从 `allVisibleRows(boards)` 换成 `descZhRows`,且 `search` 那一批行改成**读一次、两处用**(同一份 `readSearchRow(deps)` 的产物既喂视图也喂 `starsView` ⇒ 读两次就是第二份真相;这一条**没有可见判据、没进电池**,属等价变异,只由注释与那条律守着));★ 补译批次 `boardZh.run(descZhRows({ boards: snap.boards, allStarsRows: snap.stars?.allStars?.rows ?? [], allStarsEnabled: snap.prefs?.allStarsEnabled === true, dedupe: true }))`(★ **10-10**:吃的是同一份参与行集合,`dedupe: true` 只作用在榜面那一段 —— 批次与视图**同源**,否则就是"排队里没有它、屏上却有它") **只挂在 `check` 服务那一帧 `update` 之后**(`GET /api/snapshot` 与 SSE 首帧都在读路径上,一处都不许挂),且**只有真补成了行**(`r.ok>0`)才追推第二帧 —— 否则一轮检查白刷三次面板);★ **第二十三轮**:快照多一格 `stars`(= `starsView()` 整个输出,**纯读、渲染期零请求**,回落批直接从 `search` 表读),那一发 search 由 `createAllStarsRunner` **同样只挂在 `check` 服务那一帧 `update` 之后**(与补译批次同处触发、两个 runner 各立 —— 两道闸门顺序语义相反,合并一个就得选一个顺序),**开关没开连 runner 都不进**,屏上念的仍是库里上一批;★ **同日改判(开启即拉)**:门面把那一枚 runner 挂回自己的 deps(`d.allStars`),`POST /api/prefs` 在**写入之前**先取库里的旧值,认出 `false → 递来 true` 那一趟就 `await deps.allStars.runOnEnable()`,**发完才回回执**、`sent > 0` 就再追一帧(`savePrefs` 的回执只并 `prefs` 那一格,那一批不追帧上不了屏)⇒ "只挂轮次"那条律的完整表述变成 **检查轮那一发挂轮次、开启那一发挂转换**,而不带 `at` 的偏好变更帧照旧走 `no_round`(改一次节拍不该烧一发配额);★ **第二十八轮**:路由表从七条变**八条**(新增 `POST /api/repo/readme`,也是**第八条里第四条被回环闸门拦下的**,且它是**第一条由浏览器发起、当场花模型额度**的写 ⇒ 那一行**自己在路由表上标 `loopback:true`**,不许靠"是 POST 就顺带闸"那条隐式规则),装配侧多一个 `attachManual(view)`:**只在 `view.ok === true` 时**把那一整格 `manual` 挂上详情载荷(`ok:false` 不挂 —— 三枚按钮不许摆在一段错误上面),`action` 越界与 `name` 缺失走 400 且把合法值念回来、服务没装配 501;那一趟重走的 `svc.load` 坏了 ⇒ **200 交回 `errKey` + domain 那句成品话**且整篇那一发零调用;`path` 从 `svc.load` 的载荷**透传**给编排层(客户端一个字节都不递裸串) ★ **第三十轮(10-12)**:`attachZh` 里**摘要那一发的第三道闸门**从 `.hit`(`cjk` ∪ `lang` 都算命中)收窄成 `readmeZhOnScreen(view.readmeExcerpt).via !== 'cjk'` ⇒ 只有**节选里真有中文**才不派。理由是一条形状账:`lang` 说的是「那行写着有中文版」,那是**推测**;推测**兑现**的仓库档名会落在 `zh_file` / `zh_section`,上面那格 `readmeSource === 'en_default'` 本来就把活挡了(⇒ `lang` 在那一支上从未起过作用),推测**没兑现**的(真机 `debpalash/VoiceStudio`:中文那份在根目录、库里那行被 304 冻在 `en_default`)被它挡下来的结果就是用户那两问 ——「开了摘要现译,点开没有翻译」⇒ **屏上既没中文也没摘要**。★ 段名后缀那**两支照旧都给**(`README_ZH_GATE_SUFFIXES[gate.via]` 说的是"这一篇为什么这么念",与派不派活是两件事,第一次在这一行分列);判据 `test/api.test.mjs` 那条整条替换成三支表(`cjk` 不派 / `lang` 照派 / 真机那形 7 个 CJK 照派)+ 两支各断一次段名,**条数净 0** ★ **第三十二轮(收藏 §8.15)三处落点**:① 快照多一格 `fav` = `favView()` 整个输出,~~★ **排在 `stars` 之后装配**因为它吃的是**同一帧已经算好的那两批行**(`stars.rows` 与 `search.rows`)—— 「这一轮」问的是"屏上此刻有没有它",回头再读一遍榜面那三行就会与各判一次~~ ★ **第三十五轮那段作废**:撤掉那一列之后这里**只剩两样原料**(`fav` 本帧读出的行 + 同一帧那份 `descZhHits` 的 hits),`boards` / `starsRows` / `allStarsRows` 三格喂料当场删掉,与 `stars` 的装配先后**不再有依赖**(判据 `hc-24` 钉那个调用点键表 `deepEqual` 只有三格、且 `boards` / `starsRows` / `allStarsRows` 三个死料词在 `lib/api.js` 一个都不出现);读路径**只多读一张本地表**,一发不问 GitHub;② 新路由 `POST /api/fav`(`loopback:true`,理由与 `GET /api/repo` **不同一条**:这一路不花上游配额、它改的是**本机库存** ⇒ 放给邻居点等于让别人替我收藏):body 只认 `{repo, action}`、`action` 走 `FAV_ACTIONS` 封闭枚举越界 400 并念出合法值、`repo` 走详情那一路的**同一把** `normalizeRepoKey`(不在这里抄第二份 `owner/name` 正则)、仓储没装配 501;★ 三件"不做的事"各有判据 —— **不发一发 GitHub**、**不派现译**(那一屏读快照原文)、**不写 `events`**(流水的判据是"榜变了什么",用户点了个星不是榜的变化);写完**恒追一帧**(`add` 幂等时 `already` 为真也要追 —— 那枚 ★ 的样式与页签计数本来就该跟着这一按走),回执带整份 `fav` 视图;③ `favSeedOf(deps, key)` = 收藏那一刻的**快照原料**,四路按屏上顺序找(三榜**切片行**吃 `prefs.topN` ⇒ 屏上只有那几行,榜上第 30 行的 ☆ 用户根本点不到,拿整表去找会把"不在屏上"念成出处 → 「全站高星」那一批 → 榜史 `seen` ⇒ 榜史行**只有显示名**,不许从别处补一个用户没看见过的星数 → 详情缓存 `repo` **表**),四路都没有 ⇒ 出处落 `详情`、四格在屏上是 `—`。⚠️ **本轮取证出的一处真缺陷(分形律,§0 那条律第八次兑现)**:`kv-records-base.js` 的 `get available()` 说的是「**有设施且没关**」,⚠️ **不等于** `open()` 成功、更不等于这一帧真读得出来 ⇒ 只看门面那一位就会把"读不到"念成"库里真没行"(界面两句互相拆台),`storageAvailable` 因此改成**两道都问**(`favStore?.available === true && !favRead.unreadable`,`readFavRows` 的 `unreadable` 位);判据 `hc-22` 那一族 + 电池 ⑭ ★ **第三十三轮(§8.16 ③)两处落点**:① `transStore` 那一整表**一帧只读一次**(`const transRows = await readTransRows(deps)` 提到 `descZhView` 与 `favView` 之前)⇒ 榜面那份 `zhView` 与收藏那份 `favZh` 吃**同一个值**,读两遍就是"中间落库一次给两个答案"(判据把计数包装套在**真仓储门面**上、数的是产品侧信号不是替身自报);② 收藏那一份 hits = `descZhHits(favRead.rows, transRows)`(★ 吃的是**收藏自己那批行**,不是榜面那一份 —— 收藏里那个不在屏上的仓库照样上屏,把两个 hits 混用就漏这一形),喂进 `favView({ descHits: favZh.hits, … })`;⚠️ **只喂 `hits`、不喂 `counts`/`todo`** ⇒ 装配点结构上派不出活,`descZhRows` 一个字不改,那一屏的出网账恒 0 ★ **第三十六轮(§8.18)这一层多三样**:① **第十条路由 `POST /api/search`**(体只认 `{query}`:trim 后空 ⇒ 400 且**那一发压根没出发**、超 `SEARCH_QUERY_MAX` ⇒ 400 并把边界念出来、检索服务没装配 ⇒ 501 那句实话、一发在飞 ⇒ **409 `GHT_SEARCH_IN_FLIGHT`**;★ 那一发**坏了不是 5xx** —— `limited`/`error`/`empty` 三支都回 200 而载荷里的 `state` 各说各的话,故障是 GitHub 给的答案不是路由的故障;★ **零入库 + 不广播**:成功那一趟八张表逐张不多一行、SSE 一帧不追,判据两条 + 电池第 ② 发;⚠️ 这条路**在 `loopback:true` 名单里**(六条之一)—— 理由比 `POST /api/fav` 更硬:它当场花的是本机那个匿名 search 池,别机来一发就能把这台机器的榜面预算吃掉);② `POST /api/fav` 的体白名单**两格 → 四格** `{repo, action, from, seed}`(`from` 按 `FAV_SCREEN_IDS` 校验、越界 400 念合法值;★ `seed` 只在 `action==='add' && from==='search'` 那一支被读,其余支**结构上碰不到它** —— 装配处那一行 `const seed = screenId === 'search' ? src.seed : null;` 就是这一条的出处,清洗走 `favSeedClean()`、优先级走四路 first-hit,两边各有判据;改判一作废旧的「四路全空 ⇒ 落 `FAV_FROM_DETAIL`」那一支 ⇒ **出处与读数解耦**);③ `d.searchRun` 由 `mkApi` **只在真接上才造**(`if (typeof deps.searchFetcher === 'function')` 才 `createSearchRunService({ fetchBatch, logger, now })`,缺位 ⇒ `d.searchRun` 为空 ⇒ 路由回 501,★ 而不是造一枚调到 `undefined` 的 runner —— 那会在用户按下去的那一刻炸);⚠️ 快照那一格 `search: searchView({})` **恒 `idle` + 恒零行**,它是**文案格不是结果库存**(客户端在飞的那一会儿靠它也有话说,而检索结果一个字都不落在这里 ⇒ `hc-25` 三面 + 判据「不读 `snap.search.rows`」)
lib/caps.js         能力位(现取现算,不在 apply 顶层锁死)
test/               十七个离线套件(★ **第三十六轮**加 `search.test.mjs`:检索那一屏的三圈 —— `searchRepoUrl`/`searchRepositories` 那一发参数化、那颗**只在飞一发**的锁(★ 两条互为反面:并发第二问压根没出发 / 第一发结算后第三问照样出发)、`searchView()` 那一格载荷(六态句子逐字吃 domain、`empty` 与 `error` 形状可区分、键表封闭),23 条**全离线**(假 `fetchFn` 按整条 URL 精确匹配,★ 没有任何一条吃真回包 —— 这一屏的额度读数吃的是替身头里的 `x-ratelimit-*`);★ **第二十八轮**加 `full-readme.test.mjs`:详情那三枚按钮的编排;★ **第三十二轮**加 `favs.test.mjs`:`lib/favs.js` 那一屏的纯视图 —— 快照不刷新 / ~~「这一轮」单值与改名归一 / 命中优先级~~(★ **第三十五轮随那一列一起撤**:那一族七条整条删,见下面「合计」那处) / 同刻按主键收尾 / `available` 只看传进来的存储位 / 缺位给 `null` 不是 `0`,24 条全离线;★ **第三十三轮**同一套 +4(~~第 11 格~~ ★ 第三十五轮改口:**`descZh` 那一格**逐字搬而不覆盖 `desc` / 比键吃同一把归一 / 脏 `descHits` 一律 `null` / 卡脚那句要说清中文从哪来),★ **第三十五轮**同一套 −6(撤 7 改 1 立 1:新立那条「★ 撤一列连入参一起撤」),合计 **22 条**)+ 五类夹具(趋势页切片 `make-fixtures.mjs` / api.github.com 原文 `make-repo-fixtures.mjs` / 现译四路各一份 `fixtures/trans-*.json`,逐条 `provenance` 见下 / ★**第二十三轮**多一份 `fixtures/repo-search.json`:由 `make-search-fixture.mjs` 落的**一次真抓**(`GET /search/repositories?q=stars:>=100000&per_page=30` → 200,`capturedAt` 与 `route` 那两格是当场读数),裁剪口径写在文件头 `_note` 里 —— 前 3 条 `item` 逐字节全留、其余只留被读的四个键,真实长度与条数记在 `fullLength` / `keptLength` / `originalItems`,**用例不许把裁过的行当全文**;那份回包同时是 `SEARCH_RATE_ANON=10` 的出处(`x-ratelimit-limit: 10`,与 REST core 的 60 是两套池子)/ ★第十一轮多一份 `fixtures/repo-zh-section.json`:`zh_section` 那一路的**形状夹具**,文件级 `provenance:"synthetic"`(**不是实抓**,命中侧本机零真样本),`shapeSources` 逐条写明每一格的形状从哪个真文件借(噪声行 ← ant-design、围栏里的中文行 ← Qwen),键集与状态码口径照 `repo-api.json`;由 `make-zh-fixture.mjs` 生成,用例不许把它当"GitHub 真的这么答")
docs/design-spec.md 设计规格(含 §9.1 S0 探针读数台账、§9.2 测试台账、§9.3 真机走查读数与仍未验证清单)
tmp/                真机走查脚本(shot.mjs 六签走查 / shot-bad.mjs 注入坏帧三态 / shot-proxy.mjs 三档出网方式逐档走查 /
                    shot-links.mjs 外链配色 / shot-detail*.mjs 详情弹框逐档 / shot-llm.mjs 现译两档走查 / probe-*.mjs 量几何、代理与详情数据源读数、
                    probe-title.mjs 页头字号与五家兄弟插件 `-title` 规则的墨迹对表)与截图 tmp/shots/;
                    `gen-desc-zh.mjs` + `desc-src-all.json` + `desc-zh-authoring.json` 是预译表的生成三件套(原文列由解析器取、中文列人工写,幂等);
                    `web-*.bak-*` 是走查前那份 web profile 的 `package.json` / `cordis.patch.yml` 备份(拆场按它 `cmp` 还原,第九轮收尾时两份都已 `diff` 过与 profile 现文件逐字节一致),`walk-llm*.txt` 是第七轮的逐屏读数原文;
                    ★ 第九轮留的:证伪脚本 `wt-falsify.mjs` / `hc-falsify.mjs`(还原源 `api.bak.js` / `web-translate.bak.js` / `wt2.bak.js` 三份 `cmp` 过与现源一致,纯重复)、
                    逐套复跑读数 `rerun-ski_local.txt`(330/0/2)与 `rerun-full.txt`(**已被 13:5x 那次覆盖成 331/1/0** —— 挂的是真出网那条 `wt-19`,撞的是外部 429;13:2x 那份 332/0/0 只留在 spec §9.2 台账里)、免费接口真回包 `p-g1.json`~`p-g5.json`、
                    以及**没落地成引擎的探路痕迹** `p-bing-*` / `p-yd.json` / `p-long*`(为什么最终只有百度那一路,见 spec §8.4)。
                    ★ 第十轮留的:证伪电池 `r10-falsify.mjs` + 输出原文 `r10-falsify-out.txt`(**14 条 / 未抓到红 0 条**,退出码 0,四条源文件跑完 `cmp` 过与备份逐字节一致)、
                    逐套复跑读数 `rerun-r10.txt`(`SKIP_LOCAL=1` 下 340/0/2,直跑 342/0/0)、真机走查探针与读数 `probe-engine10.mjs` / `probe-engine10.txt`(带 body 的 POST 实为 **9** 发)
                    与 `probe-regrow.mjs` / `probe-regrow.txt`(切档后旧译文是否重译那一档)、快照原文 `snap-web-1006-r10.json`、
                    截图 **13** 张 `shots/60-engine10-01-出厂keyless.png` ~ `66-engine10-07-注册行贴标签-{百度,腾讯,阿里}.png`(五档逐档 + 空凭据/已存/已清除/收尾出厂 + 那处「注册链接被推到行尾」的前后两张),
                    两份浏览器 profile `chrome-profile-engine10/` / `chrome-profile-regrow/`,以及旧夹具备份 `bak/trans-official.json.round9`(第九轮那一份「只登记百度」的 `trans-official.json`,现拆成 `test/fixtures/trans-{baidu,tencent,aliyun}.json` 三份)。
                    ★ 第十一轮留的(A:自带中文探测 + 结构化段表,**新增出网为零**,探针那几发的账见 spec §9.1):探测与读数 `probe-zh-section.mjs` / `probe-zh-section.txt`(那篇真 README 的分段现场)、
                    `probe-zh-scan.mjs` + `probe-zh-scan.txt` / `probe-zh-scan2.txt`(榜面 78 行候选池扫描,两轮)、`probe-zh-ratio.mjs` / `probe-zh-ratio.txt`(CJK 个数 vs 占比那条律的对照)、
                    `probe-desc-zh.txt`(描述侧中文频次,0 发);★ 名字相近但**不是本轮的**:`probe-repo-zh.mjs` / `probe-repo-zh.txt` 与 `probe-zh-ratio.mjs` / `probe-zh-ratio.txt` 是 10-05 详情那一层的旧探针(mtime 10-05 12:3x),别当第十一轮的读数引;
                    ★ `probe-zh-fixture.mjs`(计划把 `QwenLM/Qwen` 抓成真夹具,**按"认围栏"口径重跑后那段中文其实是代码注释 ⇒ 命中侧退回零样本、没落盘**,这一发的出网数**没留档**,是本轮唯一的读数缺口,spec §9.1 如实登记);
                    合成夹具生成器 `make-zh-fixture.mjs`;文档读数探针 `probe-zh-readings.mjs` / `probe-zh-readings.txt`(**零出网**:假 fetch 吃夹具走真 `fetchRepoDetail`→`repoView`→`applyZh`,实测编排 3 发 / 载荷两侧各 21 键 / 段表形状);
                    证伪电池 `r11-falsify.mjs` + 输出原文 `r11-falsify-out.txt`(**13 条 / 未抓到红 0 条**,四个源文件跑完逐字节等于备份,末行 `[还原 ok]`)、逐套复跑读数 `rerun-r11.txt`(`SKIP_LOCAL=1` 下 350/0/2)。
                    ★ 这一轮**没有真机截图**(详情弹框重排要重启宿主才能看,没点头 ⇒ 图与逐段 rect 都欠着,见 spec §9.3 第十一轮那条)。
                    ★ 第十二轮留的(撤废话 + 详情缓存时长,**新增出网为零**):证伪电池 `r12-falsify.mjs` + 输出原文 `r12-falsify-out.txt`(10:23)与 `r12-falsify-out2.txt`(10:3x 复跑,逐行一字不差)
                    (**19 条 / 未抓到红 0 条**,退出码 0,六个源文件跑完逐字节等于备份、末行 `[还原 ok]`;首跑那条"跨行锚点只吃半句"的缺陷已补锚并给电池加了一档「植入改坏源文件」的显式读数,**那一遍的原始输出没留档、被修好后那一遍覆盖**)、
                    逐套复跑读数 `rerun-r12.txt`(`SKIP_LOCAL=1` 下 354/0/2,直跑 355/1/0,挂的仍是 `wt-27` 那发真出网的 429);**10:3x 为核对文档同步又离线复跑一遍 ⇒ 仍是 354/0/2,与 `rerun-r12.txt` 一字不差**。
                    ★ 一次事故如实登记:同步 `docs/design-spec.md` 时误用**整文件写入**把它截成 416 字节,已从会话历史快照逐字节还原(1695 行 / 257,462 字节),
                    **代价是那一窗口内先做的 8 处第十二轮同步全部丢失、随后重做**(现在的规格文档是重做后的那份,含第十二轮 31 处口径)⇒ 教训落进记忆:**大文档只用逐处替换,永不整写**。
                    ★ 与第十一轮同样:**这一轮也没有真机截图**(`index.js` 动了装配半边 ⇒ 要看效果得重启 dsh desktop 宿主;详情弹框那一屏 + 设置页新加的「详情缓存」那一行**并成一次走查**,图与逐段 rect 仍欠着)。
                    ★ 第十三轮留的(修「存储不可用」事故,**零出网**):真库存只读探针 `probe-storage-open.mjs`(吃 `C:/Users/<本机用户>/.dsh/storages/gh_trending.json` 的真行过 `GHT_DOMAIN.tables[t].valueSchema.parse`,
                    读数 `六表 239 行 / 读不出 0 行` + 自证 prefs 缺 `repoCacheHours`、repo 缺 `readmeSection`、trans 缺 `engine`;★ **只报行数与缺哪一格,绝不打印行值**)+
                    复跑读数 `rerun-r12-fix.txt`(`SKIP_LOCAL=1` 下 **355/0/2**,与探针末行同档)+ 电池扩条后的输出 `r12-falsify-out3.txt`(**20 条 / 未抓到红 0 条**,末行 `[还原 ok]`)。
                    ★ 同一遍里探针首版被抓出的一处**空输出冒充读数**(拿 `valueSchema.shape` 数声明键,而 `record()` 不暴露 `shape` ⇒ "缺的声明键 无"是假的),已改成从 `parse` 结果读并拿"改坏成 required"那一发验它真会红。
                    ★ 第十四轮留的(名次徽章分档,**零出网**):无头几何探针 `probe-rank.mjs`(CSS 逐字抠 `client.js`、`RankBadge` **函数本体抠出来跑**、`<colgroup>` 与表头从 `BoardCard` 源码逐条读 ⇒ 它自己拒绝为对不上的脚手架出数)
                    写出页面 `shot-rank.html` + 图 `shots/67-rank-medals.png`;复跑读数 `rerun-r14.txt`(`SKIP_LOCAL=1` 下 **356/0/2**);
                    证伪电池 `r14-falsify.mjs`(只圈 `client.js`)两份输出 `r14-falsify-out.txt`(7 条 / 未抓到红 0 条)与 `r14-falsify-out2.txt`(同 7 条,多打**是哪一头断言抓到的**)。
                    ★ 同一轮删掉了 `make-rank-page.mjs`:它被 `probe-rank.mjs` 整件取代(同一份 `shot-rank.html` 留两个写主 = 两份真相)。
                    ★ 第十五轮留的(四件合并那一版,`api.github.com` 走查 10 发只读匿名 GET、翻译那四个域名 0 发):走查脚本 `shot-r15.mjs` + 读数全文 `r15-walkthrough.txt` + 宿主日志 `r15-host.log`;
                    图 3 张 `shots/68-r15-set-keyless.png` / `69-r15-set-host-llm.png` / `70-r15-detail-excerpt.png`(设置页两档各有几行开关 + 详情弹框那一屏);
                    第二路真回包两份 `r15-ocr-live.json` / `r15-ocr-live2.json`(同一仓库相邻两次 `refresh=1`,配额读数 55 → 51 就是"那一屏真发四发"的现场证据;★ 这条差值只在相邻两次之间作数);
                    ⚠️ `r15-ocr.json` 是**旧读数**(12:24 那个旧进程写进库的缓存行:`cached:true` + 节选恒 600 字),原样留着只为当"库里那行旧 ≠ 代码没生效"的对照,**别拿它当本轮证据引**;
                    复跑读数 `rerun-r15.txt`(`SKIP_LOCAL=1` 下 **366/0/2**)与 `rerun-r15-full.txt`(**不带 SKIP_LOCAL 的直跑 368/0/0**);
                    证伪电池 `r15-falsify.mjs` + 输出原文 `r15-falsify-out.txt`(**12 条 / 未抓到红 0 条**,五个源文件跑完逐字节等于备份,末行 `[还原 ok]`);
                    profile 备份 `bak/web-package.json.r15-before`(收尾 `cmp` 逐字节还原);一次性 DOM 探针 `probe-r15-dom.mjs` 与浏览器目录 `chrome-profile-r15/` 收尾已删(`tmp/` 现无残留)。
                    ★ 第十六轮留的(回执带请求号 + 同屏一条失败句只念一次,**两处改动本身零出网**):复跑读数 `rerun-r16.txt`(`SKIP_LOCAL=1` 下 **369/0/2**)与 `rerun-r16-full.txt`(不带 SKIP_LOCAL 的直跑 **371/0/0**;
                    ⚠️ 这一直跑里 `wt-27` 那条老的真口径用例**真的经代理朝免费接口发了一发** —— 本轮的出网数是这一发,不是新增的,别读成"本轮新接口通了");
                    证伪电池 `r16-falsify.mjs`(只圈 `lib/services/web-translate.js` 与 `lib/services/repo.js`,★ 其中 `repo.js` 那五条里的两条**另在 `client` 套件里各跑一遍**)+ 输出原文 `r16-falsify-out.txt`(**11 条 / 未抓到红 0 条**,末行 `[还原 ok]`,每条都带**是哪一句断言抓到的**)。
                    ★ 这一轮**没有真机截图,也没重启宿主**:那两屏(厂商回执行、摘要段只留段名)都要么吃真凭据、要么吃改过的库档位,动的会是用户自己的东西 ⇒ 屏上的读数暂时由 `wt-29` 最坏那一发(403 + 64 字顶满的号 + 约 700 字错误体,真走假 net)与 `client-55`(真渲染树数那句话出现几次)两份离线现场顶着;
                    顺带删掉本轮中途为"把两件旧账的原文捞回来"而从会话记录里导出的一份 `r16-asked.txt`(**不是读数**,内容全是聊天记录)。
                    ★ **第二十三轮留的**(明星仓库那一屏,产品侧出网 **1 发** = 落夹具那一发):形状 B 的**可交互原型** `proto-stars-tab.html`(几何读数写在文件里那一行 `#geo`,主区 1600/1280/956/760/692 五档实测 + 薄快照与全站高星两档;草图和 A 形状那份已删);
                    两张证伪电池 —— 客户端那版 `mutate-client-6.mjs`(**14 发 / 未拿到失败信号 0**,只圈 `client.js`,末行自查「还原逐字相同:是」)与宿主那版 `r23-stars-falsify.mjs`(**8 发 / 未抓到红 0**,圈 `lib/domain.js` / `lib/stores.js` / `lib/services/all-stars.js` / `lib/stars.js` / `client.js` 五个源,输出原文 `r23-falsify-out.txt`,末行 `[还原 ok]`);
                    逐套复跑读数 `rerun-r23.txt`(`SKIP_LOCAL=1` 下 **492/0/2**,基线 415 → **494**);★ 两发首跑没红的过程登记在 spec §9.2 本轮那条(一发是**断言空跑**、一发是**等价变异** ⇒ 修法都是亲手造矛盾的载荷 / 把状态挪到条件成立那一档,而不是放宽判据)。
                    收尾删掉本轮中途误建的一份 85 字节残留 `probe-stars.mjs`(内容只有一行 `import`,零引用、零读数,不是探针)。
                    ★ **同日「开启的时候默认拉取一次」那一遍留的**(产品侧出网 **0 发** —— 九发变异全打在假 fetcher 上):证伪电池 `r24-enable-falsify.mjs`(**9 发 / 未抓到红 0**,圈 `lib/api.js` / `lib/services/all-stars.js` / `lib/domain.js` 三个源,输出原文 `r24-falsify-out.txt`,末行 `[还原 ok] 三个文件跑完逐字节等于进来时`)与逐套复跑读数 `rerun-r24.txt`(`SKIP_LOCAL=1` 下 **502/0/2**,基线 494 → **504**)。
                    ★ 同日**第二条裁定「间隔内已拉过就不再拉」**那一遍留的(产品侧出网 **0 发** —— 九发变异全打在假 fetcher 与假库行上):证伪电池 `r25-fresh-falsify.mjs`(**9 发 / 未抓到红 0**,圈 `lib/domain.js` / `lib/services/all-stars.js` / `lib/api.js` 三个源,输出原文 `r25-falsify-out.txt`,末行 `[还原 ok] 三个文件跑完逐字节等于进来时`)与逐套复跑读数 `rerun-r25.txt`(`SKIP_LOCAL=1` 下 **512/0/2**,基线 504 → **514**);★ 电池首跑第 ② 发(把判据改成吃 `lastFetchAt`)**没抓到指定那条 ⇒ 等价变异**,过程与补的那条 2d 判据一并写在这里的读数列与 spec §9.2。
                    ★ **10-10 第三条裁定「那一档接上现译,条件判定加 `allStarsEnabled`」**那一遍留的(产品侧出网 **0 发** —— 九发变异全打在假 translator 与假库行上):证伪电池 `r26-starszh-falsify.mjs`(**9 发 / 未抓到红 0**,圈 `lib/board-zh.js` / `lib/api.js` **两个**源,输出原文 `r26-falsify-out.txt`,末行 `[还原 ok] 两个文件跑完逐字节等于进来时`)与逐套复跑读数 `rerun-r26.txt`(`SKIP_LOCAL=1` 下 **519/0/2**,基线 514 → **521**);★ 电池**首跑第 ③ 发报"没抓到"而套件里红的正是目标那条** ⇒ 是电池的期望串对不上用例标题(**改期望串不动判据**);另有「`api.js` 里那批行**读一次、两处用**」这一处结构约束**离线拿不到失败信号(等价变异)⇒ 没进电池**,两件都在这里和 spec §9.2 如实登记而不是假装验过。
                    ★ **第二十七轮补记**(那四件在上一版的这份清单里**漏登了**,这一遍接回来;产品侧出网 **0 发**,真出网只有两遍**只读**探针的 9 发匿名 GET):匿名 304 探针 `probe-detail-304.mjs` / 读数 `probe-detail-304.txt`(★ 三条路全支持 304、正文回 0 字节,而 **`x-ratelimit-remaining` 照扣 1** ⇒ GitHub 文档那句"304 不计入速率限制"被本机实测推翻)、schema 丢弃探针 `probe-schema-drop.mjs` / `probe-schema-drop.txt`(未声明的多余键被 `record()` 静默丢掉 ⇒ 撤那一格**零迁移**)、本机库存对账探针 `probe-r27-live-storage.mjs`(只读、零出网、一个行值都没打印)、证伪电池 `r27-detail304-falsify.mjs`(**13 发 / 未抓到红 0**,圈 `lib/services/repo.js` / `client.js` 两个源,输出原文 `r27-falsify-out.txt`)与复跑读数 `rerun-r27.txt`(**528/0/2**,基线 521 → 530;那份是**接完五套 import 之后**的,第一次全量跑有 5 套在 import 处 SyntaxError 的病历记在 spec §9.2,不是判据变红)。
                    ★ **第二十八轮留的**(详情那三枚手动按钮;产品侧出网 **0 发** —— 19 条编排用例与 15 发变异全打在替身 `fetchFull` 与替身翻译服务上):可交互原型 `proto-r28-detail-actions.html`(三枚按钮的常驻/置灰形状);编排层冒烟 `r28-smoke.mjs` / 读数 `r28-smoke.txt`(★ 那 11 节照出**一处隐式耦合**:`readRows` 与 `runOnce` 对同一张 `trans` 表用了两种键形状,生产没坏、靠表内部再归一一次);证伪电池 `r28-manual-falsify.mjs`(**15 发 / 未抓到红 0**,圈 `lib/services/full-readme.js` / `lib/services/repo.js` / `lib/api.js` / `client.js` **四个**源,输出原文 `r28-falsify-out.txt`,末行 `[还原 ok]`,支持 `node tmp/r28-manual-falsify.mjs 2 14` 只重跑某几发);逐套复跑读数 `r28-suites-1.txt` / `-2` / `-3`(`-3` 是键形状改动之后的那一份,含**两个来源**的回算)与全文 `rerun-r28.txt`;⚠️ 收尾那一遍另加一份 `r28-label-dups.mjs`(**查用例短号重号**的脚本:那一轮新写的三条详情判据错填成 `client-56 / 57 / 58`,与第二十一、二十二轮那三条撞短号 ⇒ 改判成 `client-64 / 65 / 66` 后**整把电池重跑**,撞号前的读数留在 `r28-falsify-out-before-rename.txt`、重跑的控制台原文在 `r28-falsify-rename-run.txt`)。
                    ★ **第二十九轮留的**(面板选中态落 `localStorage`;产品侧出网 **0 发**、取证全程只读):宿主安装包抽取器 `host-asar.mjs`(Chromium Pickle 头口径:偏移 4 = 跟随块长度、12 = 字符串长度、JSON 从 16 起,`filesBase = 8 + headerSize`;三种模式 `list` / `unpack` / `grep`,`grep` 把整块 121MB 读进内存再按 offset 区间映射回文件名)与抽出来的三个包 `host-asar/`(`dsh-client-ui-layout` / `dsh-client-ui-renderer` / `dsh-client-ui-sidebar-right`,**只读副本**,那是宿主的实现不是本插件的源码,别拿去改);
                    证伪电池 `r29-ui-state-falsify.mjs`(**10 发 / 未抓到红 0**,只圈 `client.js` 一个源,输出原文 `r29-falsify-out.txt`,末行 `[还原 ok]`)与逐套复跑 `rerun-r29.txt`(`SKIP_LOCAL=1` 下 **566/0/2**,基线 565 → **568**);★ 本轮踩到的 CRLF 与第十四件那条同族:`client.js` 盘上是 **CRLF**,电池里多行锚点必须先按文件自己的 EOL 拼(`EOL` / `nl()`),否则 ⑥⑦ 两发静默报"锚点在源码里找不到";
                    另有一份提交前复跑 `rerun-r28-precommit.txt`(**563/0/2**,那是第二十八轮那批改动提交前工作树的读数,用来确认本轮动手之前基线没被谁动过)。
                    ★ **第三十轮留的**(详情那两笔 bug 的修复;产品侧出网 **0 发**,取证 **10 发**全匿名、走系统代理,**没吃用户令牌**):现场取证 `r30-probe-cjk.mjs`(量出那一屏节选里 CJK 只有 **7** 个、闸门回 `{hit:true, via:"lang"}` ⇒ "开了摘要却没翻译"的那颗牙)与 `r30-probe-zh-file.mjs`(**走产品函数**两趟 **6 发**:第一趟 4 发裸取探到 `zh_file`、第二趟 2 发条件请求**全 304** ⇒ 库里那行被冻在 `en_default` 的现场复现);抓取原文 `r30-vs-readme.md` / `r30-vs-cn.md` / `r30-vs-cn-raw.md` / `r30-vs-cn-rawaccept.txt`(`debpalash/VoiceStudio` 的默认 README、根目录 `contents` 清单与 `README_CN.md` 那 10,615 字节,含两种 `Accept` 各一发,共 **4 发**);分支口径探针 `r30-branches.mjs`(★ 那**八形** `zhProbed` 的实际读数由它打出,`test/repo.test.mjs` 那条表驱动用例逐形对齐它、不凭猜);证伪电池 `r30-zh-probed-falsify.mjs`(**11 发 / 未抓到红 0 / 等价变异 1**,圈 `lib/services/repo.js` / `lib/api.js` / `client.js` / `lib/domain.js` **四个**源,输出原文 `r30-falsify-out.txt`,末行 `[还原 ok] 4 个源文件跑完逐字节等于进来时`,支持 `node tmp/r30-zh-probed-falsify.mjs 7` 只重跑那一发)与全量复跑 `rerun-r30.txt`(`SKIP_LOCAL=1` 下 **571/0/2**,基线 568 → **573**)。
                    ★ **第三十一轮留的**(详情缓存那一档摆回来 + 60 秒窗口整键删 + 落款回两截;产品侧出网 **0 发**、**零新增探针** —— 304 照扣 1 配额那份读数 10-10 已由 `probe-detail-304.txt` 证过,本轮只是把它从"反驳 GitHub 文档"变成"支撑用户裁定"):代码位扫描 `scan-cache-keys.mjs`(抹掉注释后扫哪几个文件认得 `repoCacheHours` / `cacheHours` / `repoCacheTtlMs` 那一串 ⇒ 输出**六个文件**:`client.js` / `index.js` / `lib/api.js` / `lib/domain.js` / `lib/services/repo.js` / `lib/stores.js`,给 `hc-20` 那条白名单当**独立来源**,判据里不手抄清单);证伪电池 `r31-ttl-falsify.mjs`(**10 发 / 未抓到红 0 / 等价变异 0**,圈上面那六个源,输出原文 `r31-falsify-out.txt`(全文 11 条 `FAIL`:只有 ⑦ 一发红 2 条),末行 `[还原 ok] 6 个源文件跑完逐字节等于进来时`,同样支持 `node tmp/r31-ttl-falsify.mjs 7` 只重跑那一发);全量复跑 `rerun-r31.txt`(`SKIP_LOCAL=1` 下 **572/0/2**,基线 573 → **574**)+ 逐套全文留档 `suites-r31/`(15 个文件 —— 第三个来源数的是**它们**的 `^ok`,不是那份摘要);★ 本轮踩到的坑与第二十二轮那条"漏网有两种"同族:电池 ③ 那发最初圈 `test/repo.test.mjs`,而那套件**不 import `index.js`** ⇒ 变异结构上拿不到失败信号,改指 `host-compat` 后**整把十发重跑**,过程写在 `r31-falsify-out.txt` 与上面第三十一轮那段。
                    ★ **第三十二轮留的**(项目收藏那一屏;产品侧出网 **0 发**、**零截图**):原型两份 `r32-fav-proto.html`(那一枚 ☆ 摆在哪一列、那一屏八列长什么样的**单文件零依赖原型**,用户回「可以」收下三条推荐)与 `r32-fav-proto-live.html`(同一屏吃真载荷形状的那一份);取证探针 `r32-domain-probe.mjs`(那几份名单/句子/`favRecord` 的当场读数)与 `r32-api-probe.mjs`(★ 真装配 + 假 fetch 走 `POST /api/fav` 四形:切片内的日榜行 / **切片外**那一形 / 明星那一批 / 四路都没有 ⇒ 打印出处与五格读数;**这份的标签错过一次**,`topN:2` 被 `clampPrefs` 兜回出厂 15、那条"切片外"其实在切片内,改成 `topN:5` + 七行才验到,见上面第三十二轮那段),合并读数 `r32-probe-out.txt`;代码位扫描仍用 `scan-cache-keys.mjs`(本轮只作**零出网对账**,认得那串键名的文件数没变);证伪电池 `r32-fav-falsify.mjs`(**22 发 / 未抓到红 0 / 等价变异 1**,圈 `client.js` / `lib/favs.js` / `lib/domain.js` / `lib/api.js` / `lib/stores.js` / `index.js` **六个**源,输出原文 `r32-falsify-out.txt`,末行 `[还原 ok] 6 个源文件跑完逐字节等于进来时`,★ 本轮起植入前先做**锚点唯一性预检**,支持 `node tmp/r32-fav-falsify.mjs N…` 只重跑指定那发);全量复跑两份 `rerun-r32-step4.txt`(步骤 4 落地后那次)与 `rerun-r32-step8.txt`(收尾复跑,`SKIP_LOCAL=1` 下 **624/0/2**,基线 574 → **626**、套件 15 → **16**,末尾两行是两个独立来源的交叉核对)。
                    ★ **第三十三轮留的**(收藏那一屏接上本机已有的那一份中文;产品侧出网 **0 发**、**零新增额度**、**零截图**、**零新增探针** —— 本轮没有从真 GitHub 或厂商接口取任何新数,两根钉子(`morluto/rea` 不在内置表、判据钉的确实是「不派」)靠的是 `grep -c` 与测试文件行号):证伪电池 `r33-desc-zh-falsify.