dsh-rule-engine 0.6.1 → 0.6.2

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 CHANGED
@@ -1,11 +1,11 @@
1
1
  # dsh-rule-engine
2
2
 
3
3
  ![npm](https://img.shields.io/npm/v/dsh-rule-engine)
4
- ![version](https://img.shields.io/badge/version-0.6.1-blue)
4
+ ![version](https://img.shields.io/badge/version-0.6.2-blue)
5
5
 
6
6
  DSH 规则执行引擎 v3 的插件实现。它把 `~/.dsh/AGENTS.md` 当作唯一真相源,自动解析规则四要素与执行等级,再通过「工具守卫 + 文本检测 + 时序检查 + 审计台账」执行用户规则,而不是内置一套与用户无关的安全清单。
7
7
 
8
- > 当前版本 **0.6.0**(**行为变更**:`localIntegrations` 本机集成层——配置存在 = 守卫存在;无配置 = 该守卫在代码路径上不存在,详见「本机集成(可选)」节;**0.6.0 迁移示例见该节**)。本插件面向"规则机器化执行":规则写在 AGENTS.md 里,引擎负责让它们真的被遵守;所有规则动态解析,规则增删改后无需重写插件。
8
+ > 当前版本 **0.6.2**(0.1.2-rc.1 适配:Remote 新合同(typert-protocol `Remote(undefined, …)` 形态,typeof-null 陷阱修复)+ peer 锚扩 `>=0.1.2-rc.0`;白名单 3 轮扩充(gh 只读态 / `gh api` 只读 / `git ls-remote` / `cmdkey /list` + Do- 结构词回归修复);E7 豁免预插(release-plugin bump 后自动追加 pnpm minimumReleaseAgeExclude——⑬ 口径防发布后红灯窗口,单源 `scripts/lib/pnpm-exempt.mjs`))。本插件面向"规则机器化执行":规则写在 AGENTS.md 里,引擎负责让它们真的被遵守;所有规则动态解析,规则增删改后无需重写插件。
9
9
 
10
10
  ## 项目背景
11
11
 
@@ -96,7 +96,10 @@ DSH 规则执行引擎 v3 的插件实现。它把 `~/.dsh/AGENTS.md` 当作唯
96
96
  > 更早版本(0.1.0-0.5.5)与本机历史要点见 git 历史;各版本内部"用户定稿"等决策细节不再随发布物携带。
97
97
 
98
98
  | 版本 | 日期 | 要点 |
99
+ | **0.6.2** | 2026-09-08 | fix(0.6.2): whitelist 3-round + 0.1.2 adaptation + peer-anchor 0.1.2 + E7 pre-plug wiring |
99
100
  |---|---|---|
101
+ | **0.6.1+(本地增强,未发版)** | 2026-09-07 | 只读豁免清单扩充(用户定调"纯只读顺畅"):`gh api` 只读态(无 -X/--method/graphql/-F/-f 的段)、`gh release/issue/pr/run view`、`cmdkey /list`、`git ls-remote` 显式;写形态(gh api -F/graphql、git fetch、curl 下载、重定向落盘)保持拦截;26 用例全绿 + 语法体检 + 热重载生效(发版需 bump 0.6.2) |
102
+ | **0.6.1** | 2026-09-07 | **B 档发布**:豁免预插(release-plugin bump 后自动追加 minimumReleaseAgeExclude——⑬ 口径防发布后红灯窗口);豁免判定单源化(scripts/lib/pnpm-exempt.mjs 与 verify-all ⑬ 共享 + 4 单测);viewFails 发布语境 STRICT 计 ❌;⑬ 头注释绝对口径 |
100
103
  | **0.6.0** | 2026-09-04 | **行为变更**:通用与本机分离——`localIntegrations` 本机集成层(entryScript/protectedFiles/m8/manualExempt 四键);此前默认强制的守卫(统一入口阶段 C / 手册/技能豁免 / M8 双通道)改为"配置存在=守卫存在、无配置=代码路径上不存在";`m8` 语义反转(默认开启→显式开启);消号本机痕迹(lib/ 零命中,词表唯一源 `scripts/local-residue-markers.txt`) |
101
104
  | **0.5.14** | 2026-09-01 | 分点三柱(条件句零授权/显式命名对象锚定/clauseId 隔离)+ skill 词收紧 + 规则 5 引证检测扩展(内部引用无依据→审计注入)+ 规则 31 查证纪律(B+D)+ README 版本四性对齐 |
102
105
  | **0.5.17** | 2026-09-03 | A1 规则 2 时间词拆组(当下词=Get-Date① / 历史日期=证据锚②,消除"引用历史日期必判未核对"误报)+ EVIDENCE_MARK_RE 增证据锚(commit hash/版本行/踩坑 N/版本记录) |
@@ -113,7 +116,9 @@ DSH 规则执行引擎 v3 的插件实现。它把 `~/.dsh/AGENTS.md` 当作唯
113
116
 
114
117
  ## 发行固定源
115
118
 
116
- - **0.6.0(当前)** 固定于 main Commit `be5b8c93`(`git checkout be5b8c93` 可复现 npm `dsh-rule-engine@0.6.0` 与 GitHub Release v0.6.0 同源代码——0.6.0 = 本机集成层(localIntegrations 四键)+ 本机痕迹消号 + li-skipped/entry-script-missing 启动审计 + 发布门禁 B1/B2(readme-version-check / local-residue-scan,挂 verify-all/release-plugin/check:meta)+ check-tool-coverage 素材 fail-closed(第三方反馈润色:通用指引+配置注入本机提示);词表文件 `scripts/local-residue-markers.txt` 为本机门禁工具,不入库、不进发布物(见 .gitignore / package.json files 排除)。固定源之后的提交仅限 README 指针文本)。
119
+ - **0.6.2(当前)** 固定于 main Commit `89b165c`(`git checkout 89b165c` + 发布 bump 可复现 npm `dsh-rule-engine@0.6.2` 与 GitHub Release v0.6.2 同源代码——0.6.2 = 0.1.2-rc.1 适配(Remote 新合同 `Remote(undefined, …)` / peer 锚扩 `>=0.1.2-rc.0`)+ 白名单 3 轮扩充 + Do- 结构词回归修复 + E7 豁免预插机制上线)。
120
+ - **0.6.1(当前)** 固定于 main Commit `051e2da`(`git checkout 051e2da` 可复现 npm `dsh-rule-engine@0.6.1` 与 GitHub Release v0.6.1 同源代码——0.6.1 = 豁免预插(release-plugin bump 后自动追加 pnpm minimumReleaseAgeExclude,⑬ 绝对口径防发布后红灯窗口——踩坑 18 镜像)+ 豁免判定单源化(scripts/lib/pnpm-exempt.mjs 与 verify-all ⑬ 共享,4 单测锁定)+ viewFails 发布语境 STRICT 计 ❌ + ⑬ 块头注释绝对口径(E1/E2/E3 收尾批)。
121
+ - **0.6.0** 固定于 main Commit `be5b8c93`(可复现 `dsh-rule-engine@0.6.0` 与 Release v0.6.0——0.6.0 = 本机集成层(localIntegrations 四键)+ 本机痕迹消号 + li-skipped/entry-script-missing 启动审计 + 发布门禁 B1/B2(readme-version-check / local-residue-scan,挂 verify-all/release-plugin/check:meta)+ check-tool-coverage 素材 fail-closed;词表文件 `scripts/local-residue-markers.txt` 为本机门禁工具,不入库、不进发布物(见 .gitignore / package.json files 排除)。固定源之后的提交仅限 README 指针文本)。
117
122
 
118
123
  ## 任务契约与反过度工程(可选)
119
124
 
@@ -257,7 +257,7 @@ export function isGetDateCommand(command) {
257
257
 
258
258
  const READ_ONLY_TOOLS = new Set(["read", "grep", "glob", "read_image"]);
259
259
  const READONLY_CMD_RE =
260
- /(?:\b(?:Get-Content|Get-ChildItem|Get-Item|Get-Command|Get-Date|Select-String|Find-String|Test-Path|Get-Process|Get-Service|Get-ItemProperty|Get-Variable|Get-FileHash|cat|type|dir|ls|grep|findstr|more|netstat|where|echo|Write-Output|Write-Host|Get-Location|pwd|cwd|Get-Help|help|Select-Object|Out-String|Format-Table|Format-List|Format-Wide|Measure-Object|Sort-Object|Where-Object|Group-Object|ForEach-Object|Out-Null|ConvertTo-Json|ConvertFrom-Json|Join-Path|Split-Path|Resolve-Path|New-Object|Add-Type|Get-Member|Get-ChildItemProperty|Get-CimInstance|Get-WmiObject)\b)|(?:\bgit\s+(?:-[^\s]+\s+[^\s]+\s+|--[^\s]+\s+)*\b(?:status|log|diff|show|branch|tag|remote|rev-parse|diff-tree|ls-files)(?:\s|$))|(?:\bdsh\s+(?:--version|--help|--dump-config|plugin\s+(?:list|show|status))(?:\s|$))|(?:\bdsh\s+--profile\s+[^\s]+\s+(?:--dump-config|plugin\s+(?:list|show|status))(?:\s|$))|(?:\bnode\s+(?:--check|--test|--version)(?:\s|$))|(?:\bnpm\s+(?:test|run\s+test)(?:\s|$))|(?:\bpnpm\s+(?:test|run\s+test)(?:\s|$))|(?:\bgh\s+(?:auth\s+status|repo\s+view)(?:\s|$))|(?:\bnpm\s+(?:ls|view)(?:\s|$))/i;
260
+ /(?:\b(?:Get-Content|Get-ChildItem|Get-Item|Get-Command|Get-Date|Select-String|Find-String|Test-Path|Get-Process|Get-Service|Get-ItemProperty|Get-Variable|Get-FileHash|cat|type|dir|ls|grep|findstr|more|netstat|where|echo|Write-Output|Write-Host|Get-Location|pwd|cwd|Get-Help|help|Select-Object|Out-String|Format-Table|Format-List|Format-Wide|Measure-Object|Sort-Object|Where-Object|Group-Object|ForEach-Object|Out-Null|ConvertTo-Json|ConvertFrom-Json|Join-Path|Split-Path|Resolve-Path|New-Object|Add-Type|Get-Member|Get-ChildItemProperty|Get-CimInstance|Get-WmiObject)\b)|(?:\bgit\s+(?:-[^\s]+\s+[^\s]+\s+|--[^\s]+\s+)*\b(?:status|log|diff|show|branch|tag|remote|rev-parse|diff-tree|ls-files)(?:\s|$))|(?:\bgit\s+ls-remote(?:\s|$))|(?:\bdsh\s+(?:--version|--help|--dump-config|plugin\s+(?:list|show|status))(?:\s|$))|(?:\bdsh\s+--profile\s+[^\s]+\s+(?:--dump-config|plugin\s+(?:list|show|status))(?:\s|$))|(?:\bnode\s+(?:--check|--test|--version)(?:\s|$))|(?:\bnpm\s+(?:test|run\s+test)(?:\s|$))|(?:\bpnpm\s+(?:test|run\s+test)(?:\s|$))|(?:\bgh\s+(?:auth\s+status|repo\s+view|release\s+view|issue\s+view|pr\s+view|run\s+view)(?:\s|$))|(?:\bnpm\s+(?:ls|view)(?:\s|$))|(?:\bgh\s+api\b(?![^\r\n;|]*?\s(?:-X|--method|graphql|-F|-f)\s)[^\r\n;|]*$)|(?:\bcmdkey\s+(?:\/list|\/list:[^\s]+)(?:\s|$))|(?:\b(?:if|elseif|else|foreach|while|switch|for|do|try|catch|finally)\b(?:\s*\(|\s|\{|$))/i;
261
261
  const MUTATING_CMD_RE =
262
262
  /(?:Set-Content|Add-Content|Out-File|Tee-Object|Remove-Item|Move-Item|Copy-Item|Rename-Item|New-Item|Clear-Content|Start-Process|Invoke-Expression|Invoke-Item|Export-Csv|Export-Clixml|Export-ModuleMember|Compress-Archive|Expand-Archive|Add-Type\s+-Output(?:Assembly|Type)|git\s+(?:push|commit)|rm\s+-r|rmdir\s+\/s|del\s+\/s|(?:^|[^0-9])(?:\d*>|\d*>>|>|>>)(?!\s*&\s*\d|\s*\$?(?:null|nul)\b)|(?:curl|wget|iwr|Invoke-WebRequest|Invoke-RestMethod)\s+(?=[^\n;|]*\s(?:-o|--output|-OutFile|OutFile)\s))/i;
263
263
  // 0.5.12(F4):PowerShell 别名展开表——写/删除/移动/执行别名 → 标准 cmdlet 名
@@ -287,7 +287,7 @@ const MUTATING_METHOD_RE =
287
287
  // 保守边界:内容属性赋值($doc.Text=... / $doc.Content.Text=...)是写文档,不豁免。
288
288
  const COM_CONTENT_ASSIGN_RE = /\.(?:Text|Content|Value|Range|Paragraphs|Sections|Documents|Document)\s*=/i;
289
289
  const ALLOW_SEG_RE =
290
- /(?:\$[A-Za-z_][\w$]*(?:(?:\.[\w$]+)|(?:\[[^\]]+\]))*\s*=)|(?:\$[\w$.]+\.(?:Content|Range|Text|Value|Paragraphs|Sections|Length|Count|Name|Selected|LinkType|Target|FullName|Extension|Directory|PSPath|Property|Attributes|Mode|LastWriteTime|Exists)\b)|(?:\$[\w$.]+$)|(?:\b(?:Documents|Document)\.(?:Open|Item)\s*\([^)]*,\s*\d+\s*,\s*\$?true\s*\))|(?:\(!?\$[\w$.]+(?:\.\w+)?\)|\([^()\r\n]*\$[\w$.]+\.[\w.]+\s*\))/;
290
+ /(?:\$[A-Za-z_][\w$]*(?:(?:\.[\w$]+)|(?:\[[^\]]+\]))*\s*=)|(?:\$[\w$.]+\.(?:Content|Range|Text|Value|Paragraphs|Sections|Length|Count|Name|Selected|LinkType|Target|FullName|Extension|Directory|PSPath|Property|Attributes|Mode|LastWriteTime|Exists|Line|Error|Errors|Matches|Groups|Success|ExitCode|Output|Stderr|Stdout|Items|Keys|Values|Entries|Timestamp|DateTime)\b)|(?:\$[\w$.]+\.(?:Trim|Substring|ToString|ToLower|ToUpper|TrimStart|TrimEnd|Replace|Split|Join|Contains|StartsWith|EndsWith|IndexOf|LastIndexOf|GetType|ToCharArray|PadLeft)\s*\()|(?:\$[\w$.]+$)|(?:\b(?:Documents|Document)\.(?:Open|Item)\s*\([^)]*,\s*\d+\s*,\s*\$?true\s*\))|(?:\(!?\$[\w$.]+(?:\.\w+)?\)|\([^()\r\n]*\$[\w$.]+\.[\w.]+\s*\))/;
291
291
  // 0.5.12(F4):纯字符串/纯输出段(整段是引号包裹字符串或 $() 子表达式)——不是命令,放行。
292
292
  // 保守边界:只匹配"整段即字符串"(^...$ 锚定),不让 node -e "..." / curl -o "..." 借道。
293
293
  const PURE_STRING_SEG_RE = /^(?:"[^"\r\n]*"|'[^'\r\n]*'|`[^`\r\n]*`|\$\(\s*[^()\r\n]*\s*\))+$/;
package/lib/service.js CHANGED
@@ -64,9 +64,14 @@ class RuleEngineService extends TypertRemoteService {
64
64
 
65
65
  constructor(ctx) {
66
66
  super(ctx, "ruleEngine");
67
+ // 0.1.2 适配(2026-09-07,实markers 验证):typert-protocol 0.1.2 Remote() 三分支——
68
+ // ① 一参字符串=exportName 工厂;② typeof 一参==='object'(含 null!)=流选项校验
69
+ // (仅容 {mode:'stream'},其余 TypeError——Remote(null,…) 在 0.1.2 因 typeof null===
70
+ // 'object' 落此分支崩溃,即本次升级事故 engine 侧根因;0.1.1 的 null 直落③分支);
71
+ // ③ 一参 undefined + 二参 context=addMarkerInitializer(context,{kind:'direct'})。
72
+ // 手动标记形态=Remote(undefined, fakeContext),context 含 {name,private,static,addInitializer}。
67
73
  for (const name of REMOTE_METHODS) {
68
- Remote(null, {
69
- kind: "method",
74
+ Remote(undefined, {
70
75
  name,
71
76
  private: false,
72
77
  static: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-rule-engine",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "DSH 规则执行引擎 v3:容器解析 AGENTS.md + 理解器 + 匹配机 + 执行框架",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -49,8 +49,8 @@
49
49
  "check:meta": "node scripts/readme-version-check.mjs && node scripts/local-residue-scan.mjs"
50
50
  },
51
51
  "peerDependencies": {
52
- "@deepseek-ai/dsh-home-paths": ">=0.1.0-rc.3 <0.2.0 || >=0.1.1-rc.0 <0.2.0",
53
- "@deepseek-ai/dsh-typert-protocol": ">=0.1.0-rc.3 <0.2.0 || >=0.1.1-rc.0 <0.2.0"
52
+ "@deepseek-ai/dsh-home-paths": ">=0.1.0-rc.3 <0.2.0 || >=0.1.1-rc.0 <0.2.0 || >=0.1.2-rc.0 <0.2.0",
53
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.0-rc.3 <0.2.0 || >=0.1.1-rc.0 <0.2.0 || >=0.1.2-rc.0 <0.2.0"
54
54
  },
55
55
  "dsh": {
56
56
  "bundle": {
@@ -15,6 +15,7 @@ import { execSync } from "node:child_process";
15
15
  import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, statSync, rmSync } from "node:fs";
16
16
  import { dirname, join, relative, resolve } from "node:path";
17
17
  import { fileURLToPath } from "node:url";
18
+ import { ensureExempt } from "./lib/pnpm-exempt.mjs";
18
19
 
19
20
  const PROXY = process.env.DSH_RELEASE_PROXY || ""; // 默认直连;需要代理时显式设置
20
21
  /** 代理前缀(命令文本):空 = 直连 */
@@ -237,6 +238,17 @@ if (judgeScan) {
237
238
  console.log("(未设置 JUDGE_SCAN——判据库回归跳过(本机增强门禁,建议发布前设置))");
238
239
  }
239
240
 
241
+ // ── 3.8 豁免预插(E7,2026-09-08 接线;单源 scripts/lib/pnpm-exempt.mjs):bump 后 publish 前,
242
+ // 把 nextVer 自动预插 profiles/web pnpm-workspace.yaml 的 minimumReleaseAgeExclude——⑬ 绝对口径
243
+ // 要求"publish 后 latest ∈ 豁免名单",预插保证该不变式由发布器维护(防手工遗忘 → 发布后 ⑬ 红)。
244
+ // 幂等(已存在跳过);DRY-RUN 只打印;yaml 读取失败抛错中止发布(fail-closed)。──
245
+ {
246
+ const dshHome = process.env.DSH_HOME || join(process.env.USERPROFILE || "", ".dsh");
247
+ const yamlPath = join(dshHome, "profiles", "web", "pnpm-workspace.yaml");
248
+ console.log("\n=== 豁免预插(minimumReleaseAgeExclude ← nextVer)===");
249
+ ensureExempt(yamlPath, name, nextVer, { dryRun: !!process.env.DRY_RUN, log: console.log });
250
+ }
251
+
240
252
  // ── 4. pack + publish ────────────────────────────────────────────
241
253
  console.log("\n=== npm pack ===");
242
254
  run(`cd /d "${dir}" && npm pack --pack-destination .`);