---
name: lina-openspec-archive-consolidate
description: >-
  按功能职责对已归档的 OpenSpec 迭代内容进行聚合分类和高价值摘要压缩，并要求插件相关聚合归档和 specs 目录以 <plugin-id> 前缀区分主框架内容。
  必须用户手动触发，禁止自动触发该技能。
---

# Archive Consolidate（归档迭代聚合）

扫描 `openspec/changes/archive/` 下以日期开头命名的原始已归档变更，按功能职责分类，对每个分类下的多个迭代进行**语义合并**和**高价值摘要压缩**，生成一个结构与普通归档变更完全一致、内容连贯自然的新归档目录。执行压缩时必须逐个输入目录读取并理解`proposal.md`、`design.md`、`tasks.md`和`specs/`下全部规范内容；脚本只能用于目录枚举、文件检查、校验和格式验证，禁止用于生成摘要正文或替代语义覆盖判断。合并后的文档不包含"本文档聚合了 N 个迭代"等元描述，读起来像一个从头设计的完整变更，同时保证需求背景、设计决策、最终规范、反馈闭环、验证证据和审查治理影响不丢失。聚合结果写入并验证语义覆盖后，默认清理本次实际输入且已成功合并的原始日期前缀归档目录，避免`archive/`下同时保留原始碎片和聚合结果。归档数量 ≥ 8 时自动通过完整`OpenSpec`流程跟踪聚合任务。该流程生成的`openspec/changes/archive-consolidation/`仅是临时执行记录，不是需要长期保留的业务变更；聚合完成后必须删除该临时变更目录，避免它继续被判定为活跃变更。

**默认读取边界**：未指定变更列表时，只读取目录名匹配 `^[0-9]{4}-[0-9]{2}-[0-9]{2}-` 的归档目录。不要把已生成的聚合归档目录（如 `plugin-framework/`、`system-config/`、`i18n/` 这类不以日期开头的功能分组目录）再次作为输入，避免重复聚合。只有当用户显式指定这些目录名时，才允许按指定列表读取。

**默认清理边界**：聚合成功后，默认只删除本次待处理集合中目录名匹配 `^[0-9]{4}-[0-9]{2}-[0-9]{2}-` 的原始归档目录。即使用户显式指定了非日期前缀目录，也不要默认删除这些目录；只有用户明确要求清理指定的非日期目录时才允许删除。

**摘要压缩边界**：聚合输出必须把普通任务流水压缩为维护摘要，但不得丢失 `FB-*` 反馈闭环、根因、修复说明、验证证据、审查结论、`i18n`、缓存一致性、数据权限、DI、跨平台和测试策略等高价值维护信息。`tasks.md`压缩以减少存储空间为首要目标，尽可能只保留最短维护证据；无法确认语义覆盖时，必须保留原始归档目录并报告阻断原因。

**交互语言**：与用户交互的内容语言以用户上下文使用的语言为准，用户使用英文则使用英文，用户使用中文则使用中文。

## 插件相关 OpenSpec 命名规则

“插件相关内容”指用户在`apps/lina-plugins/<plugin-id>/`下开发的具体业务插件功能及其 OpenSpec 规范，例如`john-content-cms`插件提供的 CMS 系统能力。不包括`apps/lina-core`中的插件宿主框架、插件生命周期、插件治理、`pluginbridge`、host service、源码插件嵌入或动态插件运行时等主框架通用能力。

聚合插件相关内容时，必须优先保证输出目录能区分主框架规范和插件业务规范：

- 优先从归档文档中的`apps/lina-plugins/<plugin-id>/`路径、`plugin.yaml`中的插件`id`、插件清单描述或规范正文识别`<plugin-id>`。
- 插件相关聚合归档目录必须以`<plugin-id>`开头。若聚合的是某个插件的整体能力，目录使用`openspec/changes/archive/<plugin-id>/`；若同一插件需要拆分多个独立功能分组，目录使用`openspec/changes/archive/<plugin-id>-<capability>/`。
- 插件相关`specs/`能力目录必须以`<plugin-id>`开头。允许使用`specs/<plugin-id>/spec.md`承载插件根能力，也允许使用`specs/<plugin-id>-<capability>/spec.md`承载插件内细分能力；禁止输出`specs/cms/`、`specs/article-management/`或`specs/settings/`这类无插件前缀目录。
- 同一次聚合中不同插件必须进入不同归档分组；不得把多个插件的业务规范合并到同一个泛化分组或同一个无插件前缀的`specs/`能力目录。
- 读取到历史遗留的无插件前缀插件规范时，聚合输出必须归一化为带`<plugin-id>`前缀的目录；归一化事实只写入最终报告，不写进`proposal.md`、`design.md`、`tasks.md`或`specs/`正文。
- 主框架插件基础设施仍按主框架能力分组，例如`plugin-framework`、`plugin-governance`、`plugin-host-service-extension`，不要套用某个业务插件 ID。

## 输入参数

调用技能时，用户可选择性地指定要处理的变更列表：

| 情况 | 行为 |
|---|---|
| **未指定变更列表** | 仅处理 `openspec/changes/archive/` 下目录名以 `YYYY-MM-DD-` 开头的原始归档变更 |
| **指定了变更列表** | 仅处理用户指定的变更，忽略其余已归档变更；显式指定的目录即使不是日期前缀也可以处理 |
| **明确要求压缩既有聚合目录** | 可以读取用户指定的非日期前缀聚合目录并执行摘要压缩，但默认不得删除这些非日期目录 |

默认行为是在聚合成功后清理已成功合并的原始日期前缀归档目录。若用户明确要求保留原始归档目录，则跳过原始归档清理，并在最终报告中说明这些目录仍保留在 `openspec/changes/archive/` 下。

指定方式示例（用户输入中包含变更名即视为指定）：
- "聚合 `2026-04-12-plugin-framework` 和 `2026-04-13-dynamic-plugin-rest-runtime`"
- "只处理 plugin 相关的这几个：plugin-framework, dynamic-plugin-rest-runtime, dynamic-plugin-embed-snapshot"
- "压缩既有聚合目录 plugin-framework 和 scheduled-jobs 的 tasks.md"
- "聚合 `john-content-cms` 插件相关归档，输出目录必须以 `john-content-cms` 开头"
- 直接粘贴一组目录名列表

若指定的变更目录不存在于 `openspec/changes/archive/`，在执行前报错并停止：

```
错误：以下指定变更在归档目录中不存在：
  - <change-id>
请检查目录名是否正确后重新执行。
```

## 执行流程

### 第一步 — 确定待处理变更集

```bash
find openspec/changes/archive -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort
```

- 若**用户已指定变更列表**：验证列表中每个目录名存在于归档目录，将该列表作为待处理集合
- 若**用户未指定**：只将目录名匹配 `^[0-9]{4}-[0-9]{2}-[0-9]{2}-` 的子目录作为待处理集合
- 若**用户未指定**：明确排除不以日期开头的目录，包括既有聚合目录 `<归档分组键>/`、手工汇总目录、临时目录或其他非原始归档目录
- 若用户明确要求压缩既有聚合目录：仅读取用户指定的非日期前缀目录；这些目录默认不进入可清理目录列表
- 不要通过"目录下存在 proposal.md/design.md/specs"来反推输入集合；默认输入集合必须由日期前缀规则决定

统计待处理数量。若**少于 8 个**，跳过第五步（无需进入 OpenSpec 流程）。记录所有目录名备用，并单独记录后续允许清理的目录列表：默认只包含待处理集合中匹配 `^[0-9]{4}-[0-9]{2}-[0-9]{2}-` 的目录。

### 第二步 — 读取待处理变更

对**第一步确定的待处理集合中的每个**变更目录，逐个目录读取以下文件（文件不存在时记录缺失并跳过该文件，不得跳过同目录其他文件）：

```
openspec/changes/archive/<name>/proposal.md
openspec/changes/archive/<name>/design.md
openspec/changes/archive/<name>/tasks.md
openspec/changes/archive/<name>/specs/**/*.md   （所有 Markdown 规范文件）
```

读取要求：
- 必须逐个输入目录完整读取`proposal.md`、`design.md`、`tasks.md`和`specs/`下所有`*.md`文件的语义；不要只读取标题、目录名、文件名或关键字命中片段
- 可以使用命令枚举目录和文件路径，但高价值摘要压缩正文必须由执行者基于已读取内容逐段语义重写
- 禁止使用脚本、正则拼接、自动摘要程序或批量文本转换工具生成`proposal.md`、`design.md`、`tasks.md`或`specs/`的摘要正文
- 禁止把脚本输出、文件清单、关键字计数或未实际阅读的路径列表作为语义覆盖证据
- 若某目录内容过多导致上下文压力，必须按目录或按 `specs/`能力分批读取和压缩；每批仍需完整覆盖该目录下对应文件语义

对每个变更收集以下信息：
- **change-id**：目录名（如 `2026-04-12-plugin-framework`）
- **date**：目录名的日期前缀（若用户显式指定了非日期目录，则留空）
- **title**：从目录名或 proposal.md 第一个标题推导
- **why**：proposal.md 中"Why / 背景"章节（逐字原文）
- **what**：proposal.md 中"What Changes / 变更内容"章节（逐字原文）
- **capabilities**：proposal.md 中"Capabilities / 能力"章节（逐字原文，如有）
- **impact**：proposal.md 中"Impact / 影响"章节（逐字原文，如有）
- **design-summary**：design.md 全文
- **tasks-summary**：tasks.md 全文
- **specs**：`specs/`下每个 Markdown 规范文件的全文
- **plugin-id**：若该变更属于`apps/lina-plugins/<plugin-id>/`下的具体业务插件能力，记录识别到的插件 ID；若属于主框架插件基础设施，明确记录为主框架能力而非业务插件
- **plugin-spec-normalization**：若输入中存在无插件前缀的插件能力目录，记录需要归一化到的`<plugin-id>`前缀目录

### 第三步 — 按功能职责分类

将每个变更归入唯一的功能分组。目标是把触及同一功能领域的变更聚在一起。推荐分组分类（根据实际内容增减或拆分）：

| 分组键 | 典型变更内容 |
|---|---|
| `foundation` | 项目初始化、框架搭建、目录结构、Go/前端脚手架 |
| `user-auth` | 登录/登出、JWT、会话管理、认证中间件、密码重置 |
| `user-management` | 用户 CRUD、角色、权限、菜单管理 |
| `org-structure` | 部门、岗位、字典模块 |
| `system-config` | 系统设置、配置管理、上传配置、运行时配置 |
| `system-monitor` | 系统信息、服务器监控、操作/登录日志 |
| `notification` | 通知、消息、公告模块 |
| `file-storage` | 文件上传、存储后端、静态资源 |
| `plugin-framework` | 插件加载、注册、生命周期、嵌入、WASM/Go 插件运行时 |
| `plugin-governance` | 插件鉴权、路由可见性、安装/启用快捷方式、Mock 数据安装 |
| `scheduled-jobs` | 任务管理、Cron 调度、内置任务边界 |
| `i18n` | 国际化基础、i18n 治理、硬编码字符串清除 |
| `e2e-testing` | E2E 测试套件结构、测试隔离、Playwright 规范 |
| `devops-tooling` | 升级治理、数据库配置去重、性能审计技能、开发工具 |
| `code-quality` | GoFrame 规范对齐、panic 治理、代码质量改进、分布式缓存 |
| `distributed-infra` | 分布式锁、缓存一致性 |

每个变更最多归入一个分组。有歧义时优先选择描述该变更**主要交付物**的分组。

插件业务能力必须先按`<plugin-id>`隔离，再按插件内功能职责细分：

- 若变更属于`apps/lina-plugins/<plugin-id>/`下的具体业务插件能力，分组键必须是`<plugin-id>`或`<plugin-id>-<capability>`，例如`john-content-cms`或`john-content-cms-content-workflow`。
- 插件业务能力不得归入`plugin-framework`、`system-config`、`notification`、`cms`等主框架或泛化业务分组，除非该变更的主要交付物确实是主框架通用能力。
- 多个插件即使能力相似，也必须分别生成各自的插件前缀分组，避免后续主框架升级或插件迁移时混淆规范来源。

### 第四步 — 为每个分组生成语义合并后的归档目录

对**至少包含一个变更的每个分组**，在归档目录下新建：

```
openspec/changes/archive/<归档分组键>/
  proposal.md
  design.md
  tasks.md
  specs/
    <能力名>/          ← 主框架能力使用 kebab-case；插件能力必须以 <plugin-id> 开头
      spec.md
    <能力名>/
      spec.md
    …
```

其中`<归档分组键>`必须满足第三步分类结果。主框架能力使用原功能分组键；插件业务能力必须使用`<plugin-id>`或`<plugin-id>-<capability>`，例如`openspec/changes/archive/john-content-cms/`，不得使用`openspec/changes/archive/cms/`。

#### 语义合并原则

**语义合并不是拷贝，而是理解后重写。** 目标是让生成的文档像一个从头完整设计的变更，而非多个迭代的拼接。具体要求：

- **去掉一切元信息**：不写"本文档聚合了 N 个迭代"、不出现"原迭代 change-id"之类的说明
- **合并同类语义**：多个迭代涉及同一能力（如"插件生命周期"）时，将其描述整合为一段连贯的陈述，不重复
- **保留所有语义节点**：每个迭代引入的需求动机、设计决策、约束条件、验收场景都必须体现在合并结果中，不能因为"已在其他迭代说过类似的"而丢弃
- **消解矛盾与演进**：若后续迭代修订了早期迭代的设计，以最终版本为准，但保留背后的演进动机（"为什么从 A 改为 B"），将其作为设计约束或背景说明融入文档

#### 高价值摘要压缩原则

聚合结果必须按维护目标分层承载历史信息，不要把所有过程记录都放回`tasks.md`。压缩必须基于每个输入目录的`proposal.md`、`design.md`、`tasks.md`和`specs/`完整语义综合判断，不能只从`tasks.md`抽取摘要。

| 信息类型 | 输出位置 | 处理方式 |
|---|---|---|
| 背景、痛点、目标、影响 | `proposal.md` | 合并为稳定背景和范围说明 |
| 架构决策、方案演进、废弃方案、关键约束 | `design.md` | 以最终设计为准，保留演进动机 |
| 最终需求、验收场景、能力契约 | `specs/<capability>/spec.md` | 同名能力语义合并，不重复拼接 |
| `FB-*`、根因、修复说明、验证、审查、治理影响 | `tasks.md` | 压缩为最短维护摘要 |
| 普通 checklist、重复命令、逐文件搬迁流水 | `tasks.md` | 优先裁剪，必要时合并为一句关键交付摘要 |

裁剪低价值流水时，必须确认它已经被`proposal.md`、`design.md`、`specs/`或`tasks.md`摘要覆盖。无法确认时，保留最短摘要并在最终报告中列为未压缩或未清理原因。不要为了模板完整保留空章节、重复的“无”项或没有维护价值的任务清单。

#### proposal.md — 语义合并写法

将所有迭代的 **Why / 背景**、**What Changes / 变更内容**、**Capabilities / 能力**、**Impact / 影响** 合并为一份结构完整的 proposal，格式与普通归档 proposal.md 一致：

```markdown
## Why

<将各迭代"Why"中的动机、背景、痛点整合为一段或几段连贯叙述。
 相同动机只写一次，不同动机各自保留。>

## What Changes

<将各迭代的变更项整合为一份统一的能力/功能列表。
 同一能力多个迭代都涉及时，合并为一条并体现完整语义。>

## Capabilities

### New Capabilities

<整合所有迭代新增的能力，去重后按能力主题列出>

### Modified Capabilities

<整合所有迭代修改的能力>

## Impact

<整合所有迭代的影响说明，去重后列出>
```

#### design.md — 语义合并写法

将各迭代的 design.md 内容理解后重新组织，按**能力主题或架构模块**分节，而非按迭代分节：

```markdown
# Design

## <能力主题一>（如：插件注册与生命周期）

<融合所有迭代中与该主题相关的设计决策、架构选择、关键约束，
 写成连贯的设计描述。若迭代间存在演进关系，以最终设计为准，
 将演进动机作为约束或背景说明融入（"最初设计为 X，因 Y 原因改为 Z"）。>

## <能力主题二>

<同上>

…
```

若某迭代无 design.md，其设计信息通过 proposal.md 中的设计相关描述补充进来。

#### tasks.md — 维护摘要压缩写法

将各迭代的`tasks.md`压缩为一份以**减少存储空间**为首要目标的维护摘要，而非按迭代分节，也不是保留完整执行流水。只保留未来排障、审查或设计追溯仍需要的信息；已被`proposal.md`、`design.md`或`specs/`稳定承载的内容不要在`tasks.md`重复。

```markdown
# Tasks

## Summary

- [x] <最短关键交付摘要；如设计和规范已完整覆盖，可省略普通交付流水>
- [x] FB-<N>: <反馈主题>；根因：<根因或合理假设>；处理：<最终修复方向>；验证：<验证结论>
- [x] 验证：<必要的自动化验证、手工验证、静态检查或 OpenSpec 校验摘要>
- [x] 治理：<必要的 i18n / 缓存一致性 / 数据权限 / DI / 跨平台 / 测试策略影响判断>

## Retained

- [x] <仅当存在无法安全压缩的历史片段时保留本节并说明原因>
```

所有已完成摘要项标记为`[x]`（归档变更均已完成）。不同迭代中语义相同的任务合并为一条；普通 checklist、重复验证命令、逐文件搬迁清单和已被`proposal.md`、`design.md`或`specs/`覆盖的执行流水必须优先裁剪。若没有`FB-*`、根因、关键验证、审查结论或治理影响判断，`tasks.md`可以只保留`# Tasks`和一个最短`## Summary`。不要为了保持固定模板写入空泛的“未压缩或保留原因：无”。包含`FB-`编号、用户反馈、根因、修复说明、关键验证、审查结论、`i18n`、缓存一致性、数据权限、DI、开发工具跨平台或测试策略的内容不得直接删除，必须进入最短维护摘要、迁移到`design.md`，或在最终报告中说明无法压缩原因。

#### specs/ — 语义合并写法

与标准 OpenSpec `specs/` 目录结构完全一致：每个能力对应一个子目录，目录内只有一个 `spec.md`：

```
specs/
  <能力名>/
    spec.md
  <能力名>/
    spec.md
  …
```

**能力名**使用 kebab-case（如`plugin-manifest-lifecycle`、`cron-job-management`）。主框架能力与原迭代中的`specs`子目录命名保持一致；插件业务能力必须使用`<plugin-id>`或`<plugin-id>-<capability>`，例如`john-content-cms`或`john-content-cms-article-management`。

**合并规则：**
- 收集分组内所有迭代的 `specs/<能力名>/` 子目录，将同名能力的多份 `spec.md` 语义合并为一份，写入 `specs/<能力名>/spec.md`
- 不同迭代涉及不同能力时，各自独立写入对应子目录，不合并
- 若多个迭代对同一能力的规范存在演进，以最终版本为合并基准，将演进约束或修订动机融入 spec.md 正文，不出现"迭代 X 修改了此条"之类的元标注
- 规范内容按标准规范格式书写（需求声明、场景、验收标准等），不出现来源迭代信息
- 对插件业务能力，若输入历史归档使用了无插件前缀目录（如`specs/cms/`），输出时必须按识别到的`<plugin-id>`归一化为`specs/<plugin-id>/`或`specs/<plugin-id>-<capability>/`；不能继续沿用无插件前缀目录
- 对主框架插件基础设施，继续使用主框架能力目录（如`specs/plugin-framework/`），不要误改为某个业务插件前缀

### 第五步 — 通过完整 OpenSpec 流程跟踪聚合工作

**仅在归档数量 ≥ 8 时执行本步骤。**

不直接创建变更文件，而是走完整的 OpenSpec 研发流程：**探索 → 提案 → 实施**。该流程中的 `archive-consolidation` 变更只用于跟踪本次归档聚合，不作为长期活跃变更保留。

#### 5a. 探索阶段（/opsx:explore）

调用 `/opsx:explore` 技能，向用户呈现以下探索输入，引导分析聚合需求：

- **背景**：归档目录已积累 `<N>` 个变更，涉及 `<M>` 个功能分组
- **分组清单**：列出第三步识别的所有分组及其成员迭代数量
- **核心问题**：
  - 哪些分组优先聚合？（按迭代数量、功能重要性）
  - 聚合时哪些语义细节需要重点保留？
  - 是否有分组需要进一步拆分或合并？

与用户确认分组方案和优先级后，进入提案阶段。

#### 5b. 提案阶段（/opsx:propose）

调用 `/opsx:propose archive-consolidation` 技能，基于探索阶段的结论自动生成：

- **proposal.md**：聚合背景、目标、各分组说明
- **design.md**：分组归属清单、输出目录结构、语义合并策略
- **tasks.md**：每个分组对应一条实施任务，按优先级排序

tasks.md 任务格式参考：

```markdown
# Tasks

## Implementation

- [ ] **T-<N>**: 语义合并 `<归档分组键>` 分组 → `archive/<归档分组键>/` — <数量> 个迭代：<逗号分隔的 change-id 列表>
```

#### 5c. 实施阶段（/opsx:apply）

提案确认后，调用 `/opsx:apply` 按 tasks.md 中的任务逐条执行第四步的语义合并工作。

### 第六步 — 清理已聚合的原始归档迭代目录

**仅在所有聚合归档目录已经写入完成、必要验证通过且语义覆盖门禁通过后执行本步骤。**

删除本次实际输入且已成功合并的原始归档迭代目录：

```
openspec/changes/archive/<YYYY-MM-DD-...>/
```

清理要求：

- 默认只清理第一步记录的可清理目录列表；这些目录必须同时满足“属于本次待处理集合”和“目录名匹配日期前缀”
- 清理前必须确认每个输入归档的背景、设计决策、增量规范、反馈闭环、验证证据和审查治理影响均已进入聚合输出，或已明确判定为不存在
- 清理前逐项确认每个待删路径严格位于 `openspec/changes/archive/` 下，且目录名匹配 `^[0-9]{4}-[0-9]{2}-[0-9]{2}-`
- 禁止使用通配符、父目录路径或基于归档分组键推导出的路径执行删除；删除目标必须来自第一步记录的明确目录名列表
- 禁止删除或清空 `openspec/changes/archive/<归档分组键>/` 聚合结果目录、非日期前缀手工目录、未参与本次处理的目录，以及 `openspec/changes/archive/` 根目录
- 若某个原始归档目录未能成功合并到任何聚合结果，或无法确认高价值语义已经被摘要覆盖，禁止删除该目录，并在最终报告中列为未清理项
- 若用户明确要求保留原始归档目录，则跳过本步骤，并在最终报告中说明保留原因
- 若清理失败，必须在最终报告中明确列出失败目录和失败原因，不得声称这些目录已经清理

### 第七步 — 清理临时 OpenSpec 跟踪变更

**仅当第五步实际创建或复用了 `openspec/changes/archive-consolidation/` 时执行本步骤。**

删除整个临时跟踪目录：

```
openspec/changes/archive-consolidation/
```

清理要求：

- 删除的是 `openspec/changes/archive-consolidation/` 目录本身，而不是只清空其中的文件；只清空内容会留下空目录，仍可能被文件系统规则判定为活跃变更
- 删除前必须确认目标路径严格等于 `openspec/changes/archive-consolidation/`，禁止使用通配符、父目录路径或任何会影响 `openspec/changes/archive/` 的路径
- 只有在所有聚合归档目录已经写入完成、必要验证已经执行、最终报告内容已经准备完毕之后，才允许清理该临时目录
- 若用户明确要求保留临时跟踪记录，则跳过清理，并在最终报告中说明该目录仍会被视为活跃 OpenSpec 变更
- 若清理失败，必须在最终回复中明确说明失败原因，不得声称当前工作区已经没有该临时活跃变更

### 第八步 — 输出报告

所有文档写入和清理完成后，输出以下报告：

```
## 归档聚合完成

归档数量：<N> 个变更
识别分组数：<M> 个
已生成聚合归档目录：
  - openspec/changes/archive/<归档分组键>/  （<N> 个迭代）
  … （每个分组一行）
已清理原始归档迭代目录：
  - openspec/changes/archive/<YYYY-MM-DD-...>/
  … （每个已清理目录一行；若用户要求保留或清理失败，列出原因）
摘要压缩结果：
  保留的高价值信息类别：<背景 / 设计决策 / specs / FB / 根因 / 验证 / 审查 / i18n / 缓存 / 数据权限 / DI / 跨平台 / 测试策略>
  裁剪的低价值信息类别：<普通 checklist / 重复命令 / 逐文件流水 / 已被设计或规范覆盖的任务>
  插件规范命名处理：<无插件内容 / 已按 plugin-id 前缀输出 / 存在无法识别 plugin-id 的阻断项>
  未压缩或未清理原因：<如无则写"无">
  语义覆盖验证：<通过 / 未通过，并说明依据>

<如果执行了第五步：>
归档数量 ≥ 8，已进入 OpenSpec 完整流程：
  探索阶段（/opsx:explore）：分组方案已与用户确认
  提案阶段（/opsx:propose）：archive-consolidation 变更已生成
  实施阶段（/opsx:apply）：按任务逐条执行语义合并
  临时跟踪变更：已删除 openspec/changes/archive-consolidation/（若失败则列出原因）

<如果跳过了第五步：>
（归档数量少于 8 个，无需进入 OpenSpec 流程。）
```

## 硬性规则

- **只清理本次已成功合并的原始归档目录** — 默认只允许删除本次待处理集合中匹配 `^[0-9]{4}-[0-9]{2}-[0-9]{2}-` 的原始归档目录；禁止删除聚合结果目录、非日期前缀手工目录、未参与本次处理的目录或 `openspec/changes/archive/` 根目录
- **必须清理临时跟踪变更** — 当归档数量 ≥ 8 且创建或复用了 `openspec/changes/archive-consolidation/` 时，完成报告后必须删除该临时目录；该规则不适用于 `openspec/changes/archive/` 下的任何聚合结果或原始归档目录
- **逐目录完整读取** — 高价值摘要压缩前必须逐个输入目录读取`proposal.md`、`design.md`、`tasks.md`和`specs/`下全部 Markdown 规范文件；不得只依赖目录名、标题、关键字扫描、文件清单或片段抽取
- **禁止脚本压缩正文** — 脚本和命令只能用于目录枚举、文件检查、校验和格式验证；不得用脚本、正则拼接、自动摘要程序或批量文本转换生成聚合文档正文
- **`tasks.md`优先减小体积** — `tasks.md`以减少存储空间为首要目标，只保留最短维护证据；已由`proposal.md`、`design.md`或`specs/`承载的执行流水必须优先裁剪
- **语义不能丢失** — 合并后的文档必须覆盖每个迭代引入的所有需求动机、设计决策、约束条件和验收场景，即使表述方式与原文不同
- **维护证据不能丢失** — `FB-*`、根因、修复说明、验证证据、审查结论、`i18n`、缓存一致性、数据权限、DI、跨平台和测试策略必须进入摘要、设计或最终报告，不得作为普通任务流水直接裁剪
- **插件规范必须带插件前缀** — 聚合`apps/lina-plugins/<plugin-id>/`下具体业务插件能力时，输出归档目录和`specs/`能力目录都必须以`<plugin-id>`开头；无法识别唯一`<plugin-id>`时不得生成泛化目录，必须报告阻断原因
- **清理前必须通过语义覆盖门禁** — 无法确认聚合输出覆盖输入归档高价值语义时，必须失败或保留原始目录，不得静默删除
- **不出现元信息** — 合并结果中不允许出现迭代 ID、"本文档聚合了 N 个迭代"、"原迭代 change-id 新增"等说明；文档应读起来像从头设计的完整变更
- **演进以最终版本为准** — 若多个迭代对同一设计存在修订，以最终版本为合并基准，将演进动机以约束或背景说明的形式融入，而非并列罗列
- 若某个分组只有一个变更，仍需生成对应归档目录，并按本技能要求完成语义重写和`tasks.md`压缩；不得因为无需跨迭代合并而直接复制原文
- 若 `archive/<归档分组键>/` 目录已存在（后续有新归档迭代加入同一分组），将新迭代的语义合并进已有文档，而非覆盖或跳过；在报告中注明哪些迭代是本次新增合并的
- 若 `archive-consolidation` 变更已存在且处于活跃状态，不再新建，而是将新任务追加到其现有 tasks.md 中；该目录仍是临时跟踪目录，完成后必须按第七步删除
- 所有路径均相对于仓库根目录
