@whaletalk/dsh-codex-collab 0.1.9 → 0.1.10
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/CHANGELOG.md +9 -0
- package/README.md +105 -25
- package/codex-plugin/plugins/dsh/.codex-plugin/plugin.json +1 -1
- package/codex-plugin/plugins/dsh/skills/dsh-collab/SKILL.md +63 -3
- package/codex-plugin/plugins/dsh/skills/dsh-collab/scripts/review.mjs +91 -6
- package/codex-plugin/plugins/dsh/skills/dsh-collab/scripts/task.mjs +443 -39
- package/docs/CODEX_DSH_APPROVAL_DELEGATION_PLAN.md +130 -0
- package/docs/CODEX_DSH_APPROVAL_M0_EVIDENCE.md +285 -0
- package/docs/CODEX_DSH_DELIVERY_CONTROL_PLAN.md +81 -0
- package/docs/CODEX_DSH_MODEL_ROUTING_PLAN.md +75 -0
- package/docs/DSH_APPROVAL_DELEGATION.md +142 -0
- package/docs/DSH_DELIVERY_M0_EVIDENCE.md +69 -0
- package/docs/DSH_MODEL_ROUTING_M0_EVIDENCE.md +166 -0
- package/harness/audit-tail.mjs +32 -0
- package/harness/codex-approvals.mjs +1078 -0
- package/harness/codex-associations.mjs +39 -7
- package/harness/dsh-bridge.mjs +1950 -191
- package/harness/model-route-host.mjs +530 -0
- package/harness/model-routing.mjs +500 -0
- package/harness/session-observer.mjs +217 -0
- package/harness/session-target.mjs +161 -6
- package/harness/task-table.mjs +6 -4
- package/mcp/dsh-mcp.mjs +474 -12
- package/package.json +2 -2
|
@@ -121,14 +121,25 @@ const foldRecords = (events) => {
|
|
|
121
121
|
error: undefined,
|
|
122
122
|
reason: undefined,
|
|
123
123
|
stopReason: undefined,
|
|
124
|
+
// 投递控制(第四轮):父关系/投递模式是**不可变关系**,在 bind 时就落盘(不能等执行后补)。
|
|
125
|
+
deliver: event.deliver,
|
|
126
|
+
parentTaskId: event.parentTaskId,
|
|
127
|
+
resultScope: event.resultScope,
|
|
128
|
+
requestSeq: event.requestSeq,
|
|
129
|
+
receiptState: event.receiptState,
|
|
130
|
+
route: event.route,
|
|
131
|
+
routePolicy: event.routePolicy,
|
|
124
132
|
})
|
|
125
133
|
continue
|
|
126
134
|
}
|
|
127
135
|
if (event.type === 'update') {
|
|
128
136
|
const record = records.get(event.taskId)
|
|
129
137
|
if (record === undefined) continue
|
|
130
|
-
for (const key of ['status', 'delivered', 'result', 'error', 'reason', 'stopReason', 'requestId', 'dshTurn']) {
|
|
131
|
-
if (event[key]
|
|
138
|
+
for (const key of ['status', 'delivered', 'result', 'error', 'reason', 'stopReason', 'requestId', 'dshTurn', 'deliver', 'parentTaskId', 'receiptState', 'observedTurn', 'resultScope', 'requestSeq', 'route', 'routePolicy', 'routeStopReason']) {
|
|
139
|
+
if (event[key] === undefined) continue
|
|
140
|
+
// 显式 null = **清除**(回执绝不允许残留父任务的 result/reason 等旧值)
|
|
141
|
+
if (event[key] === null) { delete record[key]; continue }
|
|
142
|
+
record[key] = event[key]
|
|
132
143
|
}
|
|
133
144
|
record.updatedAt = event.at
|
|
134
145
|
}
|
|
@@ -182,7 +193,7 @@ export const openAssociations = (options = {}) => {
|
|
|
182
193
|
* 登记一条关联。**必须在执行前调用**:写盘失败就抛错,让调用方放弃启动 DSH 执行
|
|
183
194
|
* (绝不出现"执行了却没绑定")。
|
|
184
195
|
*/
|
|
185
|
-
bind({ originThreadId, taskId, kind, target, delivered }) {
|
|
196
|
+
bind({ originThreadId, taskId, kind, target, delivered, deliver, parentTaskId, resultScope, requestSeq, receiptState, route, routePolicy }) {
|
|
186
197
|
if (!isValidOrigin(originThreadId)) {
|
|
187
198
|
throw fail(ASSOC_REASONS.INVALID_ORIGIN, 'originThreadId must be a non-empty string of at most ' + MAX_ORIGIN_LENGTH + ' characters without control characters')
|
|
188
199
|
}
|
|
@@ -204,6 +215,15 @@ export const openAssociations = (options = {}) => {
|
|
|
204
215
|
profile,
|
|
205
216
|
status: 'accepted',
|
|
206
217
|
delivered: delivered === true ? true : undefined,
|
|
218
|
+
// 不可变父关系 / 投递模式(第四轮 A):执行前就落盘,重启后仍在
|
|
219
|
+
deliver: deliver === 'steer' || deliver === 'queue' ? deliver : undefined,
|
|
220
|
+
parentTaskId: typeof parentTaskId === 'string' && parentTaskId !== '' ? parentTaskId : undefined,
|
|
221
|
+
resultScope: typeof resultScope === 'string' ? resultScope : undefined,
|
|
222
|
+
requestSeq: typeof requestSeq === 'number' ? requestSeq : undefined,
|
|
223
|
+
receiptState: typeof receiptState === 'string' ? receiptState : undefined,
|
|
224
|
+
// 模型路由(第一版验收修正):派活前就落盘的选择/策略(重启后可按 origin+task 取回)
|
|
225
|
+
route: route !== null && typeof route === 'object' ? route : undefined,
|
|
226
|
+
routePolicy: routePolicy !== null && typeof routePolicy === 'object' ? routePolicy : undefined,
|
|
207
227
|
at,
|
|
208
228
|
})
|
|
209
229
|
return load().get(taskId)
|
|
@@ -222,12 +242,24 @@ export const openAssociations = (options = {}) => {
|
|
|
222
242
|
taskId,
|
|
223
243
|
status: typeof patch.status === 'string' ? patch.status : undefined,
|
|
224
244
|
delivered: patch.delivered === undefined ? undefined : patch.delivered === true,
|
|
225
|
-
result: typeof patch.result === 'string' ? patch.result : undefined,
|
|
226
|
-
error: typeof patch.error === 'string' ? patch.error : undefined,
|
|
227
|
-
reason: typeof patch.reason === 'string' ? patch.reason : undefined,
|
|
228
|
-
stopReason: typeof patch.stopReason === 'string' ? patch.stopReason : undefined,
|
|
245
|
+
result: patch.result === null ? null : (typeof patch.result === 'string' ? patch.result : undefined),
|
|
246
|
+
error: patch.error === null ? null : (typeof patch.error === 'string' ? patch.error : undefined),
|
|
247
|
+
reason: patch.reason === null ? null : (typeof patch.reason === 'string' ? patch.reason : undefined),
|
|
248
|
+
stopReason: patch.stopReason === null ? null : (typeof patch.stopReason === 'string' ? patch.stopReason : undefined),
|
|
229
249
|
requestId: typeof patch.requestId === 'string' ? patch.requestId : undefined,
|
|
230
250
|
dshTurn: typeof patch.dshTurn === 'number' ? patch.dshTurn : undefined,
|
|
251
|
+
// 投递控制(第四轮 A):投递模式与父/回执关系(持久化,重启后仍能查);
|
|
252
|
+
// `null` = 显式清除(回执绝不允许残留父任务的旧 result/reason)。
|
|
253
|
+
deliver: patch.deliver === 'steer' || patch.deliver === 'queue' ? patch.deliver : undefined,
|
|
254
|
+
parentTaskId: patch.parentTaskId === null ? null : (typeof patch.parentTaskId === 'string' ? patch.parentTaskId : undefined),
|
|
255
|
+
receiptState: patch.receiptState === null ? null : (typeof patch.receiptState === 'string' ? patch.receiptState : undefined),
|
|
256
|
+
observedTurn: patch.observedTurn === null ? null : (typeof patch.observedTurn === 'number' ? patch.observedTurn : undefined),
|
|
257
|
+
resultScope: patch.resultScope === null ? null : (typeof patch.resultScope === 'string' ? patch.resultScope : undefined),
|
|
258
|
+
requestSeq: patch.requestSeq === null ? null : (typeof patch.requestSeq === 'number' ? patch.requestSeq : undefined),
|
|
259
|
+
// 模型路由(第一版验收修正):选择/策略/终止原因随任务落盘(重启后按 origin+task 可取回)
|
|
260
|
+
route: patch.route === null ? null : (patch.route !== null && typeof patch.route === 'object' ? patch.route : undefined),
|
|
261
|
+
routePolicy: patch.routePolicy === null ? null : (patch.routePolicy !== null && typeof patch.routePolicy === 'object' ? patch.routePolicy : undefined),
|
|
262
|
+
routeStopReason: patch.routeStopReason === null ? null : (typeof patch.routeStopReason === 'string' ? patch.routeStopReason : undefined),
|
|
231
263
|
at: Date.now(),
|
|
232
264
|
})
|
|
233
265
|
return load().get(taskId)
|