Skip to content

SDD 规格驱动维护规范

本仓库采用轻量 Specification-Driven Development(SDD)维护模式。需求规格是“做什么以及什么结果算完成”,实施计划是“怎么做以及如何验证”,代码和测试不能替代规格,目标环境验收不能被本地构建结果替代。

规范入口

内容唯一维护入口
需求规格docs/requirements/
实施计划docs/plans/
真实环境验收证据docs/validation/
应用和插件面向用户说明docs/ 下的应用/插件文档
跨需求架构决策docs/decisions/,仅在计划中的决策章节不足以表达时使用

不新建与 requirements/plans/ 重复的 specs/stories/ 目录。apps/*/README.mdplugins/*/README.md 保留作历史或兼容参考,不作为现行需求和面向用户文档的权威入口。

开发类文档(docs/development/)按主题分组维护:环境与工具、应用开发、插件开发、任务与构建、协作与规范。单页承担三个以上互不相关主题、或篇幅超过约 300 行时,按主题拆分并在侧边栏归入对应分组;不要把一个主题的内容分散到多页,也不要让单页变成混合罗列的长清单。拆分或改名后必须更新全部交叉引用和侧边栏配置,并用 pnpm run build -- --docs 确认链接与图表正常。

变更分类

变更类型必需产物最低验证
新功能、用户行为、权限、数据、网关或插件契约变化需求规格 + 实施计划 + 验收条件代码/测试 + 文档构建;涉及 fnOS 时必须真实 NAS 验收
现有功能行为修复原需求变更记录 + 计划调整;影响较大时新增需求回归测试和对应环境验证
安全、依赖、构建或发布变化变更说明 + 风险/回滚 + 校验结果受影响的构建、安装、升级或安全检查
仅文档、格式或内部重命名变更说明git diff --checkpnpm run build -- --docs

标准流程

text
提出变更
  ├─ 记录或新增需求规格
  ├─ 评审范围、优先级和验收条件
  ├─ 建立对应实施计划和任务追踪
  ├─ 编码并补齐测试/构建验证
  ├─ 在目标 fnOS NAS 完成功能验收
  ├─ 写入验收证据并回写需求/计划状态
  └─ 关联版本、变更记录和回滚方式

未进入计划的 P2、后续计划和未确认能力不得出现在当前计划的阶段任务、详细交互、完成状态或测试清单中。

追踪 ID

新增 P0/P1 功能建议形成以下链路:

对象格式示例
需求功能FNOS-###-##FNOS-001-10
验收条件<功能 ID>-AC-##FNOS-001-10-AC-01
计划任务PLAN-FNOS-###-T##-##PLAN-FNOS-001-T10-01
测试场景<功能 ID>-TEST-##FNOS-001-10-TEST-01
环境证据<功能 ID>-ENV-##FNOS-001-10-ENV-01

每个 P0/P1 功能至少要能从需求追踪到验收条件、计划任务、测试和目标环境结论。计划文档可以维护追踪矩阵,不复制需求正文。

状态规则

  • 已完成:代码、必要构建和目标环境验收全部完成。
  • 待完成:代码或本地验证完成,但目标环境尚未验收。
  • 规划中:已进入计划,尚未完成实现。
  • 待验证:依赖 SDK、宿主、权限或 DSH seam 的事实确认。
  • 待确认:需求边界尚未确认,未进入计划。
  • 后续计划:已登记但未进入当前计划。

状态变化必须追加到需求或计划的变更记录,不能只修改徽章。

编码边界

以下是仓库级的硬性约束,适用于所有受版本管理的文件。违反这些约束的改动不应提交,Agent 和协作者都必须遵守。

禁止绝对路径

不得在受版本管理的文件中写入开发者本机绝对路径,包括 /Users/<name>/.../home/<name>/...、Windows 盘符路径,以及指向其他检出的路径。

这类路径只在写入它的机器和检出目录下成立:换机器、换目录或仓库改名后立即失效;若指向其他检出,本仓库的检查结果还会随那个仓库的状态变化,表现为「时好时坏」而看不出原因。

按场景选择替代方式:

场景做法示例
同包或相邻模块相对导入import { x } from '../src/foo.ts'
跨 workspace 引用包名别名,由 workspace:* 解析import { y } from '@tnnevol/dsh-semi-ui'
需要绝对路径定位文件基于当前模块位置运行时解析见下
fnOS 应用脚本平台提供的环境变量${TRIM_PKGVAR}${TRIM_APPDEST}

测试中读取源码做结构断言时,用运行时解析而不是写死路径:

ts
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'

const here = dirname(fileURLToPath(import.meta.url))
const srcPath = (...segments: string[]) => join(here, '..', 'src', ...segments)

配置文件可直接用 import.meta.dirname(Node 20.11+,本项目 Node 24 满足)。

例外与边界:

  • 被忽略的目录(node_modules/.turbo/docs/.vitepress/dist)不在约束范围内。
  • 描述该规则本身时不可避免要写出被禁形态;判据以真实用户名为准,占位写法(/Users/<name>/...)属说明性文本,不算违规。
  • 文档中作为外部示例的绝对路径不受限,但不要使用真实个人主目录。

PR 检查清单

  • [ ] 已填写变更类型、需求编号和计划编号;纯文档/格式变更已说明豁免原因。
  • [ ] 新增或修改的用户行为有可观察的验收条件。
  • [ ] 计划只包含已进入实施阶段的功能。
  • [ ] 已运行与改动相关的插件测试、构建、pnpm run check -- --sddpnpm run build -- --docs
  • [ ] 涉及 fnOS 权限、宿主、FPK 安装或升级的功能已记录真实 NAS 验收状态。
  • [ ] 已说明数据影响、敏感信息、升级兼容和回滚方式。
  • [ ] 需求、计划和验证记录中的链接与追踪 ID有效。
  • [ ] 没有引入本机绝对路径;路径定位使用相对路径、包名别名或运行时解析(见编码边界)。

例外规则

依赖升级、构建修复和紧急安全修复可以不新增完整用户需求,但必须在 PR 和变更记录中说明原因、影响、验证和回滚方式。紧急修复完成后,应在下一个维护周期补齐受到影响的需求或决策记录。

基于 VitePress 构建