dsh-vibe-math 2.7.0 → 2.7.1
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.en.md +5 -0
- package/README.md +5 -0
- package/cordis.patch.yml +6 -0
- package/docs/math-computation.md +44 -2
- package/docs/release-notes/RELEASE-NOTES-2.7.1.en.md +86 -0
- package/docs/release-notes/RELEASE-NOTES-2.7.1.md +86 -0
- package/package.json +5 -3
- package/prompt-corpus-persona/persona-corpus.json +8 -8
- package/prompt-corpus-persona/persona-corpus.md +12 -0
- package/prompt-corpus-v2/formal-verify-v2.json +162 -96
- package/prompt-corpus-v2/formal-verify-v2.md +949 -0
- package/prompt-corpus-v3/formal-verify-v3.json +171 -57
- package/prompt-corpus-v3/formal-verify-v3.md +1146 -0
- package/prompt-corpus-v4/formal-verify-v4.json +10 -10
- package/prompt-corpus-v4/formal-verify-v4.md +20 -0
- package/prompt-corpus-v5/prompt-corpus-v5.json +61 -61
- package/prompt-corpus-v5/prompt-corpus-v5.md +61 -0
- package/tests/audit-math-computation-contract.mjs +13 -0
- package/tests/audit-math-computation-parity.mjs +30 -1
- package/tests/audit-math-computation-sensitivity.mjs +1 -1
- package/tests/e2e-v5-round2.test.mjs +7 -0
- package/tests/formal-verify-v2.test.mjs +70 -2
- package/tests/formal-verify-v3.test.mjs +84 -2
- package/tests/helpers/math-computation-fake-seam.mjs +30 -2
- package/tests/math-computation-shared.test.mjs +304 -2
- package/vibe-math-v2/agent.cordis.yml +2 -0
- package/vibe-math-v2/math-computation.js +390 -47
- package/vibe-math-v2/math-engines.js +47 -6
- package/vibe-math-v2/vibe-math-v2.js +17 -1
- package/vibe-math-v3/agent.cordis.yml +2 -0
- package/vibe-math-v3/math-computation.js +390 -47
- package/vibe-math-v3/math-engines.js +47 -6
- package/vibe-math-v3/vibe-math-v3.js +17 -1
- package/vibe-math-v4/agent.cordis.yml +4 -0
- package/vibe-math-v4/math-computation.js +390 -47
- package/vibe-math-v4/math-engines.js +47 -6
- package/vibe-math-v4/vibe-math-v4.js +15 -0
- package/vibe-math-v5/agent.cordis.yml +4 -0
- package/vibe-math-v5/math-computation.js +390 -47
- package/vibe-math-v5/math-engines.js +47 -6
- package/vibe-math-v5/vibe-math-v5.js +15 -3
package/README.en.md
CHANGED
|
@@ -509,6 +509,11 @@ All four presets default to `finalPaper=true`: once the respective closure signa
|
|
|
509
509
|
| `mathInstallScope` | `user` | all four | Install scope; `system` must be given **explicitly on every call and is never remembered** (most managers have no system template, in which case the request is refused) |
|
|
510
510
|
|
|
511
511
|
> **Archive = evidence**: every run writes `Computation/<id>/` and the receipt carries `scriptPath` + `scriptHash`; the script original may be opened/edited, but after editing you MUST re-run it with `mode:'file'` to get a NEW receipt - **an old receipt does not represent edited code** (`scriptChanged` / `scriptChangedDuringRun` warn explicitly). Archives are append-only and over-cap behaviour is warn-only, never delete. See [`docs/math-computation.md`](docs/math-computation.md) §4.1.
|
|
512
|
+
|
|
513
|
+
> **Declare substitutions**: when an alternative changes **exactness or conclusion strength** (exact solution -> numerical approximation, closed form -> sampling/quadrature, changed precision/tolerances/assumptions, a different algorithm class), the conclusion MUST say so and must not read as if the original result had been obtained; if the exact result is unavailable, say so plainly (rule line `MATH_SUBSTITUTION_RULE_LINE`, injected into all four personas and prompts).
|
|
514
|
+
|
|
515
|
+
> **Install and versions**: `op:'install'` dispatches on the **detected python environment** - conda/mamba (`-c conda-forge`), uv (`uv pip …`) or the documented pip fallback (ambiguous cases carry `managerAssumed`); R/Octave/Julia are **user-scope only** (`system` => `MATH_REFUSED` with a per-engine reason). **Version solving belongs to the package manager**: the tool only checks presence by base name and passes `pkg==1.2` (conda `pkg=1.2`) through verbatim; unsafe or unknown syntax => `unsupported-version-syntax`. See [`docs/math-computation.md`](docs/math-computation.md) §5.1-5.3.
|
|
516
|
+
> **Engine discovery**: PATH first, and **only as a last resort** the runtimes DSH ships itself (`<DSH_HOME or user home>/.dsh/dsh-runtimes/*/dependencies/<engine>/`, tree name **globbed**); a found engine reports its **real version** and **no** install guidance is emitted - guidance appears only when nothing usable exists, and it targets **the engine you asked for**. `op:'probe'` reports the requested engine; `mathEngineOverride` **only overrides argv templates and cannot name an executable**, so it is not a discovery escape hatch (use PATH, the DSH runtime, or `engine:'cli'` + `cli.command`). With `engine:'cli'`: the package precheck runs for `cli.command`'s family (unknown family => skipped with a `PACKAGE_PRECHECK_SKIPPED` warning), `mode:'code'` **appends the archived script to argv** (so the code really runs instead of a REPL), and the version is the real one. See §5.4.
|
|
512
517
|
| `tickIntervalMs` | 2000 | v2·v3 | Scheduler heartbeat interval (milliseconds) |
|
|
513
518
|
| `activityLogCap` | 100 | v2·v3 | Number of activity log entries retained (the report displays at most 30) |
|
|
514
519
|
| `maxExplorerRetries` | 3 | v2·v3 | Upper limit on re-dispatching after an explorer fails to split directions |
|
package/README.md
CHANGED
|
@@ -509,6 +509,11 @@ v5 的完整架构(成员生命周期、一轮时序、共识状态机、会
|
|
|
509
509
|
| `mathInstallScope` | `user` | 四套 | 安装作用域;`system` 必须**每次显式指定且不被记住**(多数包管理器没有 system 模板,此时会被拒绝) |
|
|
510
510
|
|
|
511
511
|
> **归档即证据**:每次计算都写出 `Computation/<id>/`,回执含 `scriptPath` 与 `scriptHash`;脚本原件可以打开/编辑,编辑后必须用 `mode:'file'` **重跑**得到新回执——**旧回执不代表修改后的代码**(`scriptChanged` / `scriptChangedDuringRun` 会显式告警)。归档只追加不覆盖,超上限只告警不删除。详见 [`docs/math-computation.md`](docs/math-computation.md) §4.1。
|
|
512
|
+
|
|
513
|
+
> **替代必须声明**:当替代方案改变**精确性或结论强度**(精确解→数值近似、闭式解→采样/求积、改精度/容差/假设、换算法类)时,结论**必须写明**,不得像得到了原本的结果;拿不到精确结果就直说(规则行 `MATH_SUBSTITUTION_RULE_LINE`,已注入四套 persona 与提示词)。
|
|
514
|
+
|
|
515
|
+
> **安装与版本**:`op:'install'` 按**检测到的 python 环境**分派 conda/mamba(`-c conda-forge`)、uv(`uv pip …`)或 pip 回退(歧义时标 `managerAssumed`);R/Octave/Julia **只做用户级**(`system` ⇒ `MATH_REFUSED` + 每引擎理由)。**版本求解交给包管理器**:本工具只按 base name 查存在、把 `pkg==1.2`(conda `pkg=1.2`)原样透传,危险或不认识的写法 ⇒ `unsupported-version-syntax`。详见 [`docs/math-computation.md`](docs/math-computation.md) §5.1–5.3。
|
|
516
|
+
> **引擎发现**:先看 PATH,最后才扫 **DSH 自带运行时**(`<DSH_HOME 或用户主目录>/.dsh/dsh-runtimes/*/dependencies/<engine>/`,树名**通配**);找到就报**真实版本**,**找不到才**给按 OS 的安装指引,且指引针对**你请求的那个引擎**。`op:'probe'` 报的就是请求的引擎;`mathEngineOverride` **只能覆盖 argv 模板、不能指定可执行文件**,所以它不是发现手段(正解是 PATH / DSH 运行时 / `engine:'cli'` + `cli.command`)。`engine:'cli'` 下:包预检按 `cli.command` 的族进行(不可识别则跳过并给 `PACKAGE_PRECHECK_SKIPPED` 警告)、`mode:'code'` 会**自动把归档脚本追加到 argv**(所以真的会跑代码,而不是掉进 REPL)、版本报真实值。详见 [`docs/math-computation.md`](docs/math-computation.md) §5.4。
|
|
512
517
|
| `tickIntervalMs` | 2000 | v2·v3 | 调度器心跳间隔(毫秒) |
|
|
513
518
|
| `activityLogCap` | 100 | v2·v3 | 活动日志保留条数(report 最多显示 30 条) |
|
|
514
519
|
| `maxExplorerRetries` | 3 | v2·v3 | explorer 拆方向失败的重派生上限 |
|
package/cordis.patch.yml
CHANGED
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
mode.
|
|
84
84
|
|
|
85
85
|
- math_computation {op: probe|run|receipt|install, engine, mode: code|file|expr, …} — 先 probe 预检引擎/包/许可,再调引擎计算并把脚本与输出归档成可复核回执;缺引擎/缺包只报告与给安装指引/计划;shell 兜底不算归档。
|
|
86
|
+
- 替代必须声明(诚实性):当替代方案改变了**精确性或结论强度**时(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
86
87
|
- 归档→编辑→重跑:mode:'code' 的脚本原件在回执的 scriptPath(Computation/<id>/script.<ext>),你可以用普通文件工具打开并编辑它;编辑后用 mode:'file' 指向它重跑,会写出一份**新回执/新 attempt**(含新的 scriptHash)。**旧回执对修改后的代码无效**——报告里必须引用与当前代码哈希一致的那份回执;工具会在 scriptChanged / scriptChangedDuringRun 为 true 时显式告警。
|
|
87
88
|
|
|
88
89
|
Final paper: strict termination writes Paper/<project>/{paper.md,paper.tex,paper.pdf,paper.meta.json,paper.log.md}
|
|
@@ -373,6 +374,7 @@
|
|
|
373
374
|
mode.
|
|
374
375
|
|
|
375
376
|
- math_computation {op: probe|run|receipt|install, engine, mode: code|file|expr, …} — 先 probe 预检引擎/包/许可,再调引擎计算并把脚本与输出归档成可复核回执;缺引擎/缺包只报告与给安装指引/计划;shell 兜底不算归档。
|
|
377
|
+
- 替代必须声明(诚实性):当替代方案改变了**精确性或结论强度**时(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
376
378
|
- 归档→编辑→重跑:mode:'code' 的脚本原件在回执的 scriptPath(Computation/<id>/script.<ext>),你可以用普通文件工具打开并编辑它;编辑后用 mode:'file' 指向它重跑,会写出一份**新回执/新 attempt**(含新的 scriptHash)。**旧回执对修改后的代码无效**——报告里必须引用与当前代码哈希一致的那份回执;工具会在 scriptChanged / scriptChangedDuringRun 为 true 时显式告警。
|
|
377
379
|
|
|
378
380
|
A /vibe slash command mirrors the main controls (/vibe start [override]|resume [override]|pause|abort|status|report|mode
|
|
@@ -661,6 +663,8 @@
|
|
|
661
663
|
- math_computation {op: probe|run|receipt|install, engine, mode: code|file|expr, …} — 先 probe 预检引擎/包/许可,再调引擎计算并把脚本与输出归档成可复核回执;缺引擎/缺包只报告与给安装指引/计划;shell 兜底不算归档。
|
|
662
664
|
- 归档→编辑→重跑:mode:'code' 的脚本原件在回执的 scriptPath(Computation/<id>/script.<ext>),你可以用普通文件工具打开并编辑它;编辑后用 mode:'file' 指向它重跑,会写出一份**新回执/新 attempt**(含新的 scriptHash)。**旧回执对修改后的代码无效**——报告里必须引用与当前代码哈希一致的那份回执;工具会在 scriptChanged / scriptChangedDuringRun 为 true 时显式告警。
|
|
663
665
|
- Archive -> edit -> re-run: for mode:'code' the script original is at the receipt's scriptPath (Computation/<id>/script.<ext>) and you may open/edit it with your normal file tools; after editing, re-run it with mode:'file' to write a NEW receipt/attempt with a NEW scriptHash. **An old receipt is NOT evidence for edited code** - cite the receipt whose scriptHash matches the current code; the tool warns explicitly via scriptChanged / scriptChangedDuringRun.
|
|
666
|
+
- 替代必须声明(诚实性):当替代方案改变了**精确性或结论强度**时(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
667
|
+
- Declare substitutions (honesty): when an alternative changes EXACTNESS or conclusion strength (exact symbolic solution -> numerical approximation, closed form -> sampling/quadrature, changed precision/tolerances/assumptions, a different algorithm class), the conclusion MUST say so explicitly and must not read as if the original (exact/requested) result had been obtained; if the exact result is unavailable, say so plainly.
|
|
664
668
|
objects, recorded blockers, formalization TODO, library paths).
|
|
665
669
|
- vibe_v4_prompts {which: brainstorm|normal|heartbeat|meeting|verify|coreRules, member?, target?, stage?} — read the exact prompt text a resident would receive (prompt auditing; prompt text is the product).
|
|
666
670
|
A /v4 slash command mirrors the main controls (configure|start [problem]|resume|pause|abort|status|report|message <to|all> <content>|meeting|paper [lang=zh|en] [format=md|tex|both] [editor=office|resident:<id>] [force]|members|add|remove|set <k=v>...).
|
|
@@ -994,6 +998,8 @@
|
|
|
994
998
|
- math_computation {op: probe|run|receipt|install, engine, mode: code|file|expr, …} — 先 probe 预检引擎/包/许可,再调引擎计算并把脚本与输出归档成可复核回执;缺引擎/缺包只报告与给安装指引/计划;shell 兜底不算归档。
|
|
995
999
|
- 归档→编辑→重跑:mode:'code' 的脚本原件在回执的 scriptPath(Computation/<id>/script.<ext>),你可以用普通文件工具打开并编辑它;编辑后用 mode:'file' 指向它重跑,会写出一份**新回执/新 attempt**(含新的 scriptHash)。**旧回执对修改后的代码无效**——报告里必须引用与当前代码哈希一致的那份回执;工具会在 scriptChanged / scriptChangedDuringRun 为 true 时显式告警。
|
|
996
1000
|
- Archive -> edit -> re-run: for mode:'code' the script original is at the receipt's scriptPath (Computation/<id>/script.<ext>) and you may open/edit it with your normal file tools; after editing, re-run it with mode:'file' to write a NEW receipt/attempt with a NEW scriptHash. **An old receipt is NOT evidence for edited code** - cite the receipt whose scriptHash matches the current code; the tool warns explicitly via scriptChanged / scriptChangedDuringRun.
|
|
1001
|
+
- 替代必须声明(诚实性):当替代方案改变了**精确性或结论强度**时(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
1002
|
+
- Declare substitutions (honesty): when an alternative changes EXACTNESS or conclusion strength (exact symbolic solution -> numerical approximation, closed form -> sampling/quadrature, changed precision/tolerances/assumptions, a different algorithm class), the conclusion MUST say so explicitly and must not read as if the original (exact/requested) result had been obtained; if the exact result is unavailable, say so plainly.
|
|
997
1003
|
A /v5 slash command mirrors these (configure|start|resume|pause|stop|status|report|members|message|meeting|hire|fire|add|remove|set|paper).
|
|
998
1004
|
|
|
999
1005
|
LEAN FORMAL VERIFICATION (formalVerify, a tunable parameter):
|
package/docs/math-computation.md
CHANGED
|
@@ -47,8 +47,8 @@ math_computation {
|
|
|
47
47
|
- **机读词汇表(穷举;权威副本在 `_oneoff/mc-P1-ready/tool-schema.json#refusalVocabulary`,由 parity 守卫盯着,改名即红)**:
|
|
48
48
|
- `code`(11 个):`MATH_NOT_AVAILABLE` `MATH_ENGINE_NOT_FOUND` `MATH_ENGINE_LICENSE_REQUIRED` `MATH_ENGINE_UNUSABLE` `MATH_MISSING_PACKAGES` `MATH_TIMEOUT` `MATH_NONZERO_EXIT` `MATH_ENGINE_BAD_ARGV` `MATH_REFUSED` `MATH_INVALID_ARGUMENT` `MATH_NO_SUBPROCESS`;
|
|
49
49
|
- `next.kind`(7 个):`user-install`(用户自装指引)、`agent-install`(代装计划/计划就绪)、`vendor`(商业引擎厂商指引)、`enable`(`mathComputation:'off'` 的启用建议)、`engine-override`(bad-argv ⇒ 用 `mathEngineOverride` 覆盖模板)、`reason`(机读拒绝原因)、`note`(补充说明,如无 subprocess);
|
|
50
|
-
- `next.reason
|
|
51
|
-
调用方**不必解析文案**:按 `code` + `next.kind`(必要时 `next.reason`)分支即可;新增或改名必须同时更新这里与 `tool-schema.json
|
|
50
|
+
- `next.reason`(**13** 个,仅当 `next.kind==='reason'`):`policy`、`engine-not-allowed`、`missing-cli-command`、`expr-not-supported`、`mode-not-supported`、`path-outside-project`、`file-not-found`、`system-scope-unsupported`、`plan-token-mismatch`、`archive-missing`、`receipt-unparsable`、`no-subprocess`、**`unsupported-version-syntax`**(包规格写法不被支持:版本求解交给包管理器,见 §5)。
|
|
51
|
+
调用方**不必解析文案**:按 `code` + `next.kind`(必要时 `next.reason`)分支即可;新增或改名必须同时更新这里与 `tool-schema.json`,否则守卫变红(守卫还会校验每个 `reason:` 取值都是**字符串字面量**,避免以常量绕开"穷举"检查)。
|
|
52
52
|
|
|
53
53
|
## 4. 回执:可复核的支撑材料
|
|
54
54
|
|
|
@@ -91,6 +91,47 @@ math_computation {
|
|
|
91
91
|
|
|
92
92
|
**诚实的回滚说明**:包安装**没有通用回滚**。工具保证的是——记下确切命令与 before/after 版本(卸载**可验证**)、默认 user 作用域限制影响面、提供各管理器的卸载模板;**不做**自动回滚。
|
|
93
93
|
|
|
94
|
+
### 5.1 Python 的管理器分派(检测,不猜)
|
|
95
|
+
|
|
96
|
+
`python` 的安装计划按**解释器自身环境**选择包管理器,而不是固定 pip:
|
|
97
|
+
|
|
98
|
+
| 检测到的环境 | 计划里的命令 | 依据 / 说明 |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| conda 环境(解释器路径含 `/envs/`、`/conda`、`/miniconda*`、`/anaconda*`、`/mambaforge`、`/miniforge`)且 `conda` 可解析 | `conda install -y -c conda-forge <pkg>`(卸载 `conda remove -y <pkg>`) | 路径标记 + 可解析确认 |
|
|
101
|
+
| 同上但只有 `mamba` | `mamba install -y -c conda-forge <pkg>`(卸载 `mamba remove -y <pkg>`) | 同上 |
|
|
102
|
+
| `uv` 与解释器**同目录**(uv 管理的 venv) | `uv pip install <pkg>`(卸载 `uv pip uninstall <pkg>`) | 同目录才算,PATH 上别处的 uv 不算 |
|
|
103
|
+
| 其它 | `python -m pip install --user <pkg>`(卸载 `python -m pip uninstall -y <pkg>`) | **文档化回退**,且计划里标 `managerAssumed:true` |
|
|
104
|
+
|
|
105
|
+
计划、返回消息与审计 JSON 都带 `manager` / `managerAssumed` / `managerWhy`——**歧义时回退 pip 并明说"计划假设用 pip"**,绝不猜。
|
|
106
|
+
|
|
107
|
+
### 5.2 R / Octave / Julia:只做用户级(并说明为什么)
|
|
108
|
+
|
|
109
|
+
这三个引擎**没有系统级模板**,`scope:'system'` 一律返回 `MATH_REFUSED` + `next.reason='system-scope-unsupported'`,消息里带**每引擎的理由**:
|
|
110
|
+
|
|
111
|
+
- **R**:用户库是 `R_LIBS_USER`;系统级要写发行版包目录(需 root 或发行版包管理器)。
|
|
112
|
+
- **Octave**:`pkg install` 装进用户包目录;系统级要写 Octave 的 `share/packages`(需 root)。
|
|
113
|
+
- **Julia**:`Pkg.add` 装进当前活动环境 / 用户 depot(`JULIA_DEPOT_PATH`);"系统级"不是 Julia 的概念。
|
|
114
|
+
|
|
115
|
+
python 走 pip 时仍有真实的系统模板(不带 `--user`);conda/mamba/uv **没有**系统模板,各自带理由。
|
|
116
|
+
|
|
117
|
+
### 5.3 版本约束:交给包管理器,工具只查存在
|
|
118
|
+
|
|
119
|
+
- **策略**:**版本求解由包管理器负责**,本工具**只检查包是否存在**(按 **base name** 探测与报缺),安装时把规格**原样透传**。计划里带 `versionPolicy` 说明。
|
|
120
|
+
- **接受的写法**:`名称`、`名称[extras]`、`名称<op>版本`,其中 `<op>` ∈ `==` `>=` `<=` `~=` `!=` `>` `<` `=`(例如 pip 的 `numpy==1.2`、conda 的 `numpy=1.2`)。
|
|
121
|
+
- **拒绝的写法**:空格、`;`、`|`、`&`、`$`、反引号、`@`、括号等 shell 危险或管理器不认识的语法 ⇒ `MATH_INVALID_ARGUMENT` + `next.reason='unsupported-version-syntax'`(**不会**把可疑字符串丢给 shell)。
|
|
122
|
+
|
|
123
|
+
### 5.4 引擎发现顺序、`op:'probe'` 的语义与 `mathEngineOverride` 的边界
|
|
124
|
+
|
|
125
|
+
- **发现顺序(PATH 永远优先)**:① PATH 上的描述符候选名(`python3`→`python`→`py`、`Rscript`→`R`、`octave`→`octave-cli`、`julia`);② 以上都失败、且宿主声明了可选字段 `runtimeRoots` + `listDirAbs` 时,**最后**扫描 **DSH 自带运行时** `<root>/dsh-runtimes/*/dependencies/<engine>/<候选名>{,.exe,.cmd}`——**树名通配**(不写死 `dsh-primary-runtime`),且只接受描述符自己的候选名(不会塞进无关二进制)。`<root>` 由宿主给出(当前四套预设:**若 `DSH_HOME` 已设置则以它为唯一根**,否则用用户主目录下的 `.dsh`——显式设置即隔离发现,测试与定制部署都靠这个)。
|
|
126
|
+
- **找到可用引擎就报它的真实版本**(`engineInfo.path` + `version`),**不再**给安装指引;**只有**一个可用引擎都找不到时,才按 OS 给安装指引——而且是对**请求的那个引擎**(不是"第一个允许的引擎")。`op:'probe'` 的 `engine`/`engineInfo` 就是**请求的**引擎;请求的引擎缺失时,`code`/`message`/`next` 全部指向它(历史上这里会回显 `python`)。
|
|
127
|
+
- **`mathEngineOverride` **不是**发现手段**:它只按引擎名覆盖 **argv 模板**(如 `{python:{versionArgv,scriptArgv,evalArgv,packageProbe}}`),**不能指定一个可执行文件**。所以 `MATH_ENGINE_NOT_FOUND` 的正解是:装上引擎、把解释器放进 PATH、让上面的 DSH 运行时被扫到,或用 `engine:'cli'` + `cli.command` 显式给命令。
|
|
128
|
+
- **`engine:'cli'` 的三条行为**:① **包预检按 `cli.command` 的族**执行(`python*`/`Rscript`/`octave`/`julia` 用对应描述符的探测);命令族**不可识别** ⇒ **跳过**预检并给出 `PACKAGE_PRECHECK_SKIPPED` 警告(**不误报缺包、不阻塞**逃生口)。② `mode:'code'`/`'file'` 时归档脚本的**绝对路径会自动追加到 argv 末尾**(回执里 `cli.scriptAppended: true`;`cli.argv` 仍是调用方给的 argv)——否则会掉进 REPL、`exit=0` 而 stdout 为空,读起来像成功。**但若调用方 argv 自带程序槽(`-c`/`-m`/`-e`/`--eval`/`--command`),则调用方 argv 优先、不追加**(否则脚本会被当作多余参数,例如 `python -c 'print(1)' script.txt` 会把脚本喂给 `sys.argv[1]`);此时回执给 `cli.scriptAppended:false` + `cli.scriptSkipped` 说明原因。③ `engineInfo.version` 取自**真实的版本探测**(族可识别时),不再是 `"unknown"`。
|
|
129
|
+
- **真实宿主上的"空 spawn"与失败可见性(round-7 实测)**:真实会话里宿主的 `subprocess` 通路**在会话早期可能对一次 spawn 返回空**(`exit=null`)。因此:版本探测**最多尝试 3 次**(20s / 45s / 45s + 退避),且只在**看起来像冷启动/空返回**(`timedOut`、`exit===null`、`spawned=false`)时重试——确定性失败(非零退出、输出无法解析)**不重试**。仍然失败时返回 `MATH_ENGINE_UNUSABLE` 并携带**机读诊断** `probe: {argv, exit, timedOut, ms, spawned, stderrTail, attempts, retried, retryDiag}`;**引擎已找到就绝不再给"去装引擎"的指引**(那会误导),改为 `next.kind:'note'`。包预检同样重试;若预检**始终跑不起来**,**不判缺包、不阻塞**,给出 `PACKAGE_PRECHECK_UNKNOWN` 警告(附 attempts/argv)——"探测失败"永远不会被读成"包没装"。
|
|
130
|
+
- **包存在性探测的 argv 形态**:python 的探针代码遍历 `sys.argv[1:]`,所以包名按**每个一个 argv 项**传入(`<pkgs...>`);R/Julia/Octave 的模板把逗号串插进代码(`<pkgs>`/`__PKGS__`)。真机上曾经把 `numpy,pandas` 当成**一个**包名,导致"已装的包也报缺"。
|
|
131
|
+
- **探针 argv 里不得出现 shell 元字符(round-7 实测)**:真实宿主的 subprocess 通路会**拒绝**含 `|`(以及 `%`)的 argv——表现为一次**空 spawn**(`exit=null`),而不是报错。因此所有探测/许可证代码都改成**不含 `|`/`%`** 的形式(每包一行 `名称 ok|missing`),解析器两种形态都接受(`名称:状态` 与 `名称 状态`)。**新增/修改任何探针模板时都要保持这条**。
|
|
132
|
+
- **响应必须永远可 JSON 序列化(round-7 回归)**:诊断对象曾被写成自引用(`retryDiag` 指向父对象),导致 `JSON.stringify(response)` 抛 `Converting circular structure to JSON`,调用方**看不到任何结果**。现在诊断经 `jsonSafeDiag()` 投影为纯字段(`argv/exit/timedOut/ms/spawned/stderrTail/attempts/retried/retryDiag`),共享套件有一条**横切不变量**:`probe`/`run`/`receipt`/`install` 的 13 种响应(成功与失败)都必须能 `JSON.stringify`。**新增任何响应字段都要过这条。**
|
|
133
|
+
- **探测的 cwd 必须"一定存在"(round-7 真实根因)**:版本探测/包预检/许可探测曾用 `projectRoot()` 作 cwd;**全新会话里该目录还不存在**,而宿主对"cwd 不存在"的 spawn 返回 `spawned:true` + `exit:null`(**重试无用**——同 cwd 同结果),于是新会话第一次 `probe` 会得到"引擎存在但不可用"。现在这三类探测统一走 `probeCwd(H)`:优先宿主可选字段 `probeCwd`,否则 **OS 临时目录**(`TEMP`/`TMPDIR`/`TMP`),最后才回退到项目根;**真正的 `run` 仍用项目根**(run 会先写回执,写盘本身会创建目录树,所以它一直是好的)。
|
|
134
|
+
|
|
94
135
|
## 6. 插件**能**与**不能**强制的东西
|
|
95
136
|
|
|
96
137
|
**能强制**:入参 schema(闭合;未知键拒绝)、**词法级**项目内路径守卫(见下)、cwd、超时并终止进程、输出上限、回执落盘、插件自身的写域(只写 `Computation/`)、安装两步与作用域默认、同一 archive id 的**串行分配**(并发运行不会共用 attempt 目录)。
|
|
@@ -99,6 +140,7 @@ math_computation {
|
|
|
99
140
|
- **路径守卫是字符串级的**:`projectRel` 只做词法规范化(拒绝绝对路径、盘符、`..` 越界),**不做 realpath、不解析符号链接/junction/硬链接**。项目内一个指向外部的链接可以绕过该守卫拿到 `mode:'file'` 的读取与执行;真正的容器化由宿主 `ctx.fs` 后端负责(`resolve`/`contains`),插件不重复实现。审计 A 的用例把这一**限制**钉成了断言(`tests/math-computation-shared.test.mjs` §16c)。
|
|
100
141
|
- 脚本内部的网络访问与文件访问——宿主 `subprocess.spawn` **没有 policy 槽**(`env` 层只做凭据/`DSH_*` 清洗与显式合并,不能限制网络或写盘;参见 `dsh-subprocess-local` 的 `runner-launch-*.js` 与 `vibe-math-v5.js` 中 audit M8 注释),任何被执行的计算进程都在宿主 fs 策略之外;
|
|
101
142
|
- `mathMode` 只是提示词策略:**模型仍可能直接调用宿主 shell**,插件无法阻止,也无法为 shell 路径生成回执。因此默认策略要求:走 shell 得出的结论必须标注"**未经工具归档(shell 路径)**",**只有工具路径的计算才算可复核支撑材料**;
|
|
143
|
+
- **替代必须声明(提示词规则,同样不是强制)**:当替代方案改变了**精确性或结论强度**(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。规则行由 `MATH_SUBSTITUTION_RULE_LINE`/`_EN` 提供(已并入 `MATH_RULE_LINES`/`_EN` 与四套 persona 两个文本块),但**能否照做取决于模型**——插件只能要求,不能验证。
|
|
102
144
|
- 商业引擎的 CLI 模板随版本变化(Maple 尤甚):描述符带 `VERIFY` 标记,**每次运行都回显实际 argv**;若引擎以用法/选项错退出,返回 `MATH_ENGINE_BAD_ARGV` + `next.kind='engine-override'`(指向 `mathEngineOverride` 覆盖模板),而不是裸 `MATH_NONZERO_EXIT`。有许可的机器应验证这三个模板。
|
|
103
145
|
- 真强制(禁网/限权)需要宿主 sandbox/policy 支持——**列为待上游需求**,不在本轮范围。
|
|
104
146
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# dsh-vibe-math 2.7.1 — Release Notes (English)
|
|
2
|
+
|
|
3
|
+
> Previous release: 2.7.0. This is a PATCH release that ships two batches together. **Batch 1 (honesty and install policy)**: a substitute that changes exactness or conclusion strength must be declared; python installs dispatch to conda/mamba/uv/pip from the **detected environment**; R/Octave/Julia system-scope refusals state the **per-engine reason**; **version solving is delegated to the package manager** while the tool only checks presence. **Batch 2 (seven defects found by the first real end-to-end run)**: the probe now reports the requested engine, engine discovery also finds the runtimes **DSH ships itself**, the `cli` escape hatch prechecks against `cli.command`'s own interpreter, `mode:'code'` really passes the script (caller argv wins when it already runs code), versions are real, probe argv carries no shell metacharacters, and discovery probes no longer depend on the project directory existing. Existing parameter defaults, data formats and directory structure are **unchanged**, the DSH support window is unchanged, and no migration is needed.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
- **Declare substitutions**: a new rule line (zh/en) requires that a substitute changing exactness/conclusion strength be stated explicitly; it lands in **both persona blocks of all four presets**, in the rule block and in the tool description. Missing engines/packages explicitly lead to an **alternative or an install plan**, and installation always goes `plan → planToken → confirm`.
|
|
10
|
+
- **Python package-manager dispatch**: `conda` / `mamba` (`-y -c conda-forge`) / `uv` (`uv pip …`) / the **pip fallback** (`-m pip install --user`); detection reads the interpreter's **own environment** (detect, don't guess) and an ambiguous case falls back to pip with the **assumption** recorded in plan/message/audit.
|
|
11
|
+
- **System scope now explains itself**: `system` still returns `MATH_REFUSED` + `next.reason:'system-scope-unsupported'`, but the message states **why per engine** (R→`R_LIBS_USER`, Octave→`share/packages`, Julia→`JULIA_DEPOT_PATH`, plus conda/mamba/uv reasons).
|
|
12
|
+
- **Version constraints**: `name` / `name[extras]` / `name<op>version` are accepted; anything else is refused with the new reason `unsupported-version-syntax`. **Version solving belongs to the package manager** - the tool probes presence by base name and passes the spec through verbatim.
|
|
13
|
+
- A real-host defect was fixed along the way: the install path resolved the interpreter by **engine name** (`python`) instead of the descriptor's candidate order (`python3`→`python`→`py`), which would have broken conda detection on a real machine.
|
|
14
|
+
|
|
15
|
+
- **Seven real-machine defects fixed** (all found by the first real end-to-end run, all closed on the same bytes): the probe echoed `python` for any requested engine; the bundled DSH runtime was invisible; the `cli` precheck ignored `cli.command`; `mode:'code'` never passed the archived script; `engine.version` was `"unknown"`; probe argv contained `|`/`%` (which a real host answers with a null spawn); and probes ran with a cwd that does not exist on a brand-new workspace (the single root cause behind "found but unusable" and the false "missing package").
|
|
16
|
+
- **Two permanent guards added**: §20 the JSON-serialisability invariant over 13 response shapes, and §21 the fresh-root simulation (a spawn whose cwd does not exist answers `exit:null`).
|
|
17
|
+
|
|
18
|
+
## Changes
|
|
19
|
+
|
|
20
|
+
### 1. Honesty about substitutions
|
|
21
|
+
|
|
22
|
+
- **The rule**: when an alternative changes **exactness or conclusion strength** - exact symbolic solution → numerical approximation, closed form → sampling/quadrature, changed precision/tolerances/assumptions, a different algorithm class - the conclusion **MUST say so** and must not read as if the original (exact/requested) result had been obtained; if the exact result is unavailable, say so plainly.
|
|
23
|
+
- **Where it lives** (one constant per language): `MATH_SUBSTITUTION_RULE_LINE` / `MATH_SUBSTITUTION_RULE_LINE_EN`, folded into `MATH_RULE_LINES`/`_EN` (so `mathAvailabilityLine()` carries them), with a paraphrased sentence in the tool description; **both persona text blocks of all four presets append them verbatim** (append, never replace an existing rule line).
|
|
24
|
+
- **Missing engines/packages**: still report-only, and now explicitly offer an **alternative or an agent install plan**; installation always issues a plan first and requires **`planToken` confirmation** (the token binds the plan content, so a changed plan invalidates it), scope defaults to user, and `system` must be given explicitly every time and is never remembered.
|
|
25
|
+
|
|
26
|
+
### 2. Python package-manager dispatch
|
|
27
|
+
|
|
28
|
+
The `python` install plan picks the manager from the **interpreter's own environment** instead of hard-coding pip:
|
|
29
|
+
|
|
30
|
+
| Detected environment | Commands in the plan | Basis |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| the interpreter path carries a conda marker (`/envs/`, `/conda`, `/miniconda*`, `/anaconda*`, `/mambaforge`, `/miniforge`) and `conda` resolves | `conda install -y -c conda-forge <pkg>` (uninstall `conda remove -y <pkg>`) | path marker + resolvability |
|
|
33
|
+
| same, but only `mamba` resolves | `mamba install -y -c conda-forge <pkg>` (uninstall `mamba remove -y <pkg>`) | as above |
|
|
34
|
+
| `uv` sits **next to** the interpreter (a uv-managed venv) | `uv pip install <pkg>` (uninstall `uv pip uninstall <pkg>`) | same directory only |
|
|
35
|
+
| anything else | `python -m pip install --user <pkg>` (uninstall `python -m pip uninstall -y <pkg>`) | **documented fallback**, plan flagged `managerAssumed` |
|
|
36
|
+
|
|
37
|
+
- **Detect, don't guess**: the plan, the returned message and the audit JSON all carry `manager` / `managerAssumed` / `managerWhy`; an ambiguous case falls back to pip and says "the plan assumes pip".
|
|
38
|
+
- **Install and uninstall stay paired**: the uninstall command comes from the same chosen manager (the audit carries the uninstall template; there is still **no universal automatic rollback**).
|
|
39
|
+
- **A real defect fixed on the way**: the install path used to resolve the interpreter by **engine name** (`python`) rather than the descriptor's **candidate order** (`python3`→`python`→`py`) - on a real host the conda `python3` *is* that interpreter, so dispatch would not have seen the environment markers. It now resolves exactly like the run path.
|
|
40
|
+
|
|
41
|
+
### 3. Per-engine system-scope policy
|
|
42
|
+
|
|
43
|
+
- R / Octave / Julia are **user-scope only**; `scope:'system'` returns `MATH_REFUSED` + `next.reason:'system-scope-unsupported'`, and the message gives the **engine-specific reason**:
|
|
44
|
+
- **R**: the user library is `R_LIBS_USER`; a system install would write into the distribution's package tree (root or the distro package manager).
|
|
45
|
+
- **Octave**: `pkg install` writes to the user package directory; system-wide would write Octave's `share/packages` (root).
|
|
46
|
+
- **Julia**: `Pkg.add` installs into the active environment / user depot (`JULIA_DEPOT_PATH`); "system scope" is not a Julia concept.
|
|
47
|
+
- **conda / mamba / uv** likewise have no system template and each carries its own reason; **python on pip keeps a real system template** (without `--user`), confirmed explicitly on every call.
|
|
48
|
+
|
|
49
|
+
### 4. Version-constraint policy
|
|
50
|
+
|
|
51
|
+
- **Accepted**: `name`, `name[extras]`, `name<op>version` where `<op>` ∈ `==` `>=` `<=` `~=` `!=` `>` `<` `=` (pip-style `numpy==1.2`, conda-style `numpy=1.2`).
|
|
52
|
+
- **Refused**: spaces, `;`, `|`, `&`, `$`, backticks, `@`, parentheses - anything shell-unsafe or unknown to the manager ⇒ `MATH_INVALID_ARGUMENT` + `next.reason:'unsupported-version-syntax'` (a suspicious string is **never** handed to a shell).
|
|
53
|
+
- **Division of labour**: **version solving belongs to the package manager** - the tool probes and reports missing packages by **base name**, passes the spec through **verbatim** in the install plan, and states this in the plan as `versionPolicy`.
|
|
54
|
+
- **Vocabulary**: `unsupported-version-syntax` is the new machine-readable reason; the vocabulary is now **13 reasons / 7 `next.kind` values / 11 failure codes**, kept in **set-equality** across `tool-schema.json#refusalVocabulary`, `docs/math-computation.md` §3 and the parity guard (which also requires every `reason:` value to be a string literal).
|
|
55
|
+
|
|
56
|
+
### 5. Seven real-machine defects (one root cause, three symptoms)
|
|
57
|
+
|
|
58
|
+
1. **`op:'probe'` ignored the requested engine.** The response carried `engine: null` (or the first *allowed* engine), and the failure path always blamed `params.mathEngines[0]` (python), so `probe{engine:'r'}` echoed python and told the user to install python. It now resolves the **requested** engine and reports its name/path/version; a requested engine that resolves (including `cli`) counts as available, and a missing requested engine is reported — and guided — as *that* engine.
|
|
59
|
+
2. **Engine discovery missed the runtimes DSH ships itself.** PATH is still tried first; when nothing resolves and the host declares the optional `runtimeRoots` + `listDirAbs` fields, the tool finally scans `<root>/dsh-runtimes/*/dependencies/<engine>/` — the **tree name is globbed** (never a hard-coded `dsh-primary-runtime`) and only the descriptor's own candidate names are accepted. A found engine now reports its **real version** and **no install guidance is emitted** (a winget hint for an engine that is already installed is exactly what misled the user).
|
|
60
|
+
3. **The `cli` package precheck ignored `cli.command`.** The generic `cli` descriptor has no package probe, so every package looked missing and the escape hatch blocked itself. The precheck now runs for the **family** of the resolved command (`python*`/`Rscript`/`octave`/`julia`), against that very interpreter; an unrecognisable family **skips** the precheck with an explicit warning instead of reporting a false "missing".
|
|
61
|
+
4. **`mode:'code'` never passed the script.** `cli` received only the command, so python dropped into a REPL (`exit=0`, empty stdout — which reads as success). For `mode:'code'`/`'file'` the archived script path is now appended to argv; **when the caller's argv already provides a program slot (`-c`/`-m`/`-e`/`--eval`/`--command`), the caller's argv wins** and nothing is appended (otherwise the script would be fed as an extra argument). The receipt records `cli.scriptAppended` and, when skipped, `cli.scriptSkipped` with the reason.
|
|
62
|
+
5. **`engine.version` was `"unknown"`.** For `cli` the version is now obtained with the family descriptor's real version probe (unknown families remain `"unknown"`).
|
|
63
|
+
6. **Probe argv contained shell metacharacters.** A real host answers argv containing `|` (and `%`) with a **null spawn**. All probe codes were rewritten to be metacharacter-free (one line per package: `name ok|missing`) and the parser accepts both the old `name:state` and the new `name state` shapes; python still passes **one argv item per package**.
|
|
64
|
+
7. **The root cause: probe cwd did not exist on a brand-new workspace.** Version probes, the package precheck and the licence probe spawned with `projectRoot()` as cwd — but on a fresh session that directory does not exist yet, and the host answers such a spawn with `spawned: true, exit: null` (retries cannot help: same cwd, same result). That single cause produced "found but unusable", the false "missing package", and `version: "unknown"`. Probes now use a cwd that is guaranteed to exist (`probeCwd`: optional host field → OS temp dir → project root); real runs keep the project root, which they create by writing the receipt first.
|
|
65
|
+
|
|
66
|
+
### 6. Two new permanent guards
|
|
67
|
+
|
|
68
|
+
- **§20 JSON-serialisability invariant.** The probe diagnostics had a self-referential `retryDiag`, so `JSON.stringify(response)` threw `Converting circular structure to JSON` and the caller saw **no result at all**. Diagnostics are now projected to plain fields (`jsonSafeDiag`), and the shared suite asserts that **13 response shapes** (`probe`/`run`/`receipt`/`install`, success and failure, including the retried-failure `retryDiag` case) serialise.
|
|
69
|
+
- **§21 fresh-root simulation.** The fake seam models the host ("a spawn whose cwd does not exist answers `exit:null`", and `writeText` marks the directory as created), asserting that a probe on a fresh root is still `ok:true` with a real version, that no probe reports `exit:null`, and that the precheck still runs.
|
|
70
|
+
|
|
71
|
+
### 7. Review and verification
|
|
72
|
+
|
|
73
|
+
- **Same discipline**: the four shared-module copies are **byte-identical** (`install-copies --check` ⇒ `COPIES OK`); `math-computation-shared` **278/0**, the four preset suites **114/116/153/117**, `audit-math-computation-contract` **155/0**, `audit-math-computation-parity` **92/0**, `audit-math-computation-sensitivity` **22 probes / 0 problems**, the mutation proofs **16 proved / 0 problems** (each turning a named assertion red); the gate is `TOTAL 65 PASS 65 FAIL 0` (**44 suites + 21 probes**).
|
|
74
|
+
- **Real-session evidence (fresh empty workspace, first tool call)**: `probe{engine:'python'}` ⇒ `ok:true`, `version 3.12.14`, path `…/dsh-runtimes/dsh-primary-runtime/dependencies/python/python.exe`, no `exit:null`; `run` via `cli` with the bundled interpreter and `packages:['numpy']` ⇒ `exit:0`, `stdout:"1.643935 -2.0"` (Σ1/k² for k=1..1000 and det([[1,2],[3,4]])), `packages.found.numpy:"present"`, `warnings:[]`, six receipt files.
|
|
75
|
+
- **Honest boundaries that still stand**: engine execution is now verified **via the `cli` escape hatch on the DSH-bundled runtime** (that is the only real-engine path proven here — the built-in engines are still covered only through the fake subprocess seam); `session/follow` token-level deltas, multi-client use and mid-turn `cancel` remain **unverified**; the host's `subprocess.spawn` has **no policy slot**, so the plugin cannot enforce network/write restrictions (that needs host sandbox support); the Maple/MATLAB/Wolfram templates are marked `VERIFY` with `mathEngineOverride` available; **SageMath is P2**; the two comparison experiments are **run-books** and these notes contain **no fabricated numbers**.
|
|
76
|
+
|
|
77
|
+
## Compatibility
|
|
78
|
+
|
|
79
|
+
- Existing parameter defaults, data formats and directory structure are **unchanged**; this release only adds rule text, install-plan dispatch and one machine-readable reason - **no migration**.
|
|
80
|
+
- **The only behaviour change is inside install plans**: machines without conda/uv markers still use pip (as before); **a conda/mamba/uv environment now gets that manager's commands** (which is the point of this release), and the uninstall command comes from the same manager.
|
|
81
|
+
- The `system`-scope return code and `next.reason` are **unchanged** (only the message carries more information); the python+pip system template is still there.
|
|
82
|
+
|
|
83
|
+
## Upgrade
|
|
84
|
+
|
|
85
|
+
- Upgrade directly; no migration.
|
|
86
|
+
- To keep install plans on **pip** always: run on an interpreter without conda/uv markers (or point at the system python). The tool never "guesses" a manager - it only dispatches when the interpreter's own environment says so.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# dsh-vibe-math 2.7.1 — 发布说明(中文)
|
|
2
|
+
|
|
3
|
+
> 上一版:2.7.0。本版是**补丁版**,两批改动一起发。**第一批(诚实性与安装口径)**:替代方案若改变精确性或结论强度必须声明;python 安装按**检测到的环境**分派 conda/mamba/uv/pip;R/Octave/Julia 的系统级作用域拒绝给出**每引擎理由**;**版本求解交给包管理器**,本工具只查存在。**第二批(首次真机端到端跑出来的七个缺陷)**:`probe` 回显请求的引擎、引擎发现新增 **DSH 自带运行时**、`cli` 逃生口的包预检改用它自己那个解释器、`mode:'code'` **真的把脚本传进去**(调用方 argv 自带程序槽时以调用方为准)、版本报真值、探针 argv 不含 shell 元字符、探测不再依赖项目目录已存在。既有参数默认值、数据格式与目录结构**未变**,DSH 支撑窗口不变,无需迁移。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 概览
|
|
8
|
+
|
|
9
|
+
- **替代必须声明**:新规则行(中/英)说明"替代方案改变精确性/结论强度时必须写明",进入四套预设的**两个 persona 文本块**、规则段与工具描述;缺引擎/缺包时明确给**替代方案或安装计划**,安装一律 `plan → planToken → confirm`。
|
|
10
|
+
- **python 包管理器分派**:`conda` / `mamba`(`-y -c conda-forge`)/ `uv`(`uv pip …`)/ **pip 回退**(`-m pip install --user`);按解释器**自身环境**检测,不猜;歧义时回退 pip 并在计划/消息/审计里标明**假设**。
|
|
11
|
+
- **系统级作用域有理由**:`system` 仍返回 `MATH_REFUSED` + `next.reason:'system-scope-unsupported'`,但消息现在说明**每个引擎为什么**(R→`R_LIBS_USER`、Octave→`share/packages`、Julia→`JULIA_DEPOT_PATH`,conda/mamba/uv 各自理由)。
|
|
12
|
+
- **版本约束口径**:接受 `名称` / `名称[extras]` / `名称<op>版本`;其余写法显式拒绝(新 reason `unsupported-version-syntax`)。**版本求解是包管理器的事**,本工具只按 base name 查存在、把规格原样透传。
|
|
13
|
+
- 随功能修掉一个真机缺陷:安装路径此前按**引擎名**解析解释器(`python`)而不是候选顺序(`python3`→`python`→`py`),会让 conda 检测在真机上失效。
|
|
14
|
+
|
|
15
|
+
## 变更
|
|
16
|
+
|
|
17
|
+
### 1. 替代方案的诚实性
|
|
18
|
+
|
|
19
|
+
- **规则**:当替代方案改变了**精确性或结论强度**时——精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类——结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
20
|
+
- **落点**(中/英各一条常量):`MATH_SUBSTITUTION_RULE_LINE` / `MATH_SUBSTITUTION_RULE_LINE_EN`,已并入 `MATH_RULE_LINES`/`_EN`(因此 `mathAvailabilityLine()` 自动携带),工具描述也加了同义句;**四套预设的两个 persona 文本块都逐字追加**(追加,不替换既有规则行)。
|
|
21
|
+
- **缺引擎/缺包**:仍然只报告,并明确给**用户自装指引**或**代理代装计划**;**安装一律先出计划、再由 `planToken` 确认**(token 绑定计划内容,内容变了即失效),默认 user 作用域,`system` 每次显式且不被记住。
|
|
22
|
+
|
|
23
|
+
### 2. Python 包管理器分派
|
|
24
|
+
|
|
25
|
+
`python` 的安装计划按**解释器自身环境**选择管理器,而不是固定 pip:
|
|
26
|
+
|
|
27
|
+
| 检测到的环境 | 计划里的命令 | 依据 |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| 解释器路径含 conda 标记(`/envs/`、`/conda`、`/miniconda*`、`/anaconda*`、`/mambaforge`、`/miniforge`)且 `conda` 可解析 | `conda install -y -c conda-forge <pkg>`(卸载 `conda remove -y <pkg>`) | 路径标记 + 可解析确认 |
|
|
30
|
+
| 同上但只有 `mamba` | `mamba install -y -c conda-forge <pkg>`(卸载 `mamba remove -y <pkg>`) | 同上 |
|
|
31
|
+
| `uv` 与解释器**同目录**(uv 管理的 venv) | `uv pip install <pkg>`(卸载 `uv pip uninstall <pkg>`) | 同目录才算 |
|
|
32
|
+
| 其它 | `python -m pip install --user <pkg>`(卸载 `python -m pip uninstall -y <pkg>`) | **文档化回退**,计划标 `managerAssumed` |
|
|
33
|
+
|
|
34
|
+
- **检测,不猜**:计划、返回消息与审计 JSON 都带 `manager` / `managerAssumed` / `managerWhy`;歧义时回退 pip 并明说"计划假设用 pip"。
|
|
35
|
+
- **install 与 uninstall 成对**:卸载命令来自同一个被选中的管理器(审计里带卸载模板;仍**没有**通用自动回滚)。
|
|
36
|
+
- **顺手修掉的真实缺陷**:安装路径此前用**引擎名**(`python`)解析解释器,而不是描述符的**候选顺序**(`python3`→`python`→`py`)——真机上 conda 的 `python3` 才是那个解释器,所以分派会看不到环境标记。现在与运行路径一致,按候选依次解析。
|
|
37
|
+
|
|
38
|
+
### 3. 每引擎系统级作用域策略
|
|
39
|
+
|
|
40
|
+
- R / Octave / Julia **只做用户级**,`scope:'system'` 返回 `MATH_REFUSED` + `next.reason:'system-scope-unsupported'`,消息里给出**该引擎的理由**:
|
|
41
|
+
- **R**:用户库是 `R_LIBS_USER`;系统级要写发行版包目录(需 root 或发行版包管理器)。
|
|
42
|
+
- **Octave**:`pkg install` 装进用户包目录;系统级要写 Octave 的 `share/packages`(需 root)。
|
|
43
|
+
- **Julia**:`Pkg.add` 装进当前活动环境 / 用户 depot(`JULIA_DEPOT_PATH`);"系统级"不是 Julia 的概念。
|
|
44
|
+
- **conda / mamba / uv** 同样没有系统模板,各自带理由;**python 走 pip 时仍保留真实的系统模板**(不带 `--user`),由每次调用显式确认。
|
|
45
|
+
|
|
46
|
+
### 4. 版本约束口径
|
|
47
|
+
|
|
48
|
+
- **接受的写法**:`名称`、`名称[extras]`、`名称<op>版本`,其中 `<op>` ∈ `==` `>=` `<=` `~=` `!=` `>` `<` `=`(pip 风格的 `numpy==1.2`、conda 风格的 `numpy=1.2`)。
|
|
49
|
+
- **拒绝的写法**:空格、`;`、`|`、`&`、`$`、反引号、`@`、括号等 shell 危险或管理器不认识的语法 ⇒ `MATH_INVALID_ARGUMENT` + `next.reason:'unsupported-version-syntax'`(**不会**把可疑字符串丢给 shell)。
|
|
50
|
+
- **分工**:**版本求解交给包管理器**——本工具只按 **base name** 探测与报缺,安装计划把规格**原样透传**,并在计划里带 `versionPolicy` 说明这一点。
|
|
51
|
+
- **词汇表**:`unsupported-version-syntax` 是新增的机读 reason;词汇表现共 **13 reason / 7 `next.kind` / 11 失败码**,在 `tool-schema.json#refusalVocabulary`、`docs/math-computation.md` §3 与 parity 守卫之间保持**集合相等**(守卫还要求每个 `reason:` 取值都是字符串字面量)。
|
|
52
|
+
|
|
53
|
+
### 5. 真机缺陷修复(一条根因、三个症状)
|
|
54
|
+
|
|
55
|
+
1. **`op:'probe'` 忽略请求的引擎**:响应里 `engine` 是 `null`(或"第一个允许的引擎"),失败路径总是指责 `params.mathEngines[0]`(python),于是 `probe{engine:'r'}` 回显 python 并让用户去装 python。现在解析并报告**请求的**引擎(名字/路径/版本);被请求且解析成功的引擎(包括 `cli`)也算可用,请求的引擎缺失时错误与指引都指向它。
|
|
56
|
+
2. **引擎发现漏掉 DSH 自带的运行时**:PATH 仍然优先;都没有时,若宿主声明了可选字段 `runtimeRoots` + `listDirAbs`,最后扫描 `<root>/dsh-runtimes/*/dependencies/<engine>/`——**树名通配**(从不写死 `dsh-primary-runtime`),且只接受描述符自己的候选名。找到的引擎会报**真实版本**,并且**不再给安装指引**(对已装的引擎给 winget 提示正是误导的来源)。
|
|
57
|
+
3. **`cli` 包预检忽略 `cli.command`**:通用 `cli` 描述符没有包探测,于是所有包看起来都缺、逃生口把自己堵死。现在按解析出的命令的**族**(`python*`/`Rscript`/`octave`/`julia`)用**那个解释器**探测;族不可识别时**跳过**预检并给出明确警告,而不是误报"缺包"。
|
|
58
|
+
4. **`mode:'code'` 从不传脚本**:`cli` 只拿到命令,于是 python 掉进 REPL(`exit=0`、stdout 空——读起来像成功)。现在 `mode:'code'`/`'file'` 会把归档脚本路径追加到 argv;**若调用方 argv 自带程序槽(`-c`/`-m`/`-e`/`--eval`/`--command`)则以调用方为准、不追加**(否则脚本会被当成多余参数)。回执记录 `cli.scriptAppended`,跳过时记录 `cli.scriptSkipped` 及原因。
|
|
59
|
+
5. **`engine.version` 是 `"unknown"`**:`cli` 现在用族描述符的**真实版本探测**取版本(族不可识别时仍是 `"unknown"`)。
|
|
60
|
+
6. **探针 argv 含 shell 元字符**:真实宿主对含 `|`(以及 `%`)的 argv 会返回**空 spawn**。所有探针代码改为不含元字符(每包一行 `名称 ok|missing`),解析器同时接受旧的 `名称:状态` 与新形态;python 仍是**每包一个 argv 项**。
|
|
61
|
+
7. **根因:探测的 cwd 在全新工作区不存在**。版本探测、包预检与许可探测用 `projectRoot()` 作 cwd,而全新会话里该目录还不存在,宿主对这种 spawn 返回 `spawned:true, exit:null`(**重试无用**:同 cwd 同结果)。这一条同时造成了"找到了却不可用"、误报"缺包"与 `version:"unknown"`。现在探测走**一定存在**的 cwd(`probeCwd`:可选宿主字段 → OS 临时目录 → 项目根);真正的 `run` 仍用项目根——它本来就会先写回执,写盘会创建目录树。
|
|
62
|
+
|
|
63
|
+
### 6. 新增两条永久守卫
|
|
64
|
+
|
|
65
|
+
- **§20 响应必须可 JSON 序列化**:诊断对象曾出现自引用的 `retryDiag`,导致 `JSON.stringify(response)` 抛 `Converting circular structure to JSON`,调用方**看不到任何结果**。现在诊断经 `jsonSafeDiag` 投影成纯字段,共享套件断言 **13 种响应**(`probe`/`run`/`receipt`/`install`,成功与失败,含重试后失败的 `retryDiag` 场景)都能序列化。
|
|
66
|
+
- **§21 fresh-root 仿真**:假 seam 模拟宿主("cwd 不存在 ⇒ `exit:null`",且 `writeText` 标记目录已创建),断言全新根上 `probe` 仍 `ok:true` 且版本是真值、没有任何探测报 `exit:null`、包预检照常运行。
|
|
67
|
+
|
|
68
|
+
### 7. 审查与验证
|
|
69
|
+
|
|
70
|
+
- **同一套纪律**:共享模块四份**字节一致**(`install-copies --check` ⇒ `COPIES OK`);`math-computation-shared` **278/0**、四套预设 **114/116/153/117**、`audit-math-computation-contract` **155/0**、`audit-math-computation-parity` **92/0**、`audit-math-computation-sensitivity` **22 探针 / 0 problems**、变异证明 **16 proved / 0 problems**(每一个都把**具名**断言打红);门禁 `TOTAL 65 PASS 65 FAIL 0`(**44 套件 + 21 探针**)。
|
|
71
|
+
- **真机证据(全新空工作区、第一个工具调用)**:`probe{engine:'python'}` ⇒ `ok:true`、版本 `3.12.14`、路径 `…/dsh-runtimes/dsh-primary-runtime/dependencies/python/python.exe`、无 `exit:null`;用 `cli` + 自带解释器 `run` 且 `packages:['numpy']` ⇒ `exit:0`、`stdout:"1.643935 -2.0"`(k=1..1000 的 Σ1/k² 与 det([[1,2],[3,4]]))、`packages.found.numpy:"present"`、`warnings:[]`、回执 6 个文件。
|
|
72
|
+
- **仍然成立的诚实边界**:引擎执行现在**已通过 `cli` 逃生口在 DSH 自带运行时上真机验证**(这是本项目唯一被证明的真实引擎路径——内置引擎仍只通过假 subprocess seam 覆盖);`session/follow` 的 token 级增量、多客户端与回合中 `cancel` **仍未验证**;宿主 `subprocess.spawn` **没有 policy 槽**,插件不能强制禁网/限权(需宿主 sandbox);Maple/MATLAB/Wolfram 的模板标 `VERIFY` 并提供 `mathEngineOverride`;**SageMath 属 P2**;两个对照实验只是 **run-book**,本说明**不含编造数字**。
|
|
73
|
+
|
|
74
|
+
## 兼容性
|
|
75
|
+
|
|
76
|
+
- 既有参数默认值、数据格式与目录结构**未变**;新增的只是规则文本、安装计划的分派逻辑与一个机读 reason,**无需迁移**。
|
|
77
|
+
- **行为变化仅限安装计划**:没有 conda/uv 标记的机器仍走 pip(与上一版一致);**conda/mamba/uv 环境现在会得到该管理器的命令**(这正是本版目的),卸载命令同样来自该管理器。
|
|
78
|
+
- `system` 作用域的返回码与 `next.reason` **未变**(只是消息更有信息量);python+pip 的系统模板仍在。
|
|
79
|
+
|
|
80
|
+
## 升级
|
|
81
|
+
|
|
82
|
+
- 直接升级即可,无需迁移。
|
|
83
|
+
- 若希望安装计划**总是用 pip**:在非 conda/uv 的解释器上运行(或指向系统 python);本工具不会"猜"管理器,只在解释器自身环境给出标记时才分派。
|
|
84
|
+
- **七个真机缺陷全部修复**(都来自首次真机端到端,且都在同一份字节上关闭):`probe` 对任何请求引擎都回显 `python`;DSH 自带运行时发现不到;`cli` 包预检忽略 `cli.command`;`mode:'code'` 从不传脚本;`engine.version` 是 `"unknown"`;探针 argv 含 `|`/`%`(真实宿主会以空 spawn 回应);探测用的 cwd 在**全新工作区还不存在**——**这一条是"找到了却不可用"和"误报缺包"的共同根因**。
|
|
85
|
+
- **新增两条永久守卫**:§20 **13 种响应必须可 JSON 序列化**的横切不变量;§21 **fresh-root 仿真**(cwd 不存在时宿主返回 `exit:null`)。
|
|
86
|
+
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vibe-math",
|
|
3
3
|
"description": "Multi-agent mathematical problem-solving & verification frameworks for DeepSeek Harness — FOUR agent presets in one install: vibe-math-v2 (probability-driven, classic: qs.json + Propos knowledge base + explorer→solver→review/debate verdict), vibe-math-v3 (THIRD-generation, classic: paper-style Markdown knowledge base with Problems/Progress/Propos/Methods/Verified + planner-agent scheduling that decides the next N actions + universal theory/method invention library + agents write their own Markdown directly via a per-file write lock), and vibe-math-v4 (FOURTH-generation: persistent self-organizing resident subagents that message & meet to decide all tasks, verify only by unanimous consensus, /compact at a context threshold, and stop only when all agree the problem is solved), and vibe-math-v5 (FIFTH-generation research institute: an academician as the organizational centre who decomposes and ASSIGNS work and chairs meetings; permanent researchers who hold the vote and may hire/fire their own temp workers; temp workers with no vote; a group chat and meetings; a durable per-recipient mailbox; a compare-and-set task DAG; and a boolean m-vote consensus rule where an object enters Verified/ only when at least m voting members agree AND every one of them returns exactly 1 or exactly 0). Installing this bundle auto-installs all four presets (v1 was removed at v2.0.0). Each preset also writes a FINAL PAPER by default when its run concludes — and does so BEFORE the run is marked complete: on v4/v5 the team co-authors its parts, merges them, cross-reviews, and the editor named by paperEditor finalises; the output is Paper/<run or institute id>/{paper.md,paper.tex,paper.pdf when a LaTeX engine is detected,paper.meta.json,paper.log.md} (params finalPaper/paperFormat/paperLanguage/paperCompilePdf/paperLatexCommand, plus paperEditor on v4/v5; see docs/final-paper.md).",
|
|
4
|
-
"version": "2.7.
|
|
4
|
+
"version": "2.7.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.19.0 || >=24.0.0",
|
|
@@ -137,7 +137,9 @@
|
|
|
137
137
|
"scripts/build-preset-rows.mjs",
|
|
138
138
|
"preset-declaration.js",
|
|
139
139
|
"tests/audit-preset-rows.test.mjs",
|
|
140
|
-
"docs/COMPAT-AUDIT-ROUND3.md"
|
|
140
|
+
"docs/COMPAT-AUDIT-ROUND3.md",
|
|
141
|
+
"docs/release-notes/RELEASE-NOTES-2.7.1.md",
|
|
142
|
+
"docs/release-notes/RELEASE-NOTES-2.7.1.en.md"
|
|
141
143
|
],
|
|
142
144
|
"license": "MIT",
|
|
143
145
|
"keywords": [
|
|
@@ -167,7 +169,7 @@
|
|
|
167
169
|
},
|
|
168
170
|
"minVersion": "0.1.2-alpha.4",
|
|
169
171
|
"testedVersion": "0.2.0-rc.2",
|
|
170
|
-
"compatNote": "v2.7.
|
|
172
|
+
"compatNote": "v2.7.1 补丁版:① 诚实性与安装口径(替代方案改变精确性/结论强度必须声明;python 安装按检测到的环境分派 conda/mamba/uv/pip;R/Octave/Julia 的 system 作用域给出每引擎理由;版本求解交给包管理器,只按 base name 查存在,规格原样透传)+ ② 七个真机缺陷修复(probe 回显请求的引擎、发现 DSH 自带运行时、cli 包预检用 cli.command 的解释器、mode:code 真的传脚本且调用方 argv 优先、版本报真值、探针 argv 无 shell 元字符、探测 cwd 不再依赖项目目录已存在)+ 两条永久守卫(响应必须可 JSON 序列化;fresh-root 仿真)。既有参数默认值、数据格式与目录结构未变,DSH 支撑窗口不变,无需迁移。",
|
|
171
173
|
"compatibility": {
|
|
172
174
|
"dshReleases": {
|
|
173
175
|
"0.1.2-alpha.4": "compatible",
|