@leonhardthust/dsh-decision-engine 1.9.1 → 1.10.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 +3 -2
- package/README.zh.md +2 -2
- package/config.example.yml +50 -23
- package/docs/auto-review-hotfix.md +21 -0
- package/docs/releasing.md +8 -8
- package/lib/client.js +695 -227
- package/lib/decision-log.js +501 -0
- package/lib/decision-store.js +756 -97
- package/lib/engine.js +38 -30
- package/lib/guard/advisory.js +36 -21
- package/lib/guard/audit.js +5 -1
- package/lib/guard/context.js +30 -11
- package/lib/guard/effects.js +14 -0
- package/lib/guard/listener.js +39 -9
- package/lib/guard/messages.js +35 -0
- package/lib/index.js +312 -15
- package/lib/outcomes.js +3 -1
- package/lib/providers.js +57 -8
- package/lib/tolerance.js +50 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,10 +32,11 @@ main model acts.
|
|
|
32
32
|
**Providers**: system one · bamboonode · 硅基流动 SiliconFlow (CN / Global) ·
|
|
33
33
|
Perplexity · OpenRouter · custom base URL
|
|
34
34
|
|
|
35
|
-
**
|
|
35
|
+
**Safety level (how often to ask)**: Don't ask · Ask less · Default · Ask more
|
|
36
|
+
(none of the four changes permission-mandated approval or denial)
|
|
36
37
|
|
|
37
38
|
**UI**: config page with collapsible sections · Decisions tab · stats ·
|
|
38
|
-
readable approval card
|
|
39
|
+
readable approval card · sharded decision logs (by date / session / workspace) with retention
|
|
39
40
|
|
|
40
41
|
| Config page | Decisions tab |
|
|
41
42
|
|---|---|
|
package/README.zh.md
CHANGED
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
**决策服务**:system one · bamboonode · 硅基流动 SiliconFlow(国内 / 国际)·
|
|
32
32
|
Perplexity · OpenRouter · 自定义 base URL
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
**安全档位(询问频率)**:不问 · 少问 · 默认 · 多问(四档都不改变权限强制的人工批准与拒绝)
|
|
35
35
|
|
|
36
36
|
**界面**:配置页(四个可折叠分组)· 决策历史标签页 · 统计与对比 ·
|
|
37
|
-
审批卡正文可读化
|
|
37
|
+
审批卡正文可读化 · 决策日志分文件(按日期 / 会话 / 工作区)与自动清理
|
|
38
38
|
|
|
39
39
|
| 配置页 | 决策历史 |
|
|
40
40
|
|---|---|
|
package/config.example.yml
CHANGED
|
@@ -232,11 +232,14 @@ cooldownProbeMs: 10000
|
|
|
232
232
|
# cooldownMs: 60000 # 首轮冷却时长(上限为其 10 倍)
|
|
233
233
|
# failureThreshold: 3 # 连续失败多少次进入冷却
|
|
234
234
|
|
|
235
|
-
#
|
|
236
|
-
# never
|
|
237
|
-
# auto
|
|
238
|
-
# always
|
|
239
|
-
#
|
|
235
|
+
# 决策模型思考(startlux / System One 的 think_mode),三档:
|
|
236
|
+
# never 跳过思考——最省延迟(bamboonode 实测约 1.9s),默认值,热路径首选
|
|
237
|
+
# auto 由服务端决定——实测比 never 慢(约 7.2s),“按需”在实践中常常等于思考
|
|
238
|
+
# always 总是思考——每次约多等 5 秒;质量收益尚未实测
|
|
239
|
+
# 它**只影响本插件发给决策端点的请求**,不改宿主主模型的推理档位(那个在
|
|
240
|
+
# 「自动审查回退 › 推理档位」)。bamboonode/startlux 已实测支持;systemone、
|
|
241
|
+
# 两个 SiliconFlow 与 custom 未实测(会照常发送,可能被忽略、不报错);
|
|
242
|
+
# Perplexity / OpenRouter 的公开 API 没有这个字段。
|
|
240
243
|
thinkMode: never
|
|
241
244
|
|
|
242
245
|
# ============================================================================
|
|
@@ -352,12 +355,20 @@ guardFallbackProvider: ""
|
|
|
352
355
|
guardFallbackModel: ""
|
|
353
356
|
guardFallbackReasoningEffort: ""
|
|
354
357
|
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
#
|
|
359
|
-
#
|
|
360
|
-
#
|
|
358
|
+
# 安全档位(tolerance):只调整**软性审查**多频繁地升级为询问。
|
|
359
|
+
# autonomous 不问 软性询问不弹窗、不按比例;权限强制的人工批准与拒绝照旧
|
|
360
|
+
# relaxed 少问 只按严重度尾部(校准后约最前 1%,校准前固定分 0.60);
|
|
361
|
+
# **替换**默认判断,因此同一次调用可能比默认多问也可能少问
|
|
362
|
+
# default 默认 沿用决策模型自己的判断(中/高风险、疑似注入、
|
|
363
|
+
# 不可逆且与任务无关会问)
|
|
364
|
+
# cautious 多问 默认判断之上再叠加严重度靠前一批(校准后约 25%,
|
|
365
|
+
# 校准前固定分 0.30),逐调用一定是默认的超集
|
|
366
|
+
#
|
|
367
|
+
# 四档都不改变权限边界:mandatory deny 全档不变;requires_approval 必须拿到
|
|
368
|
+
# 本次调用的宿主 allowed-once,没有审批通道时拒绝,模型不能代批。
|
|
369
|
+
# autonomous 也不是「关掉审查」:在宿主 auto 审查或本档下,软性 ask 会交给
|
|
370
|
+
# 上面的 guardFallback 裁决(失败即拒绝),因此它可能比 default 更严。
|
|
371
|
+
# severity 是排序分数,分位数就绪不代表危险概率已校准;冷启动比校准后更安静。
|
|
361
372
|
# tolerance: default
|
|
362
373
|
|
|
363
374
|
# ============================================================================
|
|
@@ -385,31 +396,47 @@ guardFallbackReasoningEffort: ""
|
|
|
385
396
|
# model、裁决、耗时、token,展开还能看到发给决策模型的现场(state)、
|
|
386
397
|
# 问题(questions)与它回来的回答(answers)。
|
|
387
398
|
#
|
|
388
|
-
# 数据只落在本机 $DSH_HOME/dsh-decision-engine/
|
|
389
|
-
#
|
|
399
|
+
# 数据只落在本机 $DSH_HOME/dsh-decision-engine/logs/,**不经过任何网络请求**,
|
|
400
|
+
# 也**不进**上面的匿名统计。
|
|
390
401
|
#
|
|
391
|
-
#
|
|
402
|
+
# 关掉之后**完全不写任何日志**(不采集内容、不占磁盘,标签页也随之消失)
|
|
392
403
|
# ——不是「写了藏起来」。明细里可能有会话正文与命令片段,用户说不记录
|
|
393
404
|
# 就该真的不落盘。
|
|
394
405
|
#
|
|
395
406
|
# decisionsTabEnabled: true # 默认开启;**这是唯一的开关**(DEC-026 / DEC-029):
|
|
396
407
|
# 开 = 记录明细,且**一定记录决策内容**;
|
|
397
|
-
# 关 =
|
|
408
|
+
# 关 = 完全不写日志(见上),
|
|
398
409
|
# 没有「只存元数据」的中间档。
|
|
399
410
|
#
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
#
|
|
411
|
+
# 日志怎么分文件(默认 date)。四选一:
|
|
412
|
+
# date logs/date/2026-11-15.log 一天一个文件(默认;日期跟随本机时区)
|
|
413
|
+
# session logs/session/<会话名>__<id 前 8>.log 一个会话一个文件
|
|
414
|
+
# workspace logs/workspace/<工作区名>.log 同一工作区的会话写在一起
|
|
415
|
+
# single logs/decisions.jsonl 全部追加到一个文件(升级前的行为)
|
|
416
|
+
# 文件名会包含会话名或工作区名(先脱敏再截断)。
|
|
417
|
+
# decisionsSplitMode: date
|
|
418
|
+
# 日期分隔符(只在 date 模式生效):- / _ / .
|
|
419
|
+
# decisionsDateSeparator: "-"
|
|
403
420
|
#
|
|
404
|
-
#
|
|
405
|
-
#
|
|
421
|
+
# 老旧日志自动删除:启动时与每 6 小时清理一次。
|
|
422
|
+
# 保留天数(0 = 不按天删,只受总量上限约束);绝不删今天与正在写的分片。
|
|
423
|
+
# decisionsRetentionDays: 30
|
|
406
424
|
#
|
|
407
|
-
#
|
|
425
|
+
# 下面几项是**高级档位**,配置页上没有对应的控件:需要时手改本文件。
|
|
408
426
|
#
|
|
409
|
-
#
|
|
410
|
-
#
|
|
427
|
+
# logs/ 目录的总量上限(字节,默认 64 MB);按 mtime 从最旧的删起。
|
|
428
|
+
# decisionsTotalMaxBytes: 67108864
|
|
411
429
|
#
|
|
430
|
+
# 单个分片的体积上限(字节)。到顶轮转成 <分片>.1(只留一代),
|
|
431
|
+
# 因此磁盘占用最多约两倍单文件上限。
|
|
412
432
|
# decisionsMaxBytes: 8388608 # 8 MB
|
|
433
|
+
#
|
|
434
|
+
# 单条内容的上限(字符)。超出时依次裁剪:工具参数预览 → 最近对话摘要 →
|
|
435
|
+
# 整个 state;只有连「问题 + 回答」都装不下时才退回只留元数据。
|
|
436
|
+
# decisionsMaxContentChars: 4000
|
|
437
|
+
#
|
|
438
|
+
# 升级时旧 decisions.jsonl(与 .1)会被一次性迁移进 logs/date/ 并改名
|
|
439
|
+
# .migrated 保留;迁移失败时旧文件仍可读,下次启动重试。
|
|
413
440
|
|
|
414
441
|
# ============================================================================
|
|
415
442
|
# 审批卡正文可读化(DEC-043)——审批卡上那块命令怎么显示
|
|
@@ -26,6 +26,27 @@
|
|
|
26
26
|
- 用户提示为可读说明,机器码留在 reasonCode / denial info。
|
|
27
27
|
- 旧记录证据不足时保持原样,不把 0ms 倒推为特定调用状态。
|
|
28
28
|
|
|
29
|
+
## 1.9.1 实录复查与后续修正(未发布)
|
|
30
|
+
|
|
31
|
+
按用户指定的北京时间 2026-11-15 00:30 起读取当前日志及 `.1` 轮转备份。首次完整提取快照有 182 条时间范围内记录,其中 39 条拒绝,JSON 均可解析。真实日志仅留在 Git 忽略目录,不提交会话标识、用户正文或工具参数。
|
|
32
|
+
|
|
33
|
+
- 26 条 `unresolved-effect-needs-model-review`:primary 已运行,但非 Auto 分支把 unknown 无条件覆盖为 ask/deny,连 tolerance=delegate 也被拒绝。
|
|
34
|
+
- 12 条 `advisory-failed-unknown-effect`:工作区 edit 已知 safe、四个核心信号有值,但 primary 解析失效;历史未记录具体 validation errors,不能反推原始错误分布。旧解析器确实会因附加 confidence/probabilities 校验失败使整体失效。
|
|
35
|
+
- 1 条 `fallback-model-deny`:唯一一条实际调用独立回退模型后拒绝的记录,不能和其余 38 条混淆。
|
|
36
|
+
- 5 条 MCP 拒绝中,4 条的 primary 与 tolerance 均已有有效 delegate,最终仍被 unknown 分支覆盖;另 1 条 primary 解析失败。5 条全部未请求 fallback。
|
|
37
|
+
|
|
38
|
+
修正非 Auto 分支:有效 primary 与所选 tolerance 不再被 unknown 无条件覆盖;只有最终确实 ask 且 approval=never 才拒绝。Auto 不确定性仍独立复核,真实硬约束保持不变。
|
|
39
|
+
|
|
40
|
+
附加概率和 confidence 元数据校验失败时只保留 warning 并弃用该元数据,不归一化、不用它抬高 severity,也不使有效必需信号整体失效;risk choice 或必需 noul 无效仍失败关闭。新审计记录 validationErrors、metadataWarnings、raw_class_probabilities,避免再只剩 answer-shape-mismatch。
|
|
41
|
+
|
|
42
|
+
服务解析依据宿主源码:先用 agentPresets.serviceFor 读取确实存在的隔离 preset 实例;正常未覆盖时使用 actor.ctx 的共享基础服务。实例存在但方法返回 undefined 不再重试更宽全局实例;解析抛错保持不可用。回退 LLM 同样按 actor 解析。日志新增 permissionPreset、approvalPolicy、automatic 和 serviceSources。历史 39 条没有 permissionPreset,不能断言它们全因 Auto 识别错误造成。
|
|
43
|
+
|
|
44
|
+
60 项匿名实录形状回归及包含作用域的 231 项组合回归通过;不是对原请求副作用的重放。全量 996 项中 993 通过、3 项失败,均为已有 Windows POSIX 文件权限断言。
|
|
45
|
+
|
|
46
|
+
本地另对 39 条拒绝的已记录核心信号和阈值运行修正后的监听器,分手动 / Auto 两种显式场景共 78 次;手动场景 28 allow / 11 deny,Auto 场景在固定 LLM allow stub 下为 39 allow(31 次独立复核、8 次核心信号与软摩擦已允许的有限编辑)。这些计数不代表真实模型效果:历史 preset、完整参数与可选原始分布未完整保留,不重建或伪造;固定 stub 也不推翻原先那一次真实 fallback deny。仅验证 unknown 不再无条件覆盖有效判定,以及符合条件的 Auto 请求确实进入回退。原始实录与逐行回放仍在 Git 忽略目录。
|
|
47
|
+
|
|
48
|
+
真实主端点探测在配置前置检查退出,没有发请求,没有更改用户配置;运行中的已发布 1.9.1 不会自动获得这些源码修正。
|
|
49
|
+
|
|
29
50
|
## 验证边界
|
|
30
51
|
|
|
31
52
|
125 项专项回归、212 项组合回归通过;24 个独立合成情景的四档矩阵通过。组合之间有重叠,不相加成独立样本数。模型 stub 的 allow/deny/failure 仅验证路由不变量,不代表真实危险 FNR 或概率校准。
|
package/docs/releasing.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# npm 发布
|
|
2
2
|
|
|
3
|
-
发布目标:`@leonhardthust/dsh-decision-engine`,当前版本 `1.
|
|
3
|
+
发布目标:`@leonhardthust/dsh-decision-engine`,当前版本 `1.10.0`,公开包。
|
|
4
4
|
|
|
5
5
|
本分支基于 `zuosus/dsh-decision-engine` 的 MIT 代码,保留原作者与许可证;npm scope、源码仓库、bundle 引用和浏览器主模块 / charts chunk 标识已同步为本分支身份。内部 API、样式标识和用户数据目录保留旧名称以兼容已有配置。不要同时启用原包与本 scoped fork,它们提供相同的服务与页面。
|
|
6
6
|
|
|
7
7
|
## 工作流
|
|
8
8
|
|
|
9
9
|
- `.github/workflows/ci.yml`:main push、PR、手动运行或发布工作流复用;Ubuntu 24.04 + Node.js 24 + Vite+ 1.6.0。执行 frozen install、完整测试与接线、隔离情景、实际打包和 tarball 检查。失败不会被忽略。
|
|
10
|
-
- `.github/workflows/publish.yml
|
|
11
|
-
-
|
|
10
|
+
- `.github/workflows/publish.yml`:每次 `main` push 自动检测版本。先比较整个 push 的 `before` 与当前 manifest,拒绝错误包名、非法或倒退版本;再只读查询 npmjs。当前版本已上传则跳过;当前版本高于 npmjs latest 且未上传则进入完整验证及发布。多提交 push 比较整个 push 前后,不仅比较 HEAD 的父提交。
|
|
11
|
+
- 后续发版只需修改 `package.json` 版本并提交到 main;无需创建 tag 或手动点运行。发布依赖检测和本次提交的完整 CI 均成功,不跳过测试。稳定版本发布到 `latest`,预发布版本自动进入 `next`。
|
|
12
|
+
- 当前 `1.10.0` 包含:安全档位改名与事实修正(不问/少问/默认/多问)、`think_mode` 作用域澄清与 provider 能力位、决策日志按日期/会话/工作区分文件与保留清理、裁决列短词与结果着色、本地未知副作用不再单独触发回退模型。设计记录见 `DECISIONS.md` 的 DEC-062 ~ DEC-066。
|
|
12
13
|
- checkout 与 setup-vp Action 固定到已核对的 commit SHA;不通过 `pull_request_target` 运行不可信 PR。
|
|
13
14
|
- 验证任务只有 `contents: read`;只有发布 job 有 `id-token: write`。发布 step 只使用 OIDC(trusted publishing),不再读取任何 npm token secret。代码 checkout 不保留 Git 凭据。此工作流不会自动修改版本、提交源码或推送 Git。
|
|
14
15
|
|
|
@@ -41,7 +42,6 @@ vp run verify
|
|
|
41
42
|
vp run verify:guard
|
|
42
43
|
vp run pack:release
|
|
43
44
|
vp run verify:package
|
|
44
|
-
$env:RELEASE_TAG = "v1.9.1"
|
|
45
45
|
vp run verify:release
|
|
46
46
|
```
|
|
47
47
|
|
|
@@ -49,7 +49,7 @@ vp run verify:release
|
|
|
49
49
|
|
|
50
50
|
`verify:package` 读取真正的 gzip/tar,检查 manifest、scoped 模块 id、bundle 引用、全部安全模块、locale、图表资源和相对 import。配置、凭据、日志、测试目录等不能进入包。输出文件数、大小和 SHA-512 integrity。
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Windows 全量测试最近仍有 3 个既有 POSIX 文件权限断言失败;旧验证检查点及安全边界见 `bench/guard-revision/validation.md` 与 `docs/auto-review-hotfix.md`(完整证据仅在源码仓库保留)。发布 CI 选择 Linux,依然必须运行完整测试,不跳过或忽略它们;本机专测通过不等同于 CI 发布成功。
|
|
53
53
|
|
|
54
54
|
## 手动发布相同的已验证 tarball
|
|
55
55
|
|
|
@@ -58,12 +58,12 @@ vp run verify:release
|
|
|
58
58
|
授权及完整验证均满足后:
|
|
59
59
|
|
|
60
60
|
```powershell
|
|
61
|
-
npm publish ./release-artifacts/leonhardthust-dsh-decision-engine-1.
|
|
61
|
+
npm publish ./release-artifacts/leonhardthust-dsh-decision-engine-1.10.0.tgz --registry "https://registry.npmjs.org/" --access public --tag latest
|
|
62
62
|
npm view @leonhardthust/dsh-decision-engine version --registry "https://registry.npmjs.org/" --json
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
本地发布不伪造 GitHub provenance;在 GitHub Actions 中由工作流增加 `--provenance
|
|
65
|
+
本地发布不伪造 GitHub provenance;在 GitHub Actions 中由工作流增加 `--provenance`。发布操作不可覆盖已存在的同版本;已发布版本的后续提交会跳过发布。若升版后的 CI 失败,修复代码并推送 main 会自动重试仍未发布的版本,无需再升版或手动触发。npmjs 查询错误会停止,不能把网络或权限错误当成未发布。自动检测不自动修改版本或源码。
|
|
66
66
|
|
|
67
67
|
## 安装
|
|
68
68
|
|
|
69
|
-
DSH 插件管理中使用 `@leonhardthust/dsh-decision-engine` 或指定 `@leonhardthust/dsh-decision-engine@1.
|
|
69
|
+
DSH 插件管理中使用 `@leonhardthust/dsh-decision-engine` 或指定 `@leonhardthust/dsh-decision-engine@1.10.0`。安装和启用是另外的用户动作,发布工作流不会修改本机 DSH profile。
|