Files
dsh_ai1net_server/交付物/项目开发-任务执行关键步骤-20260929.md
T
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

166 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目开发 · 任务执行关键步骤(全文版)
> 🔴 **每个会话、每个任务都必须按本顺序执行;跳步=违规。**
> **实体精要已在 `CODEBUDDY.md §1.5`**(那份**每次会话自动加载**,冲突以 `CODEBUDDY.md` 为准);**本文是全文版**(命令、判据、坑)。
> 权威来源:`CODEBUDDY.md`(根规)+ 技能 `dsh-workflow` → `references/00-平台改造六阶段.md`(六阶段原文)。
---
## 0 一句话总览
**开工前三件 → 六阶段(0 需求识别 → 1 调研 → 2 规划 → 3 开发 → 4 验证 → 5 归档清理)→ 收尾四件。**
其中**三道硬门禁**:**抢不到锁 ⇒ 停手**(R9)|**红线命中 ⇒ 先停手**(R1–R11)|**交付门禁**(本机改完 ≠ 交付)。
---
## 1 开工前三件(顺序固定,⛔ 不准换)
### 1.1 跑状态(1 次调用顶十几轮探索)
```bash
"$PY" "$WS/state.py" # --online 加远端基线
```
🔴 **跑完之前不许 Glob/Grep 全库摸底。** 输出里看:`[锁]` / `[git]` / `[入口]`(它会展开本线接续入口的 §2)。
### 1.2 判可锁定范围(开工门禁)
```bash
bash "$DOC\07-scripts\preflight-lock.sh" "<会话名>" <目标文件...>
```
- 【A】可独立锁 ·【B】秒级独占 ·【C】共享(构建产物/依赖树)·【D】**未归类** ·【E】**机制层**
- 🔴 **【D】或【E】非空 ⇒ `rc=1` 拒开工**:D 先归类再动;**E(机制层:`config`·`crypto`·`isolation`·`index`·`scripts`·`CODEBUDDY.md`·锁与钩子本身)必须独占**,且**仅当确认无其他会话在跑**才可开工。
### 1.3 抢锁(是"抢"不是"看")
```bash
bash "$DOC\07-scripts\handoff-guard.sh" --claim-exec "<会话名>" [--domains <域键>]
```
- 域键 = `<锚点段>/<下一段>`,多个用逗号;**⛔ 不带 `--domains` ⇒ 退化为全局独占**(机制层必走)
- 🔍 **必须"校验结果"不能"看输出"**:① 检查**退出码**(⛔ 不接管道,`| grep` 会吃掉退出码)② **复读 `.locks/<会话名>/DOMAINS` 或 `.exec-lock/OWNER` 并断言是自己的**
- ⚠️ `rc=1` 两因分清:**域冲突(停手)** vs `.gate` 占用(重试)
- ⛔ **抢不到锁 = 终点**:只读、报告、结束(**R9**:不删锁、不接管)
- ✅ **锁只约束「写」,不约束「读」**;⚠️ 会改本地状态的命令(`git fetch/checkout/stash/reset/switch`)**算写** ⇒ 要持锁
---
## 2 六阶段
### 阶段 0 · 需求识别(先盘点再动手,勿跳步)
0. ★ **开工前置检查 —— 本流程最重要的一步**(血的教训:不先查"已经有什么"就凭直觉装工具/猜机制,事后才发现文档里早写了)。任何「**装工具 / 写自动化 / 查机制**」之前按序做完三条:
1. **先看可用技能列表**(会话开始就在)⇒ 有对应的**立刻加载技能**,禁止另起炉灶;
2. **先看本机/项目已有资产**:`E:/ProgramData/.workbuddy/skills/`(技能根,改动下一请求生效)、工作区 `MEMORY.md`;
3. **要装任何东西前自问:本机已有的能否满足?** 能 ⇒ 不装;不能 ⇒ **先说清楚再装**。
1. **环境盘点**:本机 / 服务器 / 工具链 / 权限 / DB / 实例状态先行。
2. **需求边界**:区分「**方案请求**」(只输出方案 —— **方案与执行分离**,未经明确授权不改文件)与「**任务明确直接执行**」。
3. **用户确认**:关键分叉用**选项表**收敛(推荐项置首)。
4. **输出格式**:**一句话结论先行** + 表格化细节。
### 阶段 1 · 调研(源码级实证优先,⛔ 禁只靠文档推断)
0. ★ **用户报障第一步:先拿「真实失败请求」,别猜** —— 平台 journal 里有精确 URL + method + status:
```bash
ssh ... 'journalctl -u dshs --since "-30min" --no-pager \
| grep -E "401|403|404|500|502|503|crash-restart|YAMLException|ERR_MODULE" \
| grep -v "level.:30.*200"'
```
判据:`401` 先分辨**平台 401** 还是**实例 401**(改的地方完全不同);`502` = 实例没起来 ⇒ 翻同段 `YAMLException` / `ERR_MODULE_NOT_FOUND` / `crash-loop`。
1. **只读分析官方包**(允许):读 bundle 定位机制(slot 声明、inject 契约)。**绝不写官方主程序**。
2. **服务器实测 > 推断**:区分 fence 层 / 应用层错误。
3. **双端对照**:archive 源 ↔ 实例安装副本 **md5 对账**。
4. **多模型交叉验证**:关键结论不轻信单点推断。
### 阶段 2 · 规划(文档先行,方案确认后动工)
1. **方案对比表**:≥2 选项 + 各自影响/风险 + 建议。
2. 🔴 **红线自查 R1–R11**(逐条过;命中 ⇒ 先停手)。
3. **影响评估**:重启换端口 / 旧连接断连 / 权限影响…;**命中 R5(权限扩大)另附「权限影响评估」+ 改动前后 diff**。
4. **文档占位**:`04-调整方案/` 建编号档案 —— ⚠️ **档案号必须「原子占用」**(`mkdir .lock-$n` 或 `flock`),⛔ 不能"读一眼 ls 再写"(已两次撞号)。
### 阶段 3 · 开发(小步 + 备份 + 逐条验证)
1. `scp` 服务器源码 → 本地 → **读一条 → 改一条 → 验一条**(⛔ 禁批量读全部文件)
2. `scp` 回服务器 `/tmp/` → `cp` 覆盖前**先备份** `bak-<功能>-<YYYYMMDD>/`
3. `npm run build`(零报错)→ `systemctl restart dshs`
4. **本机直连验证**(绕 DNS/代理):`curl -sk --resolve <域名>:443:127.0.0.1 https://<域名>/api/...`
> ⚠️ **全量覆盖 `lib/` 前必须先在 HEAD 上 build**(曾把别人已上线的修复整体回退);**部署完立刻复验「上一次刚验收过的东西」**。
> ⚠️ **「已部署」≠「已提交」**;**不能拿服务器状态当版本事实源**。
**客户端插件(client bundle)另有链路**:**先做基线校验**(拉线上 tgz ↔ 本地源码**忽略行尾**全量 diff,确认"差异只有我要改的")→ 改 → `npm pack` → 铺 tgz(chown 用户 uid)→ kill 实例 → 抓新端口 → 验 `node_modules` 里 markers(版本、关键串计数)。⛔ **反例:先改后验**(顺序错 = 风险窗口白开)。
### 阶段 4 · 验证(全链路 + 浏览器实测 + 清理)
1. **API 链路**:portal enter → url token → 页面 200 → 关键接口 ok。
- 🔴 **用例必须同时覆盖「有请求体」与「无请求体」**(只测 `POST` 会整条漏掉 `GET`/`SSE`)。
- **模拟浏览器语义要测到底**:只带最初那个旧 cookie 再跑一遍,并显式断言 `Set-Cookie` 回写。
2. **浏览器验证栈**:**只用 `browser-harness`**(⛔ `agent-browser`、Playwright 均已禁用)。
- 🔴 **铁律 0:动手前先 `list_tabs()` 确认"你在驱动哪个浏览器"** —— ⛔ 不要假定端口号(端口归属每次都变);**看到的不是你新开的空浏览器 ⇒ 立刻停手**,只做只读检查。收尾必须 `close_tab` 关掉自己开的标签。
3. **静态 vs 后端**:改 `web/*.html` **无需重启**;改 `src/**` 才 build + restart。⛔ 别为前端改动重启服务(会打断所有用户实例)。
4. **安全面复测**:降权 uid 探测敏感目录应 denied;中间目录 711(去 r 留 x)不破坏子进程访问。
5. **清理临时物**(`poc-*` 会话用完即删、测试 tab 关闭)。
6. **截图留证**(每功能验收存 PNG + 展示)。
7. 🔴 **交付前必问一句:这份改动「出厂」了吗** —— 改完文件 ≠ 用户会看到变化。**一秒自检**:`ls -la` 对比「源文件 mtime」与「最新 tgz mtime」,**源更新 ⇒ 还没出厂**。
8. **视觉/UI 必须三层验收**:① 单测(断言 **class 名与结构**,不只文本)② 实装(`md5sum` 对齐本地产物 ↔ 实例 `node_modules` 实链,断言旧标记为 0)③ 端到端(解出真实 bundle URL → `curl` 回来 grep 新/旧标记)。
9. **用户说"参考某现成页面的样式" ⇒ 抄那个页面的源码**(逐条搬实际取值),⛔ 不要抄规范的抽象条目再自行演绎。
### 阶段 5 · 归档清理(文档同步 + 三层沉淀)
0. ★★ **交付门禁:本机改完 ≠ 交付**。收尾前逐层自问三句:**① 这次改的是哪一层?② 这一层的生效链路是什么?③ 最后一步走了吗、在「用户可见面」验了吗?**
| 改动所在层 | 生效链路(缺一步都不算交付) | 用户可见面复验 |
|---|---|---|
| 平台静态页 | `scp` 到服务器对应路径(注意 CDN/CF 缓存) | `curl` 取**线上**页面确认新内容 |
| 平台 TS(`src/**`) | `npm run build` → `systemctl restart dshs` | **线上**端点/页面实测(**不是**本地 build 通过) |
| 自研插件(client bundle / host 面) | 打 tgz → 导入候选池 → 实例「功能管理」启用 → **重启实例** | 取实例页 HTML 里**真实 bundle URL** 逐串验证 |
| 文档库 / 技能 | `docs-sync-check.sh` 对账 → `scp` → **复跑对账** | 对账「一致」计数回升 |
| 配置(env / nginx / nft / 配额) | 改 → reload / restart 对应服务 | 生效值实测 |
⛔ **四条"自我安慰"一条都不算交付**:**本机改完了 / build 通过了 / 本地打包完成 / 已 commit 了**。
⛔ **也别回头问用户"要不要部署"** —— 不打断在线用户的上线属**我的 lane 内执行细节 ⇒ 直接做完**(§3 R7-边界)。
1. **文档落盘**:**源 = 本地 `D:\github\dsh_shenxian\dsh-server-docs`**(目录即 git 工作树)。
**四件套(顺序固定)**:`docs-audit.py` → `docs-index-stats.py --write` → `docs-manifest.py` → `docs-sync-check.sh`。
传服务器用**单个 `tar` 管道**(逐个 `scp` 会因每文件一条 SSH 连接而超时),随后 `chmod`(目录 700 / 文件 600)。
⚠️ 本库**多会话共用** ⇒ 提交前 `git status`,**只 add 自己改的文件**;`docs-manifest.json` 是派生文件,别人有在途改动时**宁可让它 dirty**。
2. **档案更新**:`04-调整方案/<NN>-*.md` 写"需求→改动文件→commit→验证记录";`INDEX.md` 同步(以它为准)。
3. **三层沉淀**:治本(机制/流程固化进 skill 或档案)/失误(**append-only** 教训档)/记忆(`AGENTS.md` 或工作区规则)。
4. **汇总表**:带状态/结果列交付,列明未完成项与副作用。
5. **技能自身归档**(本 skill 有改动时**必做**):本机 → 服务器**单向推**,**md5 双端一致**才算完成;同时更新引用它的 `README` 模块表行 / `INDEX` 场景速查行。
⚠️ **改「跨载体规则」时必做全载体扫描**(`grep -rn` 关键短语,把所有命中处**全部**改掉;只改一处 ⇒ 其余载体自相矛盾,比不改更糟)。
---
## 3 收尾四件(缺一不算完成)
1. **反序释放锁**:先 `--release`,最后 `--release-exec "<会话名>"` —— ⛔ 不带会话名 ⇒ **拒绝释放**
🔓 **释放时机 = 交付闭环走完**(台账 → 四件套 → commit → 推送 + 对账 → 归档),**不是"改完就放"**;**要等用户拍板 ⇒ 先释放再等**
2. **台账 / 档案**(见阶段 5)
3. **提交边界**:未明确要求 ⇒ **不 commit / 不 push / 不同步仓库**;说了才做且**只 add 自己改的文件**;
⛔ **三类禁止入库**:`tmp/` / 中间产物 / 会话交接单。**提交前自查** `git diff --cached --name-only` 命中即 `git reset`
4. **收口清本棒 `tmp/`**;🔴 **结束语必须对锁状态负责**(写明"已释放",或点名锁在谁手上 + 原因 + 下一步)
⛔ **禁"抢到锁、做一半、不解锁就结束回合"**(带锁结束 = 把所有人挡在门外)。⚠️ 护栏额度耗尽时 release 可能 `rc=124` 卡住 ⇒ 用 `mv` 等效释放。
---
## 4 并行纪律(要点)
- 共享文件**只用 `Edit` 精确片段替换**(失败 = 天然冲突检测),**⛔ 禁整文件 `Write` 覆盖**;`settings.json` 的 `hooks` 段与用户级 `MEMORY.md` **只能增删条目,⛔ 禁整段覆盖**
- **并行度由「冲突域」定,不由任务数量定**:只读/调研可自由并行;改码 → 构建 → 重启 → 提交 → 写文档是**单通道,必须串行**
- 🔴 **域键算法 shell 与 hook 两侧必须逐字一致**(`_ANCHOR_SEGS` ⇄ `_DOMAIN_SEGS`),⛔ 改一侧 ⇒ **域锁静默失效(假绿)**
- ⚠️ **钩子 = 会话启动时快照**:对**在跑的会话无效** ⇒ 改完要**完全重启**(关窗 ≠ 退出);**脚本路径失配 = fail-closed**(Write/Edit 全被拒)
---
## 5 收尾自检清单(逐项打勾)
- [ ] 跑过 `state.py`?门禁 `preflight-lock.sh` 过?锁**校验过是自己的**?
- [ ] 阶段 0 的「开工前置检查」做了吗(**先看技能/已有资产**)?
- [ ] **红线 R1–R11 逐条过**了吗?命中 R5 出了权限影响评估吗?
- [ ] 覆盖前**备份**了吗?**部署完复验"上一次刚验收过的东西"**了吗?
- [ ] 用例覆盖**「有/无请求体」**两类了吗?
- [ ] **交付门禁三句**答得上吗?**四条自我安慰**有没有出现?
- [ ] 四件套跑了吗(顺序对)?只 add 自己的文件?
- [ ] **锁释放了吗**(带会话名)?结束语点名锁状态了吗?
- [ ] 本棒 `tmp/` 清了吗?