【OpenSpec】/opsx:archive 的作用是什么解析

/opsx:archive 的作用可以概括为:

宣告一个 OpenSpec Change 已经完成,把它从"正在进行的变更"转成"历史记录",同时确保 Main Spec 反映最终实现。

它不是压缩文件,也不是删除文档,而是 OpenSpec 生命周期中的"结项"操作。

归档前后发生什么

开发期间目录一般是:

text 复制代码
openspec/
├── specs/                         # 当前生效的主规范
└── changes/
    └── add-user-login/            # 正在开发的 Change
        ├── proposal.md
        ├── design.md
        ├── tasks.md
        └── specs/
            └── auth/
                └── spec.md        # Delta Spec

执行:

text 复制代码
/opsx:archive add-user-login

归档后变成:

text 复制代码
openspec/
├── specs/
│   └── auth/
│       └── spec.md                # 已同步最终需求
└── changes/
    └── archive/
        └── 2026-07-12-add-user-login/
            ├── proposal.md
            ├── design.md
            ├── tasks.md
            └── specs/
                └── auth/
                    └── spec.md

也就是:

text 复制代码
Active Change
    ↓
检查完成状态
    ↓
同步 Delta Spec
    ↓
移入 archive
    ↓
Historical Change

/opsx:archive 会做哪些事情?

1. 确定要归档哪个 Change

如果指定名称:

text 复制代码
/opsx:archive add-user-login

就处理该 Change。

如果没有指定:

text 复制代码
/opsx:archive

Agent 会查询:

bash 复制代码
openspec list --json

如果无法唯一确定,应该让用户选择,而不是随便挑选。

2. 检查 Artifact 是否完整

它会检查 Change 中是否存在必要产物,例如:

text 复制代码
proposal.md
specs/
design.md
tasks.md

通常会通过:

bash 复制代码
openspec status --change add-user-login --json

获取完成状态。

3. 检查任务是否完成

读取 tasks.md,检查是否还有:

markdown 复制代码
- [ ] 未完成任务

理想状态应该全部完成:

markdown 复制代码
- [x] 创建数据模型
- [x] 实现登录接口
- [x] 添加异常处理
- [x] 编写单元测试

如果仍有未完成任务,归档工作流通常会警告并要求确认。它不一定绝对阻止归档,因为有些任务可能被取消、转移或确认不再需要。

更规范的做法是先修改 tasks.md,明确反映最终状态,而不是带着含义不清的未完成项归档。

4. 判断 Delta Spec 是否已经同步

如果存在:

text 复制代码
openspec/changes/add-user-login/specs/auth/spec.md

它会检查对应的 Main Spec:

text 复制代码
openspec/specs/auth/spec.md

是否已经包含这些变更。

如果还没有同步,通常会询问:

text 复制代码
Delta specs have not been synced.
Sync now?

选择同步后,效果类似:

text 复制代码
/opsx:sync add-user-login

ADDEDMODIFIEDREMOVEDRENAMED 反映到 Main Spec。

5. 移动到带日期的归档目录

最终把:

text 复制代码
openspec/changes/add-user-login/

移动到:

text 复制代码
openspec/changes/archive/2026-07-12-add-user-login/

日期可以帮助确定变更发生的时间和先后顺序。

为什么最后必须归档?

严格地说,不归档并不会让已经写好的 Python 或其他业务代码停止运行。程序运行不依赖 archive 状态。

但从 OpenSpec 管理角度看,归档非常重要。

区分"当前状态"和"变更过程"

OpenSpec 中有两个不同概念:

text 复制代码
openspec/specs/     当前系统应该具备什么行为
openspec/changes/   当前准备改变什么行为

开发完成后,如果 Change 一直留在 active 目录,后续 Agent 会认为它仍在开发中。

这可能导致:

  • openspec list 长期显示已完成项目
  • Agent 不清楚 Change 是否还要继续
  • 新 Change 可能重复实现同一功能
  • 后续规划把已完成任务当成未完成任务
  • 多个 Change 之间更容易出现错误依赖
  • 团队无法区分进行中工作与历史工作

归档就是明确完成状态:

text 复制代码
这个 Change 已经结束,不再继续修改;
其最终需求已经进入 Main Spec;
原始决策过程保留为历史。

防止 Delta Spec 永远悬空

Delta Spec 只是"相对于当前规范要改变什么",不是系统长期的规范来源。

例如:

markdown 复制代码
## MODIFIED Requirements

### Requirement: Session Timeout

会话超时从 60 分钟修改为 30 分钟。

它只描述变化,不一定包含完整需求。

长期有效的规范应该整理到:

text 复制代码
openspec/specs/auth/spec.md

归档前同步,确保最终事实变成:

markdown 复制代码
### Requirement: Session Timeout

The system SHALL expire an inactive session after 30 minutes.

后续 Agent 只需要读取 Main Spec,就能知道当前系统要求,而不必遍历所有历史 Delta。

归档后还有作用吗?

有,而且归档记录是 OpenSpec 的重要价值之一。

1. 保留需求演变历史

Main Spec 告诉你:

系统现在应该是什么样。

Archive 告诉你:

为什么变成这样,当时考虑过什么,如何实施的。

例如:

text 复制代码
openspec/changes/archive/2026-07-12-add-user-login/

可以保留:

  • 为什么增加登录功能:proposal.md
  • 技术方案如何选择:design.md
  • 具体改变了哪些需求:Delta Spec
  • 实施时拆分了哪些任务:tasks.md
  • 哪些任务最终完成

2. 帮助后续 Agent 理解设计决策

后续开发者可能提出:

text 复制代码
把 JWT 改成服务端 Session

Agent 可以查看之前归档的 design.md,了解当时为什么选择 JWT:

  • 是否为了无状态部署
  • 是否考虑过 Session
  • 是否有移动客户端要求
  • 是否受现有网关约束

这能避免反复讨论或者推翻一个仍然有效的设计决定。

不过需要注意:正常情况下,后续 Agent 应先读取 Main Spec;只有需要理解历史原因时才读取 Archive。Archive 不是当前规范的替代品。

3. 审计和追溯

归档目录可以回答:

  • 某个需求什么时候加入?
  • 是哪个 Change 修改的?
  • 为什么删除一个 Requirement?
  • 当时预计有哪些风险?
  • 实现是否覆盖了计划任务?
  • 某项设计是一次性选择还是长期约束?

它相当于代码仓库内的轻量变更档案。

4. 帮助处理回归和故障

如果新功能上线后出现问题,可以根据归档内容对照:

text 复制代码
proposal → spec → design → tasks → code

判断问题来自:

  • 原始需求遗漏
  • 设计判断错误
  • 任务拆分遗漏
  • 实现偏离 Spec
  • 测试覆盖不足

5. 为类似功能提供参考

以后新增相似功能时,可以参考历史 Change 的:

  • Requirement 写法
  • Scenario 边界条件
  • 设计模板
  • 测试策略
  • 任务拆分粒度

但不建议直接复制整个归档,因为旧约束可能已经失效。

Archive 与 Git 历史有什么区别?

两者互补,不能完全替代。

内容 Git 历史 OpenSpec Archive
哪些代码发生变化 一般
谁在什么时候提交 依赖 Git
为什么做这个功能 通常较弱
原始需求是什么 不一定完整
设计方案是什么 不一定记录
验收场景是什么 分散在测试中 明确
任务如何拆分 通常没有 tasks.md
Main Spec 如何演变 需要分析 diff Delta Spec明确描述

Git 记录"文件怎么变了",OpenSpec Archive 记录"需求为什么变、计划如何落地"。

因此,归档目录应当和代码一起提交到 Git:

bash 复制代码
git add openspec
git commit -m "docs(openspec): archive add-user-login"

归档后还需要继续修改吗?

通常不应该直接修改归档内容。

归档目录应视为历史快照:

text 复制代码
openspec/changes/archive/2026-07-12-add-user-login/

如果后来发现需求需要改变,应创建新的 Change:

text 复制代码
/opsx:propose revise-user-login-lockout

而不是修改旧归档:

text 复制代码
2026-07-12-add-user-login

正确的历史应该是:

text 复制代码
2026-07-12-add-user-login
2026-08-03-add-login-lockout
2026-09-15-adjust-lockout-duration

这样才能看出规范如何一步步演变。

只有以下情况适合修正归档文件:

  • 明显拼写错误
  • 敏感信息误提交,需要安全清理
  • 归档过程产生结构错误
  • 仓库维护规则明确允许修复历史文档

推荐的完整收尾顺序

对于重要 Change,建议:

text 复制代码
/opsx:apply add-user-login

确认 tasks 全部完成,再执行:

text 复制代码
/opsx:verify add-user-login

运行项目测试:

bash 复制代码
pytest

检查规范:

bash 复制代码
openspec validate --all --strict

必要时单独同步:

text 复制代码
/opsx:sync add-user-login

查看差异:

bash 复制代码
git diff -- openspec/specs

最后归档:

text 复制代码
/opsx:archive add-user-login

再次检查:

bash 复制代码
openspec list
openspec list --specs
openspec validate --all --strict
git diff

一句话理解:

/opsx:archive 不是把完成的材料"收起来不用了",而是把临时的变更提案结算为当前规范,并把提案、设计和任务保存为可追溯的历史证据。后续日常开发读取 Main Spec,需要理解"为什么这样设计"时再查 Archive。

官方命令说明可参考 OpenSpec /opsx:archive 文档

相关推荐
星释1 天前
鸿蒙智能体开发实战:27.Skill 测试、发布与管理
ui·华为·log4j·harmonyos·鸿蒙·智能体
充钱大佬1 天前
Python测试基础教程
python·log4j·apache
xiaoshuaishuai82 天前
C# AI实现PR处理、单元测试
开发语言·c#·log4j
醉熏的斑马3 天前
ASP.Net MVC3 】使用Moq让单元测试变得更简单
单元测试·log4j·asp.net
cfm_29146 天前
SpringBoot MockMvc
spring boot·后端·log4j
天真的银耳汤7 天前
01 静态分析(Static Analysis)
log4j
周杰伦fans1 个月前
记一次 Visual Studio 突然报错“未能加载 Microsoft.Internal.VisualStudio.Interop”的奇葩经历
microsoft·log4j·visual studio
laplaya1 个月前
C++大型项目组件通信与依赖管理实践
c++·log4j·apache
福大大架构师每日一题1 个月前
ollama v0.30.7 正式发布:Hermes 桌面端落地,接口、文档、底层依赖全方位优化
golang·log4j