@yangdcm/dsh-expert-team 1.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.en.md +141 -0
- package/README.md +135 -0
- package/client.js +2473 -0
- package/cordis.patch.yml +24 -0
- package/lib/artifact-writer.js +379 -0
- package/lib/command-parse.js +181 -0
- package/lib/command.js +5100 -0
- package/lib/dispatch-ledger.js +229 -0
- package/lib/index.js +15 -0
- package/lib/interception.js +266 -0
- package/lib/lead-toolface.js +179 -0
- package/lib/log-parse.js +181 -0
- package/lib/loop-guard.js +165 -0
- package/lib/metrics/collect.js +70 -0
- package/lib/metrics/render.js +100 -0
- package/lib/metrics/session-usage.js +319 -0
- package/lib/metrics/timing.js +188 -0
- package/lib/metrics/token-usage.js +352 -0
- package/lib/metrics/tokens.js +271 -0
- package/lib/routes/shared.js +83 -0
- package/lib/settings.js +289 -0
- package/lib/tier.js +190 -0
- package/lib/validate.js +681 -0
- package/lib/vocab.js +121 -0
- package/lib/write-tracer.js +58 -0
- package/package.json +119 -0
- package/presets/expert-team/agent.cordis.yml +542 -0
- package/presets/expert-team/preset.yml +3 -0
- package/skills/expert-team/SKILL.md +328 -0
- package/skills/expert-team/assets/templates/AUTHORITY.md +32 -0
- package/skills/expert-team/assets/templates/PLAN.md +27 -0
- package/skills/expert-team/assets/templates/RESEARCH.md +13 -0
- package/skills/expert-team/assets/templates/RETRO.md +24 -0
- package/skills/expert-team/assets/templates/REVIEW.md +10 -0
- package/skills/expert-team/assets/templates/ROSTER.json +6 -0
- package/skills/expert-team/assets/templates/SPEC.md +62 -0
- package/skills/expert-team/assets/templates/STATE.json +10 -0
- package/skills/expert-team/assets/templates/SUMMARY.md +25 -0
- package/skills/expert-team/assets/templates/TASK.md +23 -0
- package/skills/expert-team/assets/templates/TASKS.json +3 -0
- package/skills/expert-team/assets/templates/TEST.md +9 -0
- package/skills/expert-team/assets/templates//344/273/273/345/212/241/347/234/213/346/235/277.md +23 -0
- package/skills/expert-team/references/EFFICIENCY.md +79 -0
- package/skills/expert-team/references/LOGGING.md +82 -0
- package/skills/expert-team/references/PERSIST.md +57 -0
- package/skills/expert-team/references/PIPELINE.md +58 -0
- package/skills/expert-team/references/ROLES.md +297 -0
- package/skills/expert-team/references/WORKSPACE.md +123 -0
- package/skills/expert-team/references/workflow.team.js +97 -0
- package/skills/expert-team/scripts/scan-authority.mjs +114 -0
- package/skills/expert-team/scripts/scan-single-source.mjs +292 -0
package/lib/vocab.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// 词表真源(B 线第 11b 项):**面向用户的中文标签 / 角色关键词表 / 阶段词表 / 已知角色集合,只此一份。**
|
|
2
|
+
//
|
|
3
|
+
// 为什么要收拢:这些"同一个事实"在收拢前散着好几份 —— `KIND_ZH`、`ALLOWED_KINDS`、
|
|
4
|
+
// 以及**手写字符串** `ALLOWED_KINDS_ZH` 描述的是同一件事(合法任务类型),改一处漏两处是必然。
|
|
5
|
+
// 而本仓**头号返工源正是「一个事实多份拷贝」**(一次真实 run 里同类缺陷 6 例、占那批返工 14/29)。
|
|
6
|
+
// 收拢之后,「合法类型的中文清单」由 `KIND_ZH` **推导**出来,而不是再抄一遍。
|
|
7
|
+
//
|
|
8
|
+
// 边界(必须如实说,否则会被读成"词表已经全单源了"):
|
|
9
|
+
// **client.js 那一份搬不过来** —— 它是 `__ModuleLoader__` 工厂、不能 import 本模块。
|
|
10
|
+
// host ↔ client 的等价性由 `vocab-consistency.test.mjs` 逐词盯着(关键词表缺一个词就红,
|
|
11
|
+
// 这正是当年真实分叉过的地方)。
|
|
12
|
+
//
|
|
13
|
+
// 本模块零 IO、零依赖、纯常量 + 纯函数 ⇒ 可被单独 import 与单测。
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 标签归一:去空白(含全角空格)+ 小写。
|
|
17
|
+
* ⚠️ **与 `client.js` 里的同名实现必须语义一致**(`vocab-consistency.test.mjs` 会逐例比对,
|
|
18
|
+
* 因为 `'UI 设计师'` 与 `'ui设计师'` 在两侧都必须等价)。
|
|
19
|
+
*/
|
|
20
|
+
export function roleLabelKey(s) {
|
|
21
|
+
return String(s || '').replace(/[\s\u3000]+/g, '').toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 阶段 id 的完整词表(顺序即流水线顺序;`方案确认` 是中文阶段名,必须原样保留)。 */
|
|
25
|
+
export const PHASES = ['clarify', 'research', 'design', 'spec-review', '方案确认', 'implement', 'review', 'test', 'deliver'];
|
|
26
|
+
|
|
27
|
+
// ── 面向用户的展示词表(只用于文案;协议值、日志、命令参数一律保留英文 id)──────────
|
|
28
|
+
export const PHASE_ZH = { clarify: '澄清', research: '调研', design: '设计', 'spec-review': '规格评审', '方案确认': '方案确认', implement: '实现', review: '审查', test: '测试', deliver: '交付' };
|
|
29
|
+
export const STATUS_ZH = { pending: '待开始', claimed: '已领取', in_progress: '进行中', done: '已完成', completed: '已完成', rework: '待返工', blocked: '受阻', failed: '失败', cancelled: '已取消', running: '进行中', complete: '已完成', idle: '空闲', paused: '已暂停', draft: '草稿' };
|
|
30
|
+
export const KIND_ZH = { requirements: '需求', research: '调研', design: '设计', implementation: '编码实现', verification: '验证测试', review: '代码审查', repair: '返工修复', integration: '集成', work: '任务', quality: '质量自检' };
|
|
31
|
+
export const VERDICT_ZH = { pass: '通过', approved: '已通过', needs_revision: '需修订', reject: '驳回', rejected: '驳回', fail: '未通过', failed: '未通过', pending: '待判定', none: '未判定' };
|
|
32
|
+
export const ROLE_ZH = { pm: '产品', architect: '架构', researcher: '调研', ui: '界面设计', backend: '后端', frontend: '前端', dba: '数据', sec: '安全审计', reviewer: '评审', qa: '测试', devops: '运维', docs: '文档' };
|
|
33
|
+
export const MODE_ZH = { 'one-shot': '一次性', persist: '常驻' };
|
|
34
|
+
export const ACTIVITY_ZH = { running: '运行中', idle: '空闲', ready: '就绪', inactive: '未启动', done: '已完成', failed: '失败', '': '未启动' };
|
|
35
|
+
export const DELIVER_ZH = { 'code+artifacts': '代码+工件', 'artifacts-only': '仅工件' };
|
|
36
|
+
|
|
37
|
+
// ── 合法任务类型:**由 `KIND_ZH` 推导,不再手抄第二遍** ─────────────────────────
|
|
38
|
+
//
|
|
39
|
+
// 收拢前这里有三份描述同一件事的东西:`KIND_ZH`(中文标签)、`ALLOWED_KINDS`(英文枚举)、
|
|
40
|
+
// 手写字符串 `ALLOWED_KINDS_ZH`(诊断用中文清单)。三者必须一致,却没有任何东西保证一致 ——
|
|
41
|
+
// 实测就是"加了一个 kind,诊断文案里没有它",而诊断文案恰恰是排查时被信任的那份。
|
|
42
|
+
/** 合法 `kind` 的闭集(客户端早已渲染这两套词表,此处不再拒绝真实存在的健康 run)。 */
|
|
43
|
+
export const ALLOWED_KINDS = new Set(Object.keys(KIND_ZH));
|
|
44
|
+
/** 诊断用的合法 kind 中文清单 —— **推导自 `KIND_ZH`**,不可能再与它分叉。 */
|
|
45
|
+
export const ALLOWED_KINDS_ZH = Object.values(KIND_ZH).join('/');
|
|
46
|
+
|
|
47
|
+
// ── 角色解析:关键词表(模糊匹配,"先命中先赢")+ 精确中文标签表 ────────────────────
|
|
48
|
+
/**
|
|
49
|
+
* 角色关键词表。**顺序敏感**:动态角色在前(它们的关键词与固定角色重叠,
|
|
50
|
+
* 如「产品分析」vs「产品经理」);`qa` 的 `重测`/`test` 也不能少 —— workflow 的验收腿
|
|
51
|
+
* 标签形如「[重测] test-2 …」,不含「测试」二字,少了它们每一条验收腿都会变成"无角色"
|
|
52
|
+
*(2026-09-11 实测)。
|
|
53
|
+
*/
|
|
54
|
+
export const SUB_ROLE_WORDS = [
|
|
55
|
+
['competitive-analyst', ['competitive', '竞品', '对标']],
|
|
56
|
+
['product-analyst', ['product-analyst', '产品分析', '收益成本', '差距分析']],
|
|
57
|
+
['pm', ['pm', '产品经理', '澄清', '起草', 'ultra spec', '需求', '规格']],
|
|
58
|
+
['architect', ['architect', '架构', 'chief', '接口契约']],
|
|
59
|
+
['researcher', ['research', '调研', '研究员', 'researcher', 'investigate', '现状']],
|
|
60
|
+
['backend', ['backend', '后端']],
|
|
61
|
+
['dba', ['dba', '数据', 'sql', 'ddl', '迁移', 'database', '表结构']],
|
|
62
|
+
['frontend', ['frontend', '前端', 'uni-app', 'uniapp']],
|
|
63
|
+
['ui', ['ui', '视觉', '界面', '走查', '设计', 'designer', 'design']],
|
|
64
|
+
['reviewer', ['review', '评审', '审查']],
|
|
65
|
+
['qa', ['qa', '测试', '重测', 'test', '验证']],
|
|
66
|
+
['sec', ['sec', '安全', '越权', '注入', '渗透', 'security']],
|
|
67
|
+
['devops', ['devops', '部署', '构建', 'cicd', '环境', '运维', '发布']],
|
|
68
|
+
['docs', ['docs', '文档', 'readme', '手册']],
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
/** 本插件认识的角色 id:固定班底 + 关键词表里出现过的动态角色。 */
|
|
72
|
+
export const KNOWN_ROLES = new Set([...SUB_ROLE_WORDS.map(([r]) => r), 'pm', 'architect', 'researcher', 'ui', 'backend', 'frontend', 'dba', 'sec', 'reviewer', 'qa', 'devops', 'docs']);
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 规范中文角色标签 → 角色 id(2026-09-11 起 prompt 与派工 label 用中文标签,见 ROLES.md)。
|
|
76
|
+
*
|
|
77
|
+
* 为什么需要**精确表**而不是只靠关键词:关键词是"按表序先命中先赢"的模糊匹配,而
|
|
78
|
+
* `【…】` 里的标签是**显式声明**,必须确定命中(历史事故:`【pm】产品分析员协作` 被猜成
|
|
79
|
+
* `product-analyst`、`【reviewer】测试用例复核` 被猜成 `qa`)。标签取值与浮层显示名一致
|
|
80
|
+
* (client.js 的 `ROLE_TOOL` 名字),避免同一角色两套叫法。
|
|
81
|
+
*/
|
|
82
|
+
export const ROLE_LABELS_ZH = new Map(Object.entries({
|
|
83
|
+
'产品经理': 'pm',
|
|
84
|
+
'架构师': 'architect',
|
|
85
|
+
'研究员': 'researcher',
|
|
86
|
+
'UI 设计师': 'ui',
|
|
87
|
+
'后端工程师': 'backend',
|
|
88
|
+
'前端工程师': 'frontend',
|
|
89
|
+
'数据工程师': 'dba',
|
|
90
|
+
'安全审计员': 'sec',
|
|
91
|
+
'审查官': 'reviewer',
|
|
92
|
+
'测试员': 'qa',
|
|
93
|
+
'运维': 'devops',
|
|
94
|
+
'文档工程师': 'docs',
|
|
95
|
+
'竞品分析师': 'competitive-analyst',
|
|
96
|
+
'产品分析员': 'product-analyst',
|
|
97
|
+
'UI 验证专家': 'ui-verifier',
|
|
98
|
+
'故障诊断工程师': 'debugger',
|
|
99
|
+
}).map(([label, role]) => [roleLabelKey(label), role]));
|
|
100
|
+
|
|
101
|
+
// ── 取值助手("取不到时显示什么"的展示策略;**不是**词表本身)────────────────────
|
|
102
|
+
// 放在词表真源旁边:它们是词表的**唯一合法消费者**,散到别处就会出现第二份"取不到显示什么"。
|
|
103
|
+
|
|
104
|
+
// 这里只留取值助手:它们表达的是"取不到时显示什么"的展示策略,不是词表本身。
|
|
105
|
+
export const phaseZh = (v) => (v == null || v === '') ? '—' : (PHASE_ZH[v] || String(v));
|
|
106
|
+
export const statusZh = (v) => (v == null || v === '') ? '—' : (STATUS_ZH[v] || String(v));
|
|
107
|
+
export const kindZh = (v) => (v == null || v === '') ? '任务' : (KIND_ZH[v] || String(v));
|
|
108
|
+
export const verdictZh = (v) => (v == null || v === '') ? '未判定' : (VERDICT_ZH[v] || String(v));
|
|
109
|
+
export const roleZh = (v) => (v == null || v === '') ? '—' : (ROLE_ZH[v] || String(v));
|
|
110
|
+
export const modeZh = (v) => (v == null || v === '') ? '' : (MODE_ZH[v] || String(v));
|
|
111
|
+
export const activityZh = (v) => (v == null) ? '—' : (ACTIVITY_ZH[String(v)] || String(v));
|
|
112
|
+
export const deliverZh = (v) => (v == null || v === '') ? '' : (DELIVER_ZH[v] || String(v));
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* **默认班底**(`/team <task>` 不指定 profile 时的编制)。
|
|
116
|
+
* 2026-09-13(B 线第 8 项 · command-parse)从 `command.js` 搬来这里:`command-parse.js` 的
|
|
117
|
+
* `PROFILE_DEFS.delivery` 要引用它,而 `command.js` 又要 import `command-parse.js` ——
|
|
118
|
+
* 留在 command.js 就成了**循环 import**。放在词表真源里,两边都从这儿取。
|
|
119
|
+
* ⚠️ 与 `KNOWN_ROLES` 不是一回事:那份是"认识哪些角色"(含动态补位的),这份是"默认派哪些"。
|
|
120
|
+
*/
|
|
121
|
+
export const DEFAULT_ROLES = ['pm', 'architect', 'researcher', 'ui', 'backend', 'frontend', 'dba', 'sec', 'reviewer', 'qa', 'devops', 'docs'];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// 并发写留痕(设计稿 §十二 第 3 步):**只记录、只告警,绝不阻断**。
|
|
2
|
+
//
|
|
3
|
+
// 依据(真实数据):某真实 run 的 14 条返工里 **9 条(64%)**命中「同一事实多份拷贝 / 多写者 / 口径漂移」,
|
|
4
|
+
// 其中 T29 的原文是「CONTRACT 单写者收口(**并发事故收敛** + 6 处已核实缺陷)」—— 事故已经发生才收口。
|
|
5
|
+
// 第 2 步(`AUTHORITY.md`)把"谁写哪份文件"变成了**事前声明**;本模块把"声明有没有被违反"变成**可观测**的。
|
|
6
|
+
//
|
|
7
|
+
// 三个刻意的设计取舍:
|
|
8
|
+
// ① **不阻断**。本仓的教训是"一上来就拦"会把门禁变成故障源(B2-1 的写侧门禁也踩过)。
|
|
9
|
+
// 这里先只留痕,等真实数据告诉我们"多频繁、多严重",再决定要不要收紧。
|
|
10
|
+
// ② **判据是"不同写者 + 同一文件 + 时间窗内"** —— 同一个人反复改同一文件是**正常**的,
|
|
11
|
+
// 只有**不同写者**才可能是事故(并发改同一份权威文件)。
|
|
12
|
+
// ③ **身份用字符串,由调用方给**(角色或会话 id)。本模块不认识宿主、不做 IO —— 这样它可以被纯单测,
|
|
13
|
+
// 也避免在**写路径**上塞进重活。
|
|
14
|
+
|
|
15
|
+
/** 默认时间窗:10 分钟。取值理由:一次"派工 → 写文件 → 回报"通常远小于它,而**两个角色的写入**落在这个窗口内才像并发。 */
|
|
16
|
+
export const DEFAULT_WRITE_WINDOW_MS = 10 * 60 * 1000;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 写者追踪器。
|
|
20
|
+
* @param args.windowMs - 时间窗(毫秒)。
|
|
21
|
+
* @param args.now - 时钟(可注入 ⇒ 可测)。
|
|
22
|
+
* @returns `{ record, conflicts, windowMs, _size, _reset }`
|
|
23
|
+
*/
|
|
24
|
+
export function createWriteTracer({ windowMs = DEFAULT_WRITE_WINDOW_MS, now = () => Date.now() } = {}) {
|
|
25
|
+
/** `${runId}::${abs}` → { who, at }(**最后一次**写入;只留最后一次即可判并发) */
|
|
26
|
+
const last = new Map();
|
|
27
|
+
/** 冲突历史(可审计;只保留最近 200 条,避免长跑进程里无界增长) */
|
|
28
|
+
const conflicts = [];
|
|
29
|
+
|
|
30
|
+
function record({ runId, abs, who, at = now() }) {
|
|
31
|
+
const w = String(who || '');
|
|
32
|
+
const key = `${String(runId || '')}::${String(abs || '')}`;
|
|
33
|
+
if (!w) return { conflict: null }; // 说不出写者 ⇒ **不猜**(宁可不报)
|
|
34
|
+
const prev = last.get(key);
|
|
35
|
+
last.set(key, { who: w, at });
|
|
36
|
+
if (!prev || !prev.who || prev.who === w) return { conflict: null };
|
|
37
|
+
const gapMs = Math.max(0, at - prev.at);
|
|
38
|
+
if (gapMs > windowMs) return { conflict: null }; // 超出窗口 ⇒ 不算并发
|
|
39
|
+
const conflict = { runId, abs, from: prev.who, to: w, gapMs };
|
|
40
|
+
conflicts.push(conflict);
|
|
41
|
+
if (conflicts.length > 200) conflicts.shift();
|
|
42
|
+
return { conflict };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
record,
|
|
47
|
+
conflicts: () => conflicts.slice(),
|
|
48
|
+
windowMs,
|
|
49
|
+
_size: () => last.size,
|
|
50
|
+
_reset: () => { last.clear(); conflicts.length = 0; },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** 渲染成一行留痕文本(事件用;调用方决定写到哪)。 */
|
|
55
|
+
export function formatConflict(c) {
|
|
56
|
+
const secs = Math.round((c.gapMs || 0) / 1000);
|
|
57
|
+
return `concurrent-write — \`${String(c.abs).split('/').slice(-2).join('/')}\` 在 ${secs}s 内被**两个写者**先后写入:${c.from} → ${c.to}(同一份文件两个写者=并发改同一份权威文件的形状,见 SKILL 规则 35 ④)`;
|
|
58
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yangdcm/dsh-expert-team",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "dsh「专家团」bundle:一句自然语言自动组建/持久化一支 12 角色多智能体团队,共享工作区协议 + 阶段门控编排 + 结构化交接 + 质量门禁/自动调度,实现者直接改代码并产出持久工件;带 live 团队浮层(质量门禁/覆盖率/工件预览)。 · Role-based multi-agent expert team for DeepSeek Harness: one sentence in, a staged and gated team delivery out.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"dsh",
|
|
9
|
+
"dsh-plugin",
|
|
10
|
+
"deepseek",
|
|
11
|
+
"deepseek-harness",
|
|
12
|
+
"multi-agent",
|
|
13
|
+
"ai-agents",
|
|
14
|
+
"agent-team",
|
|
15
|
+
"orchestration",
|
|
16
|
+
"workflow",
|
|
17
|
+
"subagent",
|
|
18
|
+
"code-review",
|
|
19
|
+
"quality-gate"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/yangdcm/dsh-expert-team.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/yangdcm/dsh-expert-team#readme",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/yangdcm/dsh-expert-team/issues"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=20"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"dsh": {
|
|
36
|
+
"bundle": {
|
|
37
|
+
"patch": "./cordis.patch.yml"
|
|
38
|
+
},
|
|
39
|
+
"client": {
|
|
40
|
+
"platform": "web",
|
|
41
|
+
"inject": [
|
|
42
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
43
|
+
"@deepseek-ai/dsh-client-ui-conversation"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"exports": {
|
|
48
|
+
".": "./lib/index.js",
|
|
49
|
+
"./command": "./lib/command.js",
|
|
50
|
+
"./client": "./client.js",
|
|
51
|
+
"./package.json": "./package.json"
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"lib",
|
|
55
|
+
"client.js",
|
|
56
|
+
"cordis.patch.yml",
|
|
57
|
+
"skills",
|
|
58
|
+
"presets",
|
|
59
|
+
"LICENSE",
|
|
60
|
+
"README.en.md"
|
|
61
|
+
],
|
|
62
|
+
"scripts": {
|
|
63
|
+
"rename": "node scripts/rename-package.mjs",
|
|
64
|
+
"check:name": "node scripts/rename-package.mjs --check",
|
|
65
|
+
"test:regression": "node regression.test.mjs",
|
|
66
|
+
"test:e2e": "node e2e.test.mjs",
|
|
67
|
+
"test:all": "node smoke.test.mjs && node regression.test.mjs && node e2e.test.mjs && node flow.test.mjs && node plan-decide.test.mjs && node plan-discard.test.mjs && node models-honesty.test.mjs && node evidence-gate.test.mjs && node sync-gate.test.mjs && node artifact-writer.test.mjs && node dag.test.mjs && node metrics.test.mjs && node broken-chain.test.mjs && node schema-warn.test.mjs && node template-copy.test.mjs && node task-binding.test.mjs && node role-merge.test.mjs && node wf-recovery.test.mjs && node panorama.test.mjs && node run-ownership.test.mjs && node role-identity.test.mjs && node command-parse.test.mjs && node member-registry.test.mjs && node schema-check.test.mjs && node run-health.test.mjs && node cordis-fs-port.test.mjs && node scaffold-fingerprint.test.mjs && node preset-lint.test.mjs && node stranded-tasks.test.mjs && node agent-scope-guard.test.mjs && node schema-warn-noise.test.mjs && node tool-card-status.test.mjs && node dag-status.test.mjs && node capacity-limits.test.mjs && node task-cas.test.mjs && node write-lock.test.mjs && node card-stall.test.mjs && node multi-session-and-confirm.test.mjs && node standing-rules.test.mjs && node scope-overlap.test.mjs && node task-cancel-protect.test.mjs && node wait-run.test.mjs && node rework-loop.test.mjs && node client-css-integrity.test.mjs && node interception.test.mjs && node mutation-catalog.test.mjs && node write-bypass-ratchet.test.mjs && node asi-hazards.test.mjs && node dispatch-contract.test.mjs && node closure-ledger.test.mjs && node rework-nature.test.mjs && node loop-guard.test.mjs && node vocab-consistency.test.mjs && node state-no-write.test.mjs && node routes-shared.test.mjs && node metrics-render.test.mjs && node metrics-collect.test.mjs && node first-runnable.test.mjs && node closing-budget.test.mjs && node scan-single-source.test.mjs && node tier.test.mjs && node dispatch-ledger.test.mjs && node tier-gate.test.mjs && node tier-badge.test.mjs && node validate-module.test.mjs && node settings.test.mjs && node settings-page.test.mjs && node policy.test.mjs && node phase-accounting.test.mjs && node log-parse-module.test.mjs && node command-parse-module.test.mjs && node authority.test.mjs && node write-tracer.test.mjs && node token-accounting.test.mjs && node lead-toolface.test.mjs",
|
|
68
|
+
"test:toolcard": "node tool-card-status.test.mjs",
|
|
69
|
+
"test:flow": "node flow.test.mjs",
|
|
70
|
+
"test:decide": "node plan-decide.test.mjs",
|
|
71
|
+
"test:discard": "node plan-discard.test.mjs",
|
|
72
|
+
"test:models": "node models-honesty.test.mjs",
|
|
73
|
+
"test:evidence-gate": "node evidence-gate.test.mjs",
|
|
74
|
+
"test:sync-gate": "node sync-gate.test.mjs",
|
|
75
|
+
"test:artifact-writer": "node artifact-writer.test.mjs",
|
|
76
|
+
"test:dag": "node dag.test.mjs",
|
|
77
|
+
"test:metrics": "node metrics.test.mjs",
|
|
78
|
+
"test:chain": "node broken-chain.test.mjs",
|
|
79
|
+
"test:schema": "node schema-warn.test.mjs",
|
|
80
|
+
"test:template": "node template-copy.test.mjs",
|
|
81
|
+
"test:binding": "node task-binding.test.mjs",
|
|
82
|
+
"test:role-merge": "node role-merge.test.mjs",
|
|
83
|
+
"test:wf-recovery": "node wf-recovery.test.mjs",
|
|
84
|
+
"test:panorama": "node panorama.test.mjs",
|
|
85
|
+
"test:ownership": "node run-ownership.test.mjs",
|
|
86
|
+
"gate:preset": "node scripts/validate-agent-preset.mjs",
|
|
87
|
+
"gate:evidence": "node scripts/check-evidence.mjs",
|
|
88
|
+
"gate:sync": "node scripts/check-sync.mjs",
|
|
89
|
+
"gate:bypass": "node scripts/check-write-bypass.mjs",
|
|
90
|
+
"gate:mutation": "node scripts/mutate.mjs",
|
|
91
|
+
"fix:sync": "node scripts/check-sync.mjs --fix",
|
|
92
|
+
"gate": "npm run gate:preset && npm run gate:evidence && npm run gate:sync && npm run gate:bypass && npm run test:all && npm run gate:mutation",
|
|
93
|
+
"test:identity": "node role-identity.test.mjs",
|
|
94
|
+
"test:parse": "node command-parse.test.mjs",
|
|
95
|
+
"test:members": "node member-registry.test.mjs",
|
|
96
|
+
"test:schema-check": "node schema-check.test.mjs",
|
|
97
|
+
"test:health": "node run-health.test.mjs",
|
|
98
|
+
"test:cordis-fs": "node cordis-fs-port.test.mjs",
|
|
99
|
+
"test:scaffold": "node scaffold-fingerprint.test.mjs",
|
|
100
|
+
"test:preset-lint": "node preset-lint.test.mjs",
|
|
101
|
+
"test:stranded": "node stranded-tasks.test.mjs",
|
|
102
|
+
"test:agent-scope": "node agent-scope-guard.test.mjs",
|
|
103
|
+
"test:schema-noise": "node schema-warn-noise.test.mjs",
|
|
104
|
+
"test:dagstatus": "node dag-status.test.mjs",
|
|
105
|
+
"preview:dag": "node scripts/preview-dag.mjs",
|
|
106
|
+
"test:capacity": "node capacity-limits.test.mjs",
|
|
107
|
+
"test:cas": "node task-cas.test.mjs",
|
|
108
|
+
"test:write-lock": "node write-lock.test.mjs",
|
|
109
|
+
"test:card-stall": "node card-stall.test.mjs",
|
|
110
|
+
"test:multi-session": "node multi-session-and-confirm.test.mjs",
|
|
111
|
+
"test:rules": "node standing-rules.test.mjs",
|
|
112
|
+
"test:scope": "node scope-overlap.test.mjs",
|
|
113
|
+
"test:cancel-protect": "node task-cancel-protect.test.mjs",
|
|
114
|
+
"test:wait": "node wait-run.test.mjs",
|
|
115
|
+
"test:loop": "node rework-loop.test.mjs",
|
|
116
|
+
"test:tokens": "node token-accounting.test.mjs",
|
|
117
|
+
"test:toolface": "node lead-toolface.test.mjs"
|
|
118
|
+
}
|
|
119
|
+
}
|