diff --git a/.dsh/skills/board-ui-nav/.gitignore b/.dsh/skills/board-ui-nav/.gitignore new file mode 100644 index 00000000..ea76404e --- /dev/null +++ b/.dsh/skills/board-ui-nav/.gitignore @@ -0,0 +1,6 @@ +# 台架存证目录(`--walk` 的截图/步迹、抓屏帧、录波样本) +# +# 这些是**跑出来的产物**,不是技能源码:能重跑、要按窗口覆盖、体积大, +# 一律不入库(与 `ci-artifacts/` 同一判据,见仓库根 `.gitignore` 那段注释)。 +# 放进技能目录是为了让「谁的证据跟谁走」,而不是随手丢在仓库根的杂物堆里。 +artifacts/ diff --git a/.dsh/skills/board-ui-nav/SKILL.md b/.dsh/skills/board-ui-nav/SKILL.md index bf011fdf..d69302aa 100644 --- a/.dsh/skills/board-ui-nav/SKILL.md +++ b/.dsh/skills/board-ui-nav/SKILL.md @@ -68,6 +68,7 @@ whenToUse: 需要上真机/台架进某页面看图(如故障录波、回放 - 本脚本不申请锁、不碰串口与烧录;锁的取还见 task-worktree 技能 (`lock acquire bench --task `)。 -- 台架证据只进 `ci-artifacts/`(`--walk` 默认 `ci-artifacts/uinav/walk/`,与 BOARD_TRUTH - 读取目录已并一),不进工作树。 +- 台架证据只进本技能目录下的 `artifacts/`(`--walk` 默认 + `.dsh/skills/board-ui-nav/artifacts/uinav/walk/`,与 BOARD_TRUTH 读取目录已并一),不进工作树: + 该目录由同目录 `.gitignore` 排除,与 `ci-artifacts/` 同一判据(跑得出来、按窗口覆盖、体积大)。 - UI 源码改动的前后回归是 ui-verify 技能(5 门禁),本技能只管"人到板上去看"。 diff --git a/docs/UI设计/UI_自动化测试流程.md b/docs/UI设计/UI_自动化测试流程.md index 4aa4e568..082abaf6 100644 --- a/docs/UI设计/UI_自动化测试流程.md +++ b/docs/UI设计/UI_自动化测试流程.md @@ -180,9 +180,10 @@ cmake --build simulator/build --config Debug # 0) 构建模拟器(须 0 警 板子注入了按键,而那时台架属于验收窗的准备方。「必须持锁」写在文档里防不住「我只是跑 一下」,所以把确认做成命令行参数:要动真机,就得在命令行里留下字面证据(脚本不代取锁, 也不替人判断「应该没人在用」)。 -- **存证不进工作树**:`--walk` 的帧默认落 `ci-artifacts/uinav/walk/`(版本控制之外), - `--outdir` 可改;给的路径若落在版本控制内(且不在 `ci-artifacts` 之下),脚本**直接拒绝 - 执行**并退出 3。理由与提交门禁同一条:产物一旦写进工作树,`git status` 就不再是判据, +- **存证不进工作树**:`--walk` 的帧默认落技能目录下的 + `.dsh/skills/board-ui-nav/artifacts/uinav/walk/`(该目录 `.gitignore` 已排除,版本控制之外), + `--outdir` 可改;给的路径若落在版本控制内(且不在忽略区:存证根或 `ci-artifacts` 之下), + 脚本**直接拒绝执行**并退出 3。理由与提交门禁同一条:产物一旦写进工作树,`git status` 就不再是判据, 而「记得删」只防得住记得的人。 - 步迹只在 `--trace <路径>` 给出时落盘;认错那一屏只在 `--dump-fail <目录>` 给出时留存—— 两者都指到 `ci-artifacts/` 下,窗口结束把工作目录交回来时工作树仍是干净的。 @@ -246,9 +247,8 @@ cmake --build simulator/build --config Debug # 0) 构建模拟器(须 0 警 写路径;`clear`/`reset` 主机与固件双侧默认拒绝(直开即到达可执行态,没有第二段确认的 余地)。MCU 侧要拿到 bench 能力须临时给 `MDK-ARM/STM32F407-Demo.uvprojx` 加 `DTU_BENCH` 宏烧录,测完**必须还原宏并重烧产品构建**(uvprojx 抖动不入库,同构建节律)。 -- **留档帧目录已并一**:`WALK_DIR` 与 `--walk` 存证目录同指 `ci-artifacts/uinav/walk/` - (#69 前指 `ci-artifacts/uiwalk/`,走的新帧 BOARD_TRUTH 段永远读不到,静默"跳过(无 - 留档)")。 +- **留档帧目录已并一**:`WALK_DIR` 与 `--walk` 存证目录同指存证根下的 `uinav/walk/` + (`#69` 之前两者分指不同目录,走的新帧 BOARD_TRUTH 段永远读不到,静默"跳过(无留档)")。 - **实机验证记录(2026-11-02 台架,两档实烧,输出全文贴在 PR #70 的台架证据评论)**: bench 档(`fw build: Nov 2 2026 22:25:12`)上 STATUS 首答 `{kind=MENU depth=0 path=[0] sel=[0]}`;GOTO `wave_play` 一次往返到达——#38 那趟"进故障录波看波形"的级联盲走就此降为 diff --git a/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md b/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md index b8de34e2..29ace3a2 100644 --- a/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md +++ b/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md @@ -143,7 +143,7 @@ flowchart LR - [ ] `FILLER.BIN` 已从 `/` 删除;`/WAVE` 里**只剩真实段**(坏段样本若留着,在 `docs/子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」里点名它是坏段,回放页翻到必须显拒收态——留着当常设负样本也行,二选一并记录) - [ ] 标定与定值按**决定二**处置完毕,处置结果已写进 `docs/子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」的后续小节 - [ ] 设备跑的是**产品构建**且启动锚点全过;UI 停在主菜单;两把锁(build/bench)空闲 -- [ ] 现场记录表数值入档、抓屏证据归档到会话的 `ci-artifacts/wavebench/`,`docs/子系统设计/故障录波设计说明.md` §10 状态同步更新 +- [ ] 现场记录表数值入档、抓屏证据归档到会话的 `.dsh/skills/board-ui-nav/artifacts/wavebench/`(忽略区,不入库),`docs/子系统设计/故障录波设计说明.md` §10 状态同步更新 ## 8. 出问题怎么办(三条,都别硬试) diff --git a/scripts/board_ui_nav.py b/scripts/board_ui_nav.py index a797f519..801daea1 100644 --- a/scripts/board_ui_nav.py +++ b/scripts/board_ui_nav.py @@ -26,7 +26,7 @@ 按 s/l 无效、要按 e 才进菜单,2026-10-26 task-24 台架实测) --board / --walk 属真机动作:必须另加 --i-hold-bench-lock 显式确认已持 bench 锁, 否则直接拒绝(退出码 3,不碰网络)——台架是独占资源,脚本不替人判断有没有在用。 - --walk 的存证目录默认在 ci-artifacts/uinav/walk(版本控制之外),--outdir 可改; + --walk 的存证目录默认在 .dsh/skills/board-ui-nav/artifacts/uinav/walk(版本控制之外), 落在版本控制内会被直接拒绝——台架证据不进工作树,工作树才能保持干净可比对。 2026-10-31 板级远程半轮补三条(本文件当这三条的纪律属主;事实现场见 docs/子系统设计/故障录波设计说明.md §10「板级远程半轮记录」): @@ -78,9 +78,13 @@ REPO = os.environ.get("DTU_REPO_ROOT") or os.path.abspath(os.path.join(HERE, os. HARNESS = os.path.join(REPO, "simulator", "tests", "check_content_pages.py") SIM_EXE = os.path.join(REPO, "simulator", "build", "Debug", "lvgl_sim.exe") MENU_TREE = os.path.join(REPO, "ui_menu_tree.txt") +# 台架存证根:跟着技能走(.dsh/skills/board-ui-nav/artifacts/,该目录 .gitignore 已排除)。 +# 这些是**跑出来的产物**(截图/步迹/抓屏帧),能重跑、按窗口覆盖、体积大,一律不入库; +# 判据与仓库根 .gitignore 里 ci-artifacts/ 那段一致。 +STORAGE_ROOT = os.path.join(REPO, ".dsh", "skills", "board-ui-nav", "artifacts") # 真机留档帧目录:不在版本控制里(各次台架各自的产物),缺就跳过那一段并说明 -WALK_DIR = os.environ.get("DSH_UINAV_WALK") or os.path.join(REPO, "ci-artifacts", "uinav", "walk") -# 2026-11-02 #69:原默认 ci-artifacts/uiwalk 与 --walk 的存证目录 uinav/walk 两处不一—— +WALK_DIR = os.environ.get("DSH_UINAV_WALK") or os.path.join(STORAGE_ROOT, "uinav", "walk") +# 2026-11-02 #69:原默认 uiwalk 与 --walk 的存证目录 uinav/walk 两处不一—— # 每次台架走新帧,BOARD_TRUTH 那段永远读不到(静默"跳过(无留档)"),两处并一。 # 轨迹/失败帧**默认不写进仓库**:只有 --trace / --dump-fail 显式给了路径才落盘 # (判据脚本自己在提交门禁里跑,顺手往 scripts/ 写 json 就是把工作树弄脏) @@ -1052,7 +1056,7 @@ class Navigator(object): # ---------------------------------------------------------------- 自检与入口 -# Lead 大窗留档帧(ci-artifacts/uiwalk/)的身份。 +# Lead 大窗留档帧(artifacts/uiwalk/)的身份。 # ⚠ 右边的期望值**不是照抄文件名**:本表按"认屏结果应当是什么"来写,实测证据是 # 文件名声称到达的 9 个态里只有 3 个真是那个态(00 根 / 01 装置信息 / 02 交流量), # 其余 6 帧的墨量与内容说明它们停在别处——03 是**菜单级联**(ink 4961、没有页标题)、 @@ -1442,7 +1446,7 @@ def main(argv): ng, badg = selftest_safety_gates(clf) print("汇总:黄金参考 %d 帧错 %d;留档帧 %d 帧错 %d;闭环 %d 页失败 %d;硬闸用例 %d 条错 %d" % (nr, len(badr), n, len(bad1), m, len(bad2), ng, len(badg))) - # 留档帧目录(ci-artifacts/uiwalk,不受版本控制)可以不存在 → 那一段不算失败; + # 留档帧目录(artifacts/uiwalk,不受版本控制)可以不存在 → 那一段不算失败; # 但黄金参考与闭环必须真跑过:任一为 0 说明这次"自检"其实什么都没检查 return 1 if (badr or bad1 or bad2 or badg or nr == 0 or m == 0 or ng == 0) else 0 if "--walk" in argv: @@ -1451,22 +1455,22 @@ def main(argv): return rc # 台架窗口用:一条命令走完菜单树上**所有绑定页**,每页存一帧 + 一份轨迹。 # 之所以要"一条命令",是因为 5 分钟窗口里没时间让人逐页手按;跑完只需把 - # 存证目录(默认 ci-artifacts/uinav/walk/)与 --trace 落下的步迹交给 Lead, + # 存证目录(默认 artifacts/uinav/walk/)与 --trace 落下的步迹交给 Lead, # 判据失败在哪一屏、当时认出的是什么都在文件里,不用现场再猜。 pid = None # 存证**必须落在版本控制之外**。第一版写 HERE/walk = <仓库根>/scripts/walk/,等于 # 把台架产物写进工作树:git status 立刻脏、done 的并集残留审计会把它当成任务遗留 - # 物,下一个窗口还盖掉上一个窗口的证据。默认落 ci-artifacts/uinav/walk/(已 - # gitignore,本仓台架产物一贯在此),--outdir 可改。 - # 反向拒绝:落在版本控制内且不在 ci-artifacts 之下就**直接不跑**——规矩一旦依赖 - # "跑完记得删",它就只防得住记得的人(这条道理同 bom-guard 的立项理由)。 + # 物,下一个窗口还盖掉上一个窗口的证据。默认落 artifacts/uinav/walk/(技能目录下已 + # gitignore),--outdir 可改。 + # 反向拒绝:落在版本控制内、又不在忽略区(台架存证根或 ci-artifacts)之下就**直接不跑** + # ——规矩一旦依赖"跑完记得删",它就只防得住记得的人(这条道理同 bom-guard 的立项理由)。 outdir = argv[argv.index("--outdir") + 1] if "--outdir" in argv else \ - os.path.join(REPO, "ci-artifacts", "uinav", "walk") + os.path.join(STORAGE_ROOT, "uinav", "walk") rp = os.path.abspath(outdir) if rp.lower().startswith(os.path.abspath(REPO).lower() + os.sep) \ - and ("ci-artifacts" not in rp.lower()): + and not any(seg in rp.lower() for seg in ("ci-artifacts", os.sep + "artifacts" + os.sep)): print("[FAIL] --walk 的存证目录不能落在版本控制内:%s" % rp) - print(" 默认 ci-artifacts/uinav/walk/;换目录请用 --outdir <忽略区里的路径>") + print(" 默认 %s;换目录请用 --outdir <忽略区里的路径>" % os.path.join(STORAGE_ROOT, "uinav", "walk")) return 3 print("⚠ --walk 直连真机:调用方必须已持 bench 锁;存证目录 %s" % rp) dev = BoardDevice()