@godv61/dsh-task-engine 0.1.1 → 0.3.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/README.md +21 -6
- package/defaults/eng.json +8 -3
- package/hooks/commit-msg +214 -0
- package/lib/engine.d.ts +29 -1
- package/lib/engine.js +103 -0
- package/lib/engine.js.map +1 -1
- package/lib/index.js +88 -13
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
- package/skills/eng-delivery/SKILL.md +4 -1
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
- **阶段流转**:只能沿 `.dsh/eng.json` 配的阶段图走;非法流转直接报错拒绝。
|
|
8
8
|
- **确认/验证门**:需求/方案未确认 → 进不了设计/开发;实施项没完 → 不能交付;高风险没验证证据 → 不能过评审。
|
|
9
|
+
- **产物门**:每个阶段可声明必交产物 + 必填字段(需求说明 / 设计文档 / 评审记录…),字段没填全 → 不让流转。
|
|
9
10
|
- **提交门禁**:到检查点才能提交,消息必须匹配 `message_pattern`,`manual` 策略永不自动提交。
|
|
10
11
|
|
|
11
12
|
## 目录
|
|
@@ -13,7 +14,8 @@
|
|
|
13
14
|
```
|
|
14
15
|
cordis.patch.yml bundle 声明 + host 组合 patch(一行,注册本插件)
|
|
15
16
|
defaults/eng.json 内置默认工作流(可被项目 .dsh/eng.json 覆盖)
|
|
16
|
-
|
|
17
|
+
hooks/commit-msg git 提交门禁钩子(install_hook 装进 .git/hooks/)
|
|
18
|
+
src/engine.ts 纯函数状态机 + 配置校验(无 harness 依赖,可单测)
|
|
17
19
|
src/index.ts 插件:注册 dev_task 工具 + 内置技能
|
|
18
20
|
skills/eng-delivery/ 内置交付技能
|
|
19
21
|
preset/preset.yml 预设元数据
|
|
@@ -58,14 +60,27 @@ dsh plugin --profile <name> add .
|
|
|
58
60
|
在项目根放 `.dsh/eng.json`(复制 `defaults/eng.json` 改字段即可):
|
|
59
61
|
|
|
60
62
|
- `stages` / `start_stage` / `transitions`:阶段与流转图;每条边的 `requires` 用引擎原生 guard。
|
|
63
|
+
- `artifacts`:每个阶段要交的产物(`stage` + `id` + `name` + `fields`)。给某条边加 `artifacts_present` guard,就能让「该阶段产物字段没填全」挡住流转。
|
|
61
64
|
- `commit.policy`(`task|item|manual`)、`commit.message_pattern`/`message_hint`、`commit.checkpoints`。
|
|
62
65
|
- `high_risk_requires_verification`。
|
|
63
66
|
|
|
64
|
-
原生 guard:`requirement_confirmation`、`solution_confirmation`、`todos_done`、`verified`、`review_passed`。
|
|
67
|
+
原生 guard:`requirement_confirmation`、`solution_confirmation`、`todos_done`、`verified`、`review_passed`、`artifacts_present`。
|
|
68
|
+
|
|
69
|
+
产物落库用 `dev_task`(operation=record, artifact=..., fields=...):字段不合法会拒绝,没填全会提示 still missing;被 `artifacts_present` 挡住的 `advance` 会报「guards unmet: artifacts_present」。
|
|
70
|
+
|
|
71
|
+
**配置写错会报错,不再悄悄退回默认**:结构校验(阶段重复/缺失、流转指向未知阶段、guard 拼错、坏正则等)逐条列出。用 `dev_task`(operation=config)随时查看「当前生效配置 + 哪里配错了」。
|
|
72
|
+
|
|
73
|
+
## git 提交门禁(防止绕过)
|
|
74
|
+
|
|
75
|
+
默认提交是「工具校验 + 模型执行 git」,模型理论上能绕过 `dev_task` 直接 `git commit`。装个机械钩子彻底封死:
|
|
76
|
+
|
|
77
|
+
1. 用 `dev_task`(operation=install_hook)装进 `.git/hooks/commit-msg`(每个克隆本机装一次)。
|
|
78
|
+
2. 之后任何 `git commit`,钩子都用和引擎**同一套规则**检查:没有 dev_task 任务、阶段没到提交检查点、消息不匹配 `message_pattern`——一律拒绝并打印原因。
|
|
79
|
+
|
|
80
|
+
> 钩子读 `.dsh/eng.json` + `.dsh/task-*.json`,跨仓库零依赖、自包含。
|
|
65
81
|
|
|
66
82
|
## 已知待办(Phase 0 边界)
|
|
67
83
|
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
- 阶段产物(设计文档/评审字段)的硬 schema 校验属于你未选的"更重"档,Phase 0 不包含。
|
|
84
|
+
- **已验证**:strict `tsc` typecheck/build 零错误;`dsh plugin add` 装进独立实例 web profile、`--dump-config` 确认 `task-engine` 进组合树、可选 `eng` 预设可被 roster 发现;`validateWorkflow`(配置校验)、`artifacts_present`(产物门)与 `hooks/commit-msg`(机械提交门禁)已单测/冒烟——非法配置逐条报错、产物没填全挡流转、钩子该放放该拦拦。
|
|
85
|
+
- **没跑**:真实模型会话端到端(模型实际调用 `dev_task` 走完整流程 + `install_hook` 装钩子),要 `DEEPSEEK_API_KEY`。
|
|
86
|
+
- **后续档**:按「文件范围」拦截提交、网页图形化配置界面(Phase 1b)。
|
package/defaults/eng.json
CHANGED
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
"stages": ["requirement_review", "design", "implement", "deliver", "review", "done"],
|
|
3
3
|
"start_stage": "requirement_review",
|
|
4
4
|
"transitions": [
|
|
5
|
-
{ "from": "requirement_review", "to": "design", "requires": ["requirement_confirmation"] },
|
|
6
|
-
{ "from": "design", "to": "implement", "requires": ["solution_confirmation"] },
|
|
5
|
+
{ "from": "requirement_review", "to": "design", "requires": ["requirement_confirmation", "artifacts_present"] },
|
|
6
|
+
{ "from": "design", "to": "implement", "requires": ["solution_confirmation", "artifacts_present"] },
|
|
7
7
|
{ "from": "implement", "to": "deliver", "requires": ["todos_done"] },
|
|
8
8
|
{ "from": "deliver", "to": "review", "requires": ["verified"] },
|
|
9
|
-
{ "from": "review", "to": "done", "requires": ["review_passed"] }
|
|
9
|
+
{ "from": "review", "to": "done", "requires": ["review_passed", "artifacts_present"] }
|
|
10
|
+
],
|
|
11
|
+
"artifacts": [
|
|
12
|
+
{ "stage": "requirement_review", "id": "requirement", "name": "需求说明", "fields": ["scope", "acceptance_criteria"] },
|
|
13
|
+
{ "stage": "design", "id": "design", "name": "设计文档", "fields": ["approach", "risks", "impact"] },
|
|
14
|
+
{ "stage": "review", "id": "review", "name": "评审记录", "fields": ["conclusion", "issues"] }
|
|
10
15
|
],
|
|
11
16
|
"commit": {
|
|
12
17
|
"policy": "task",
|
package/hooks/commit-msg
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// dsh-task-engine commit-msg hook — mechanical commit gate.
|
|
3
|
+
//
|
|
4
|
+
// Installed into `.git/hooks/commit-msg` by `dev_task` (operation=install_hook).
|
|
5
|
+
// Self-contained mirror of src/engine.ts (`commitCheckpoint` + `validateCommitMessage`
|
|
6
|
+
// + `guardSatisfied`). KEEP IN SYNC with that source when the gate semantics change.
|
|
7
|
+
//
|
|
8
|
+
// Policy: refuse any `git commit` that is not backed by a dev_task record sitting
|
|
9
|
+
// at a commit-allowed checkpoint whose message matches the configured pattern.
|
|
10
|
+
'use strict'
|
|
11
|
+
|
|
12
|
+
const fs = require('node:fs')
|
|
13
|
+
const path = require('node:path')
|
|
14
|
+
const { execSync } = require('node:child_process')
|
|
15
|
+
|
|
16
|
+
const messageFile = process.argv[2]
|
|
17
|
+
|
|
18
|
+
function refuse(reason) {
|
|
19
|
+
console.error('')
|
|
20
|
+
console.error('dsh-task-engine 提交门禁拒绝: ' + reason)
|
|
21
|
+
console.error('请先用 dev_task 走完前置阶段(或修正提交消息),再提交。')
|
|
22
|
+
console.error('')
|
|
23
|
+
process.exit(1)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function readJson(abs) {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(fs.readFileSync(abs, 'utf8'))
|
|
29
|
+
} catch {
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Mirrors defaults/eng.json — keep in sync.
|
|
35
|
+
const DEFAULTS = {
|
|
36
|
+
stages: ['requirement_review', 'design', 'implement', 'deliver', 'review', 'done'],
|
|
37
|
+
start_stage: 'requirement_review',
|
|
38
|
+
transitions: [
|
|
39
|
+
{ from: 'requirement_review', to: 'design', requires: ['requirement_confirmation', 'artifacts_present'] },
|
|
40
|
+
{ from: 'design', to: 'implement', requires: ['solution_confirmation', 'artifacts_present'] },
|
|
41
|
+
{ from: 'implement', to: 'deliver', requires: ['todos_done'] },
|
|
42
|
+
{ from: 'deliver', to: 'review', requires: ['verified'] },
|
|
43
|
+
{ from: 'review', to: 'done', requires: ['review_passed', 'artifacts_present'] },
|
|
44
|
+
],
|
|
45
|
+
artifacts: [
|
|
46
|
+
{ stage: 'requirement_review', id: 'requirement', name: '需求说明', fields: ['scope', 'acceptance_criteria'] },
|
|
47
|
+
{ stage: 'design', id: 'design', name: '设计文档', fields: ['approach', 'risks', 'impact'] },
|
|
48
|
+
{ stage: 'review', id: 'review', name: '评审记录', fields: ['conclusion', 'issues'] },
|
|
49
|
+
],
|
|
50
|
+
commit: {
|
|
51
|
+
policy: 'task',
|
|
52
|
+
message_pattern: '^【(\\S+)】【(?:TASK|T\\d+)】.+',
|
|
53
|
+
message_hint: '【<module>】【TASK/T1】说明',
|
|
54
|
+
checkpoints: ['deliver'],
|
|
55
|
+
},
|
|
56
|
+
high_risk_requires_verification: true,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function loadWorkflow(override) {
|
|
60
|
+
if (!override) return DEFAULTS
|
|
61
|
+
return {
|
|
62
|
+
stages: override.stages ?? DEFAULTS.stages,
|
|
63
|
+
start_stage: override.start_stage ?? DEFAULTS.start_stage,
|
|
64
|
+
transitions: override.transitions ?? DEFAULTS.transitions,
|
|
65
|
+
artifacts: override.artifacts ?? DEFAULTS.artifacts,
|
|
66
|
+
commit: { ...DEFAULTS.commit, ...(override.commit ?? {}) },
|
|
67
|
+
high_risk_requires_verification:
|
|
68
|
+
override.high_risk_requires_verification ?? DEFAULTS.high_risk_requires_verification,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Mirrors engine.guardSatisfied.
|
|
73
|
+
function guardSatisfied(guard, state, config) {
|
|
74
|
+
switch (guard) {
|
|
75
|
+
case 'requirement_confirmation': return state.requirement_confirmed === true
|
|
76
|
+
case 'solution_confirmation': return state.solution_confirmed === true
|
|
77
|
+
case 'todos_done':
|
|
78
|
+
return Array.isArray(state.items) && state.items.length > 0 && state.items.every(item => item.status === 'done')
|
|
79
|
+
case 'verified':
|
|
80
|
+
if (!state.verification || state.verification.passed !== true) return false
|
|
81
|
+
return config.high_risk_requires_verification && state.risk_level === 'high_risk'
|
|
82
|
+
? Array.isArray(state.verification.evidence) && state.verification.evidence.length > 0
|
|
83
|
+
: true
|
|
84
|
+
case 'review_passed': return state.review && state.review.outcome === 'pass'
|
|
85
|
+
case 'artifacts_present': {
|
|
86
|
+
const recorded = state.artifacts || {}
|
|
87
|
+
return (config.artifacts || []).filter(artifact => artifact.stage === state.stage).every(artifact => {
|
|
88
|
+
const fields = recorded[artifact.id]
|
|
89
|
+
if (!fields) return false
|
|
90
|
+
return (artifact.fields || []).every(field => typeof fields[field] === 'string' && fields[field].trim() !== '')
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
default: return false
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Mirrors engine.commitCheckpoint.
|
|
98
|
+
function commitCheckpoint(state, config) {
|
|
99
|
+
const { policy, checkpoints } = config.commit
|
|
100
|
+
if (policy === 'manual') {
|
|
101
|
+
return { allowed: false, reason: 'commit policy is manual — await an explicit user instruction' }
|
|
102
|
+
}
|
|
103
|
+
if (checkpoints.includes(state.stage)) {
|
|
104
|
+
const ready = config.transitions
|
|
105
|
+
.filter(transition => transition.from === state.stage)
|
|
106
|
+
.every(transition => (transition.requires ?? []).every(guard => guardSatisfied(guard, state, config)))
|
|
107
|
+
if (!ready) return { allowed: false, reason: 'checkpoint stage reached but its outgoing guards are unmet' }
|
|
108
|
+
return { allowed: true, label: 'TASK' }
|
|
109
|
+
}
|
|
110
|
+
if (policy === 'item') {
|
|
111
|
+
const done = (state.items ?? []).filter(item => item.status === 'done').length
|
|
112
|
+
if (done > 0) return { allowed: true, label: 'T' + done }
|
|
113
|
+
}
|
|
114
|
+
return { allowed: false, reason: 'no commit is due at this stage under the current policy' }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Mirrors engine.validateCommitMessage.
|
|
118
|
+
function validateCommitMessage(message, config) {
|
|
119
|
+
if (config.commit.message_pattern === '') return { ok: true }
|
|
120
|
+
try {
|
|
121
|
+
return new RegExp(config.commit.message_pattern).test(message)
|
|
122
|
+
? { ok: true }
|
|
123
|
+
: { ok: false, reason: 'commit summary does not match ' + config.commit.message_hint }
|
|
124
|
+
} catch {
|
|
125
|
+
return { ok: false, reason: 'commit.message_pattern is not a valid regular expression' }
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// --- gather project state ---
|
|
130
|
+
const cwd = process.cwd()
|
|
131
|
+
const configPath = path.join(cwd, '.dsh', 'eng.json')
|
|
132
|
+
let config
|
|
133
|
+
if (fs.existsSync(configPath)) {
|
|
134
|
+
let raw = ''
|
|
135
|
+
try {
|
|
136
|
+
raw = fs.readFileSync(configPath, 'utf8')
|
|
137
|
+
} catch {
|
|
138
|
+
raw = ''
|
|
139
|
+
}
|
|
140
|
+
let parsed
|
|
141
|
+
try {
|
|
142
|
+
parsed = JSON.parse(raw)
|
|
143
|
+
} catch (error) {
|
|
144
|
+
refuse('invalid JSON in .dsh/eng.json: ' + (error && error.message ? error.message : String(error)))
|
|
145
|
+
}
|
|
146
|
+
config = loadWorkflow(parsed)
|
|
147
|
+
} else {
|
|
148
|
+
config = loadWorkflow(undefined)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function loadTasks() {
|
|
152
|
+
const dir = path.join(cwd, '.dsh')
|
|
153
|
+
if (!fs.existsSync(dir)) return []
|
|
154
|
+
const out = []
|
|
155
|
+
const names = fs.readdirSync(dir).filter(name => name.startsWith('task-') && name.endsWith('.json'))
|
|
156
|
+
for (const name of names) {
|
|
157
|
+
const task = readJson(path.join(dir, name))
|
|
158
|
+
if (task && task.id) out.push({ file: path.join(dir, name), task })
|
|
159
|
+
}
|
|
160
|
+
return out
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function currentBranch() {
|
|
164
|
+
try {
|
|
165
|
+
return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim()
|
|
166
|
+
} catch {
|
|
167
|
+
return ''
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function fileMtime(file) {
|
|
172
|
+
try {
|
|
173
|
+
return fs.statSync(file).mtimeMs
|
|
174
|
+
} catch {
|
|
175
|
+
return 0
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function pickTask(tasks, branch) {
|
|
180
|
+
if (tasks.length === 0) return undefined
|
|
181
|
+
const byBranch = tasks.find(({ task }) => task.branch === branch)
|
|
182
|
+
if (byBranch) return byBranch.task
|
|
183
|
+
if (tasks.length === 1) return tasks[0].task
|
|
184
|
+
const sorted = [...tasks].sort((a, b) => fileMtime(b.file) - fileMtime(a.file))
|
|
185
|
+
return sorted[0].task
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// --- the gate ---
|
|
189
|
+
if (!messageFile) {
|
|
190
|
+
process.exit(0)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const state = pickTask(loadTasks(), currentBranch())
|
|
194
|
+
if (!state) {
|
|
195
|
+
refuse('没有找到 dev_task 任务记录(.dsh/task-*.json)——请先 dev_task operation=create 建立任务')
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const checkpoint = commitCheckpoint(state, config)
|
|
199
|
+
if (!checkpoint.allowed) {
|
|
200
|
+
refuse(checkpoint.reason + '(当前阶段: ' + state.stage + ')')
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const message = fs.readFileSync(messageFile, 'utf8')
|
|
204
|
+
.split('\n')
|
|
205
|
+
.filter(line => !line.startsWith('#'))
|
|
206
|
+
.join('\n')
|
|
207
|
+
.trim()
|
|
208
|
+
|
|
209
|
+
const verdict = validateCommitMessage(message, config)
|
|
210
|
+
if (!verdict.ok) {
|
|
211
|
+
refuse(verdict.reason)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
process.exit(0)
|
package/lib/engine.d.ts
CHANGED
|
@@ -13,13 +13,24 @@ export type WorkSize = 'tiny' | 'standard' | 'complex';
|
|
|
13
13
|
export type RiskLevel = 'standard' | 'high_risk';
|
|
14
14
|
export type ItemStatus = 'todo' | 'doing' | 'done';
|
|
15
15
|
/** Guard names the engine resolves natively. Opaque names are config errors. */
|
|
16
|
-
export type GuardName = 'requirement_confirmation' | 'solution_confirmation' | 'todos_done' | 'verified' | 'review_passed';
|
|
16
|
+
export type GuardName = 'requirement_confirmation' | 'solution_confirmation' | 'todos_done' | 'verified' | 'review_passed' | 'artifacts_present';
|
|
17
17
|
/** One allowed stage transition and the guards that must already hold. */
|
|
18
18
|
export interface Transition {
|
|
19
19
|
from: string;
|
|
20
20
|
to: string;
|
|
21
21
|
requires?: GuardName[];
|
|
22
22
|
}
|
|
23
|
+
/** A stage-owned artifact: the `record` operation writes it, `artifacts_present` checks it. */
|
|
24
|
+
export interface ArtifactDef {
|
|
25
|
+
/** Stage that owns this artifact (checked against the state's current stage). */
|
|
26
|
+
stage: string;
|
|
27
|
+
/** Stable id the `record` operation writes under (unique per stage). */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Human-readable name surfaced in errors. */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Non-empty field keys; `artifacts_present` requires each to hold a non-empty value. */
|
|
32
|
+
fields: string[];
|
|
33
|
+
}
|
|
23
34
|
/** Commit policy and message shape. Empty `message_pattern` disables format checking. */
|
|
24
35
|
export interface CommitRule {
|
|
25
36
|
policy: 'task' | 'item' | 'manual';
|
|
@@ -32,6 +43,8 @@ export interface WorkflowConfig {
|
|
|
32
43
|
stages: string[];
|
|
33
44
|
start_stage: string;
|
|
34
45
|
transitions: Transition[];
|
|
46
|
+
/** Artifacts each stage must record before its `artifacts_present` guard passes. */
|
|
47
|
+
artifacts: ArtifactDef[];
|
|
35
48
|
commit: CommitRule;
|
|
36
49
|
/** A high_risk task cannot cross an edge guarded by `verified` without passing evidence. */
|
|
37
50
|
high_risk_requires_verification: boolean;
|
|
@@ -59,6 +72,8 @@ export interface TaskState {
|
|
|
59
72
|
review: {
|
|
60
73
|
outcome: 'pending' | 'pass' | 'blocked';
|
|
61
74
|
};
|
|
75
|
+
/** Recorded artifacts (artifact id -> field -> value). */
|
|
76
|
+
artifacts: Record<string, Record<string, string>>;
|
|
62
77
|
commits: {
|
|
63
78
|
label: string;
|
|
64
79
|
hash?: string;
|
|
@@ -68,8 +83,21 @@ export interface Result {
|
|
|
68
83
|
ok: boolean;
|
|
69
84
|
errors?: string[];
|
|
70
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Validate a merged workflow for structural soundness.
|
|
88
|
+
*
|
|
89
|
+
* Returns one human-readable problem per defect, or an empty list when the
|
|
90
|
+
* config can drive the state machine. This is what makes a hand-edited
|
|
91
|
+
* `.dsh/eng.json` fail loudly instead of driving gates that reference stages
|
|
92
|
+
* or guards that do not exist.
|
|
93
|
+
* @param config - the merged workflow to check.
|
|
94
|
+
* @returns problem strings; empty means valid.
|
|
95
|
+
*/
|
|
96
|
+
export declare function validateWorkflow(config: WorkflowConfig): string[];
|
|
71
97
|
/** Stage-merge an override over a default; absent fields keep the default. */
|
|
72
98
|
export declare function loadWorkflow(defaults: WorkflowConfig, override?: Partial<WorkflowConfig>): WorkflowConfig;
|
|
99
|
+
/** Artifacts a stage owns; `artifacts_present` checks these against the recorded values. */
|
|
100
|
+
export declare function artifactsForStage(stage: string, config: WorkflowConfig): ArtifactDef[];
|
|
73
101
|
/** Target stages reachable from `stage` via a configured transition. */
|
|
74
102
|
export declare function legalTargets(stage: string, config: WorkflowConfig): string[];
|
|
75
103
|
/** The edge from `from` to `to`, or undefined when not configured. */
|
package/lib/engine.js
CHANGED
|
@@ -9,6 +9,94 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @module dsh-task-engine/engine
|
|
11
11
|
*/
|
|
12
|
+
/** The full guard vocabulary. Unknown guard names are configuration errors. */
|
|
13
|
+
const GUARD_NAMES = [
|
|
14
|
+
'requirement_confirmation',
|
|
15
|
+
'solution_confirmation',
|
|
16
|
+
'todos_done',
|
|
17
|
+
'verified',
|
|
18
|
+
'review_passed',
|
|
19
|
+
'artifacts_present',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Validate a merged workflow for structural soundness.
|
|
23
|
+
*
|
|
24
|
+
* Returns one human-readable problem per defect, or an empty list when the
|
|
25
|
+
* config can drive the state machine. This is what makes a hand-edited
|
|
26
|
+
* `.dsh/eng.json` fail loudly instead of driving gates that reference stages
|
|
27
|
+
* or guards that do not exist.
|
|
28
|
+
* @param config - the merged workflow to check.
|
|
29
|
+
* @returns problem strings; empty means valid.
|
|
30
|
+
*/
|
|
31
|
+
export function validateWorkflow(config) {
|
|
32
|
+
const problems = [];
|
|
33
|
+
if (config.stages.length === 0)
|
|
34
|
+
problems.push('stages must not be empty');
|
|
35
|
+
const seen = new Set();
|
|
36
|
+
for (const stage of config.stages) {
|
|
37
|
+
if (seen.has(stage))
|
|
38
|
+
problems.push(`duplicate stage "${stage}"`);
|
|
39
|
+
seen.add(stage);
|
|
40
|
+
}
|
|
41
|
+
if (!config.stages.includes(config.start_stage)) {
|
|
42
|
+
problems.push(`start_stage "${config.start_stage}" is not in stages`);
|
|
43
|
+
}
|
|
44
|
+
const edges = new Set();
|
|
45
|
+
config.transitions.forEach((transition, index) => {
|
|
46
|
+
if (!config.stages.includes(transition.from)) {
|
|
47
|
+
problems.push(`transition ${index + 1}: from "${transition.from}" is not a stage`);
|
|
48
|
+
}
|
|
49
|
+
if (!config.stages.includes(transition.to)) {
|
|
50
|
+
problems.push(`transition ${index + 1}: to "${transition.to}" is not a stage`);
|
|
51
|
+
}
|
|
52
|
+
const edge = `${transition.from}->${transition.to}`;
|
|
53
|
+
if (edges.has(edge))
|
|
54
|
+
problems.push(`duplicate transition "${edge}"`);
|
|
55
|
+
edges.add(edge);
|
|
56
|
+
for (const guard of transition.requires ?? []) {
|
|
57
|
+
if (!GUARD_NAMES.includes(guard)) {
|
|
58
|
+
problems.push(`transition ${index + 1}: unknown guard "${String(guard)}"`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const artifactKeys = new Set();
|
|
63
|
+
config.artifacts.forEach((artifact, index) => {
|
|
64
|
+
if (!config.stages.includes(artifact.stage)) {
|
|
65
|
+
problems.push(`artifact ${index + 1}: stage "${artifact.stage}" is not a stage`);
|
|
66
|
+
}
|
|
67
|
+
const key = `${artifact.stage}:${artifact.id}`;
|
|
68
|
+
if (artifactKeys.has(key))
|
|
69
|
+
problems.push(`duplicate artifact "${key}"`);
|
|
70
|
+
artifactKeys.add(key);
|
|
71
|
+
if (artifact.fields.length === 0) {
|
|
72
|
+
problems.push(`artifact ${index + 1} ("${artifact.id}"): fields must not be empty`);
|
|
73
|
+
}
|
|
74
|
+
const fieldSet = new Set();
|
|
75
|
+
for (const field of artifact.fields) {
|
|
76
|
+
if (fieldSet.has(field)) {
|
|
77
|
+
problems.push(`artifact ${index + 1} ("${artifact.id}"): duplicate field "${field}"`);
|
|
78
|
+
}
|
|
79
|
+
fieldSet.add(field);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
if (!['task', 'item', 'manual'].includes(config.commit.policy)) {
|
|
83
|
+
problems.push(`commit.policy "${config.commit.policy}" is not task|item|manual`);
|
|
84
|
+
}
|
|
85
|
+
for (const checkpoint of config.commit.checkpoints) {
|
|
86
|
+
if (!config.stages.includes(checkpoint)) {
|
|
87
|
+
problems.push(`commit.checkpoint "${checkpoint}" is not a stage`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (config.commit.message_pattern !== '') {
|
|
91
|
+
try {
|
|
92
|
+
new RegExp(config.commit.message_pattern);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
problems.push('commit.message_pattern is not a valid regular expression');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return problems;
|
|
99
|
+
}
|
|
12
100
|
function requireKnownStage(stage, config) {
|
|
13
101
|
if (!config.stages.includes(stage)) {
|
|
14
102
|
return { ok: false, errors: [`unknown stage "${stage}"`] };
|
|
@@ -23,10 +111,15 @@ export function loadWorkflow(defaults, override) {
|
|
|
23
111
|
stages: override.stages ?? defaults.stages,
|
|
24
112
|
start_stage: override.start_stage ?? defaults.start_stage,
|
|
25
113
|
transitions: override.transitions ?? defaults.transitions,
|
|
114
|
+
artifacts: override.artifacts ?? defaults.artifacts,
|
|
26
115
|
commit: { ...defaults.commit, ...(override.commit ?? {}) },
|
|
27
116
|
high_risk_requires_verification: override.high_risk_requires_verification ?? defaults.high_risk_requires_verification,
|
|
28
117
|
};
|
|
29
118
|
}
|
|
119
|
+
/** Artifacts a stage owns; `artifacts_present` checks these against the recorded values. */
|
|
120
|
+
export function artifactsForStage(stage, config) {
|
|
121
|
+
return config.artifacts.filter(artifact => artifact.stage === stage);
|
|
122
|
+
}
|
|
30
123
|
/** Target stages reachable from `stage` via a configured transition. */
|
|
31
124
|
export function legalTargets(stage, config) {
|
|
32
125
|
return config.transitions
|
|
@@ -53,6 +146,15 @@ function guardSatisfied(guard, state, config) {
|
|
|
53
146
|
: true;
|
|
54
147
|
case 'review_passed':
|
|
55
148
|
return state.review.outcome === 'pass';
|
|
149
|
+
case 'artifacts_present': {
|
|
150
|
+
const required = artifactsForStage(state.stage, config);
|
|
151
|
+
return required.every(artifact => {
|
|
152
|
+
const recorded = state.artifacts[artifact.id];
|
|
153
|
+
if (recorded === undefined)
|
|
154
|
+
return false;
|
|
155
|
+
return artifact.fields.every(field => recorded[field] !== undefined && recorded[field].trim() !== '');
|
|
156
|
+
});
|
|
157
|
+
}
|
|
56
158
|
}
|
|
57
159
|
}
|
|
58
160
|
/**
|
|
@@ -137,6 +239,7 @@ export function newTask(input, config) {
|
|
|
137
239
|
items: [],
|
|
138
240
|
verification: { passed: false, evidence: [] },
|
|
139
241
|
review: { outcome: 'pending' },
|
|
242
|
+
artifacts: {},
|
|
140
243
|
commits: [],
|
|
141
244
|
};
|
|
142
245
|
}
|
package/lib/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
import { readFileSync, readdirSync } from 'node:fs';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
10
|
-
import { assertAdvance, commitCheckpoint, legalTargets, loadWorkflow, newTask, validateCommitMessage, } from "./engine.js";
|
|
10
|
+
import { assertAdvance, commitCheckpoint, legalTargets, loadWorkflow, newTask, validateCommitMessage, validateWorkflow, } from "./engine.js";
|
|
11
11
|
export const name = 'task-engine';
|
|
12
12
|
export const inject = ['tools', 'fs'];
|
|
13
13
|
const DEFAULTS = JSON.parse(readFileSync(fileURLToPath(new URL('../defaults/eng.json', import.meta.url)), 'utf8'));
|
|
14
|
+
/** Bundled commit-msg hook, copied into `.git/hooks/` by the `install_hook` operation. */
|
|
15
|
+
const HOOK_TEMPLATE = readFileSync(fileURLToPath(new URL('../hooks/commit-msg', import.meta.url)), 'utf8');
|
|
16
|
+
/** Pins the hook directory to CommonJS so the extensionless hook runs under any repo `type`. */
|
|
17
|
+
const HOOK_PACKAGE_JSON = '{\n "type": "commonjs"\n}\n';
|
|
14
18
|
async function readText(fs, relPath) {
|
|
15
19
|
try {
|
|
16
20
|
return await fs.readText(fs.resolve(relPath));
|
|
@@ -26,32 +30,57 @@ function sanitize(id) {
|
|
|
26
30
|
return id.replace(/[^0-9a-zA-Z_-]/g, '-');
|
|
27
31
|
}
|
|
28
32
|
const taskPath = (id) => `.dsh/task-${sanitize(id)}.json`;
|
|
29
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the effective workflow, distinguishing a missing config from a bad one.
|
|
35
|
+
*
|
|
36
|
+
* `default` means no `.dsh/eng.json` (bundled defaults). `project` means the
|
|
37
|
+
* project config is present and structurally sound. `invalid` means the project
|
|
38
|
+
* config exists but is unparsable or fails {@link validateWorkflow}; its
|
|
39
|
+
* problems are surfaced so a misconfigured gate fails loudly instead of
|
|
40
|
+
* silently degrading to the default.
|
|
41
|
+
*/
|
|
30
42
|
async function resolveWorkflow(fs) {
|
|
31
43
|
const raw = await readText(fs, '.dsh/eng.json');
|
|
32
44
|
if (raw === undefined)
|
|
33
|
-
return DEFAULTS;
|
|
45
|
+
return { config: DEFAULTS, problems: [], source: 'default' };
|
|
46
|
+
let parsed;
|
|
34
47
|
try {
|
|
35
|
-
|
|
48
|
+
parsed = JSON.parse(raw);
|
|
36
49
|
}
|
|
37
|
-
catch {
|
|
38
|
-
return
|
|
50
|
+
catch (error) {
|
|
51
|
+
return {
|
|
52
|
+
config: DEFAULTS,
|
|
53
|
+
problems: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],
|
|
54
|
+
source: 'invalid',
|
|
55
|
+
};
|
|
39
56
|
}
|
|
57
|
+
const config = loadWorkflow(DEFAULTS, parsed);
|
|
58
|
+
const problems = validateWorkflow(config);
|
|
59
|
+
return { config, problems, source: problems.length === 0 ? 'project' : 'invalid' };
|
|
60
|
+
}
|
|
61
|
+
/** Write the bundled notch gate into `.git/hooks/` so `git commit` is mechanically gated. */
|
|
62
|
+
async function installCommitHook(fs) {
|
|
63
|
+
await writeText(fs, '.git/hooks/commit-msg', HOOK_TEMPLATE);
|
|
64
|
+
await writeText(fs, '.git/hooks/package.json', HOOK_PACKAGE_JSON);
|
|
40
65
|
}
|
|
41
66
|
async function loadTask(fs, id) {
|
|
42
67
|
const raw = await readText(fs, taskPath(id));
|
|
43
68
|
if (raw === undefined)
|
|
44
69
|
throw new Error(`no task "${id}" under ${taskPath(id)}`);
|
|
45
|
-
|
|
70
|
+
const state = JSON.parse(raw);
|
|
71
|
+
// Tasks recorded before the artifacts feature lack the field; treat them as empty.
|
|
72
|
+
state.artifacts = state.artifacts ?? {};
|
|
73
|
+
return state;
|
|
46
74
|
}
|
|
47
75
|
async function writeTask(fs, state) {
|
|
48
76
|
await writeText(fs, taskPath(state.id), JSON.stringify(state, null, 2));
|
|
49
77
|
}
|
|
50
|
-
const OPERATIONS = ['status', 'create', 'confirm', 'advance', 'verify', 'review', 'commit'];
|
|
78
|
+
const OPERATIONS = ['status', 'create', 'confirm', 'record', 'advance', 'verify', 'review', 'commit', 'config', 'install_hook'];
|
|
51
79
|
const TOOL_DESCRIPTION = 'Own the engineering delivery workflow as hard state. Read or create the task record, record a ' +
|
|
52
|
-
'confirmation, advance one stage (rejected unless every configured guard already
|
|
53
|
-
'verification or review, and gate a commit on
|
|
54
|
-
'instead of degrading — treat a rejection as a
|
|
80
|
+
'confirmation or a stage artifact, advance one stage (rejected unless every configured guard already ' +
|
|
81
|
+
'holds, including the stage artifacts), record verification or review, and gate a commit on ' +
|
|
82
|
+
'stage/scope/message. The tool refuses illegal moves instead of degrading — treat a rejection as a ' +
|
|
83
|
+
'fact to fix, not a prompt to retry another way.';
|
|
55
84
|
export function apply(ctx) {
|
|
56
85
|
ctx.tools.register(defineTool({
|
|
57
86
|
name: 'dev_task',
|
|
@@ -81,6 +110,12 @@ export function apply(ctx) {
|
|
|
81
110
|
passed: { type: 'boolean', description: 'Verification passed (verify).' },
|
|
82
111
|
evidence: { type: 'array', items: { type: 'string' }, description: 'Verification evidence (verify).' },
|
|
83
112
|
outcome: { type: 'string', enum: ['pass', 'blocked'], description: 'Review outcome (review).' },
|
|
113
|
+
artifact: { type: 'string', description: 'Artifact id to record fields for (record).' },
|
|
114
|
+
fields: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
description: 'Field values for the artifact (record).',
|
|
117
|
+
additionalProperties: true,
|
|
118
|
+
},
|
|
84
119
|
message: { type: 'string', description: 'Commit summary to validate (commit).' },
|
|
85
120
|
hash: { type: 'string', description: 'Commit hash to record after the git commit (commit).' },
|
|
86
121
|
},
|
|
@@ -92,7 +127,24 @@ export function apply(ctx) {
|
|
|
92
127
|
},
|
|
93
128
|
async execute(args) {
|
|
94
129
|
const a = args;
|
|
95
|
-
|
|
130
|
+
if (a.operation === 'config') {
|
|
131
|
+
const resolved = await resolveWorkflow(ctx.fs);
|
|
132
|
+
return JSON.stringify({
|
|
133
|
+
source: resolved.source,
|
|
134
|
+
valid: resolved.problems.length === 0,
|
|
135
|
+
problems: resolved.problems,
|
|
136
|
+
workflow: resolved.config,
|
|
137
|
+
}, null, 2);
|
|
138
|
+
}
|
|
139
|
+
if (a.operation === 'install_hook') {
|
|
140
|
+
await installCommitHook(ctx.fs);
|
|
141
|
+
return 'installed commit-msg hook at .git/hooks/commit-msg — git commit is now gated by the task state';
|
|
142
|
+
}
|
|
143
|
+
const resolved = await resolveWorkflow(ctx.fs);
|
|
144
|
+
if (resolved.problems.length > 0) {
|
|
145
|
+
throw new Error(`invalid .dsh/eng.json — fix the project config first:\n- ${resolved.problems.join('\n- ')}`);
|
|
146
|
+
}
|
|
147
|
+
const workflow = resolved.config;
|
|
96
148
|
if (a.operation === 'create') {
|
|
97
149
|
if (!a.task_id || !a.title || !a.branch) {
|
|
98
150
|
throw new Error('create requires task_id, title, and branch');
|
|
@@ -122,6 +174,7 @@ export function apply(ctx) {
|
|
|
122
174
|
items_done: `${state.items.filter(i => i.status === 'done').length}/${state.items.length}`,
|
|
123
175
|
verification: state.verification,
|
|
124
176
|
review: state.review,
|
|
177
|
+
artifacts: state.artifacts,
|
|
125
178
|
legal_next: legalTargets(state.stage, workflow),
|
|
126
179
|
commit: commitCheckpoint(state, workflow),
|
|
127
180
|
}, null, 2);
|
|
@@ -138,6 +191,7 @@ export function apply(ctx) {
|
|
|
138
191
|
await writeTask(ctx.fs, state);
|
|
139
192
|
return `commit approved (${checkpoint.label ?? ''}) — git add <task files>; git commit -m "${a.message ?? ''}"`;
|
|
140
193
|
}
|
|
194
|
+
let note;
|
|
141
195
|
switch (a.operation) {
|
|
142
196
|
case 'confirm':
|
|
143
197
|
if (a.field === 'requirement')
|
|
@@ -147,6 +201,27 @@ export function apply(ctx) {
|
|
|
147
201
|
else
|
|
148
202
|
throw new Error('confirm requires field: requirement|solution');
|
|
149
203
|
break;
|
|
204
|
+
case 'record': {
|
|
205
|
+
if (!a.artifact)
|
|
206
|
+
throw new Error('record requires artifact (the artifact id)');
|
|
207
|
+
const def = workflow.artifacts.find(artifact => artifact.id === a.artifact);
|
|
208
|
+
if (!def) {
|
|
209
|
+
throw new Error(`unknown artifact "${a.artifact}"; declared: ${workflow.artifacts.map(x => x.id).join(', ') || 'none'}`);
|
|
210
|
+
}
|
|
211
|
+
const merged = { ...(state.artifacts[def.id] ?? {}) };
|
|
212
|
+
for (const [field, value] of Object.entries(a.fields ?? {})) {
|
|
213
|
+
if (!def.fields.includes(field)) {
|
|
214
|
+
throw new Error(`artifact "${def.id}" has no field "${field}"; fields: ${def.fields.join(', ')}`);
|
|
215
|
+
}
|
|
216
|
+
merged[field] = value === undefined || value === null ? '' : String(value);
|
|
217
|
+
}
|
|
218
|
+
state.artifacts[def.id] = merged;
|
|
219
|
+
const missing = def.fields.filter(field => !merged[field] || merged[field].trim() === '');
|
|
220
|
+
note = missing.length === 0
|
|
221
|
+
? `recorded ${def.name} ("${def.id}") — all required fields present`
|
|
222
|
+
: `recorded ${def.name} ("${def.id}"); still missing: ${missing.join(', ')}`;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
150
225
|
case 'advance': {
|
|
151
226
|
const result = assertAdvance(state, a.target_stage ?? '', workflow);
|
|
152
227
|
if (!result.ok)
|
|
@@ -166,7 +241,7 @@ export function apply(ctx) {
|
|
|
166
241
|
throw new Error(`unknown operation ${a.operation}`);
|
|
167
242
|
}
|
|
168
243
|
await writeTask(ctx.fs, state);
|
|
169
|
-
return `ok (stage ${state.stage})`;
|
|
244
|
+
return note ?? `ok (stage ${state.stage})`;
|
|
170
245
|
},
|
|
171
246
|
}));
|
|
172
247
|
// Ship the bundled engineering skills into this bundle's layer of the host
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godv61/dsh-task-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Config-driven engineering delivery engine for DeepSeek Harness: a `dev_task` tool that hard-gates workflow stage transitions and commit scope/message, plus bundled skills and an opt-in preset.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"lib/**",
|
|
19
19
|
"cordis.patch.yml",
|
|
20
20
|
"defaults/eng.json",
|
|
21
|
+
"hooks/**",
|
|
21
22
|
"skills/**",
|
|
22
23
|
"preset/**",
|
|
23
24
|
"README.md"
|
|
@@ -11,11 +11,14 @@ whenToUse: 开始任何开发、改 bug、加功能、代码评审或提交任
|
|
|
11
11
|
## 入口
|
|
12
12
|
|
|
13
13
|
1. 先 `dev_task`(operation=status)读当前分支任务;没有任务则(operation=create)建立任务并停在起始阶段。
|
|
14
|
-
2.
|
|
14
|
+
2. 每阶段:完成本阶段产物后:
|
|
15
|
+
- 若本阶段配置了必交产物(`dev_task` operation=status 会列出 still missing 的字段),先用 `dev_task`(operation=record, artifact=..., fields=...)逐字段记录;字段不填全,流转会被 `artifacts_present` guard 拒绝。
|
|
16
|
+
- 再用 `dev_task`(operation=advance)流转到目标阶段;被拒绝说明 guard 未满足(确认没过 / 产物字段没填全 / 实施项没完 / 高风险没验证 / 评审没过),先补齐再重试,不得绕过。
|
|
15
17
|
3. 提交前用 `dev_task`(operation=commit)校验阶段、提交范围与消息格式;拿到 approved 消息后再执行 `git add <任务内文件>; git commit -m "<approved>"`,并把 commit hash 通过 `dev_task`(operation=commit, hash=...)回写。
|
|
16
18
|
|
|
17
19
|
## 硬规则
|
|
18
20
|
|
|
19
21
|
- 需求、Bug、继续开发、验证、评审、提交请求一律经 `dev_task` 状态机推进,不自行绕过。
|
|
22
|
+
- 阶段必交产物(如需求说明、设计文档、评审记录)必须用 `dev_task` operation=record 落库,字段不能留空、不能装样子。
|
|
20
23
|
- 只做任务范围内的本地提交;绝不 push、合并、创建 PR、执行数据库、操作 Jenkins、部署或发布。
|
|
21
24
|
- `dev_task` 的拒绝是硬事实:修正前置条件,而不是换一种方式绕过。
|