@betterdanlins/ai-memory 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +158 -14
- package/README.zh-CN.md +170 -0
- package/bin/cli.js +189 -5
- package/package.json +1 -1
- package/src/framework.js +260 -0
- package/src/legacy-v0.1.js +43 -0
- package/src/manifest.js +20 -1
- package/src/migrations.js +28 -0
- package/src/model-routing.js +108 -0
- package/src/path-safety.js +51 -0
- package/src/scaffold.js +114 -13
- package/src/workflow.js +185 -0
- package/templates/claude/.claude/agents/economy-test-worker.md +8 -0
- package/templates/claude/.claude/agents/premium-implementer.md +8 -0
- package/templates/claude/.claude/agents/premium-planner.md +8 -0
- package/templates/claude/.claude/agents/premium-reviewer.md +8 -0
- package/templates/claude/.claude/agents/standard-implementer.md +8 -0
- package/templates/claude/.claude/agents/standard-test-worker.md +8 -0
- package/templates/claude/.claude/commands/delivery-readiness.md +6 -0
- package/templates/claude/.claude/commands/design-feature.md +6 -0
- package/templates/claude/.claude/commands/finalize-requirement.md +1 -1
- package/templates/claude/.claude/commands/project-inception.md +5 -0
- package/templates/claude/.claude/settings.json +1 -1
- package/templates/claude/.claude/skills/critic/SKILL.md +2 -2
- package/templates/claude/.claude/skills/delivery-readiness/SKILL.md +6 -0
- package/templates/claude/.claude/skills/feature-design/SKILL.md +6 -0
- package/templates/claude/.claude/skills/memory-update/SKILL.md +1 -1
- package/templates/claude/.claude/skills/model-routing/SKILL.md +6 -0
- package/templates/claude/.claude/skills/project-inception/SKILL.md +6 -0
- package/templates/claude/CLAUDE.md +11 -5
- package/templates/codex/.agents/skills/critic/SKILL.md +2 -2
- package/templates/codex/.agents/skills/delivery-readiness/SKILL.md +6 -0
- package/templates/codex/.agents/skills/feature-design/SKILL.md +6 -0
- package/templates/codex/.agents/skills/memory-update/SKILL.md +1 -1
- package/templates/codex/.agents/skills/model-routing/SKILL.md +6 -0
- package/templates/codex/.agents/skills/project-inception/SKILL.md +6 -0
- package/templates/codex/.codex/agents/economy_test_worker.toml +6 -0
- package/templates/codex/.codex/agents/premium_implementer.toml +6 -0
- package/templates/codex/.codex/agents/premium_planner.toml +6 -0
- package/templates/codex/.codex/agents/premium_reviewer.toml +6 -0
- package/templates/codex/.codex/agents/standard_implementer.toml +6 -0
- package/templates/codex/.codex/agents/standard_test_worker.toml +6 -0
- package/templates/codex/AGENTS.md +11 -5
- package/templates/common/.ai/README.md +5 -1
- package/templates/common/.ai/config/model-routing.json +5 -0
- package/templates/common/.ai/memory/project-state.md +1 -1
- package/templates/common/.ai/memory/session-log.md +1 -1
- package/templates/common/.ai/runs/.gitignore +2 -0
- package/templates/common/.ai/skills/architecture.md +24 -14
- package/templates/common/.ai/skills/code-review.md +1 -1
- package/templates/common/.ai/skills/critic.md +4 -2
- package/templates/common/.ai/skills/delivery-readiness.md +34 -0
- package/templates/common/.ai/skills/feature-design.md +35 -0
- package/templates/common/.ai/skills/memory-update.md +19 -14
- package/templates/common/.ai/skills/model-routing.md +39 -0
- package/templates/common/.ai/skills/project-inception.md +33 -0
- package/templates/common/.ai/skills/requirements-flow.md +33 -16
- package/templates/common/docs/architecture/data-model.md +43 -0
- package/templates/common/docs/architecture/deployment.md +40 -0
- package/templates/common/docs/architecture/quality-attributes.md +50 -0
- package/templates/common/docs/architecture/system-context.md +35 -0
- package/templates/common/docs/design/README.md +22 -0
- package/templates/common/docs/design/v1.0.0/.gitkeep +0 -0
- package/templates/common/docs/requirements/README.md +2 -1
package/src/workflow.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { readModelRoutingConfig, resolveModelRouting, STAGES } from './model-routing.js';
|
|
5
|
+
import { assertNoSymlinkPath } from './path-safety.js';
|
|
6
|
+
|
|
7
|
+
const RISKS = ['S', 'M', 'L'];
|
|
8
|
+
|
|
9
|
+
export async function prepareHandoff({
|
|
10
|
+
targetDir, feature, stage, risk, inputs, acceptanceCriteria = [], allowedChangeScope = [], unresolvedDecisions = [],
|
|
11
|
+
}) {
|
|
12
|
+
validateFeature(feature);
|
|
13
|
+
if (!STAGES.includes(stage)) throw new Error(`未知工作流阶段: ${stage}`);
|
|
14
|
+
if (!RISKS.includes(risk)) throw new Error(`risk 仅支持 S、M、L,收到: ${risk}`);
|
|
15
|
+
if (!Array.isArray(inputs) || inputs.length === 0) throw new Error('至少需要一个 --input 正式输入文件');
|
|
16
|
+
if (requiresAcceptance(stage) && acceptanceCriteria.length === 0) {
|
|
17
|
+
throw new Error(`阶段 ${stage} 至少需要一个 --acceptance 验收标准编号`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const routing = resolveModelRouting(await readModelRoutingConfig(targetDir));
|
|
21
|
+
const records = [];
|
|
22
|
+
for (const input of [...new Set(inputs)]) {
|
|
23
|
+
const { relative, absolute } = resolveProjectInput(targetDir, input);
|
|
24
|
+
await assertNoSymlinkPath(targetDir, absolute);
|
|
25
|
+
let content;
|
|
26
|
+
try {
|
|
27
|
+
content = await readFile(absolute);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
if (err.code === 'ENOENT' || err.code === 'EISDIR') throw new Error(`交接输入不是可读文件: ${relative}`, { cause: err });
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
records.push({ path: relative, sha256: createHash('sha256').update(content).digest('hex') });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const handoff = {
|
|
36
|
+
schemaVersion: 1,
|
|
37
|
+
featureId: feature,
|
|
38
|
+
riskLevel: risk,
|
|
39
|
+
stage,
|
|
40
|
+
executorTier: routing[stage],
|
|
41
|
+
createdAt: new Date().toISOString(),
|
|
42
|
+
inputs: records,
|
|
43
|
+
acceptanceCriteria: uniqueStrings(acceptanceCriteria),
|
|
44
|
+
unresolvedDecisions: uniqueStrings(unresolvedDecisions),
|
|
45
|
+
allowedChangeScope: uniqueStrings(allowedChangeScope),
|
|
46
|
+
};
|
|
47
|
+
const handoffPath = handoffFile(targetDir, feature);
|
|
48
|
+
await assertNoSymlinkPath(targetDir, handoffPath);
|
|
49
|
+
await mkdir(path.dirname(handoffPath), { recursive: true });
|
|
50
|
+
await writeFile(handoffPath, JSON.stringify(handoff, null, 2) + '\n');
|
|
51
|
+
return { handoff, path: relativeFromRoot(targetDir, handoffPath) };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function verifyHandoff({ targetDir, feature, expectedStage }) {
|
|
55
|
+
validateFeature(feature);
|
|
56
|
+
const handoffPath = handoffFile(targetDir, feature);
|
|
57
|
+
await assertNoSymlinkPath(targetDir, handoffPath);
|
|
58
|
+
let handoff;
|
|
59
|
+
try {
|
|
60
|
+
handoff = JSON.parse(await readFile(handoffPath, 'utf8'));
|
|
61
|
+
} catch (err) {
|
|
62
|
+
if (err.code === 'ENOENT') throw new Error(`缺少交接清单: ${relativeFromRoot(targetDir, handoffPath)}`);
|
|
63
|
+
if (err instanceof SyntaxError) throw new Error(`交接清单不是有效 JSON: ${relativeFromRoot(targetDir, handoffPath)}`, { cause: err });
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
validateHandoff(handoff, feature);
|
|
67
|
+
if (expectedStage && handoff.stage !== expectedStage) {
|
|
68
|
+
throw new Error(`交接阶段不匹配: 期望 ${expectedStage},实际 ${handoff.stage}`);
|
|
69
|
+
}
|
|
70
|
+
if (handoff.unresolvedDecisions.length) {
|
|
71
|
+
throw new Error(`仍有 ${handoff.unresolvedDecisions.length} 个未决问题,不能进入 ${handoff.stage}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const routing = resolveModelRouting(await readModelRoutingConfig(targetDir));
|
|
75
|
+
if (handoff.executorTier !== routing[handoff.stage]) {
|
|
76
|
+
throw new Error(`模型路由已变化: ${handoff.stage} 当前应使用 ${routing[handoff.stage]},请重新 prepare`);
|
|
77
|
+
}
|
|
78
|
+
for (const record of handoff.inputs) {
|
|
79
|
+
const { absolute } = resolveProjectInput(targetDir, record.path);
|
|
80
|
+
await assertNoSymlinkPath(targetDir, absolute);
|
|
81
|
+
let current;
|
|
82
|
+
try {
|
|
83
|
+
current = await readFile(absolute);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
if (err.code === 'ENOENT') throw new Error(`交接输入已不存在: ${record.path}`);
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
const currentHash = createHash('sha256').update(current).digest('hex');
|
|
89
|
+
if (currentHash !== record.sha256) throw new Error(`交接输入已变化,请重新 prepare: ${record.path}`);
|
|
90
|
+
}
|
|
91
|
+
return handoff;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function recordStageResult({ targetDir, feature, resultPath }) {
|
|
95
|
+
const handoff = await verifyHandoff({ targetDir, feature });
|
|
96
|
+
const source = resolveProjectInput(targetDir, resultPath);
|
|
97
|
+
await assertNoSymlinkPath(targetDir, source.absolute);
|
|
98
|
+
let result;
|
|
99
|
+
try {
|
|
100
|
+
result = JSON.parse(await readFile(source.absolute, 'utf8'));
|
|
101
|
+
} catch (err) {
|
|
102
|
+
if (err.code === 'ENOENT') throw new Error(`阶段回执不存在: ${source.relative}`);
|
|
103
|
+
if (err instanceof SyntaxError) throw new Error(`阶段回执不是有效 JSON: ${source.relative}`, { cause: err });
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
validateStageResult(result, handoff);
|
|
107
|
+
const destination = path.join(targetDir, '.ai', 'runs', feature, `${handoff.stage}-result.json`);
|
|
108
|
+
await assertNoSymlinkPath(targetDir, destination);
|
|
109
|
+
await writeFile(destination, JSON.stringify(result, null, 2) + '\n');
|
|
110
|
+
return { result, path: relativeFromRoot(targetDir, destination) };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function validateHandoff(handoff, feature) {
|
|
114
|
+
if (!handoff || handoff.schemaVersion !== 1 || handoff.featureId !== feature) {
|
|
115
|
+
throw new Error(`交接清单格式或 featureId 无效: ${feature}`);
|
|
116
|
+
}
|
|
117
|
+
if (!STAGES.includes(handoff.stage) || !RISKS.includes(handoff.riskLevel)) {
|
|
118
|
+
throw new Error(`交接清单阶段或风险等级无效: ${feature}`);
|
|
119
|
+
}
|
|
120
|
+
if (!Array.isArray(handoff.inputs) || !handoff.inputs.length
|
|
121
|
+
|| !Array.isArray(handoff.acceptanceCriteria)
|
|
122
|
+
|| !Array.isArray(handoff.unresolvedDecisions)
|
|
123
|
+
|| !Array.isArray(handoff.allowedChangeScope)) {
|
|
124
|
+
throw new Error(`交接清单缺少必要字段: ${feature}`);
|
|
125
|
+
}
|
|
126
|
+
if (!['inherit', 'premium', 'standard', 'economy', 'none'].includes(handoff.executorTier)
|
|
127
|
+
|| handoff.inputs.some(record => !record || typeof record.path !== 'string' || !/^[a-f0-9]{64}$/.test(record.sha256))) {
|
|
128
|
+
throw new Error(`交接清单输入或执行等级无效: ${feature}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function validateStageResult(result, handoff) {
|
|
133
|
+
if (!result || typeof result !== 'object' || result.stage !== handoff.stage) {
|
|
134
|
+
throw new Error(`阶段回执 stage 必须为 ${handoff.stage}`);
|
|
135
|
+
}
|
|
136
|
+
if (!['completed', 'blocked', 'failed'].includes(result.status)) throw new Error(`阶段回执 status 无效: ${result.status}`);
|
|
137
|
+
for (const field of ['changedFiles', 'tests', 'designDeviations', 'unresolvedRisks']) {
|
|
138
|
+
if (!Array.isArray(result[field]) || result[field].some(value => typeof value !== 'string')) {
|
|
139
|
+
throw new Error(`阶段回执 ${field} 必须是字符串数组`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (!result.acceptanceCoverage || typeof result.acceptanceCoverage !== 'object' || Array.isArray(result.acceptanceCoverage)) {
|
|
143
|
+
throw new Error('阶段回执 acceptanceCoverage 必须是对象');
|
|
144
|
+
}
|
|
145
|
+
for (const [id, coverage] of Object.entries(result.acceptanceCoverage)) {
|
|
146
|
+
if (!id.trim() || !['covered', 'partial', 'not-covered', 'not-applicable'].includes(coverage)) {
|
|
147
|
+
throw new Error(`阶段回执验收覆盖无效: ${id}=${coverage}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const missing = handoff.acceptanceCriteria.filter(id => !(id in result.acceptanceCoverage));
|
|
151
|
+
if (missing.length) throw new Error(`阶段回执缺少验收覆盖: ${missing.join(', ')}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function resolveProjectInput(targetDir, input) {
|
|
155
|
+
if (typeof input !== 'string' || !input.trim() || path.isAbsolute(input)) throw new Error(`输入路径必须是项目内相对路径: ${input}`);
|
|
156
|
+
const root = path.resolve(targetDir);
|
|
157
|
+
const absolute = path.resolve(root, input);
|
|
158
|
+
const relative = path.relative(root, absolute);
|
|
159
|
+
if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
160
|
+
throw new Error(`输入路径越出项目目录: ${input}`);
|
|
161
|
+
}
|
|
162
|
+
return { absolute, relative: relative.split(path.sep).join('/') };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function handoffFile(targetDir, feature) {
|
|
166
|
+
return path.join(targetDir, '.ai', 'runs', feature, 'handoff.json');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function relativeFromRoot(targetDir, filePath) {
|
|
170
|
+
return path.relative(path.resolve(targetDir), filePath).split(path.sep).join('/');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function validateFeature(feature) {
|
|
174
|
+
if (typeof feature !== 'string' || !/^[\p{L}\p{N}][\p{L}\p{N}._-]*$/u.test(feature)) {
|
|
175
|
+
throw new Error(`feature 必须是单个安全目录名,收到: ${feature}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function uniqueStrings(values) {
|
|
180
|
+
return [...new Set(values.map(value => value.trim()).filter(Boolean))];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function requiresAcceptance(stage) {
|
|
184
|
+
return ['implementation', 'routine-tests', 'adversarial-testing', 'final-review'].includes(stage);
|
|
185
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: standard-implementer
|
|
3
|
+
description: 按已批准设计和计划实现功能。仅在模型路由要求 standard 实现或修复时使用。
|
|
4
|
+
model: sonnet
|
|
5
|
+
tools: Read, Edit, Write, Bash, Grep, Glob
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
先验证 handoff 并读取全部正式输入。只在 allowedChangeScope 内按计划实现和测试;不得重新定义需求或接口。发现设计缺口时停止并升级给 premium-planner。完成后写结构化阶段回执。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: critic
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when an M/L-risk requirement, architecture baseline, or implementation design needs independent adversarial review, or when the user explicitly requests critique, rebuttal, or challenge
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
派发 critic subagent(独立上下文,只给文档路径与 `.ai/skills/critic.md`,不给对话历史),随后按其纪律逐条回应质疑。
|
|
6
|
+
派发 critic subagent(独立上下文,只给文档路径与 `.ai/skills/critic.md`,不给对话历史),随后按其纪律逐条回应质疑。S 级需求由 requirements-flow 直接做精简自检,不要为其触发本 skill。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: delivery-readiness
|
|
3
|
+
description: Use when a feature is preparing to merge, release, deploy, or hand over and needs evidence-based verification of contracts, tests, migration, rollback, performance, observability, reliability, security, or operational readiness
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
读取并严格遵循 `.ai/skills/delivery-readiness.md`,按 S/M/L 风险检查适用项;不要重新执行需求澄清或技术设计。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: feature-design
|
|
3
|
+
description: Use when an M/L-risk finalized requirement needs implementation design, module or service boundaries, technical interface contracts, data-model changes, quality-attribute impact, migration, rollback, or an implementation-ready how document
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
读取并严格遵循 `.ai/skills/feature-design.md`,以 final 需求和项目架构基线为输入;不要重新讨论已确认的 what/why,也不要默认启动完整 Superpowers 流程。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memory-update
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when completing an independently verifiable feature, phase, or release; making a durable decision; changing requirement/design/delivery status; preserving a cross-session risk; switching tools; or when the user explicitly asks to update memory
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
读取并严格遵循 `.ai/skills/memory-update.md` 的写入路由与硬性约束执行。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-inception
|
|
3
|
+
description: Use when starting a 0-to-1/greenfield project, establishing its first engineering and architecture baseline, or planning a major redesign that changes system boundaries, data ownership, deployment topology, or quality-attribute targets
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
读取并严格遵循 `.ai/skills/project-inception.md`,建立或增量更新 `docs/architecture/` 四份工程基线;普通功能迭代不要触发。
|
|
@@ -4,14 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
进场先读 `.ai/memory/MEMORY.md`,随后遵循 `.ai/README.md` 的进场协议。
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- 0→1 项目/首次架构基线/重大重构 → project-inception skill,产物在 `docs/architecture/`;普通功能不要重复触发
|
|
8
|
+
- 需求 what/why 与外部行为定稿 → requirements-flow skill,产物在 `docs/requirements/vX.Y.Z/{draft,final}/`
|
|
9
|
+
- M/L 级功能 how 与技术接口 → feature-design skill,产物在 `docs/design/vX.Y.Z/`;S 级可直接实现
|
|
10
|
+
- 交付前 → delivery-readiness skill,按风险验证契约、测试、迁移、回滚、性能与可观测性
|
|
11
|
+
- 记忆更新 → 只在可验收工程节点、关键决策、状态变化或会话切换时写;手动 /update-memory
|
|
12
|
+
- 反驳检查 → S 级精简自检;M/L 级或用户明确要求时用 /critic 独立审查
|
|
13
|
+
- 模型路由 → 读取 `.ai/config/model-routing.json`;非 inherit 时按 model-routing skill 创建/验证 handoff,再调用匹配的 planner/implementer/test-worker/reviewer
|
|
10
14
|
|
|
11
15
|
## 与 superpowers 的编排(未安装则忽略本节)
|
|
12
16
|
|
|
13
|
-
1.
|
|
14
|
-
2.
|
|
17
|
+
1. final 需求已经确认 what/why,不要用 brainstorming 重复澄清目标与范围
|
|
18
|
+
2. S 级跳过 brainstorming/writing-plans;M 级只对未决高影响 how 选择性使用;L 级可使用完整流程
|
|
19
|
+
3. 所有 Superpowers 结论必须回写 `docs/design/`,临时 spec/plan 不是唯一事实源
|
|
20
|
+
4. code review 使用适合风险等级的流程,叠加 `.ai/skills/code-review.md` 的项目检查项
|
|
15
21
|
|
|
16
22
|
## 项目信息
|
|
17
23
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: critic
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when an M/L-risk requirement, architecture baseline, or implementation design needs adversarial review, or when the user explicitly requests critique, rebuttal, or challenge
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
读取 `.ai/skills/critic.md
|
|
6
|
+
读取 `.ai/skills/critic.md`,按四类清单攻击目标文档;输出带严重度的质疑列表后,逐条回应「接受并修改」或「有理由反驳」。S 级只做精简自检;M/L 级在当前工具无法提供独立上下文时降级自检,刻意抵制自我辩护。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: delivery-readiness
|
|
3
|
+
description: Use when a feature is preparing to merge, release, deploy, or hand over and needs evidence-based verification of contracts, tests, migration, rollback, performance, observability, reliability, security, or operational readiness
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
读取并严格遵循 `.ai/skills/delivery-readiness.md`,按 S/M/L 风险检查适用项;不要重新执行需求澄清或技术设计。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: feature-design
|
|
3
|
+
description: Use when an M/L-risk finalized requirement needs implementation design, module or service boundaries, technical interface contracts, data-model changes, quality-attribute impact, migration, rollback, or an implementation-ready how document
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
读取并严格遵循 `.ai/skills/feature-design.md`,以 final 需求和项目架构基线为输入;不要重新讨论已确认的 what/why,也不要默认启动完整 Superpowers 流程。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memory-update
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when completing an independently verifiable feature, phase, or release; making a durable decision; changing requirement/design/delivery status; preserving a cross-session risk; switching tools; or when the user explicitly asks to update memory
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
读取并严格遵循 `.ai/skills/memory-update.md` 的写入路由与硬性约束执行。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-inception
|
|
3
|
+
description: Use when starting a 0-to-1/greenfield project, establishing its first engineering and architecture baseline, or planning a major redesign that changes system boundaries, data ownership, deployment topology, or quality-attribute targets
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
读取并严格遵循 `.ai/skills/project-inception.md`,建立或增量更新 `docs/architecture/` 四份工程基线;普通功能迭代不要触发。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
name = "premium_planner"
|
|
2
|
+
description = "高风险需求定稿、功能设计和实施计划;仅在模型路由要求 premium 规划时使用。"
|
|
3
|
+
model_reasoning_effort = "high"
|
|
4
|
+
developer_instructions = """
|
|
5
|
+
先验证 .ai/runs/<feature>/handoff.json,读取其中全部正式输入和 .ai/skills/model-routing.md。只输出需求、设计或计划,不修改实现。输入过期、矛盾或仍有未决问题时停止。
|
|
6
|
+
"""
|
|
@@ -4,14 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
进场先读 `.ai/memory/MEMORY.md`,随后遵循 `.ai/README.md` 的进场协议。
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- 0→1 项目/首次架构基线/重大重构 → project-inception skill,产物在 `docs/architecture/`;普通功能不要重复触发
|
|
8
|
+
- 需求 what/why 与外部行为定稿 → requirements-flow skill,产物在 `docs/requirements/vX.Y.Z/{draft,final}/`
|
|
9
|
+
- M/L 级功能 how 与技术接口 → feature-design skill,产物在 `docs/design/vX.Y.Z/`;S 级可直接实现
|
|
10
|
+
- 交付前 → delivery-readiness skill,按风险验证契约、测试、迁移、回滚、性能与可观测性
|
|
11
|
+
- 记忆更新 → 只在可验收工程节点、关键决策、状态变化或会话切换时写
|
|
12
|
+
- 反驳检查 → S 级精简自检;M/L 级或用户明确要求时用 critic skill
|
|
13
|
+
- 模型路由 → 读取 `.ai/config/model-routing.json`;非 inherit 时按 model-routing skill 创建/验证 handoff,再调用 `.codex/agents/` 中匹配的执行者
|
|
10
14
|
|
|
11
15
|
## 与 superpowers 的编排(未安装则忽略本节)
|
|
12
16
|
|
|
13
|
-
1.
|
|
14
|
-
2.
|
|
17
|
+
1. final 需求已经确认 what/why,不要用 brainstorming 重复澄清目标与范围
|
|
18
|
+
2. S 级跳过 brainstorming/writing-plans;M 级只对未决高影响 how 选择性使用;L 级可使用完整流程
|
|
19
|
+
3. 所有 Superpowers 结论必须回写 `docs/design/`,临时 spec/plan 不是唯一事实源
|
|
20
|
+
4. code review 使用适合风险等级的流程,叠加 `.ai/skills/code-review.md` 的项目检查项
|
|
15
21
|
|
|
16
22
|
## 项目信息
|
|
17
23
|
|
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
1. 读 `memory/MEMORY.md`(记忆索引)
|
|
9
9
|
2. 读 `memory/session-log.md` 末尾条目(接上进度)
|
|
10
10
|
3. 按任务类型按需加载 `skills/` 对应方法论
|
|
11
|
+
4. 跨模型阶段先按 `skills/model-routing.md` 创建并校验 handoff,不用对话摘要替代正式输入
|
|
11
12
|
|
|
12
13
|
## 目录
|
|
13
14
|
|
|
15
|
+
- `ai-memory.json` — 框架版本、Schema、启用工具、文件所有权与生成基线哈希;供安全升级预检使用
|
|
16
|
+
- `config/model-routing.json` — 可选阶段模型策略;默认 `inherit` 不改变旧行为
|
|
14
17
|
- `memory/` — 记忆层:MEMORY.md 索引、project-state 全景、session-log 流水、user-profile/feedback 用户级记忆、features/ 功能档案
|
|
15
|
-
- `
|
|
18
|
+
- `runs/` — 本地交接清单和阶段回执;默认不进入 Git
|
|
19
|
+
- `skills/` — 方法论层:project-inception、requirements-flow、feature-design、delivery-readiness、model-routing、architecture、code-review、critic、memory-update
|
|
16
20
|
|
|
17
21
|
## 与工具专属配置的关系
|
|
18
22
|
|
|
@@ -1,22 +1,32 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 架构方法论(语言无关)
|
|
2
2
|
|
|
3
3
|
## 模块边界
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
- 每个模块用一句话说明职责;无法说明通常意味着边界混乱。
|
|
6
|
+
- 模块间只通过显式接口通信,依赖保持单向并避免循环。
|
|
7
|
+
- 只为真实变化或隔离需求建立抽象,不为未知未来预留扩展点。
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 两层契约
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### 外部行为契约(需求阶段)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- **输入**:参数、类型、边界值约定
|
|
15
|
-
- **输出**:返回结构、错误路径(每种失败如何表达给调用方)
|
|
16
|
-
- **幂等/并发**:重复调用的后果,是否需要去重或加锁
|
|
17
|
-
- **兼容**:后续变更如何不破坏既有调用方
|
|
13
|
+
记录参与者、输入、输出、失败表达、副作用、兼容性和可观察验收结果,不固定内部实现。
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
### 技术边界契约(how 阶段)
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
仅为跨模块、服务、进程、持久化或事件边界的接口写清:
|
|
18
|
+
|
|
19
|
+
- 名称、职责与明确不负责的内容
|
|
20
|
+
- 输入输出及类型/模式
|
|
21
|
+
- 错误、超时、重试与降级
|
|
22
|
+
- 状态变化、事务边界、一致性、幂等和并发
|
|
23
|
+
- 版本、兼容和迁移策略
|
|
24
|
+
- 可观测信号与契约测试
|
|
25
|
+
|
|
26
|
+
私有实现细节不需要逐函数建档。
|
|
27
|
+
|
|
28
|
+
## 项目基线与功能增量
|
|
29
|
+
|
|
30
|
+
- `docs/architecture/` 保存系统、数据、质量属性和部署基线。
|
|
31
|
+
- `docs/design/` 只记录功能相对基线的 how 与增量影响。
|
|
32
|
+
- 实现完成后的稳定决策摘要进入 `.ai/memory/features/`,不要复制整份设计文档。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 不注册为 skill;供 superpowers 的 code review 流程作为附加检查项引用。
|
|
4
4
|
|
|
5
|
-
- **契约一致**:实现与 `final/*.md`
|
|
5
|
+
- **契约一致**:实现与 `final/*.md` 的外部行为契约、验收标准及适用的 `docs/design/` 技术接口逐条对照
|
|
6
6
|
- **错误路径**:失败表达与契约声明一致,没有吞掉错误
|
|
7
7
|
- **记忆同步**:功能行为变化已更新 `features/` 对应档案
|
|
8
8
|
- **范围**:未引入需求「不做什么」里排除的内容
|
|
@@ -17,5 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
- 主 agent 必须逐条回应「接受并修改」或「给出理由反驳」,不允许沉默跳过
|
|
19
19
|
- 全部处理完毕才算通过
|
|
20
|
-
-
|
|
21
|
-
-
|
|
20
|
+
- S 级低风险需求可在同上下文按四类清单做一次精简自检,不启动独立 agent
|
|
21
|
+
- M/L 级需求、架构基线和高影响技术设计优先由独立 critic 执行,只给文档路径与本方法,不给对话历史
|
|
22
|
+
- 工具不支持独立上下文时才降级为同上下文自检,并刻意抵制为自己刚写内容辩护
|
|
23
|
+
- 启用模型路由时,M/L 对抗性检查和最终审查使用 premium reviewer;只传 handoff、正式文档路径、diff 和验证证据
|