2026-09-15 18:47:13 +08:00
|
|
|
|
---
|
|
|
|
|
|
name: dsh-decision-method
|
2026-09-24 07:25:16 +08:00
|
|
|
|
description: dsh 多租户平台(ai1net.com)「改造 / 优化功能交互 / UI 界面」的**决策方法论**。当用户提出一个新需求、问「这是不是最优方案 / 还有没有更好的做法」、要在多个方案里选型、要判断某个决策是否该做 / 该不该扩大范围、要**自主给技术实现选取最优解**、或者要复盘「为什么这么定」时使用。⛔ **用户点名「决策方法」/「参考决策方法」/「按你的规划」/「别问我」/「自行决策」/「自主决策」⇒ 必须立即加载本技能,不得凭记忆代替**(机制层由钩子 `dsh-server-docs/07-scripts/skill-load-guard.py` 强制注入加载提醒;2026-09-16 实证:用户点名后 AI 全程 `Skill` 调用 **0 次**)。核心 = 决策素材库(用户有效决策 **U1-U28** / AI 有效决策 A1-A25 / 反例 X1-X14,**素材源含 180 条用户真实发言**)+ 「如何确认最优解」的十问与判定矩阵 + **技术实现的默认裁决顺序(8 条,AI 自主用、不问用户)** + 决策流程十步 + 交互 UI 改造专项清单 + 决策语言对照表 + **复跑脚本 `extract-user-voice.py`**。**v2.0.0(2026-09-14)结构变更:素材库(U/A/X)已拆到 `references/`,按需读;本文件只留判定核心 + 触发词索引**(索引绑定可识别动作)。**与 dsh-change-workflow 分工:本技能管「怎么想、怎么定」,那个管「怎么落地」。** 与 dsh-feature-first 分工:那个管「谁定什么」,本技能管「怎么定得对」。
|
|
|
|
|
|
version: 1.0.0
|
2026-09-16 11:28:53 +08:00
|
|
|
|
updated_at: 2026-09-16
|
2026-09-15 18:47:13 +08:00
|
|
|
|
created_from: 本工作区 62 份改造档案 + 5 天工作日志(2026-09-08 ~ 09-12)全量提炼
|
2026-09-24 07:25:16 +08:00
|
|
|
|
last_change: 【2026-09-22 按要求统一版本号】frontmatter `version` → `1.0.0`(原 v2.8.0);正文与历史中的版本号为当时记录,未改动。
|
2026-09-15 18:47:13 +08:00
|
|
|
|
agent_created: true
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# dsh-decision-method — 平台改造的思考与决策方法
|
|
|
|
|
|
|
|
|
|
|
|
> **一句话**:把「这个需求该怎么定」从**直觉**变成**可复用的判定**。
|
|
|
|
|
|
> 材料来源 = 本工作区 `dsh-server-docs/04-调整方案/` 62 份档案 + `.workbuddy/memory/` 五天日志里的**真实决策痕迹**(含被驳回的)。
|
|
|
|
|
|
> 每条模式都带**实例出处**,可以回溯核验,不是抽象原则。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 0. 定位:和 `dsh-change-workflow` 的分工
|
|
|
|
|
|
|
|
|
|
|
|
| | 本技能 | `dsh-change-workflow` |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 管什么 | **需求和方案怎么定**(选型 / 收敛 / 判方向 / 拍板) | **定了之后怎么落地**(六阶段 / 红线 / 档案模板) |
|
|
|
|
|
|
| 什么时候用 | 用户刚提需求、问"最优方案"、要在选项间选、要判"该不该做" | 决策已定,开始改码 / 验证 / 归档 |
|
|
|
|
|
|
| 产出 | **选项表 + 决策点 + 判定依据** | 代码改动 + 验证记录 + 档案 |
|
|
|
|
|
|
|
2026-09-24 07:25:16 +08:00
|
|
|
|
> 顺序:**先本技能定案 → 再 dsh-change-workflow 执行**。规划会话只做前者,执行会话只做后者(交接载体 = `dsh-server-docs/05-交接单/`)。
|
2026-09-15 18:47:13 +08:00
|
|
|
|
|
|
|
|
|
|
### 0.1 素材来源与复跑方式(**honest provenance,勿含糊**)
|
|
|
|
|
|
|
|
|
|
|
|
| 素材 | 位置 | 说明 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 改造档案 | `dsh-server-docs/04-调整方案/NN-*.md` | 每份含「触发 / 用户裁定 / 方案对比 / 事故踩坑」——**会话的结论层** |
|
|
|
|
|
|
| 工作日志 | `.workbuddy/memory/YYYY-MM-DD.md` | 五天过程日志,含用户原话引用——**会话的过程层** |
|
2026-09-24 07:25:16 +08:00
|
|
|
|
| 现行事实层 | `BRIEF.md` / `INDEX.md` / `README.md` / `01-规范/06-工作台UI规范.md` / `05-交接单/README.md` | 约定与红线 |
|
2026-09-15 18:47:13 +08:00
|
|
|
|
| **原始会话转录** | `~/.workbuddy/projects/<工作区目录名>/*.jsonl` | **用户真实发言的原始记录**(含被否决、被纠正的内容) |
|
|
|
|
|
|
|
|
|
|
|
|
**复跑命令(只读)**:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 抽出本工作区全部历史会话里的「用户真实发言」(2026-09-12 实测 = 180 条,跨 09-08→09-12)
|
2026-09-24 07:25:16 +08:00
|
|
|
|
python3 dsh-server-docs/07-scripts/extract-user-voice.py
|
2026-09-15 18:47:13 +08:00
|
|
|
|
# 查某个决策的来龙去脉
|
2026-09-24 07:25:16 +08:00
|
|
|
|
python3 dsh-server-docs/07-scripts/extract-user-voice.py --needle 复用价值
|
2026-09-15 18:47:13 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
> ⚠️ **本方法 v1.0 的素材边界(如实记录)**:首版只从**档案 + 日志**提炼(当时会话检索接口返回 0 命中)。
|
|
|
|
|
|
> 2026-09-12 用上面的提取器回补核对 —— **U1–U12 里 11 条能在原始发言中找到对应原话**(覆盖良好),
|
|
|
|
|
|
> 据此**补上了 U13–U19** 这 7 条只在原始对话里才看得见的模式。**以后迭代本技能,先跑这个脚本。**
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 决策素材库 · 用户的有效决策(U1–U28) → **`references/素材库-U-用户决策.md`**
|
|
|
|
|
|
|
|
|
|
|
|
> **已被拆出本文件**(原占全文 55%)。本文件只留「**判决核心 + 指针**」:素材库是**查阅型**(看了更准、不看也不违规),判定核心才是每次都要用的。
|
|
|
|
|
|
> **触发词 → 直接查哪条**(**必须去读**,别凭印象答用户口径):
|
|
|
|
|
|
|
|
|
|
|
|
| 你正在判断什么 | 去查 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 「这件事该不该问用户 / 我是不是又在上抛了」 | **U20 · U21 · U22** + 本文件 §4.1 两条总闸 |
|
|
|
|
|
|
| 「要不要自己开发 / 有没有现成的」 | **U23**(官方库优先 + 体检三关) |
|
|
|
|
|
|
| 「多期方案 / 兼容性怎么定」 | **U24** |
|
|
|
|
|
|
| 「要给用户看什么 / UI 怎么排」 | U5 · U7 · U11 + 本文件 §6 |
|
|
|
|
|
|
| 「这个改动会不会让项目变差」 | **U28**(十维净变差即命中 ⇒ **停下复盘**;无正向做法 ⇒ **立即停止**)+ 红线 R11 |
|
|
|
|
|
|
| 「要不要降级/延期/先这样跑」 | **U27**(要的是解决问题,不是将就妥协)+ A6 边界(目标不打折、路径取最小代价)|
|
|
|
|
|
|
| 「方案有风险/问题,能不能先干着看」 | **U26**(先优化到「当下最优解」+ 残余风险写清,再走下一步)|
|
|
|
|
|
|
| 「抢了锁之后怎么收口 / 能不能先放着」 | **U25**(锁的生命周期 = 任务的生命周期;带锁结束不算完成)+ 本文件 §4 判据 |
|
|
|
|
|
|
| 「删 / 留 / 清理 / 收尾怎么定」 | U3 · U6 · U14 |
|
|
|
|
|
|
| 「用户那句话到底是什么意思」 | 读全表(每条 = 原话 + 落地 + 判据) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 决策素材库 · AI 的有效决策(A1–A22) → **`references/素材库-A-AI推理.md`**
|
|
|
|
|
|
|
|
|
|
|
|
> **已被拆出本文件**。**触发词 → 直接查**:
|
|
|
|
|
|
|
|
|
|
|
|
| 你正在判断什么 | 去查 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 「我的证据够不够 / 结论能不能下」 | A1 · A4 · A5 · **A18**(静默失败会伪造结论)· **A19**(验收要含第二环境) |
|
|
|
|
|
|
| 「我凭什么说这是限制 / 做不到」 | **A17**(配置项 / 已抽象层 / 真硬编码,三层取证) |
|
|
|
|
|
|
| 「写状态 / 写支持度 / 交付回执」 | **A15**(三态词表:✅已验证 / ⚠️待开发验证 / ❌已知不支持) |
|
|
|
|
|
|
| 「删除 / 迁移 / 回滚 / 替换」 | A8 · **A16**(伴随物清单)· **A20**(存量烂账选只增不改)· **A22**(先补位再退役) |
|
|
|
|
|
|
| 「我做完了吗 / 能不能宣布完成」 | **A25**(本机改完 ≠ 交付:先画「改动层 → 生效链路」;四条"自我安慰"不算交付)|
|
|
|
|
|
|
| 「我装的门禁/钩子到底管用吗」 | **A24**(拦截面必须覆盖真实行为面 —— 先核账再装)|
|
|
|
|
|
|
| 「判据 / 分类 / 索引怎么设计」 | **A21**(必须报分布、要有区分度) |
|
|
|
|
|
|
| 「失败面 / 报错 / 能力不确定」 | A10 · A11 |
|
|
|
|
|
|
| 「流程走到哪一步了 / 我是不是跳步了」 | **A23**(流程类失效 = 触发词没命中;规则要进常驻层、触发用动作词)+ `dsh-change-workflow` 六阶段 |
|
|
|
|
|
|
| 「拍板前还要问自己什么」 | A2(必含"不做")· A3(决策点)· A6 · A7 · A9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 反例库:被驳回 / 被纠正的决策(X1–X13) → **`references/素材库-反例-X.md`**
|
|
|
|
|
|
|
|
|
|
|
|
> **已被拆出本文件**。**每条反例 = 一条避免规则**。**触发词 → 直接查**:
|
|
|
|
|
|
|
|
|
|
|
|
| 你正在判断什么 | 去查 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 「我刚被纠正了,同类还有哪些坑」 | X1(批量)· X4(归因)· X9(过度上抛)· X10(答非所问)· X11(越界)· **X12**(把用户材料当权威)· **X13**(把自己的解析失败当成版本差异)· **X14**(一批改造拆成多次中断动作)|
|
2026-09-17 17:03:34 +08:00
|
|
|
|
| **「这个库 / 方案成熟、star 高,所以选它」** | **§4.6**(选型判据轴:⛔ 热度≠安全/性能;先立轴再排序;必查默认值 + CVE 历史)|
|
2026-09-15 18:47:13 +08:00
|
|
|
|
| 动手前的"别踩"清单 | 读全表 13 条 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 如何确认最优解(本技能的核心)
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 判定矩阵:先给方案贴标签
|
|
|
|
|
|
|
|
|
|
|
|
> **⭐ 两条总闸(顺序在前:先问「是不是我的 lane」,再问「要不要停手」)**
|
|
|
|
|
|
> **闸 1 · lane**:这件事**落在谁的 lane**?—— ① **我自己负责的**(我的插件源码/产物、该 profile 的依赖、我自己的临时脚本、我方案内的执行细节)⇒ **自己拍**;② **平台级 / 全局 / 别人 lane 的**(`/var/lib/**`、全局符号链接、别人的 profile、别人的产物)⇒ **只报告、不动手**,**哪怕改它能让自己流程跑通**(2026-09-13 用户原话:「谁让你去改这个的」「不是自己负责的任务相关文件不要去改」→ **X11**)。
|
|
|
|
|
|
> **闸 2 · 门禁**:命中**真门禁**才停等确认 —— 现行只剩两条:① **不可逆破坏性操作**(删数据 / 迁 DB / 清目录)② **边界外**(业务目标与优先级 / 花钱与资源承诺 / 对外承诺与合规 / 需用户提供的凭据 / 无客观优劣的偏好 / 影响面超出本平台)。**其余一律自决**(含部署上线、重启、改配置),事后一句「我选了什么(可推翻)」(**U20 / X9**)。
|
|
|
|
|
|
> ⚠️ 两条闸**对称**:闸 1 治「**越界动手**」,闸 2 治「**过度上抛**」—— 2026-09-13 两类各犯过一次。
|
|
|
|
|
|
|
|
|
|
|
|
| 判定问题 | 若答案是 | 处置 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 这次是**扩大**还是**收窄**可见面/权限?(R5) | 扩大 | **停手**,出「权限影响评估」四问 + 等确认 |
|
|
|
|
|
|
| | 收窄 | 可直接做,但**遮蔽类必须真启动一次实例验证** |
|
|
|
|
|
|
| 有没有**不扩大也能实现**的方案? | 有 | **必须先提**;提不出才说明为什么没有 |
|
|
|
|
|
|
| 改动**影响多少文件**?(R7) | >10 或有"所有/整个/全库" | 先出**受影响清单** + 等确认;先 1 个对象单点验证 |
|
|
|
|
|
|
| 会不会**中断在线用户**?(R8) | 会 | 先说明影响面 + 取得确认;能避开活跃时段就避开 |
|
|
|
|
|
|
| 会不会**中断在线用户**?(R8)——**按实际影响面判,不按动作名字判** | **不会**(只换包 / 传产物 / 改静态页 / 投放候选池) | **属边界内的「部署与同步」⇒ 做完即上线,不要问**(U20 / X9);先做完,再用一句「我选了什么」交代 |
|
|
|
|
|
|
| 这个改动**失败**会怎样? | 实例起不来 / 全站不可达 / 不可逆 | 必须有回滚点(备份路径 + 恢复命令)**先就位** |
|
|
|
|
|
|
| **删除/迁移**的收益 vs 潜在破坏? | 收益小、破坏大 | **不删**——标注废弃 + 禁再加功能 |
|
|
|
|
|
|
| **这个改动会让项目某一维度净变差吗?**(**R11 · 十维**:目标/方向/架构/功能/性能/安全/交互/UI/便利性/扩展性) | **会** | **立即停下复盘** → 找保住正向收益的做法;**拿不出 ⇒ 立即停止、只报告**(不许"先做着看",见 **U28**) |
|
|
|
|
|
|
| 会不会造出**第二个漂移源**? | 会 | 改成**指针**(单一来源)——清单/待办/部署事实各只有一个权威文件 |
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 「确认最优解」十问(拍板前逐条答,答不出就是还没想清)
|
|
|
|
|
|
|
|
|
|
|
|
1. **一句话目标**是什么?做完了**没有**(可判定)?
|
|
|
|
|
|
2. 这条结论我**用什么命令/证据**证明?(说不出 = 还在推断,见 A1)
|
|
|
|
|
|
3. 有哪 **≥2 个选项**、以及**"不做"**这一条?(A2)
|
|
|
|
|
|
4. 这个改动是**扩大**还是**收窄**?(U8 / R5)
|
|
|
|
|
|
5. 有没有**更小**的改动达到同样目的?(A6)
|
|
|
|
|
|
6. 会影响**谁**(全部租户 / 单租户 / 仅 admin)?会**断多久**?(R8)
|
|
|
|
|
|
7. **回滚**怎么做?备份在哪?(写得出可执行命令才算数)
|
|
|
|
|
|
8. 造出**第二个真相源**了吗?(单一来源原则)
|
|
|
|
|
|
9. 用户**能不能感知到**(新入口 / 新反馈 / 新文案),还是只有后端变了?(U5)
|
|
|
|
|
|
10. 谁来**验收**?我能不能给一个**第三方可复现**的命令 + 期望输出 + 退出码?
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 验收口径分级(越靠后越权威)
|
|
|
|
|
|
|
|
|
|
|
|
| 级别 | 手段 | 能证明什么 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| L1 推断 | 读代码 / 读文档 | **什么都不能证明**(只用来生成假设) |
|
|
|
|
|
|
| L2 命令 | `curl` 状态码 / `--dump-config` / 日志 grep | 机制是否被触达(**注意 `--dump-config` 不反映 bundle/patch 层**) |
|
|
|
|
|
|
| L3 对账 | md5 双端 / `docs-sync-check.sh` / 可见面清单 diff / 工具清单前后对比 | 一致性、无回归 |
|
|
|
|
|
|
| L4 端到端 | 铸造临时 session 实跑 → 越界用例(`../../etc/passwd` 应 400) | 安全与功能闭环 |
|
|
|
|
|
|
| L5 用户实测 | 用户浏览器硬刷新 + 体感确认 | **最终验收**(前端渲染、动画、位置类只能到此为止) |
|
|
|
|
|
|
|
|
|
|
|
|
> **做不到就明说**:「未做浏览器渲染验证(本机无 Chromium,装它成本不成比例)→ 待用户硬刷新确认」是**合格交付**;把 L1 说成 L5 才是事故。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.4 技术实现的默认裁决顺序(**AI 自主用,不问用户**)
|
|
|
|
|
|
|
|
|
|
|
|
> 这是「技术实现找最优解」的可执行算法:**按序自答,第一个"是"就是答案**。全部答"否"才说明确实需要新造东西。
|
|
|
|
|
|
> 配套 `dsh-feature-first`:用户在技术层没有判断依据 → 这 8 条**不构成决策点**,不要上抛。
|
|
|
|
|
|
|
|
|
|
|
|
| 序 | 自问 | 若"是" → 选它 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| **1** | 有没有**既有机制 / 扩展点**能复用? | 扩展,**不新建**(U2:不做两套) |
|
|
|
|
|
|
| **2** | 有没有**更小改动**达到同一效果? | 取**最小改动半径**(A6) |
|
|
|
|
|
|
| **3** | 能不能**用配置解决**而不是改代码?(cordis patch / env / bundle 声明) | **配置优先** —— 不改码 = 免 build、免重启 |
|
|
|
|
|
|
| **4** | 能不能**只改一层**?(门户静态页 / 编排器 / profile / bwrap / nginx) | **单层**;绝不"跨层顺手改" |
|
|
|
|
|
|
| **5** | 失败代价**是否对称**? | 不对称 → 选**可回滚、可保留**的那条(删除/迁移类尤其,A8);**删除类先走 A14「删除前三问」** |
|
|
|
|
|
|
| **6** | 结果**能不能被验证**?(命令 / 日志标记 / 端点) | 不可验证 → **顺手加可 grep 的标记或端点**(A5) |
|
|
|
|
|
|
| **7** | 这个改动是**收窄**还是**扩大**可见面 / 权限? | 收窄可直接做;**扩大 → 回 R5 门禁,先取得确认** |
|
|
|
|
|
|
| **8** | 与**官方契约的耦合面**有多大? | 耦合越小越好;**每一处耦合都要写进升级回归清单**(档案 26 六类) |
|
|
|
|
|
|
|
2026-09-16 11:28:53 +08:00
|
|
|
|
**三条硬约束**:
|
2026-09-15 18:47:13 +08:00
|
|
|
|
1. **第 3 条优先于第 2 条** —— "能配置就不改码":改码要走 build + 重启,而重启**会中断在线用户**(触及 R8);配置改动(尤其静态页)常常即时生效。
|
2026-09-16 11:28:53 +08:00
|
|
|
|
2. ⚠️ **2026-09-16 修正**:原表述「任一条与红线冲突 → 红线赢」**过宽**,是会话 `ddea70b7` 上抛的诱因 —— 把"平台级 / 全局 ⇒ 只报告不动手"(R7-边界②)当红线读,于是"红线赢"⇒ **该自己做的事被推给用户**。正确表述:**与「真门禁」冲突 → 门禁赢**(真门禁只有两类 ✓ 见 §4.5);**与表述重叠/打架的规则冲突 → 按 §4.5 裁决顺序**。
|
|
|
|
|
|
3. 🔀 **规则冲突时按 `R8 → §1 边界内自决清单 → 其余红线` 取首个命中项**,⛔ **不许"自行取保守侧"**(详见 §4.5)。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.5 规则冲突裁决顺序 + 上抛前三问(**2026-09-16 加,源自会话 `ddea70b7` 复盘**)
|
|
|
|
|
|
|
|
|
|
|
|
> **案例**:用户要求"完成 guest 迁移",AI 在结尾用「## 四、待你拍板」提了两问(① 106 旧控制面停/留 ② D1–D6 先做哪些)。用户 U6 回:「**D1–D6 先做哪些 按照你的规划执行,中间有问题参考决策方法**」,再两次(U5 / U7)自行给出"删除"的答案。
|
|
|
|
|
|
> **代价**:AI 那两问**都不是真门禁** —— 用户不但没被"省事",还多花一轮把答案喂回来;且 AI 全程 `Skill` 调用 **0 次**(用户点名的方法没被取用)。
|
|
|
|
|
|
|
|
|
|
|
|
**A. 冲突裁决顺序(同一对象被多条规则给出相反结论时)**
|
|
|
|
|
|
|
|
|
|
|
|
| 序 | 取谁 | 命中即停 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 1 | **R8** | 开发环境服务器 ⇒ **该动就动**,只需动手前一句话说明;⛔ 不必等确认 |
|
|
|
|
|
|
| 2 | **§1 边界内自决清单** | 部署 / 重启 / 改配置 / nginx·nft / drain / 技术选型 / 命名 / 调参 ⇒ **自决** |
|
|
|
|
|
|
| 3 | **其余红线** | R5 权限扩大 / R7 批量写入 / R9 锁 / R10 uid —— **永远是硬约束**,不参与裁决 |
|
|
|
|
|
|
|
|
|
|
|
|
**B. "平台级" ≠ "别人的"**(本次误判根源)
|
|
|
|
|
|
`dshs*`·`dsh-*` 单元、`/var/lib/dshs/**`、nginx·nft、端口,只要在**我们自己的 47 / 106 / 本工作区**上,就是**本平台自己的资源** ⇒ 按 §1 + R8 **直接做**。
|
|
|
|
|
|
R7-边界② 的"只报告不动手"**只针对「别人的 / 归属不明」的对象**。**判据看"归属",不看"是不是平台组件"。**
|
|
|
|
|
|
|
|
|
|
|
|
**C. 上抛前三问 —— 任一条为"是"即自决(不必三问全过)**
|
|
|
|
|
|
|
|
|
|
|
|
| # | 自问 | 结论 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 1 | 对象是**我们自己的**平台资源吗? | 是 ⇒ **自决** |
|
|
|
|
|
|
| 2 | 我**查证过**关键不确定点吗?(如"还有谁在用 / 有没有访问记录") | 没查 ⇒ **先查**,⛔ 不许把"我不确定"当上抛理由 |
|
|
|
|
|
|
| 3 | 候选按优劣排序后,**第一名是否明显更优**? | 是 ⇒ **自决**(只有"各有优有劣、客观分不出高下"才算真取舍) |
|
|
|
|
|
|
|
|
|
|
|
|
⛔ **同时禁止**:把"我有倾向"降级成"建议 + 待你拍板" —— 有倾向 ⇒ 直接做完,写一句「我选了什么(可推翻)」。
|
|
|
|
|
|
⛔ **冲突 ≠ 门禁**:两条规则打架**不构成**上抛理由。
|
2026-09-15 18:47:13 +08:00
|
|
|
|
|
|
|
|
|
|
**产出**:把 1–8 的答案写进档案的「技术选择」段(一行一条,**含被否决的选项与否决理由**)。
|
|
|
|
|
|
→ 这样用户**事后可推翻**、但**事前不被打扰**(对应 `dsh-feature-first` §5 的"默认自主 + 事后可推翻")。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-09-17 17:03:34 +08:00
|
|
|
|
### 4.6 技术选型:**先立判据轴,再排序**;⛔ 不许用 star / 年龄 / 生态当选型依据(**2026-09-16 加,源自覆盖网络 relay 选型**)
|
|
|
|
|
|
|
|
|
|
|
|
**反例(我当场犯的)**:把 `frp` 排「首选」,排查依据只有 **~10.6 万 star + 约一月一版 + 生态最好** —— 那是**「省心度」轴**,不是**「安全 / 性能」轴**。用户一句「**项目时间比较久,性能和安全性还真不一定是最好**」直接击穿,复查后**撤销排序**。
|
|
|
|
|
|
复查出的**真实安全面**:`CVE-2026-40910`(认证绕过 + 未授权 DoS,**影响 ≥0.53.0**)|dashboard **默认 `admin:admin` 且口令明文存配置**|**`proxyBindAddr` 默认跟随 `bindAddr`**(官方自己写「**大多数指南遗漏的配置**」—— 不设则代理监听器**绑到公网**)|服务端**默认不强制 TLS**|`auth.token` 是**单一静态共享令牌**、frpc 明文存、`allowPorts` 白名单**默认关**(⇒ 一台客户端失陷可申请**任意**端口)。
|
|
|
|
|
|
⇒ **"项目久"是双刃**:稳定 + 文档好 **vs 漏洞历史长 + 默认值停在历史约定(安全靠运维纪律补)**。
|
|
|
|
|
|
|
|
|
|
|
|
**四条硬规矩**
|
|
|
|
|
|
|
|
|
|
|
|
1. **⛔ 不用「star / fork / 项目年龄 / 发布频率 / 生态」做首轮排序** —— 它们度量的是**热度与省心度**,推不出"在本案里更安全 / 更快"。**只能当同分时的决胜项**,不能当**排序主依据**。
|
|
|
|
|
|
2. **判据轴必须从"本案的真实约束"反推**,并且**每条都要能回答"这条轴上的差异会不会改变本项目的结论?"** —— 不会 ⇒ **该轴不参与选型**。
|
|
|
|
|
|
· 本例立出六条:**① 认证模型(身份 > 每服务密钥 > 共享 token)② 默认拒绝还是默认放行 ③ 能否零新增入站 ④ 单节点失陷的爆炸半径 ⑤ 可观测 ⑥ 生态**。
|
|
|
|
|
|
· 结果:**frp 在 ①②④ 三条里都最差一档**(共享 token / 默认放行 / 可申请任意端口),只在 ⑤⑥ 领先 ⇒ 排序翻转为 **证书身份型(OpenZiti / Nebula)> rathole(Noise_NK 双向认证 + 每服务 token 必填)> frp**。
|
|
|
|
|
|
3. **性能轴先自证"它是不是本案瓶颈"**:本例**第一瓶颈是 presence 不是带宽**、量级是「每 worker 几十个 HTTP 会话」⇒ **吞吐 benchmark 不参与选型**(且多为厂商/二手自测)。**真要测就测链路本身**(RTT / jitter / 带宽)—— **任何 relay 的上限由链路决定,不由实现决定**。
|
|
|
|
|
|
4. **老 / 流行项目必查两张单子**:① **默认值清单**(逐项问"**不设它会怎样**"—— 本例 5 项里任何一项漏设都会**静默**破掉既定安全目标)② **CVE / 安全公告历史**(编号 + 影响版本区间)。**"成熟" ≠ "默认安全"。**
|
|
|
|
|
|
|
|
|
|
|
|
**配套两条(本例同时验证)**
|
|
|
|
|
|
|
|
|
|
|
|
- **"可选性"优先于"选对"**:先把接口抽出来(`Reachability.via` + `Rendezvous` 注册表)⇒ **换实现是 env 级切换** ⇒ 选型**可以推迟**,选错也不致命。**能在不选的情况下保留选择权,就别为"一次选对"付引入成本。**
|
|
|
|
|
|
- **替换 ≠ 无条件升级**:换第三方 = 用**我们不掌控的攻击面**替换**已收窄、且有系统补丁渠道的面**(例:sshd + `restrict,port-forwarding`)。⇒ **没有明确痛点之前,"维持现状"也是合法候选**,别把"换掉旧的"默认当成正向。
|
|
|
|
|
|
|
|
|
|
|
|
**判定触发器**:只要出现「成熟 / 久经考验 / 用得最多 / star 高 / 大家都在用」这类**热度型论据**给排序 ⇒ **立即反问三句**:① 这条论据落在**哪个轴**上?② 这个轴是**本案的瓶颈轴**吗?③ 它的**默认值**与 **CVE 历史**查过没有?
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-09-15 18:47:13 +08:00
|
|
|
|
## 5. 决策流程十步(新需求到手照这个走)
|
|
|
|
|
|
|
|
|
|
|
|
| 步 | 动作 | 产出 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 1 | **判类型**:这是「方案请求」还是「任务明确直接执行」? | 方案请求 → 只输出方案,**未经明确授权不改文件** |
|
|
|
|
|
|
| 2 | **开工前置检查**:先看已有技能/资产/记忆,"本机已有的能否满足?" | 决定"扩展还是新建"(→ U2) |
|
|
|
|
|
|
| 3 | **取证**:源码级 / 命令级实证,先拿真实失败请求 | 事实清单(每条带命令 + 期望输出) |
|
|
|
|
|
|
| 4 | **判方向**:扩大 / 收窄 / 中性 | 扩大 → 立即停手出四问 |
|
|
|
|
|
|
| 5 | **出选项表**:≥2 选项 + "不做" + 影响/风险 + 推荐项 | 方案对比表 |
|
|
|
|
|
|
| 6 | **选路径**:优先"最小代价合法路径""能一行代码就不要改平台""删除类判代价对称性" | 推荐方案 + 被否决方案的否决理由 |
|
|
|
|
|
|
| 7 | **列决策点**:已定的标"已定(谁定的/依据)",未定的标"开跑前问用户" | 3–5 个决策点 |
|
|
|
|
|
|
| 8 | **用户拍板** | 决策语言落成文字(见 §7) |
|
|
|
|
|
|
| 9 | **小步落地 + 回滚点就位**(单点验证 → 再推广) | 备份路径 + 恢复命令 |
|
|
|
|
|
|
| 10 | **可复现验收 + 沉淀** | 档案(需求→改动→验证→红线→回滚)+ 红线/技能/记忆三层沉淀 |
|
|
|
|
|
|
|
|
|
|
|
|
> **第 1 步和第 4 步是"停止点"** —— 这两步没结论就不要往下走。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 交互 / UI 改造专项决策清单
|
|
|
|
|
|
|
2026-09-24 07:25:16 +08:00
|
|
|
|
> 用户对本项目的界面要求有明确取向,以下是**已验证有效的取向**(源自档案 16/31/36/45/56/57/59/60/61/62 + `01-规范/06-工作台UI规范`)。
|
2026-09-15 18:47:13 +08:00
|
|
|
|
|
|
|
|
|
|
### 6.1 反馈与状态(最高频痛点)
|
|
|
|
|
|
|
|
|
|
|
|
| 场景 | 必须做到 | 实例 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 有任何等待(实例启动 / 拉目录 / 上传) | **可见进度**,且**导航路径与 XHR 路径都要有** | 档案 59:只有导航有 `wake.html` 动画,XHR 静默 20 秒 → 用户"以为死了" |
|
|
|
|
|
|
| 长耗时 | **3 秒后才亮**覆盖层(短请求不打扰) | 同上:`SLOW_MS = 3000` |
|
|
|
|
|
|
| 状态可缓存 | 页面明示「缓存更新于 X 前(6 小时内直接复用,不联网)」 | 档案 62:功能早已存在**但完全看不出来** |
|
|
|
|
|
|
| 不可编辑 / 只读 | 明示原因,不要"点了没反应" | 档案 36 |
|
|
|
|
|
|
| 失败 | 行内提示(`.toolbar-note` / `.empty`),给出**下一步** | 06 规范 §4.8 |
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 信息层级与术语
|
|
|
|
|
|
|
|
|
|
|
|
- **首列放用户读得懂的那一列**(说明 > 名称 > 技术标识);技术标识降副行(U7)
|
|
|
|
|
|
- **内部术语不上页面**:「候选池」→「导入到平台」;并显式解释易误解的关系(「**投放 ≠ 生效**」)
|
|
|
|
|
|
- **数值列右对齐 + `tabular-nums`**(否则滚动时数字跳动);超宽字段移出共享网格
|
|
|
|
|
|
- **文件名/标题默认同正文色,hover 才变蓝**(避免整列花掉)
|
2026-09-24 07:25:16 +08:00
|
|
|
|
- **图表类改动先看 `01-规范/06-工作台UI规范`**,冲突时以 `06` 的**实测 Token** 为准
|
2026-09-15 18:47:13 +08:00
|
|
|
|
|
|
|
|
|
|
### 6.3 布局与滚动(踩过的坑)
|
|
|
|
|
|
|
|
|
|
|
|
- `main#view` 高度 = `calc(100vh - 55px)`(**55 是实测值**,写 54 会多出 1px 第二层滚动条)
|
|
|
|
|
|
- **"视口自适应高度"必须上下都算** —— 档案 61 第一次修正只算了列表上方 372px,漏了下方 116px(按钮行 50 + card padding 18 + `#view` padding-bottom 48)→ 仍然溢出。正解 `calc(100vh - 520px)`
|
|
|
|
|
|
- `.modal-mask` 是 `display:flex` → **必须显式写** `[hidden] { display: none }`,否则弹窗关不掉
|
|
|
|
|
|
- 同名类二次定义会互相覆盖(`.tab` 有胶囊式与下划线式两套)→ 新页面**另起类名**(如 `.pg-tab`)
|
|
|
|
|
|
|
|
|
|
|
|
### 6.4 危险与不可逆操作
|
|
|
|
|
|
|
|
|
|
|
|
- 确认弹窗 **必须写明后果**(「将重启实例,会话可能中断」)
|
|
|
|
|
|
- 危险按钮用 `--danger` 系;保存/查看类靠**底色深浅**区分(保存=浅灰底深字 `.btn-import`,查看=白底蓝字 `.btn-view`)
|
|
|
|
|
|
- **不静默提升权限**:档位过时只**提示**,不自动改(安全语义变更必须用户知情)→ 档案 45/56
|
|
|
|
|
|
|
|
|
|
|
|
### 6.5 UI 决策的验收口径
|
|
|
|
|
|
|
|
|
|
|
|
- 静态文件(`web/*.html`)改完**立即生效、无需重启**;只有 `src/**` 才 build + restart
|
|
|
|
|
|
- 改完 `node --check` 内联 JS;用**独立 headless Chrome**(`--headless=new` + 独立 profile + CDP)验证,**绝不碰用户日常浏览器**
|
|
|
|
|
|
- **`section` 名是运行时注册的,`curl` 抓不到** → 这类改动只能靠用户硬刷新确认,**如实标注"未做浏览器渲染验证"**
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 决策语言对照表(用户怎么说 → 怎么落)
|
|
|
|
|
|
|
|
|
|
|
|
| 用户的话 | 真实含义 | 该怎么落 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 「按建议处理」 | **只授权那条建议本身** | 不做顺带优化;范围外的发现**先报告**(R7) |
|
|
|
|
|
|
| 「是不是最优方案 / 还有更好的方式吗」 | 要**选项对比 + 依据 + 风险** | 出对比表 + 十问,不要直接开干 |
|
|
|
|
|
|
| 「一次性优化到位」 | 同主题**做透**,别留尾巴 | 一次列全所有子项,附完成清单 |
|
|
|
|
|
|
| 「不需要 / 是不需要的」 | 先**扫引用与依赖**再定范围 | 出"引用实测表",只剔真 0 引用的(U3) |
|
|
|
|
|
|
| 「暂缓 / 还没准备好」 | **parked** | 保留侦察结论 + 列出"需你先办的事",**不再推进,等用户主动提起** |
|
|
|
|
|
|
| 「确认开始执行」 | 决策已定,**可以动刀** | 立即执行;但 R7/R8 门禁仍生效 |
|
|
|
|
|
|
| 「为什么要等我确认才部署呢」 | **部署 / 上线属执行细节** —— 不打断用户的动作不该上抛 | 直接做完上线,让用户**看线上效果**判断需求是否被满足(U20 / X9) |
|
|
|
|
|
|
| 「需要告诉我的是 是否已实现,如果未实现:为什么不能,需要我拍板可以问我」 | 要**结论三件套**,不要过程与自省 | 用 **U21** 四节骨架:判定 → 为什么不行(分层)→ 需你拍板(真需要才写)→ 我接着做(陈述句)|
|
|
|
|
|
|
| 「谁让你去改这个的」 | **越界了** —— 动到了不是我 lane 的东西 | 立即停手 → 能撤就撤(并自证不依赖它)→ 报告;此后动手前先过 **U22 闸 1** |
|
|
|
|
|
|
| 「推送 / 提交」 | 明确授权 git 操作 | 此前一律**不 commit 不 push**;提交也只用定向 `git add` |
|
|
|
|
|
|
| 一行指令(无上下文) | 期望**自主拆解 + 排查到底** | 自己建任务链、自己做根因定位,别逐步问 |
|
|
|
|
|
|
| 「为什么…?」(问现象) | 要**根因链**,不是复述现象 | 先取证(真实请求/日志/实测数),再给"现象→根因→修法"三段 |
|
|
|
|
|
|
| 「有没有越过红线」 | 要**逐条对照全量红线**的结论 | 分"当时成文口径 / 新立口径"两种口径答(A13)|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 决策记录模板(写进档案的固定段落)
|
|
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
|
# <NN>-<标题>(<日期> 落地 / 调研)
|
|
|
|
|
|
- 日期: / - 状态:✅已完成|🔄进行中|⏸暂缓|❌关闭 / - 触发:<用户原话或原始报障>
|
|
|
|
|
|
> **TL;DR**|结论 / 关键 / 状态(紧贴头部,3 行内)
|
|
|
|
|
|
|
|
|
|
|
|
## 背景与动机 # 需求来源、真实失败请求、触发场景
|
|
|
|
|
|
## 用户决策 # 关键分叉 + 选择 + 理由 + 日期(原文引用优先)
|
|
|
|
|
|
## 方案对比 # 表格:方案 / 内容 / 判定 / 理由(含"不做")
|
|
|
|
|
|
## 实现 # 改动文件清单 + commit + 关键片段
|
|
|
|
|
|
## 验证记录 # 命令 + 输出 + 结论;**含失败尝试与假阴性**
|
|
|
|
|
|
## 事故 / 踩坑记录 # 现象 → 根因 → 规避
|
|
|
|
|
|
## 回滚 / 注意 # 回滚命令、副作用、后续待办
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**三层沉淀(每次决策收口都要做)**:
|
|
|
|
|
|
1. **治本层**:机制与流程固化进 skill,或写进 `04-调整方案/NN-*.md` 改造档案(可复用的留 skill,一次性的归档)
|
|
|
|
|
|
2. **失误层**:教训 append 到 `.workbuddy/memory/YYYY-MM-DD.md`(**append-only**,不改写历史)
|
|
|
|
|
|
3. **记忆层**:长期约定/红线写 `MEMORY.md`(工作区级 + 用户级)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 与其他约束的关系
|
|
|
|
|
|
|
|
|
|
|
|
- **红线优先级高于本技能**:R1 不自动升级 dsh|R2 不改官方主程序与缓存|R3 client bundle 禁 `exports.default`|R4 不用真实账号做登录测试|**R5 权限只准收窄**|**R7 禁未经确认的批量/全仓写入**|**R8 中断在线用户须先知会** —— 任一条命中,**先停手**,本技能的效率论证不构成豁免。
|
|
|
|
|
|
- **执行层**:决策定了之后走 `dsh-change-workflow`(六阶段 + 档案模板 + 并行调度协议)。
|
2026-09-24 07:25:16 +08:00
|
|
|
|
- **规划/执行分离**:本技能属**规划侧**;产出交接单(`dsh-server-docs/05-交接单/`,8 段必填),规划会话**不 ssh、不改码、不重启、不 scp**。
|
|
|
|
|
|
- **单一来源**:清单与状态 = `INDEX.md §二`;待办 = `01-规范/03-路线图与待办.md`;部署事实 = `DEPLOY-本部署.md`;UI 基线 = `01-规范/06-工作台UI规范.md`;现行事实 = `BRIEF.md`(首读)。
|
2026-09-15 18:47:13 +08:00
|
|
|
|
- **可复跑判定工具**:`docs-audit.py`(歧义/编号/悬空引用,退出码非 0 即需处理)、`docs-sync-check.sh`(双端对账)、`docs-manifest.py`(机读清单)、`handoff-guard.sh`(并发预检,推送前 `PUSH=1`)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 附:本技能的自检(用完之后问自己)
|
|
|
|
|
|
|
|
|
|
|
|
1. 我有没有**先取证再下结论**?(A1)
|
|
|
|
|
|
2. 我给的方案里有没有**"不做"**这一条?(A2)
|
|
|
|
|
|
3. 未定的决策点,我是**问用户**了还是自己替他定了?(A3)
|
|
|
|
|
|
4. 我的"最优解"能通过 §4.2 十问吗?
|
|
|
|
|
|
5. 我的验收口径是 L1 还是 L5?**有没有把推断说成实测**?
|
|
|
|
|
|
6. 这次操作**会不会命中红线 R5/R7/R8**?
|
|
|
|
|
|
7. 收口时**三层沉淀**做了吗?有没有造出第二个漂移源?
|
|
|
|
|
|
8. 技术实现我是**按 §4.4 的裁决顺序**自己定的吗?还是又把技术选项拿去问用户了?(若问了 → 违反 `dsh-feature-first`)
|
|
|
|
|
|
9. 我这次「停手等确认」,是按**实际影响面**判的吗?还是只看到「部署 / 上线 / 生产」这类**词**就触发了门禁?(X9)
|
|
|
|
|
|
10. 我的答复**第一句**是在答用户问的那件事吗?有没有把「我的失误 / 进度 / 计划」写在前两节?(X10 / U21)
|
|
|
|
|
|
11. 动手前我过「**两条总闸**」了吗?—— ① **这落在谁的 lane**(不是我的 → 只报告,**X11**)② **命中真门禁了吗**(没命中 → 自己拍,别问,**U20 / X9**)
|
|
|
|
|
|
12. 这条回复**能被扫吗**?—— 排版按 `dsh-feature-first §5.4`(首屏 3 行给判定 · 每节 ≤7 行 · 加粗只留关键词 · 表格 ≤5 列 · 一条信息只说一次)
|