Commit Graph

8 Commits

Author SHA1 Message Date
wandering1 4a4ad6bc5f chore(全仓): @build/@test 旧文档别名清退为技能调用名
现状口径:/keil-build 与 /serial-boot-test 是 DSH 会话的技能调用名,
不是 shell 命令;「名 + 命令行参数」的命令形态改为可执行体
run_boot_test.py 的真实调用。

- AGENTS.md:别名说明重写为「技能调用名不是 shell 命令」,两条目改
  「编译(/keil-build)」「串口回归(/serial-boot-test)」
- keil-build / serial-boot-test 两 skill 调用名与示例同步;task-worktree
  方案文档去掉 @build/@test 惯例从句;@task 保留(不在点名范围)
- 123 文件现状陈述全改;台架捕获、变更记录/时间线、rename 映射输入
  等 41 行历史证据保留旧名
- gen_memory_svg.py 6 处措辞随改,3 张 SVG 产物同批重跑
- 顺手补并行方案同行漏网计数 51→52 钩子

验证:提交期快钩子对 123 文件实跑全 Passed;check_doc_links --all
rc=0(3038 处、无法判定 0);check_mermaid --all rc=0;YAML 解析 52
钩子不变;skill-size rc=0;py_compile 全过;字节卫生零漂移。
2026-10-30 13:03:12 +08:00
wandering1 21c68521ff feat(task-worktree): 桥接 DSH worktree 插件——补共享联接、锁归属 pw:<name>、修释放不掉
诉求最初是升级 dsh-task-worktree:实测已装 0.4.6 = npm dist-tags.latest,无需升级;
真正的缺口是本仓 skill 看不见插件建的树(.dsh-worktrees/),故按用户追加指令把两套
系统接起来。回收方向刻意不打通:本 skill 永不删插件的树。

脚本 task_worktree.py:新增 plugin 子命令 list/adopt/unadopt,事实源是 git worktree
list(不是插件 manifest,免得被绕过);adopt 只补缺失的 .venv 与 simulator/SDL2
联接,已有联接跳过、实体目录绝不碰;锁归属用 pw:<name> 前缀;new 顺带提示另有 N 棵
插件树、不占活跃上限 3。
一并修一处真 bug:lock release --bench-pass 在任务无台账时先 EnvError 退出、锁释放
不掉,导致每个任务的 done 收口连坐失败;现在改为警告后仍然释放。

keil-build:default_lock_task() 增加 .dsh-worktrees/ 反推分支,插件树内的构建归属
pw:<name> 而不是兜底的 build-cli(主树行为未变,本次 @build 实测仍走 build-cli)。

.gitignore 预先忽略 .dsh-worktrees/,让插件的 ensureIgnored() 找到同一字面量、不再
改写这份受控文件。check_doc_links / check_layer_deps / gen_refgraph 三处扫描面同步
排除:仓里再放一份仓会让 doc-links 假红、并让生成的配图字节漂移到 generated-fresh。

文档:并行任务工作树方案新增 §3.4 两套系统边界对照;SKILL.md 加 §F 共存一节,同时把
§B 从 53 行压到 29 行(净 +39,用户此前在飞的改写已 rebase 保留、未被覆盖)。

验证:@build 0 错误 0 警告;scripts/ci_local.py 48 根提交期钩子与 gitlint 全绿;
check_doc_links --all --sections-strict 通过(2596 章节引用、无法判定 0);id-check-new
通过;改动文件字节体检无 BOM、CRLF 与 U+FFFD。桥接行为在临时 scratch 仓端到端跑过
(adopt 建两个 reparse、unadopt 只摘联接、pw 锁取放、缺台账也能释放、越界 name 退 2)。
2026-10-29 07:50:05 +08:00
wandering1 261bd9fd31 fix(keil-build): 定性并挡住 %SystemDrive% 字面量垃圾目录(并发会话在飞工作)
@build 与 fontTools 类脚本在残缺环境里起子进程时(run_code 的 Node
进程 process.env 为空),Windows known-folder 的**可展开串**展开不了
→ 变成相对路径,于是仓库根长出 %SystemDrive%/ProgramData/Microsoft/
/Windows/Caches/(约 1 MB 缓存的字面量复刻),它不是任何人在飞的改动。

- SKILL.md:新增「构建副产物」一节——症状 / 根因(三条现场证据)/
  清理(只用 bash 引号形态,明令禁止 rd /s /q %SystemDrive%,cmd 会
  把它展开成 C: 等于对系统盘下令递归强删)/ 两层防复发(.gitignore
  已入库 + 脚本守卫),并在坑表加一条速查
- keil_build.py +115 行:拉起 UV4 前 harden_windows_env() 回填缺失的
  SystemDrive/SystemRoot/ProgramData/USERPROFILE/TMP 等并就地展开残留
  的 %VAR% 字面量,命中打 WARN: ENV_SPARSE;构建后
  check_percent_literal_junk() 见到字面量目录只打 WARN: JUNK_DIR 并
  给出安全删除命令(守卫是兜底不是许可:@build 仍须走继承完整环境
  的 shell,删目录也不由构建脚本代劳)

py_compile 通过、--help 正常。本笔是并行会话在飞的改动,按用户
「把所有内容都 commit」的指示代为落盘;要退回:git reset --soft HEAD~1。
2026-10-28 22:22:59 +08:00
wandering1 e5d3dc1205 fix(task-worktree): build/bench 分锁 TTL + done 自动接管陈旧锁
A:LOCK_TTL_HOURS 由全局 6h 改为按锁分设(build 1h / bench 6h)——
   兜底窗口应与操作真实时长同量级:编译是秒~分钟级,6h 太钝。
   并支持 lock acquire --ttl 自报窗口(keil_build 按其 --timeout 自报,
   timeout/3600+15min,下限 0.5h),使 build 锁窗口自动跟随构建上限。
B:done 收口前置把陈旧锁视为空闲并自动释放(原为硬失败),
   仅当锁仍被有效占用时才拒绝。

新增 lock_ttl_hours / lock_is_stale / release_stale_locks 三个辅助;
lock status 显示各锁 TTL;cmd_done 改调 release_stale_locks。

验证:20 项 TTL 探针 + 5 项 lock_cli 接线探针全绿;
假 UV4 端到端(exit 0 自持自释、payload ttl=0.5)与 busy 路径(exit 4)。
2026-10-12 18:59:49 +08:00
wandering1 3c7ad9c75c fix(skill): 修正 @build 退出码口径不符(环境错误 1→2、用法 2→3)
`AGENTS.md` 与 `keil-build` / `new-machine-setup` 的 SKILL.md 一直写着
"2=UV4 未找到/无效(环境错误)、3=用法",但实现是反的:
- 环境错误走 `raise SystemExit("...")` → **实际退出码 1**(与"构建失败"
  撞号,调用方分不清"编译不过"和"UV4 没配好");
- 用法错误由 argparse 抛 `SystemExit(2)` → 恰好占用了文档里"环境错误"
  的位置,于是 `new-machine-setup` 里"报 exit 2 先分清真没设还是没继承"
  这条排障指引**从未生效**。

改法(让实现服从既有文档口径,而非改文档):
- 新增 `BuildEnvError`;`find_uv4` / `find_project` / `load_config` 失败
  一律抛它,由 `main()` 捕获 → 打印 + 退出码 **2**;
- 覆盖 argparse 的 `error()`(默认 `SystemExit(2)`)→ 用法错误退出码 **3**;
- `run_build` 的档案解析失败原为 `return 3`(用法),实属环境错误 → 并入 2。

调用方安全性:`test/run_all_suites.py` 与 `task-worktree` 的 `run_script`
都只判 `rc == 0` / `rc != 0`,不区分具体码,故本次改动不影响它们。

验证(全部实测,用假 UV4 避免与在途构建争 UV4 与 build 锁):
| 场景 | 期望 | 实测 |
|---|---|---|
| `--help` | 0 | 0 |
| 成功构建(假 UV4 写 0E0W) | 0 | 0(BUILD_OK) |
| 构建失败(假 UV4 写 `error:`) | 1 | 1(BUILD_FAIL) |
| `--project` 不存在 | 2 | 2 |
| 档案 `uvprojx` 不存在 | 2 | 2 |
| 档案 JSON 解析失败 | 2 | 2 |
| 未知参数 `--bogus` | 3 | 3 |
| 参数缺值 `--timeout` | 3 | 3 |
| build 锁被占用 | 4 | 4(B9 在构建时实测) |

同步更新 `AGENTS.md` 的退出码行(补 2 的完整含义与 4)与 `keil-build`
SKILL.md(记录本次修正的来龙去脉)。pre-commit 全绿。
2026-10-12 18:49:24 +08:00
wandering1 1b450be0ef fix(skill): @build 自持自释 build 锁,根治忘记 release 的泄漏
问题:锁不绑定进程存活(`lock acquire` 是短命进程,真正用 UV4 的是另一个
进程),所以释放只能靠调用方记得。Agent 手工 `lock acquire build` 后忘
了 `release`,锁要挂到 6 小时 TTL 才被下次 acquire 接管——期间其他任务
要么立即失败、要么干等。`done` 自己已用 try/finally 兜住,但手工路径没有。

改法:让**用资源的人**持锁。`keil_build.py` 进入 acquire、`finally`
**无条件** release(构建失败 / 异常 / SystemExit 都会释放)。
- `--lock-task`:持有者名。默认 `$DTU_TASK_ID` → 从 cwd 的
  `_wt/<ID>-<slug>/` 反推 `<ID>` → `build-cli`。反推意味着"手工
  `lock acquire build --task <ID>` 后再跑 @build"仍幂等,不会自我死锁。
- `--lock-wait N`:锁被占时等待(默认 0 = 立即失败)。
- `--no-lock`:完全不加锁。
- 新增退出码 **4 = build 锁被占用**(原先无此语义,占用会直接去构建)。
- 锁工具 = 兄弟 skill `task-worktree`;**找不到则降级为不加锁并告警**,
  保持本 skill 可独立搬运。

`done` 的兼容处理:它自己持锁,给子进程设 `DTU_LOCK_HELD=build` 告知
跳过自持自释。**对"工作树里还是旧 keil_build.py"的在途任务同样安全**
——旧版根本不看该变量、也不会自锁,故不会出现"双重持锁"死锁。

`bench` 锁**不动**:它是**会话作用域**(跨烧录→@test→探针多条命令),
逐命令自动释放会让别的任务插进来扰动设备,必须继续由 Agent 持有。

验证(主工作树实测):
- 自持自释:acquire → BUILD_OK → release,前后 `lock status` 均空闲;
- 被占:由 other-task 占锁 → exit 4,且**未触发构建**;
- 调用方持锁:`DTU_LOCK_HELD=build` → 打印"跳过自持自释",且
  **未释放调用方的锁**(锁仍归 __done__)——关键安全性质;
- 错误路径:无调用方持锁 + `--project` 不存在 → 失败但 **finally 已释放**;
- 持有者名推导:主工作树 → `build-cli`,`_wt/N33-stack-margins` → `N33`;
- 门禁:`mem-numbers` 一致;pre-commit 全绿。
2026-10-12 18:07:58 +08:00
wandering1 c77c5824f9 build: 删除 MDK-ARM/build.bat,@build 完全收敛到 keil-build skill
- test/run_all_suites.py 是唯一真正执行它的地方:BUILD_BAT 常量改为
  KEIL_BUILD(.dsh/skills/keil-build/scripts/keil_build.py);两处构建点
  改传 --timeout(脚本内超时先于 _run 超时触发,超时得 rc=1 + BUILD_FAIL
  文案,而不是被 _run 杀掉)
- AGENTS.md / keil-build SKILL.md / new-machine-setup SKILL.md:删除
  "等价原生入口"口径,改为注明该文件已于 2026-10-10 删除
- 环境与部署 3 篇 / 项目架构总览 / README / MDK-ARM/README /
  download.bat 注释 / check_mem_numbers.py 提示串:移除 build.bat 引用
- 刻意未改:docs/问题记录/项目审查与优化建议报告.md 的 P2-14 / N-18
  (历史审计条目;doc-links 不校验裸文件名,保留不影响门禁)
- 验证:keil_build.py --timeout 300 -> BUILD_OK / rc=0;
  run_all_suites.py --dry-run 正确解析 skill 路径;doc-links 123 文档通过
2026-10-10 16:23:54 +08:00
wandering1 aac5f99fe9 移除 OpenCode 配置与命令,技能与串口单一配置源迁移至 .dsh/skills 与 .serialtest,同步更新全部文档引用 2026-10-10 14:05:36 +08:00