# 〖共创稿事节〗HarmonyOS 7 新特性实战(68):backend 门禁 8 红拍板——worktree 回基线取证,三处改钉、两处刷新、两处起服

> 本篇是系列第 68 篇,兑现任务板上挂了近一个月的欠账:「8 项 backend 门禁失败(未拍板)」。结论先说:6 红里没有一个是「修代码」能单独解决的——3 处是钉点过期(改钉保意图),2 处是审读基线过期(复读刷新),2 处根本不是内容问题(先起 mock 服务再谈红绿)。凑不回 8 是因为其中 2 处在第 64 篇的内容修复里已经顺手收掉,账本没记。收口后 backend 套件 12/12、应用侧 54/54、HAP 构建同日通过。

一、欠账对账:8 红从哪来,怎么变成 6 红

这笔欠账难办的地方在于:任务板上只记了一个数——「8 项 backend 门禁失败(未拍板)」,没有名单、没有日期快照。要拍板,先得还原当时的盘面。

办法是 git worktree:把仓库在 2026-10-13 当天最后一个提交上展开成独立工作树,12 项门禁照跑一遍。它不碰主工作区,跑完即删,是给历史盘面取证最干净的工具(git 官方文档对 worktree 的定义只有一句:管理多个工作树):

git worktree add %TEMP%\h7-69-baseline be36b13
# 在 backend\scripts 与 backend\mock-api\scripts 各跑一遍 verify-*.mjs,记录 PASS/FAIL
git worktree remove %TEMP%\h7-69-baseline --force

复跑结果:内容类 7 项直接报红,名单与欠账高度吻合。两个走 mock 服务的门禁需要服务在场才可比——本机服务加载的是主工作区当前内容,跨提交对照会失真,所以拍板口径以「本次开工实测」为准。三个时点摆在一起,账就对上了:

时点盘面说明
2026-10-13 欠账记入4 PASS / 8 FAIL只记了数,没记名单
基线提交复跑(be36b13)7 项内容红复现含 batch2 两项——正是第 64 篇当日修复的对象
2026-11-09(第 64 篇)8 红 → 6 红鹿蜀钉点改写、相柳边界句恢复,batch2-pilot-content 与 rich-beast-depth 随之转绿,账本未记
2026-11-10 本次开工6 PASS / 6 FAIL拍板对象,下文逐条处置

backend 门禁老账三时点对账:8 红如何变成 6 红

差额本身是个教训:第 64 篇修复内容时顺手让两道门禁转绿,但任务板上的「8 项」没动——欠账只增不减的账本,会让后来者把已经还掉的钱再还一遍。

二、三处钉点过期:改钉保意图

6 红里有 3 处是同一类:钉点门禁断言「定稿必须包含某句话」,之后的审读改写了措辞,句子走了、事实还在。断言撞上的第一堵墙是白泽:

// verify-baize-reader-narration.mjs:旧钉断在 detail 上,审读后早已不匹配
assert.match(baize.detail, /把所述内容绘录成图/);
// 2026-11-10 改钉:detail 现用语是「一场问答与随后的图写」;
// 对账时发现「绘录成图」的事实句并未消失,只是挪进了 readingNote——随行补钉防再丢。
assert.match(baize.detail, /一场问答与随后的图写/);
assert.match(baize.readingNote, /将这些内容绘录成图/);

对账时特意查了旧短语的下落:它没有从语料里消失,而是从 detail 挪到了 readingNote(「黄帝命人将这些内容绘录成图,传示天下」)。这决定了拍板方向——不是删钉,而是把钉子钉到事实现在住的字段上,一处两钉。

应龙是同一模式的两个变体:detail 的悬念句被改写成新问法,knowledge 的「故」字讲解句换了措辞;readingNote 则原封未动,维持原钉。穷奇那处在连环修订门禁里:出处对照句从「另写穷奇状如虎、有翼」改成「另有状如虎、有翼的穷奇」,出处事实不变:

对象旧钉(过期)现文(事实仍在)新钉
白泽 detail把所述内容绘录成图一场问答与随后的图写一场问答与随后的图写
白泽 readingNote——(未钉)将这些内容绘录成图将这些内容绘录成图(新增)
应龙 detail / knowledge没有说明不能返回的原因 / 「故」才明确……相接「不能再回到天上」之后发生了什么 / 才把不能复上与下界屡旱连起来按定稿措辞重钉
穷奇(连环修订)《海内北经》另写穷奇状如虎、有翼《海内北经》另有状如虎、有翼的穷奇《海内北经》另有状如虎、有翼

改钉有一条底线:新钉必须保住旧钉的意图。旧钉防的是「图写」「出处对照」「因果关节」这三个事实从文案里消失,新钉逐条对应,一句不少。应龙与穷奇两处的落点如下——注意应龙的 readingNote 逐字未动,原钉维持,改钉只动过期的:

// verify-yinglong-reader-narration.mjs
// 2026-11-10 改钉:detail 改问「“不能再回到天上”之后发生了什么」,同一悬念重心的现用语。
assert.match(item.detail, /“不能再回到天上”之后发生了什么/);
// readingNote 未改动维持原钉;knowledge 的「故」句按定稿措辞重钉。
assert.match(item.readingNote, /东北隅交代开篇山名的方位,南极交代应龙的处所/);
assert.match(item.knowledge.content, /才把不能复上与下界屡旱连起来/);

// verify-sequential-reader-revisions.mjs
// 2026-11-10 改钉:审读后定稿为「另有状如虎、有翼的穷奇」;出处对照事实不变。
assert.match(allText('beast_qiongqi'), /《海内北经》另有状如虎、有翼/);

三处钉点过期的改钉对照:句子挪字段、换措辞,事实不丢

三、审读基线刷新:两层哈希的过期与复读

第 4 红是审读门禁:ShanhaiMockData.ets: 公共文本快照缺失或已变化。这套机制值得展开,因为它防的正是第二节的这种漂移——基线文件里存了两层哈希,都基于 Node.js crypto 的 createHash 计算:一层是 9 个公共文案文件的全文 sha256,一层是 36 篇异兽内容的全对象哈希(键序无关、文字或值一变即失效)。对账函数逐层核对:

for (const path of expectedFiles) {
  if (snapshot.publicFiles?.[path] !== sha256(publicFiles[path])) problems.push(`${path}: 公共文本快照缺失或已变化`);
}
for (const item of items) {
  const row = entries.find(entry => entry.beastId === item.beastId);
  if (row.sha256 !== articleHash(item)) problems.push(`${item.beastId}: 内容变化,需重新审读`);
}

刷新前先回答一个问题:基线之后变了的文本,变对了吗?逐处核对后确认两处过期,性质不同。

第一处是公共文件层。ShanhaiMockData.ets 的工作区里躺着一行未提交改动,正是第 66 篇立的术语门禁(套件第 53 项)钉住的那类修订:

-    content: '……还可以继续认识猼訑、陆吾与开明兽;收录这条路线的全部神兽后,再到山海护照查看昆仑印章。',
+    content: '……还可以继续认识猼訑、陆吾与开明兽;发现这条路线的全部神兽后,再到山海护照查看昆仑印章。',

这句话已经被第 53 项门禁逐文件钉住,再做候选扫描零命中——合法修订,基线哈希随之刷新(5e704eaa… → c3b36cc9…)。

第二处是内容层:beast_xiangliu: 内容变化,需重新审读。来源明确——第 64 篇当日恢复了相柳故事卡被误删的审读边界句,内容变了,基线里的逐篇记录却停在 10 月 13 日。处理走流程而不是改数字:候选扫描 0 命中后,该篇重记 reread_passed、reviewedOn 更新到当日,引用出处字段保持原有报告引用不变。

审读基线的两层哈希:公共文件层与逐篇内容层,各自的过期成因与复读刷新

四、两处环境依赖:先起服务再谈红绿

最后 2 红的报错长得完全不同——不是断言失败,是 ECONNREFUSED:连接本机 3199 端口被拒。这两个门禁验的是 HTTP 契约:详情 36、卡片 72、主题 144 走接口逐一核对,服务不在场就谈不上红绿。这类红和内容红必须分开拍板,混在一起会把「环境缺条件」误判成「文案出问题」:

cd backend\mock-api
$env:PORT='3199'; node server.mjs
# verify-curator-topic-content.mjs
#   PASS curator topic contract: 白泽四主题正文去前缀/标题后两两不同,并各自命中对应主题正文。
# verify-rich-beast-content-v3.mjs
#   PASS rich API content: 36 details and 72 reading cards match active canonical copy
#                        (2026.09.14-v4.13-sequential-reader-revision).

起服即绿,内容零改动。拍板结论:这两项的「失败」从第一天起就是运行条件缺失,值得改的只是跑门禁的前置说明——先把服务拉起来,再看红绿。至此六红的处置口径全部分清,三类红的修法互不可替代:

红的类型断言形态处置不可混淆的理由
钉点过期(×3)正则 / 子串断言失配改钉保意图删钉等于放弃事实防回归
基线过期(×1 门禁两层)哈希对账失配复读后刷新记录只改数字会把证据变成橡皮章
环境依赖(×2)连接失败,非断言起服务补条件当内容红去修会误伤正确文案

五、收口与反向验证

六红处置完毕,三套证据同日复跑:backend 套件 12/12 PASS(2026-10-13 以来第一次全绿);应用侧套件 54/54 PASS 无回归;HAP 构建 BUILD SUCCESSFUL in 34s 971ms(25 executed / 8 up-to-date)。

改钉和刷新这类操作自己也可能出错,所以照例做反向验证——故意把事情改坏,看门禁叫不叫:

反向用例操作预期实测
旧钉复活白泽新钉换回 /把所述内容绘录成图/报红AssertionError,正则失配如实报出
基线哈希篡改快照里 ShanhaiMockData 哈希改成 64 个 0报红「公共文本快照缺失或已变化」逐字报出
还原后复跑恢复新钉与原快照全绿12/12 PASS

六红拍板总览与收口复跑:12/12 与 54/54

复跑项结果
backend 套件(scripts 9 项 + mock-api 2 项 + 审读 1 项)12/12 PASS
应用侧全量门禁套件54/54 PASS,无回归
HAP 构建BUILD SUCCESSFUL in 34 s 971 ms(25 executed / 8 up-to-date)
反向验证2 组报红均成立,还原后复绿

拍板清单沉淀成三分法,下回再遇到门禁红,先分类再动手:钉点过期(事实还在、措辞变了 → 改钉保意图)、基线过期(合法修订未重记录 → 复读刷新,流程走完不改数字)、环境依赖(服务或条件缺失 → 补条件,不碰内容)。任务板上与此欠账并列的「来源卡 → 出处」措辞一项,核对后确认早在第八轮已收口(应用侧全文 0 命中,规则库保留为侦测词),属账本残留,一并清账。剩下的 UX 自检遗留(状态栏、挖孔区各 1 例低频)留给下轮自检观察,不在此篇展开。

收个尾

这笔欠账挂了近一个月,期间三次全量复跑都路过它,三次都以「与基线一致、非本次引入」为由放行。放行有当时的道理——每轮改动确实没引入新红——但「没变坏」和「拍板」是两回事。这次真正的产出不是改掉的几行:三处改钉、两处刷新、一次起服,而是把门禁红拆成了三类,每类有了可复用的处置路径;账本也顺手正了本清——第 64 篇顺手收掉的两红补记在案,第八轮就已收口的「来源卡」措辞移出仍欠。门禁全绿不是终点,名单可追溯、差额有解释,账本才配得上「已拍板」三个字。下一篇见。

证据清单

  • 钉点改钉:backend/scripts/verify-baize-reader-narration.mjs、verify-yinglong-reader-narration.mjs、verify-sequential-reader-revisions.mjs(改钉原因与日期随行注释)
  • 基线刷新:docs/development/reader-copy-review-2026-10-13.json——ShanhaiMockData.ets 哈希 5e704eaa… → c3b36cc9…;beast_xiangliu 重记 reread_passed / reviewedOn 2026-11-10,引用出处字段保持原报告引用
  • 历史盘面取证:git worktree 于基线提交 be36b13 复跑 12 项门禁(取证后工作树已删)
  • mock 服务:backend/mock-api(PORT=3199,node server.mjs),两个 HTTP 契约门禁起服即绿
  • 全量复跑:backend 12/12 PASS · 应用侧 54/54 PASS(2026-11-10);HAP 构建 BUILD SUCCESSFUL in 34 s 971 ms(25 executed / 8 up-to-date)
  • 欠账出处:第十六轮任务板「仍欠」条目与第八轮「4 PASS / 8 FAIL」记录
  • 系列前置:第 64 篇(详情层去重与 batch2 内容修复)· 第 66 篇(术语钉点门禁,套件第 53 项)· 第 67 篇(生僻字覆盖对账,套件第 54 项)
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐