agentic-flow-kit 2.0.0 → 2.1.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 +92 -23
- package/bin/flow-kit.mjs +3 -1
- package/locales/en/installer.json +87 -2
- package/locales/en/overrides/.codebuddy/skills/tfs-pr/SKILL.md +1 -1
- package/locales/en/overrides/workflow/README.md +2 -0
- package/locales/zh-CN/installer.json +87 -2
- package/package.json +2 -2
- package/schemas/install-manifest.schema.json +3 -1
- package/schemas/project-profile.schema.json +1 -1
- package/src/cli/args.mjs +3 -1
- package/src/cli/main.mjs +9 -2
- package/src/commands/doctor.mjs +50 -4
- package/src/commands/install.mjs +160 -13
- package/src/hosts/registry.mjs +154 -10
- package/src/i18n.mjs +3 -0
- package/src/install/apply.mjs +17 -3
- package/src/install/frontmatter.mjs +84 -0
- package/src/install/plan.mjs +174 -16
- package/src/models/known.mjs +13 -0
- package/src/models/probe.mjs +163 -0
- package/src/models/resolve.mjs +312 -0
- package/src/render/tokens.mjs +56 -9
- package/src/tui/ansi.mjs +55 -0
- package/src/tui/flows.mjs +306 -0
- package/src/tui/prompts.mjs +139 -0
- package/src/tui/screen.mjs +217 -0
- package/src/tui/widgets.mjs +111 -0
- package/src/tui/wizard.mjs +68 -0
- package/templates/engine/.agents/commands/new-task.md +2 -2
- package/templates/engine/.agents/commands/pipeline-run.md +5 -1
- package/templates/engine/.agents/commands/stages.md +2 -1
- package/templates/engine/.agents/config/agent-eval.json +17 -0
- package/templates/engine/.agents/config/mechanism-registry.md +2 -1
- package/templates/engine/.agents/config/memory-tiers.json +13 -0
- package/templates/engine/.agents/config/pipeline.json +36 -0
- package/templates/engine/.agents/config/steering.json +28 -0
- package/templates/engine/.agents/evals/README.md +49 -0
- package/templates/engine/.agents/evals/tasks.tsv +6 -0
- package/templates/engine/.agents/hooks/pre-write-check.cjs +27 -0
- package/templates/engine/.agents/notes/injected-memory.md +14 -0
- package/templates/engine/.agents/notes/steering-tiers.md +28 -0
- package/templates/engine/.agents/scripts/agent-eval.mjs +268 -0
- package/templates/engine/.agents/scripts/check-pipeline-state.mjs +85 -0
- package/templates/engine/.agents/scripts/claims.mjs +166 -0
- package/templates/engine/.agents/scripts/dream-run.mjs +78 -3
- package/templates/engine/.agents/scripts/fix-task.mjs +77 -0
- package/templates/engine/.agents/scripts/memory-tier.mjs +196 -0
- package/templates/engine/.agents/scripts/memory-wiki.mjs +296 -0
- package/templates/engine/.agents/scripts/outcome-metrics.mjs +195 -0
- package/templates/engine/.agents/scripts/path-lease.mjs +177 -0
- package/templates/engine/.agents/scripts/session-log.mjs +157 -0
- package/templates/engine/.agents/scripts/steering.mjs +75 -0
- package/templates/engine/.agents/scripts/verify.mjs +16 -5
- package/templates/engine/.agents/skills/arena/SKILL.md +4 -0
- package/templates/engine/.agents/skills/dream/SKILL.md +21 -2
- package/templates/engine/.agents/skills/eval/SKILL.md +16 -0
- package/templates/engine/.agents/skills/model-upgrade/SKILL.md +41 -0
- package/templates/engine/.agents/skills/session-resume/SKILL.md +7 -0
- package/templates/engine/.agents/skills/show-me-your-work/SKILL.md +14 -0
- package/templates/engine/.agents/skills/wiki/SKILL.md +4 -1
- package/templates/git/.gitattributes +1 -0
- package/templates/git/.githooks/package.json +3 -0
- package/templates/git/.github/workflows/ci.yml +32 -0
- package/templates/git/azure-pipelines.yml +46 -0
- package/templates/host-meta/SKILLS.md +3 -0
- package/templates/host-meta/claude/skill-pointer.md +6 -0
- package/templates/host-meta/cline/skill-index.md +6 -0
- package/templates/host-meta/codebuddy/skill-pointer.md +6 -0
- package/templates/host-meta/commandcode/skill-index.md +5 -0
- package/templates/host-meta/opencode/skill-pointer.md +6 -0
- package/templates/host-meta/qoder/skill-index.md +5 -0
- package/templates/host-meta/qwen/skill-index.md +5 -0
- package/templates/host-meta/trae/skill-index.md +6 -0
- package/templates/hosts/claude/settings.hardened.json +94 -0
- package/templates/hosts/claude/settings.json +1 -3
- package/templates/hosts/commandcode/settings.json +1 -3
- package/templates/hosts/qoder/settings.json +1 -3
- package/templates/hosts/qwen/settings.json +1 -3
- package/templates/profiles/go/AGENTS.md +52 -0
- package/templates/profiles/java/AGENTS.md +52 -0
- package/templates/profiles/rust/AGENTS.md +52 -0
- package/templates/profiles/typescript/AGENTS.md +52 -0
- package/templates/scaffold/workflow/INDEX.md +16 -0
- package/templates/scaffold/workflow/README.md +2 -0
- package/templates/scaffold/workflow/artifact-sources.md +25 -0
- package/templates/scaffold/workflow/non-engineer-intent.md +51 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// 状态机 + 视图行,不接触 IO(不读 stdin、不写 stdout),渲染与接线由上层完成。
|
|
2
|
+
import { cyan, dim, green, red } from './ansi.mjs';
|
|
3
|
+
|
|
4
|
+
// select:单选列表。items: [{ value, label, hint? }]
|
|
5
|
+
export function createSelect({ items, cursor = 0 }) {
|
|
6
|
+
let idx = cursor;
|
|
7
|
+
const n = items.length;
|
|
8
|
+
return {
|
|
9
|
+
view() {
|
|
10
|
+
return items.map((it, i) => {
|
|
11
|
+
const head = i === idx ? cyan(`❯ ● ${it.label}`) : dim(` ○ ${it.label}`);
|
|
12
|
+
return it.hint ? `${head} ${dim(it.hint)}` : head;
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
onKey(key) {
|
|
16
|
+
if (key.name === 'up') idx = (idx - 1 + n) % n;
|
|
17
|
+
else if (key.name === 'down') idx = (idx + 1) % n;
|
|
18
|
+
else if (key.name === 'return') return { value: items[idx].value };
|
|
19
|
+
return undefined;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// multiselect:多选列表,min 为最少勾选数。items: [{ value, label, hint?, checked? }]
|
|
25
|
+
// minMessage:最少数量提示文案(可本地化注入),缺省为内置中文
|
|
26
|
+
export function createMultiSelect({ items, cursor = 0, min = 1, minMessage = `至少选择 ${min} 项` }) {
|
|
27
|
+
let idx = cursor;
|
|
28
|
+
const checked = items.map((it) => it.checked === true);
|
|
29
|
+
let error = false;
|
|
30
|
+
const n = items.length;
|
|
31
|
+
return {
|
|
32
|
+
view() {
|
|
33
|
+
const rows = items.map((it, i) => {
|
|
34
|
+
const head = checked[i]
|
|
35
|
+
? `${i === idx ? '❯ ' : ' '}◉ ${cyan(it.label)}${green(' ✓')}`
|
|
36
|
+
: `${i === idx ? '❯ ' : ' '}○ ${dim(it.label)}`;
|
|
37
|
+
return it.hint ? `${head} ${dim(it.hint)}` : head;
|
|
38
|
+
});
|
|
39
|
+
if (error) rows.push(red(minMessage));
|
|
40
|
+
return rows;
|
|
41
|
+
},
|
|
42
|
+
onKey(key) {
|
|
43
|
+
if (error) error = false; // 任意键先清除错误提示
|
|
44
|
+
if (key.name === 'up') idx = (idx - 1 + n) % n;
|
|
45
|
+
else if (key.name === 'down') idx = (idx + 1) % n;
|
|
46
|
+
else if (key.name === 'space' || key.sequence === ' ') checked[idx] = !checked[idx];
|
|
47
|
+
else if (key.name === 'a' || key.sequence === 'a') checked.fill(!checked.every(Boolean));
|
|
48
|
+
else if (key.name === 'return') {
|
|
49
|
+
if (checked.filter(Boolean).length < min) {
|
|
50
|
+
error = true;
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
return { value: items.filter((_, i) => checked[i]).map((it) => it.value) };
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// textinput:单行文本(模型 ID 手填)。view 返回一行;Esc 返回 null。
|
|
61
|
+
export function createTextInput({ initial = '', placeholder = '', validate = () => null } = {}) {
|
|
62
|
+
let value = String(initial);
|
|
63
|
+
let error = null;
|
|
64
|
+
return {
|
|
65
|
+
view() {
|
|
66
|
+
const line = value ? `❯ ${value}█` : dim(`❯ ${placeholder}`);
|
|
67
|
+
return error ? [line, red(error)] : [line];
|
|
68
|
+
},
|
|
69
|
+
onKey(key) {
|
|
70
|
+
if (!key) return undefined;
|
|
71
|
+
if (key.name === 'return') {
|
|
72
|
+
const err = validate(value);
|
|
73
|
+
if (err) {
|
|
74
|
+
error = err;
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
return { value };
|
|
78
|
+
}
|
|
79
|
+
if (key.name === 'escape') return { value: null };
|
|
80
|
+
if (key.ctrl) return undefined;
|
|
81
|
+
if (key.name === 'backspace') {
|
|
82
|
+
value = value.slice(0, -1);
|
|
83
|
+
error = null;
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
if (key.sequence && !/[\x00-\x1f]/.test(key.sequence)) {
|
|
87
|
+
value += key.sequence;
|
|
88
|
+
error = null;
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// confirm:是/否二选一(题干归 runPrompt 渲染,view 只返回两行选项)
|
|
96
|
+
export function createConfirm({ yesLabel = '是', noLabel = '否', defaultYes = true }) {
|
|
97
|
+
let yes = defaultYes === true;
|
|
98
|
+
const row = (text, active) => (active ? cyan(`❯ ● ${text}`) : dim(` ○ ${text}`));
|
|
99
|
+
return {
|
|
100
|
+
view() {
|
|
101
|
+
return [row(yesLabel, yes), row(noLabel, !yes)];
|
|
102
|
+
},
|
|
103
|
+
onKey(key) {
|
|
104
|
+
if (key.name === 'left' || key.name === 'right') yes = !yes;
|
|
105
|
+
else if (key.name === 'y' || key.sequence === 'y') yes = true;
|
|
106
|
+
else if (key.name === 'n' || key.sequence === 'n') yes = false;
|
|
107
|
+
else if (key.name === 'return') return { value: yes };
|
|
108
|
+
return undefined;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// TUI 向导入口:主循环表驱动 FLOWS;交互终端走 keypress 状态机(screen.mjs),
|
|
2
|
+
// 非交互终端降级为「编号 + 回车」问答(prompts.mjs)。
|
|
3
|
+
// 任何一步 EOF(stdin 关闭)都干净退出返回码 0;Ctrl+C 同样以退出码 0 退出。
|
|
4
|
+
import { createScreen, createLineReader, QuitError } from './screen.mjs';
|
|
5
|
+
import { pickOne, confirmYes, showError } from './prompts.mjs';
|
|
6
|
+
import { FLOWS, baseArgs } from './flows.mjs';
|
|
7
|
+
|
|
8
|
+
// 主菜单:无位置参数且无任何选项、交互终端时由 cli/main.mjs 懒加载进入
|
|
9
|
+
export async function wizardCommand({ t, lang }) {
|
|
10
|
+
const screen = createScreen({ input: process.stdin, output: process.stdout });
|
|
11
|
+
screen.setup();
|
|
12
|
+
const ctx = { screen, t, lang };
|
|
13
|
+
// 降级模式:会话级读行器(交互模式禁用,避免与 keypress 抢输入)
|
|
14
|
+
if (!screen.interactive) ctx.reader = createLineReader(screen.input, screen.output);
|
|
15
|
+
try {
|
|
16
|
+
while (true) {
|
|
17
|
+
const action = await pickOne(ctx, {
|
|
18
|
+
question: t('tui.menuQuestion'),
|
|
19
|
+
hint: t('tui.hint.moveEnter'),
|
|
20
|
+
items: [
|
|
21
|
+
{ value: 'install', label: t('tui.menu.install') },
|
|
22
|
+
{ value: 'upgrade', label: t('tui.menu.upgrade') },
|
|
23
|
+
{ value: 'add-host', label: t('tui.menu.addHost') },
|
|
24
|
+
{ value: 'doctor', label: t('tui.menu.doctor') },
|
|
25
|
+
{ value: 'list-hosts', label: t('tui.menu.listHosts') },
|
|
26
|
+
{ value: 'quit', label: t('tui.menu.quit') },
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
if (action === null || action === 'quit') return 0;
|
|
30
|
+
try {
|
|
31
|
+
await FLOWS[action]?.(ctx);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (err instanceof QuitError) return 0;
|
|
34
|
+
// 命令抛错(如无 manifest):红字 box 显示 message,confirm 后回菜单,不裸抛堆栈
|
|
35
|
+
showError(ctx, err);
|
|
36
|
+
}
|
|
37
|
+
// 命令输出可能推进过光标,confirm 从当前位置新起一块
|
|
38
|
+
screen.print('');
|
|
39
|
+
const again = await confirmYes(ctx, t('tui.backOrQuit'));
|
|
40
|
+
if (!again) return 0;
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
if (err instanceof QuitError) return 0;
|
|
44
|
+
throw err;
|
|
45
|
+
} finally {
|
|
46
|
+
screen.restore();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 纯函数:向导选择 → runInstall 入参(argv 形状与 cli/args.mjs parseArgs 经 baseArgs 一致)。
|
|
51
|
+
// git 配置 CLI 侧默认开,--no-git-config 关闭
|
|
52
|
+
export function buildInstallArgs({ hosts, lang, stack, gitConfig = true, dryRun = false, force = false, models = null }) {
|
|
53
|
+
const args = {
|
|
54
|
+
...baseArgs(),
|
|
55
|
+
_: ['install'],
|
|
56
|
+
agents: hosts,
|
|
57
|
+
lang,
|
|
58
|
+
stack,
|
|
59
|
+
flags: new Set([
|
|
60
|
+
...(gitConfig ? [] : ['no-git-config']),
|
|
61
|
+
...(dryRun ? ['dry-run'] : []),
|
|
62
|
+
...(force ? ['force'] : []),
|
|
63
|
+
]),
|
|
64
|
+
};
|
|
65
|
+
// 模型参数保持 opt-in:默认路径不新增 flag,避免破坏既有 argv 断言。
|
|
66
|
+
if (models && Object.keys(models).length) args.tuiModels = models;
|
|
67
|
+
return args;
|
|
68
|
+
}
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
1. **定级**:用 §1 两问和 L2 闭集。未命中即 L1,`级别` 写在 plan frontmatter。完成标准:plan 头里的级别与两问结论一致。
|
|
65
65
|
2. **检索**:`node .agents/scripts/kb-search.mjs --scope workflow --module <token> "<关键词>"`。命中的 incident 根因写进下一步 plan 的自查。完成标准:命令跑过;命中根因备写进 plan,无命中粘贴脚本输出即可(免另写说明)。命中同功能 spec / features $\rightarrow$ 按 `workflow/README.md`「同功能续作」改原件不新建。
|
|
66
66
|
3. **立 plan**:`node .agents/scripts/fill-plan.mjs --level L1 --topic <主题> --output workflow/plans/<YYYY-MM-DD>-<主题>.md`。可加 `--lite`(三节:入口 / 改动方案 / 验证与验收;条件:第 2 步检索无 incident 命中且红线全不勾),缺省仍为五节。填实入口(来源、目标、红线)、改动方案、约束与风险、验证计划、验收标准,并把第 2 步的检索结果写进自查。frontmatter `模块` 改成主导模块。不写 intent,不写预判字段。完成标准:所选模板各节有正文(五节或 lite 三节)、检索结论已入 plan;验收写不出可测试判据就停;红线要么勾中升 L2/L3,要么明确不勾。
|
|
67
|
-
4. **确认后动手**:`node .agents/scripts/confirm-doc.mjs <plan> --delegated "<用户原话>"` 把 draft 收到 approved(确认门口径单源:逐件调用禁并录、逐件原话禁复用、逐跳迁移禁单跳),然后再改代码。只改 plan 列出的文件。四条红线:不提交密钥或 `.env`、不用 `--no-verify`、最小改动、偏离 plan 先停。**承诺面锁定**:approved 之后改「承诺面」(验收判据文本 / 红线 / 目标 / 改动方案)须先让用户重新点头并重录承诺面指纹——重确认口令见 `workflow/README.md`「承诺面绑定」;否则关单被拒、推送被检查 15 hard 拦(勾验收 + 证据回填不算改承诺)。改完不单独提交:验证(第 5 步)绿后按第 6 步连跳 done 并与代码同笔提交。改码前开 /tour 全景,每批刷新(skills/dev-tour
|
|
68
|
-
5. **验证**:`node .agents/scripts/verify.mjs --scope
|
|
67
|
+
4. **确认后动手**:`node .agents/scripts/confirm-doc.mjs <plan> --delegated "<用户原话>"` 把 draft 收到 approved(确认门口径单源:逐件调用禁并录、逐件原话禁复用、逐跳迁移禁单跳),然后再改代码。只改 plan 列出的文件。四条红线:不提交密钥或 `.env`、不用 `--no-verify`、最小改动、偏离 plan 先停。**承诺面锁定**:approved 之后改「承诺面」(验收判据文本 / 红线 / 目标 / 改动方案)须先让用户重新点头并重录承诺面指纹——重确认口令见 `workflow/README.md`「承诺面绑定」;否则关单被拒、推送被检查 15 hard 拦(勾验收 + 证据回填不算改承诺)。改完不单独提交:验证(第 5 步)绿后按第 6 步连跳 done 并与代码同笔提交。改码前开 /tour 全景,每批刷新(skills/dev-tour)。**修复类**改码前 `node .agents/scripts/fix-task.mjs start`,关单后 `stop`——窗口内既有测试只读,新建复现测试放行。完成标准:改动留在工作区,plan 仍是 approved。
|
|
68
|
+
5. **验证**:`node .agents/scripts/verify.mjs --scope`(口径见头注)。触及 `.agents/skills|commands|roles` 或模型配置时,另跑 `node .agents/scripts/agent-eval.mjs check`(无凭证先按 eval 技能跑并 record)。有前端改动再打开 `.agents/skills/verify-ui/SKILL.md`。失败就改代码,不在本页改门禁。完成标准:命令退出码 0,前端改动另有实测证据。
|
|
69
69
|
6. **关单=单笔提交**:`node .agents/scripts/confirm-doc.mjs <plan> --delegated "<用户原话>"` 连续再跳一次把 approved 收到 done,随后单笔提交——plan(done) + 代码 + 确认分片 + verify 凭证同一笔入库,L1 无独立关单提交。仅 plan 独立关单场景(代码已在前笔入库)才打开 `.agents/skills/shipyard-workflow-closeout/SKILL.md`。完成标准:plan 为 done,单笔提交已入库。
|
|
70
70
|
|
|
71
71
|
下面才打开别的文件:委派 implementer → `stages.md` Build §3;改了库连接 → `stages.md` Test §2;全量首跑红、隔离重跑转绿 → `stages.md` Test §1;L2/L3 独立复核 → `stages.md` Test §4。
|
|
@@ -14,9 +14,12 @@ next: 按 run 停机点循环推进至 done
|
|
|
14
14
|
|
|
15
15
|
阶段机已对齐 commands 手册。与手动阶段路由二选一,禁混用。
|
|
16
16
|
|
|
17
|
-
> **保留待用**:暂零 run(`cache/pipeline-runs/`
|
|
17
|
+
> **保留待用**:暂零 run(`cache/pipeline-runs/` 空)但不退役。启用前先跑
|
|
18
|
+
> `node .agents/scripts/check-pipeline-state.mjs`(静态闭包检查:stage/stopType 是否都在
|
|
19
|
+
> `.agents/config/pipeline.json` 内),再用一个小任务跑一次端到端 run——静态检查不能替代真实状态机验证。
|
|
18
20
|
|
|
19
21
|
> **分工**:确定性部分由 `pipeline-run.mjs` 状态机驱动(fill-* $\rightarrow$ confirm-doc $\rightarrow$ verify.mjs $\rightarrow$ git,退出码全记录);AI 槽位按工单协议执行;人件门到点即停、原话代录;宿主禁自行改状态。
|
|
22
|
+
> **fix 工单**:动手前 `node .agents/scripts/fix-task.mjs start`,签收后 `stop`——窗口内既有测试只读。
|
|
20
23
|
|
|
21
24
|
## 1. 驱动协议 (Protocol)
|
|
22
25
|
|
|
@@ -44,6 +47,7 @@ next: 按 run 停机点循环推进至 done
|
|
|
44
47
|
|
|
45
48
|
3. **放弃**: 用户明确不做 $\rightarrow$ `abort --run <id> --to superseded|cancelled --delegated "<原话>"` (approved 文档逐份走 confirm-doc --to)
|
|
46
49
|
4. **观测** (可选): `status [--run <id>] [--json]` 全量事件流水 / `watch` 终端轮询视图
|
|
50
|
+
5. **并行写同一页**: 多个 arm 要改同一 `workflow/` 或 `wiki/` 页面时,先 `node .agents/scripts/path-lease.mjs acquire --path <page> --owner <arm>`,写完 `release`;一页一 writer。
|
|
47
51
|
|
|
48
52
|
## 🚫 硬纪律 (违反即协议破坏)
|
|
49
53
|
|
|
@@ -212,7 +212,8 @@ L1 不在本章起草 plan,回 `.agents/commands/new-task.md` §L1 快速道
|
|
|
212
212
|
1. **执行门禁**: `node .agents/scripts/verify.mjs`(档位口径以 verify.mjs 头注为准,本文不复述)。项目构建、测试、类型检查的命令清单单源是 `.agents/hooks/commit-check.config.json`。
|
|
213
213
|
2. **故障处置**: 任一失败 $\rightarrow$ **HALT**。L1 回 `.agents/commands/new-task.md` 快速道第 5 步改代码。L2/L3 回 Build 章修复。偶发/跨层问题用 `diagnosing-bugs` 诊断。全量首跑红、隔离重跑转绿不算绿:按 flaky 立项(papercut/incident)后修复,禁以重跑绿直接关单。
|
|
214
214
|
3. **档位按任务小类**: 纯文档/业务面 → 默认档(产品门按 diff 面裁);跨面或发版前 → `--full`。引擎面无测试门,`*.test.mjs` 不入库不自动跑(2026-10-29 清库);手动工具——合并语义探针 `node .agents/scripts/check-loop-rev-semantics.mjs`(FULL 模式末尾自动跑)。
|
|
215
|
-
|
|
215
|
+
4. **行为评测(引擎面/模型面)**: 本批改动触及 `.agents/skills/**`、`.agents/commands/**`、`.agents/roles/**` 或模型配置时,跑 `node .agents/scripts/agent-eval.mjs check`。无当前内容签名的凭证 → 按 `.agents/skills/eval/SKILL.md` 跑任务集,再 `agent-eval.mjs record`。**修复类**在动手前 `node .agents/scripts/fix-task.mjs start`,关单后 `stop`——窗口内修改既有测试会被写前门拒绝(新建复现测试放行)。
|
|
216
|
+
**Output**: 静态门全绿证据 +(引擎面/模型面)行为评测凭证
|
|
216
217
|
**Note**: 运行环境细节见 `.agents/notes/runtime-env.md` §1, §2;长门禁命令(verify 全量/`dotnet test`)**分段等 + 每段回报进度**,不阻塞到 timeout 上限——口径 §6.4「后台长任务取结果」
|
|
217
218
|
|
|
218
219
|
## 2. 切库冒烟 (DB Smoke Test)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"sensitive": [
|
|
4
|
+
".agents/skills/**",
|
|
5
|
+
".agents/commands/**",
|
|
6
|
+
".agents/roles/**",
|
|
7
|
+
".agents/config/model-roles.json",
|
|
8
|
+
".agents/config/steering.json",
|
|
9
|
+
".agents/config/pipeline.json",
|
|
10
|
+
".agents/config/agent-eval.json"
|
|
11
|
+
],
|
|
12
|
+
"results": ".agents/evals/results.jsonl",
|
|
13
|
+
"threshold": 0.8,
|
|
14
|
+
"maxAgeDays": 30,
|
|
15
|
+
"minTasks": 5,
|
|
16
|
+
"advisory": false
|
|
17
|
+
}
|
|
@@ -41,10 +41,11 @@
|
|
|
41
41
|
| 接线宣称一致性(check-hook-wiring) | .githooks/pre-push(推送范围触宿主壳/.agents/hooks/registry 条件执行,实测 <1s)+ 手动——check-hook-wiring.mjs 的 CLAIMS 表 ↔ 宿主配置实态对账 | 漂移拦截计数(月,人工对账) | registry 各行接线信息改为机读结构(宣称随行携带)→ 评估退役 | 2026-10-29 建:引擎测试面退役后接线漂移无自动防线的补位(首跑产出即上行「轮询门修正」案例) | 现役 [检出型] | — |
|
|
42
42
|
| 先确认后改代码 | .githooks/commit-msg 接线 `.agents/hooks/check-confirm-order.mjs`(暂存产品路径才跑;合并族跳过;2026-11-08 档 2-D 自 pre-commit 位移——pre-commit 看不到消息)。豁免 A:消息体非空 `L0:` 行且产品 ≤5 放行(judgments 落账 L0 计数);豁免 B:覆盖 plan 与产品同批 staged(done 亦可,L1 单笔提交)放行 | hard「路径不在 approved plan 正文」拒绝计数 + L0 放行计数(月,人工对账) | 不退役(顺序红线主干。增量理由:确认指纹只核状态与承诺面,不核发生顺序;历史 done plan 仍不算覆盖,仅同批 staged 算) | 2026-11-03 建(incident 2026-11-03-po-pml-outbound-guards:实现提交先于三件套,check-loop 期间无阻塞) | 现役 [不退役主干] | — |
|
|
43
43
|
| 提交信息卫生检出(ci-commit-hygiene) | azure-pipelines.yml ci-push-before 后无条件步(中/重两档);区间三层——PR 构建取合并提交第一父(目标分支尖端)只判本 PR 新增提交、推送构建用 CI_PUSH_BEFORE、缺省退 HEAD~1(2026-11-05 build 29054 假红修正:changes API 基准会拉入目标侧存量提交)——枚举/正则单源 commit-msg-rules.json 与 .githooks/commit-msg 同判 | CI 红计数(违规笔数,检出型) | 连续 6 月 = 0 → 评估退役 | 2026-11-05 建(复盘 P0:钩子未挂/--no-verify 且消息违规 → CI 可见;不覆盖消息恰好合法的绕过) | 现役 [检出型] | 复评 2027-02-05 |
|
|
44
|
-
| Dreaming 持续运行链路(dream-run 接线) | .githooks/post-commit(advisory 第三段,≥7 天提醒)+ `.agents/skills/dream/SKILL.md`(session-resume 装载、会话内执行)+ dream-run.mjs E2 阶段 | 冷数据候选数(agg-kb-usage --stale-days 90,月;kb-search 命中遥测 `.agents/cache/kb-usage.jsonl`
|
|
44
|
+
| Dreaming 持续运行链路(dream-run 接线) | .githooks/post-commit(advisory 第三段,≥7 天提醒)+ `.agents/skills/dream/SKILL.md`(session-resume 装载、会话内执行)+ dream-run.mjs E2 阶段 + 主张依据节(claims.mjs recheck,只报告,退出码 0,不进门) | 冷数据候选数(agg-kb-usage --stale-days 90,月;kb-search 命中遥测 `.agents/cache/kb-usage.jsonl` 为数据源);主张 broken 数(dream-report,月;数据源 `workflow/claims.d/*.jsonl`) | 不退役(Anthropic Dreaming 对照的记忆维护主干);数据面按「有数据月」对账 | 2026-11-11 建(对照文章补接线:post-commit 7 天提醒 + 会话内执行链路 + kb-search 命中遥测 + E2 冷数据候选);2026-11-12 主张账:核对只报告,不改正文 | 现役 [数据面] | — |
|
|
45
45
|
| PI 宿主门禁接线(本机私有) | .pi/extensions/shipyard-gates.ts(session_start 接线自检 + tool_call → pre-shell-check.cjs / pre-write-check.cjs,判据单源在 .agents/hooks/);check-local-gates.mjs advisory 对账 4 必需文件 + project trust | 接线缺失 / trust 未检出的 WARN 计数(月,advisory 输出);pi 会话 tool_call 门 deny 计数(gates.json 判据) | 不适用零命中退役([健康静默]:0 命中 = 接线健康);本仓不再使用 pi 宿主或宿主原生提供等价门禁 → 评估退役 | 2026-11-11 建门(P0 补 ctx_execute / ctx_batch 绕过口、createRequire 修 /reload CJS 缓存);增量理由:.pi/ 不随 clone 传播,接线缺失时 session_start 自检随之消失,无外部防线 | 现役 [健康静默] | — |
|
|
46
46
|
| Cline 宿主适配(本机私有) | .cline/workflows/wf-*.md(7 指针壳 → `.agents/commands/`)+ .cline/agents/*.yml(7 角色 → `.agents/roles/`)+ `.cline/hooks/PreToolUse.cjs`(命令门/写前门协议适配层 → pre-shell-check.cjs / pre-write-check.cjs);权威源零改动 | check-local-gates.mjs advisory 对账(workflows+agents 壳 + hook 在位) | 不适用零命中退役([健康静默]:未用 ≠ 失效);弃用 → 评估退役 | 2026-11-11 建(Cline 原生读 `AGENTS.md` 与 `.agents/skills/`;hook 协议与仓库 CJS 不兼容,故建适配层,参照 `.pi/extensions/lib/gates-core.cjs` 同型映射) | 现役 [健康静默] | — |
|
|
47
47
|
| Claude Code 宿主适配(本机私有) | `.claude/settings.json` PreToolUse 两门(`Bash` → pre-shell-check.cjs;`Write\|Edit\|MultiEdit` → pre-write-check.cjs)+ `.claude/commands/wf-*.md`(7 指针壳 → `.agents/commands/`)+ `.claude/agents/*.md`(7 角色 → `.agents/roles/`);根 `CLAUDE.md` 为 AGENTS.md 镜像;权威源零改动 | check-local-gates.mjs ⑩ advisory 对账(settings 两门接线 + 7+7 壳) | 不适用零命中退役([健康静默]:未用 ≠ 失效);弃用 → 评估退役 | 2026-11-11 建(hook 协议与 Trae/CodeBuddy 同形;`.claude/` 与 CLAUDE.md gitignore 不随 clone)。增量理由:Claude 会话此前无宿主侧两门,仅 git 钩子兜底 | 现役 [健康静默] | — |
|
|
48
|
+
| 测试守卫 | pre-write §2.5 | 改测试 deny/月 | 不退役 | 2026-11-12 | 现役[不退役主干] | — |
|
|
48
49
|
|
|
49
50
|
## 维护纪律
|
|
50
51
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"stages": [
|
|
4
|
+
"triage",
|
|
5
|
+
"adopted",
|
|
6
|
+
"intent-draft",
|
|
7
|
+
"intent-fill",
|
|
8
|
+
"intent-confirm",
|
|
9
|
+
"spec-draft",
|
|
10
|
+
"spec-fill",
|
|
11
|
+
"spec-review",
|
|
12
|
+
"spec-confirm",
|
|
13
|
+
"plan-draft",
|
|
14
|
+
"plan-fill",
|
|
15
|
+
"plan-confirm",
|
|
16
|
+
"implement",
|
|
17
|
+
"verify",
|
|
18
|
+
"changes-confirm",
|
|
19
|
+
"fix",
|
|
20
|
+
"review",
|
|
21
|
+
"review-only",
|
|
22
|
+
"verify-only",
|
|
23
|
+
"deploy-prep",
|
|
24
|
+
"deploy-check",
|
|
25
|
+
"deploy-await",
|
|
26
|
+
"done-confirm",
|
|
27
|
+
"closeout",
|
|
28
|
+
"incident-draft",
|
|
29
|
+
"incident-fill",
|
|
30
|
+
"incident-confirm",
|
|
31
|
+
"incident-fixed-confirm",
|
|
32
|
+
"incident-closed-confirm",
|
|
33
|
+
"done"
|
|
34
|
+
],
|
|
35
|
+
"stopTypes": ["work-order", "await-confirm", "gate-fail", "done", "aborted"]
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"defaultTier": "standard",
|
|
4
|
+
"tiers": {
|
|
5
|
+
"frontier": {
|
|
6
|
+
"scaffolding": "goal",
|
|
7
|
+
"judgmentLatitude": "high",
|
|
8
|
+
"guidance": "给目标、约束、验收与红线;少给逐步指令。固定‘只记失败’这类规则可能削弱强模型,保留判断空间。"
|
|
9
|
+
},
|
|
10
|
+
"standard": {
|
|
11
|
+
"scaffolding": "mixed",
|
|
12
|
+
"judgmentLatitude": "medium",
|
|
13
|
+
"guidance": "保留确认门与检查清单;实现步骤可精简,关键判据必须显式。"
|
|
14
|
+
},
|
|
15
|
+
"lean": {
|
|
16
|
+
"scaffolding": "step",
|
|
17
|
+
"judgmentLatitude": "low",
|
|
18
|
+
"guidance": "给明确步骤、模板与反例;用门禁兜住判断缺口。"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"invariants": [
|
|
22
|
+
"确认门与不可逆操作红线",
|
|
23
|
+
"独立复核与职责分离",
|
|
24
|
+
"单源纪律(同一事实只写一处)",
|
|
25
|
+
"测试不可弱化",
|
|
26
|
+
"提交与推送门禁"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# 行为评测(agent-eval)
|
|
2
|
+
|
|
3
|
+
静态门回答“脚本是否还能跑”;行为评测回答“智能体的行为是否还一样”。
|
|
4
|
+
|
|
5
|
+
适用改动面(`.agents/config/agent-eval.json` 的 `sensitive`):
|
|
6
|
+
|
|
7
|
+
- `.agents/skills/**`、`.agents/commands/**`、`.agents/roles/**`
|
|
8
|
+
- 模型角色 / 严格度 / pipeline 配置
|
|
9
|
+
|
|
10
|
+
## 跑一次
|
|
11
|
+
|
|
12
|
+
1. 按 `.agents/skills/eval/SKILL.md` 准备任务集:5–10 条,有已知判据,正负例都有。
|
|
13
|
+
2. 用新子代理跑两臂(A=新配置,B=旧配置),同模型、同上下文、盲评。
|
|
14
|
+
3. 用 `eval-score.mjs` 算通过率,然后落凭证:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node .agents/scripts/agent-eval.mjs record --pass-rate 0.9 --tasks 8 --model opus --note "skill x v2"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
4. 门禁检查:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
node .agents/scripts/agent-eval.mjs check # 严格:无凭证/过期/不达标 → 非零
|
|
24
|
+
node .agents/scripts/agent-eval.mjs check --advisory # 试点:只告警
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 新装为什么严格 check 会失败
|
|
28
|
+
|
|
29
|
+
新装项目没有任何评测凭证,`check` 报 `no-eval-for-tree` 是**门在工作**,不是安装坏了。
|
|
30
|
+
此时只有两条路:
|
|
31
|
+
|
|
32
|
+
1. 按上面的流程真跑一次评测并 `record`(推荐);
|
|
33
|
+
2. 试点期在 CI 里用 `--advisory`,严格 check 留到改敏感面时再跑。
|
|
34
|
+
|
|
35
|
+
`record` 拒绝不可追溯的凭证:`--pass-rate` 必须是 0..1 的显式值,`--tasks` 不少于
|
|
36
|
+
`minTasks`(默认 5),`--model` 不能为空。不要把 `record --pass-rate 1` 当“免测开关”。
|
|
37
|
+
|
|
38
|
+
## 判据
|
|
39
|
+
|
|
40
|
+
- 凭证绑定的是**评测敏感面的内容签名**,不是提交号:只改业务代码不会让凭证失效。
|
|
41
|
+
- 凭证默认 30 天过期;模型升级、技能重写、命令改步骤都应重跑。
|
|
42
|
+
- `results.jsonl` 是 append-only 台账;多机/多分支用 jsonl-union 合并。
|
|
43
|
+
- 通过率写“A 臂命中率”;Δ 与翻转任务留在评测报告里,不进凭证。
|
|
44
|
+
- `results.jsonl` 属于运行态:不随安装器模板出厂(`listFiles` 已排除),否则新项目会继承一张假凭证。
|
|
45
|
+
|
|
46
|
+
## 放进 CI
|
|
47
|
+
|
|
48
|
+
`templates/git/azure-pipelines.yml` 与 `templates/git/.github/workflows/ci.yml`
|
|
49
|
+
在 `verify --full` 之后调用 `check --advisory`。稳定后去掉 `--advisory`。
|
|
@@ -159,6 +159,33 @@ if (proposed !== null && LEDGER_RE.test(rel)) {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
// ── 2.5) 测试不可弱化(fix 任务窗口)──────────────────
|
|
163
|
+
// Anthropic AI-native SDLC:修复时,写代码的 agent 不得削弱证明修复有效的检查。
|
|
164
|
+
// 协议:修复开始前 `node .agents/scripts/fix-task.mjs start` 落 .agents/cache/fix-task.json;
|
|
165
|
+
// 结束后 stop。窗口内改既有测试 → deny;新建测试(复现用例)放行。
|
|
166
|
+
// 逃生口:① --test 预登记允许路径;② 提议内容含 `TEST-GUARD-ALLOW: <理由>`(保留给合法重构,
|
|
167
|
+
// 复核时可见);③ 用户明示的 write-gate 解锁。
|
|
168
|
+
const TEST_PATH_RE = /(^|\/)(tests?|__tests__)\/|\.(test|spec)\.[cm]?[jt]sx?$|Tests?\.(cs|java|kt)$|_test\.(go|py)$|^test_.*\.py$|\.feature$/;
|
|
169
|
+
try {
|
|
170
|
+
const marker = path.join(root, '.agents', 'cache', 'fix-task.json');
|
|
171
|
+
if (!unlocked && TEST_PATH_RE.test(rel) && fs.existsSync(marker)) {
|
|
172
|
+
let task = null;
|
|
173
|
+
try { task = JSON.parse(fs.readFileSync(marker, 'utf8')); } catch { task = null; }
|
|
174
|
+
if (task && task.active !== false) {
|
|
175
|
+
const existed = fs.existsSync(abs);
|
|
176
|
+
const allowed = Array.isArray(task.allowedTests) && task.allowedTests.some((p) => String(p).replace(/\\/g, '/') === rel);
|
|
177
|
+
const escape = typeof proposed === 'string' && /TEST-GUARD-ALLOW:\s*\S+/.test(proposed);
|
|
178
|
+
// 新建测试 = 失败的复现用例,允许;修改/删除既有测试一律拦。
|
|
179
|
+
if (existed && !allowed && !escape) {
|
|
180
|
+
deny(`测试不可弱化:当前处于修复任务窗口(${task.id || 'fix'}),不得修改既有测试 ${rel}。\n`
|
|
181
|
+
+ '允许:新建复现测试;或让修复只改实现。\n'
|
|
182
|
+
+ '如属合法重构:在提议内容里加 `TEST-GUARD-ALLOW: <理由>`,并在复核中说明;'
|
|
183
|
+
+ '或先结束窗口 node .agents/scripts/fix-task.mjs stop。');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} catch { /* 标记读取失败 → 放行,git 钩子与独立复核兜底 */ }
|
|
188
|
+
|
|
162
189
|
// ── 3) 红线内容判据(快照-换入-跑真实门-恢复)─────────
|
|
163
190
|
const gates = [];
|
|
164
191
|
if (/^backend\/.+\.(cs|csproj|sln)$/i.test(rel)) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# 注入层(Injected Memory)
|
|
2
|
+
|
|
3
|
+
> 每次会话都会加载的文件。**上限 200 行 / 25KB**(见 `.agents/config/memory-tiers.json`)。
|
|
4
|
+
> 只放“每次都必须知道”的稳定事实;细节一律用链接下沉。
|
|
5
|
+
> 更长不等于更有效:指令文件越长,遵循度越低(Anthropic agent memory 研究)。
|
|
6
|
+
> 由 dreaming 的 `memory-tier audit/suggest` 维护;`suggest` 只出候选,不自动改本文件。
|
|
7
|
+
|
|
8
|
+
- 入口与定级:`.agents/commands/new-task.md`
|
|
9
|
+
- L2/L3 阶段流:`.agents/commands/stages.md`
|
|
10
|
+
- 会话重入:`.agents/skills/session-resume/SKILL.md`
|
|
11
|
+
- 主张账(未来会当真的话):`workflow/claims.d/`
|
|
12
|
+
- 记忆地图:`wiki/_memory/INDEX.md`
|
|
13
|
+
- 行为评测门:`.agents/scripts/agent-eval.mjs`
|
|
14
|
+
- 离线梦境:`.agents/skills/dream/SKILL.md`
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 严格度分层(steering tiers)
|
|
2
|
+
|
|
3
|
+
> 背景:Anthropic agent memory 研究显示,对更强模型,事先写死的固定规则
|
|
4
|
+
> (例如“只记录失败”)会削弱记忆带来的增益;告诉它“记忆用来做什么”,比规定“怎么用”更有效。
|
|
5
|
+
> Playbook 也提醒:更长/更细的指令文件会降低遵循度。
|
|
6
|
+
|
|
7
|
+
## 分层
|
|
8
|
+
|
|
9
|
+
| 档 | 适用 | 脚手架 | 判断空间 |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| frontier | 强推理模型(judgment/review) | goal(目标 + 约束 + 验收) | 高 |
|
|
12
|
+
| standard | 默认 | mixed(确认门 + 精简步骤) | 中 |
|
|
13
|
+
| lean | 小模型/低成本实现 | step(明确步骤 + 模板 + 反例) | 低 |
|
|
14
|
+
|
|
15
|
+
配置单源:`.agents/config/steering.json`;解析:
|
|
16
|
+
`node .agents/scripts/steering.mjs resolve --model opus`。
|
|
17
|
+
|
|
18
|
+
## 什么永远不能“按档放宽”
|
|
19
|
+
|
|
20
|
+
`invariants` 列表里的内容不随模型档位变化:确认门、独立复核、单源、测试不可弱化、提交/推送门禁。
|
|
21
|
+
分层只调整**表达方式**(目标式 vs 步骤式),不调整**底线**。
|
|
22
|
+
|
|
23
|
+
## 切换口径
|
|
24
|
+
|
|
25
|
+
- 换模型后先跑 `.agents/skills/model-upgrade/SKILL.md` 的评测。
|
|
26
|
+
- 强模型档发现命令文件步骤过细、反而降低判断质量时,把该命令的实现段改成目标式;
|
|
27
|
+
确认门与验收判据保留。
|
|
28
|
+
- 弱模型档不要靠“它应该懂”省略步骤;用模板与门禁补。
|