dsh-openwrite 0.2.27 → 0.2.33

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.
Files changed (130) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +55 -6
  3. package/THIRD_PARTY_NOTICES.md +4 -3
  4. package/companions.mjs +508 -0
  5. package/cordis.patch.yml +0 -2
  6. package/docs/CLOSED_ISSUE_FOLLOWUPS.md +5 -3
  7. package/docs/COMPANION_PLUGINS.md +142 -0
  8. package/docs/CONTEXT_SLOTS.md +60 -0
  9. package/docs/COST_MEASUREMENT.md +2 -2
  10. package/docs/DEVELOPMENT.md +6 -11
  11. package/docs/DSH_STORE.md +14 -2
  12. package/docs/EDITOR_SAFETY_REPAIRS.md +17 -0
  13. package/docs/INSTALL.md +112 -4
  14. package/docs/ISSUES_121_123.md +97 -0
  15. package/docs/ISSUES_140_142.md +58 -0
  16. package/docs/ISSUES_149_150_151.md +77 -0
  17. package/docs/ISSUES_98_100.md +2 -0
  18. package/docs/ISSUE_123_FOLLOWUP.md +55 -0
  19. package/docs/ISSUE_146_REVIEW_EVIDENCE.md +53 -0
  20. package/docs/LEARNING.md +1 -1
  21. package/docs/MOBILE_READINESS.md +62 -0
  22. package/docs/PLUGIN_MAINTENANCE.md +1 -3
  23. package/docs/RELEASE_ACCEPTANCE.md +90 -3
  24. package/docs/REVIEW_ROUND_22.md +67 -0
  25. package/docs/REVIEW_ROUND_23.md +48 -0
  26. package/docs/REVIEW_ROUND_25.md +51 -0
  27. package/docs/SELECTION_UPGRADE_REPAIRS.md +16 -0
  28. package/docs/TOOLS.md +933 -0
  29. package/docs/WORKFLOWS.md +5 -5
  30. package/package.json +18 -21
  31. package/packages/openwrite-bridge/lib/client.d.ts +0 -1
  32. package/packages/openwrite-bridge/lib/client.js +90 -9
  33. package/packages/openwrite-bridge/lib/contracts-generated.js +2 -1
  34. package/packages/openwrite-bridge/lib/dog-delivery.d.ts +1 -0
  35. package/packages/openwrite-bridge/lib/dog-delivery.js +10 -4
  36. package/packages/openwrite-bridge/lib/dog-review.js +15 -3
  37. package/packages/openwrite-bridge/lib/domain.d.ts +27 -0
  38. package/packages/openwrite-bridge/lib/domain.js +250 -29
  39. package/packages/openwrite-bridge/lib/host-llm.d.ts +188 -0
  40. package/packages/openwrite-bridge/lib/host-llm.js +657 -0
  41. package/packages/openwrite-bridge/lib/host-web.d.ts +61 -0
  42. package/packages/openwrite-bridge/lib/host-web.js +166 -0
  43. package/packages/openwrite-bridge/lib/index.d.ts +4 -0
  44. package/packages/openwrite-bridge/lib/index.js +150 -6
  45. package/packages/openwrite-bridge/lib/managed-runtime.d.ts +47 -2
  46. package/packages/openwrite-bridge/lib/managed-runtime.js +179 -35
  47. package/packages/openwrite-bridge/lib/tool-policy.js +39 -12
  48. package/packages/openwrite-bridge/lib/tools.js +1238 -1219
  49. package/packages/openwrite-bridge/package.json +7 -5
  50. package/packages/studio-panel/lib/client.js +116667 -114773
  51. package/packages/studio-panel/lib/client.js.map +1 -1
  52. package/packages/studio-panel/lib/types/client/LaunchOpenWrite.d.ts +10 -0
  53. package/packages/studio-panel/lib/types/client/ModelView.d.ts +28 -4
  54. package/packages/studio-panel/lib/types/client/OpenWriteSettings.d.ts +64 -0
  55. package/packages/studio-panel/lib/types/client/SceneWorkbench.d.ts +2 -0
  56. package/packages/studio-panel/lib/types/client/SearchSettings.d.ts +2 -0
  57. package/packages/studio-panel/lib/types/client/SerialWritingView.d.ts +2 -1
  58. package/packages/studio-panel/lib/types/client/TurnMutationSummary.d.ts +2 -0
  59. package/packages/studio-panel/lib/types/client/VditorBody.d.ts +8 -2
  60. package/packages/studio-panel/lib/types/client/api.d.ts +41 -2
  61. package/packages/studio-panel/lib/types/client/browser-download.d.ts +4 -0
  62. package/packages/studio-panel/lib/types/client/companions.d.ts +46 -0
  63. package/packages/studio-panel/lib/types/client/dto.d.ts +22 -0
  64. package/packages/studio-panel/lib/types/client/locales.d.ts +1 -1
  65. package/packages/studio-panel/lib/types/client/manuscript-annotations.d.ts +2 -1
  66. package/packages/studio-panel/lib/types/client/manuscript-overlay.d.ts +2 -1
  67. package/packages/studio-panel/lib/types/client/manuscript-selection.d.ts +18 -5
  68. package/packages/studio-panel/lib/types/client/selection-coordinates.d.ts +15 -0
  69. package/packages/studio-panel/lib/types/client/workspace-chrome.d.ts +41 -0
  70. package/packages/studio-panel/package.json +5 -3
  71. package/plugin.mjs +159 -20
  72. package/preset-definition.mjs +144 -4
  73. package/presets/openwrite/agent.cordis.yml +7 -9
  74. package/presets/openwrite/ops-integration.mjs +28 -0
  75. package/presets/openwrite/preset.yml +2 -1
  76. package/presets/openwrite/skills/canon/SKILL.md +3 -3
  77. package/presets/openwrite/skills/delivery-artifact-query/SKILL.md +41 -0
  78. package/presets/openwrite/skills/dialoguequality/SKILL.md +16 -17
  79. package/presets/openwrite/skills/dog-delivery-verification/SKILL.md +113 -0
  80. package/presets/openwrite/skills/export-book/SKILL.md +3 -3
  81. package/presets/openwrite/skills/foreshadow/SKILL.md +1 -1
  82. package/presets/openwrite/skills/foreshadowing-system/SKILL.md +16 -25
  83. package/presets/openwrite/skills/import-artifact-query/SKILL.md +30 -0
  84. package/presets/openwrite/skills/learn/SKILL.md +3 -3
  85. package/presets/openwrite/skills/novel-creator/SKILL.md +10 -10
  86. package/presets/openwrite/skills/novel-reviewer/SKILL.md +11 -11
  87. package/presets/openwrite/skills/progress/SKILL.md +1 -1
  88. package/presets/openwrite/skills/review-artifact-query/SKILL.md +41 -0
  89. package/presets/openwrite/skills/review-chapter/SKILL.md +2 -2
  90. package/presets/openwrite/skills/revise-span/SKILL.md +5 -5
  91. package/presets/openwrite/skills/style-system/SKILL.md +13 -6
  92. package/presets/openwrite/skills/truth-validation/SKILL.md +9 -12
  93. package/presets/openwrite/skills/workflow-manager/SKILL.md +13 -13
  94. package/presets/openwrite/skills/world-query/SKILL.md +16 -11
  95. package/presets/openwrite/skills/write-next/SKILL.md +1 -1
  96. package/release/{openwrite-5.8.16-py3-none-any.whl → openwrite-5.8.30-py3-none-any.whl} +0 -0
  97. package/release/runtime-manifest.json +4 -12
  98. package/release/source.json +21 -21
  99. package/release/wheels/licenses/OPENSSL-3.6.3-LICENSE.txt +225 -0
  100. package/scripts/maintenance.mjs +67 -7
  101. package/scripts/plugin-doctor.mjs +179 -0
  102. package/scripts/prepare.mjs +11 -2
  103. package/scripts/safe-upgrade.mjs +141 -13
  104. package/dog-tools.mjs +0 -11
  105. package/presets/openwrite/skills/dog-delivery-query/SKILL.md +0 -42
  106. package/presets/openwrite/skills/dog-import-query/SKILL.md +0 -29
  107. package/presets/openwrite/skills/dog-review-query/SKILL.md +0 -42
  108. package/scripts/dog/delivery-stage.js +0 -32
  109. package/scripts/dog/import-chapter.js +0 -20
  110. package/scripts/dog/import-record.js +0 -35
  111. package/scripts/dog/review-dimension.js +0 -41
  112. package/scripts/dog/review-record.js +0 -42
  113. package/vendor/dsh-dog/LICENSE +0 -29
  114. package/vendor/dsh-dog/README.md +0 -114
  115. package/vendor/dsh-dog/UPSTREAM.md +0 -30
  116. package/vendor/dsh-dog/cordis.patch.yml +0 -14
  117. package/vendor/dsh-dog/lib/client.js +0 -2960
  118. package/vendor/dsh-dog/lib/client.js.map +0 -1
  119. package/vendor/dsh-dog/lib/core-BAlgZpLq.js +0 -2074
  120. package/vendor/dsh-dog/lib/core-BiEBMLz3.d.ts +0 -495
  121. package/vendor/dsh-dog/lib/core.d.ts +0 -2
  122. package/vendor/dsh-dog/lib/core.js +0 -2
  123. package/vendor/dsh-dog/lib/index.d.ts +0 -143
  124. package/vendor/dsh-dog/lib/index.js +0 -1279
  125. package/vendor/dsh-dog/package.json +0 -110
  126. package/vendor/dsh-dog/schemas/schema-0.2/graph.schema.json +0 -139
  127. package/vendor/dsh-dog/schemas/schema-0.2/report.schema.json +0 -87
  128. package/vendor/dsh-dog/schemas/schema-0.2/run.schema.json +0 -259
  129. package/vendor/dsh-dog/schemas/schema-0.2/runtime-event.schema.json +0 -105
  130. package/vendor/dsh-dog/schemas/schema-0.2/verification.schema.json +0 -40
@@ -0,0 +1,142 @@
1
+ # 联动插件(Companion Plugins)
2
+
3
+ OpenWrite 不依赖任何联动插件:写作/审稿链路、工作台在单独安装时全部可用。
4
+ 本节说明三个**可选**联动插件装上之后会发生什么、装上之前的差别,以及判定规则。
5
+
6
+ ## 判定规则(重要)
7
+
8
+ 联动是否生效由两部分决定,任一部份不满足都保持 OpenWrite 自己的实现:
9
+
10
+ 1. **已安装**:插件出现在某个 profile 的 `dsh.profile.bundles` 里,并且其包目录真的存在于
11
+ `<DSH_HOME>/profiles/<profile>/node_modules/`。
12
+ 2. **宿主放行**:该插件自己声明的 `peerDependencies["@deepseek-ai/dsh"]` 范围覆盖当前宿主版本。
13
+ 宿主安装时用的就是这个范围,所以“声明不含当前宿主”的插件即使装了也不会被宿主加载,
14
+ OpenWrite 不会去替它加载。
15
+
16
+ 判定结果写入 `<DSH_HOME>/openwrite/companions.json`(按 profile manifest 的 mtime 做指纹缓存),
17
+ 只在 profile 变动或宿主版本变化时重新推导。任何读取失败都** fail-closed**:
18
+ 保持内嵌实现,不影响启动与写作。
19
+
20
+ 诊断可用 `npm run doctor`(末尾的 `companion plugins` 一行)或工作台启动器里的「联动插件」区;
21
+ 需要显式指定宿主版本时可用环境变量 `OPENWRITE_HOST_VERSION`(诊断与测试用)。
22
+
23
+ 宿主版本解析顺序:`OPENWRITE_HOST_VERSION` → profile 内安装的 `@deepseek-ai/dsh` →
24
+ 本插件已解析到的 `@deepseek-ai/dsh-*` 子包(与宿主同版本发布)→ 当前进程入口。
25
+ 解析不到时按未知处理,所有联动保持关闭。
26
+
27
+ ## dsh-dog(DoG 独立验收)
28
+
29
+ - OpenWrite 从 0.2.29 起不再内置 DoG 引擎、调试器或 `dog_*` 工具,也不会自动运行第三方 verifier;
30
+ OpenWrite 自己的六域评审与交付闭环照常工作。
31
+ - 安装 `@dsh-external/dsh-dog` 且当前宿主放行时:它的 `dog_*` 工具在宿主层可见(OpenWrite 预设
32
+ 的 Agent 也能调用),工作台「联动插件」区显示安装/放行状态。预设新增非斜杠技能
33
+ `dog-delivery-verification`:把当前章或整书的正文、最新评审与交付 preflight 证据写成
34
+ 工作区内的不可变 handoff 包和 DoG 0.9 图,再由 Agent 调 `dog_validate`/`dog_create`/`dog_run`
35
+ 做一次独立判断。技能要求先说明会产生模型调用并得到作者同意,且不直接改正文。
36
+ - **未安装**:写作、审稿、交付完全不受影响;Agent 不会声称跑过 DoG,回到 OpenWrite 门禁。
37
+ - OpenWrite 只提供 handoff 与流程,不替 dsh-dog 运行 verifier,也不把它的运行结果写进
38
+ OpenWrite 的 `data/dog/**` 交付产物;两者是不同引擎,不能互相冒充。图形化调试器仍由
39
+ dsh-dog 自己的面板提供,OpenWrite 不另建入口。
40
+
41
+ ## dsh-ops(token 效率工具)
42
+
43
+ - 仓库:<https://github.com/T-Auto/dsh-ops>(npm 包名 `dsh-ops`,MIT)。
44
+ - 提供有界的 Native 文件工具、渐进式工具发现(`ops_discover_tools`)与诊断(`ops_status`)。
45
+ - **未安装**:预设工具面与现在完全相同。
46
+ - **已安装且宿主放行**:预设追加一行 `openwrite-ops`,调用上游
47
+ `integration({ preset: 'openwrite', files: true, discovery: true, presentation: 'native',
48
+ replaceOfficial: false, shell: false })`。也就是:只挂文件类常驻工具 + 渐进发现,
49
+ **不替换官方文件工具、不发布 `ops_bash`、不改提示词策略**。卸载该插件即恢复原状。
50
+ - 工作台「联动插件」区会把同一组选项交给上游 `resolveIntegrationConfig`,显示实际解析出的
51
+ 文件工具/渐进发现/呈现方式/是否替换官方工具/shell 开关与常驻工具数;上游没有该导出时
52
+ 退回一句概述,不把“探测到”说成“已按某个具体配置挂载”。
53
+ - 上游声明的宿主范围是 `>=0.2.0-rc.2 <0.2.2-0`,因此 0.1.x 宿主上不会挂载(上游 peer 也不允许)。
54
+ - 安装:`dsh plugin --profile web add dsh-ops`(或按该仓库说明使用其安装入口)。
55
+
56
+ > 上游文档中的 `preset` id 必须精确匹配 OpenWrite 的稳定预设 id `openwrite`;本插件传入的就是这个值。
57
+ > 挂载前还会真的 import 一次 `dsh-ops/integration` 并用上面这组选项构建集成:npm 上的 `0.4.4`
58
+ > 还没有这个导出(`0.5.0-alpha` 起才提供),探测会报「does not expose dsh-ops/integration」并不挂载,
59
+ > 避免一次导入失败把整个预设组合拖垮。
60
+
61
+ **宿主怎么判定兼容性(重要,曾判错)**:宿主读插件的 `engines.dsh`(没有则退回
62
+ `peerDependencies` 里的 `@deepseek-ai/dsh` 与 `@deepseek-ai/dsh-*`),用
63
+ `semver.satisfies(version, range, { includePrerelease: true })` 匹配。这个 `includePrerelease`
64
+ 放宽了 npm 的规则,因此 `0.2.1-rc.5` **满足** `>=0.2.0-rc.2 <0.2.2-0`。
65
+
66
+ `companions.mjs` 曾按 npm 安装期的严格规则实现,于是比宿主更保守:在 `0.2.1-rc.5` 上把
67
+ `dsh-ops` 与 `dsh-our-free-model` 报成「已安装但宿主不放行」,而宿主实际两个都加载了
68
+ (读 `window.__DSH_BOOT__.entries` 实测确认)。已改为与宿主同一语义,并用一条测试把
69
+ `satisfiesRange` 与 semver 的 `includePrerelease` 结果逐组合钉住。
70
+
71
+ 因此 `dsh-ops` 的宿主范围 `>=0.2.0-rc.2 <0.2.2-0` 覆盖全部 `0.2.x` 宿主,0.1.x 上不挂载
72
+ (上游 peer 也不允许)。上游若放宽或收紧声明,无需改代码,探测自动跟随。
73
+
74
+ > 上游文档中的 `preset` id 必须精确匹配 OpenWrite 的稳定预设 id `openwrite`;本插件传入的就是这个值。
75
+ > 挂载前还会真的 import 一次 `dsh-ops/integration` 并用上面这组选项构建集成:npm 上的 `0.4.4`
76
+ > 还没有这个导出(`0.5.0-alpha` 起才提供),探测会报「does not expose dsh-ops/integration」并不挂载,
77
+ > 避免一次导入失败把整个预设组合拖垮。
78
+
79
+ ## dsh-our-free-model(免密钥模型车道)
80
+
81
+ - 仓库:<https://github.com/Ebony-Vinyl/dsh-our-free-model>(npm 包名
82
+ `@ebony-vinyl/dsh-our-free-model`,MIT;请勿安装 npm 上同名裸包)。
83
+ - 装上后宿主模型选择器会出现免费车道,无需登录/Key。
84
+ - **未安装**:OpenWrite 只在工作台「联动插件」区给出一句安装提示。
85
+ - **已安装**:同样只在「联动插件」区显示状态(版本、是否被当前宿主放行)。
86
+ - 该插件 2.7.4 声明的宿主范围是 `^0.1.2-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1`,
87
+ 因此 `0.2.1-rc.*` 宿主上它自己也不会被宿主加载,联动区会如实显示「已安装但当前宿主不兼容」。
88
+ - **注意**:OpenWrite 的写作/审稿调用走 OpenWrite Core(Studio 后端)自己的模型配置,
89
+ 不经过宿主 llm 服务。因此装上它**不会自动**成为 OpenWrite 的模型。
90
+ - 「联动插件」区在检测到本地转发已开启时提供一个「写入 OpenWrite 模型配置」按钮:
91
+ 它读取该插件的 `/api/our-free-model/clients`(同一 origin),把 `base_url`/`api_key`/模型名
92
+ 写成一条 id 为 `our-free-model` 的 OpenWrite 模型 profile。写入走 Studio 的
93
+ `POST /studio-panel/api/model/profiles`,与「任务 → 模型」页面同一条路由,由 Core 校验。
94
+ 已存在同 id profile 时会先要求确认,并**保留作者调过的参数**(温度、上下文窗口、超时等),
95
+ 只更新网关地址、模型与密钥;`remember_api_key` 沿用作者原来的选择,不默认代为持久化密钥。
96
+ 该路由由第三方插件提供,其鉴权行为不在本插件控制范围内(见下「安全假设」)。
97
+ 未开启本地转发时,按钮不出现,只提示去该插件的设置页打开。
98
+ 接入动作现在会同时处理**任务路由**:读取全局模型库的 `routes`,显示“当前全局路由”,
99
+ 默认勾选“同时把写作/评审切到该模型”。确认后先写 profile,再把 `chapter_write` 与 `review`
100
+ 两个键切到 `our-free-model`;规划、检索、研究等其余路由原样保留。已存在 profile 或路由
101
+ 将变化时都会二次确认;若 profile 写入成功而路由写入失败,提示会明确说“配置已写入、路由
102
+ 切换失败”,不会把部分成功报成整体成功。
103
+ 这里写的是**全局**路由;若当前作品在 `novel_config.yaml` 里单独设置了 `model_routes`,
104
+ 作品设置优先,按钮不会覆盖它。网关地址若自带 `/v1`,写入前会规范化,避免 `/v1/v1`。
105
+
106
+ ## 工作台里的「联动插件」区
107
+
108
+ 「设置 → OpenWrite → 宿主」页的「联动插件」区展示三行状态:dsh-dog、dsh-ops、dsh-our-free-model(启动器底部入口复用同一份状态),
109
+ 各自说明“已接入 / 已安装但宿主不兼容(原因)/ 未安装(装上会怎样)”。
110
+ 状态数据来自 `/studio-panel/companions`(由本插件在宿主进程内探测,与其它
111
+ `/studio-panel/*` 路由一样受宿主浏览器鉴权保护);ops 行还会带上解析后的挂载计划。
112
+
113
+ 该区域**不是**纯只读:免费模型的「写入 OpenWrite 模型配置」按钮会写一条模型 profile,
114
+ 并可同时把全局写作/评审路由切到它(语义见上一节)。除此之外它不修改任何配置。
115
+
116
+ ## 安全假设(需定期复核)
117
+
118
+ - `/studio-panel/companions` 的响应含宿主版本与联动插件清单,已按其它 `/studio-panel/*`
119
+ 路由加同一道浏览器鉴权;无鉴权的本地请求会拿到 401/503 而不是数据。
120
+ - `/api/our-free-model/clients` 由第三方插件提供,本插件假设它与 Studio 路由一样受宿主
121
+ 浏览器鉴权保护。该假设未被本插件验证,升级该插件后应重新确认;响应里的密钥只用于写入
122
+ 模型 profile,不进入日志、诊断或错误信息。
123
+
124
+ ## 维护约定
125
+
126
+ - 联动判定逻辑集中在根目录 `companions.mjs`(无第三方依赖,自带所需 semver 子集),
127
+ 单测在 `scripts/companions.test.mjs`;ops 适配在 `presets/openwrite/ops-integration.mjs`;
128
+ DoG 交付验收流程在 `presets/openwrite/skills/dog-delivery-verification/SKILL.md`。
129
+ - 三个联动插件都保持“可选、fail-closed”:探测/导入失败只影响对应联动,不影响写作与启动。
130
+ - 任何联动插件都不要变成硬依赖:探测失败、范围不匹配、包缺失都必须回到 OpenWrite 自己的实现。
131
+
132
+ ## 真实宿主验证记录(2026-10-31,macOS arm64 / Node v24.15,0 次模型调用)
133
+
134
+ | 场景 | 宿主 | 结果 |
135
+ | --- | --- | --- |
136
+ | 无联动插件(DoG 已移除) | `0.2.1-rc.3` / `0.2.1-rc.5` | 客户端验收全项通过;预设选择器只有 1 条 OpenWrite;工具面不再含 `dog_*` |
137
+ | dsh-ops `0.5.0-alpha3`(有 `./integration`) | `0.2.0-rc.2` | 探测为可用;客户端验收通过 |
138
+ | dsh-ops `0.4.4`(无 `./integration`) | `0.2.0-rc.2` | 探测报「does not expose dsh-ops/integration」并不挂载;预设组合不受影响,验收通过 |
139
+ | dsh-our-free-model `2.7.4` | `0.2.0-rc.2`(安装) | 安装后该插件自身的客户端引导未在本环境完成(其启动期网关探测),宿主本身无激活错误;OpenWrite 侧仅探测与展示,未参与该路径 |
140
+
141
+ 未覆盖:三系统 CI、Windows/Ubuntu 实机、真实手机、真实付费模型、以及「ops 工具出现在真实 Agent 工具目录」
142
+ (本验收环境不发起 Agent 轮次,预设组合不会挂载;该链路由单测证明行已按精确 preset id 插入)。
@@ -0,0 +1,60 @@
1
+ # 写手上下文槽位参考
2
+
3
+ 本表对应候选 Core 5.8.30,来源提交 `b9fcacfa743ee9865e504fa6ce02c2386a5d7b68`。由捆绑 wheel 的 SECTION_SOURCES、保护规则和 shares 生成,共 20 个来源条目,包含兼容别名;不是每次写作都会装满这些槽位。
4
+
5
+ ## 看本章实际用了什么
6
+
7
+ 先用 `novel_context_preview {"chapter":"ch_001","include_agent_payload":true}`;要看所选 writer 档案、guidance 与 target_words 的最终输入,使用 `novel_write_chapter {"chapter_id":"ch_001","dry_run":true}`。这些预览不发起写作模型请求。
8
+
9
+ `context_manifest.items` 提供实际槽位、来源指纹、字符数、估算 token、保护/压缩状态;`documents` 列出 character/setting/style 每份文档原始与装配字符数、compressed/excluded。`missing_items` 与 `excluded_items` 解释缺失/排除。来源目录是候选来源,不能把目录中所有文件都当成实际已送给模型的文档。
10
+
11
+ ## 预算怎样分配
12
+
13
+ 没有固定的每槽字符上限。先按模型上下文窗、输出预留和安全余量计算输入预算;未超预算保持原文。受保护硬约束先占预算,装不下就明确失败;不会静默删掉它们。其余容量换算为字符后,按以下 shares 归一化分配(这不是整窗百分比):
14
+
15
+ | 配额组 | 默认权重 |
16
+ | --- | --- |
17
+ | historical_outline | 0.08 |
18
+ | current_outline | 0.08 |
19
+ | previous_chapter | 0.18 |
20
+ | protagonist_state | 0.04 |
21
+ | characters | 0.13 |
22
+ | settings | 0.08 |
23
+ | style | 0.12 |
24
+
25
+ style 权重可用 novel_config.yaml 的 context_style_share 调整,限制在 0.01–0.5。风格容量还会优先保留最多 4000 字符的已有风格(不超过可选总容量的一半),其余组随剩余容量缩放。最终仍检查 token 总量。
26
+
27
+ 多文档按各自容量占比分配;同优先级按名称排序,剩余字符依次补给。设置/角色通常截取开头,上一章正文保留结尾;配额为零的文档排除。风格优先顺序见下表。目录表里的 level 是来源层级,不是逐层删除顺序。
28
+
29
+ ## 来源、选择和消费者
30
+
31
+ | 槽位 | 层级 | 作品根目录内来源 | 预算 | 选择/压缩规则 | 谁读 |
32
+ | --- | --- | --- | --- | --- | --- |
33
+ | `author_intent` | 3 | `src/story/author_intent.md` | 受保护,不截断 | 作者意图;完整保留硬约束 | 章节装配/兼容输入 → writer;manifest 展示 |
34
+ | `creative_focus` | 1 | `src/story/current_focus.md` | 受保护,不截断 | 创作罗盘;完整保留硬约束 | 章节装配/兼容输入 → writer;manifest 展示 |
35
+ | `story_background` | 3 | `src/story/background.md`、`src/story/foundation.md` | 受保护,不截断 | 兼容别名;有 core_documents 时 manifest 隐藏重复项 | 章节装配/兼容输入 → writer;manifest 展示 |
36
+ | `core_documents` | 3 | `src/story/background.md`、`src/story/foundation.md` | 受保护,不截断 | 故事背景与基础正典;完整保留 | 章节装配/兼容输入 → writer;manifest 展示 |
37
+ | `historical_arc_summaries` | 4 | `src/outline.md` | historical_outline | 已结束篇摘要;按摘要文档分配,截取开头 | 章节装配/兼容输入 → writer;manifest 展示 |
38
+ | `current_arc_sections` | 2 | `src/outline.md` | current_outline | 当前篇各节摘要;按摘要文档分配,截取开头 | 章节装配/兼容输入 → writer;manifest 展示 |
39
+ | `chapter_requirements` | 0 | `src/outline.md` | 受保护,不截断 | 当前章目标、节拍、悬念、章节承诺 promise/payoff_of 与登记的扩展字段;完整保留 | 章节装配/兼容输入 → writer;manifest 展示 |
40
+ | `scene_context` | 0 | `data/story_structure/scenes.json` | 受保护,不截断 | 仅当前正文版本匹配的场景结构;过期时排除并诊断 | ContextBuilder → writer;manifest 展示 |
41
+ | `previous_chapter_content` | 0 | `data/manuscript/` | previous_chapter | 默认上一章全文;可选 tail/有效 summary;预算压力下保留结尾 | 章节装配/兼容输入 → writer;manifest 展示 |
42
+ | `character_states` | 1 | `data/manuscript/`、`src/outline.md` | 由 ContextBuilder/检索预算决定 | ContextBuilder 提取本章涉及人物的行内状态;受该装配器预算约束 | ContextBuilder → writer;manifest 展示 |
43
+ | `semantic_references` | 4 | `data/manuscript/`、`data/sources/` | 由 ContextBuilder/检索预算决定 | ContextBuilder 语义检索的远距离正文/资料;需可用的独立 Embedding 档案;受检索与装配预算约束 | ContextBuilder → writer;manifest 展示 |
44
+ | `protagonist_state` | 1 | `data/world/current_state.md` | protagonist_state | 本章涉及人物的当前状态;可选区按配额截取 | 章节装配/兼容输入 → writer;manifest 展示 |
45
+ | `current_state` | 3 | `data/world/current_state.md` | 受保护,不截断 | 兼容连续性字段;有 continuity_documents 时隐藏重复项 | 章节装配/兼容输入 → writer;manifest 展示 |
46
+ | `ledger` | 3 | `data/world/ledger.md` | 受保护,不截断 | 兼容粒子台账;有 continuity_documents 时隐藏重复项 | 章节装配/兼容输入 → writer;manifest 展示 |
47
+ | `relationships` | 3 | `data/world/relationships.md` | 受保护,不截断 | 兼容人物关系;有 continuity_documents 时隐藏重复项 | 章节装配/兼容输入 → writer;manifest 展示 |
48
+ | `character_documents` | 2 | `src/characters/` | characters | 只选本章涉及人物;按文档容量分配、保留开头 | 章节装配/兼容输入 → writer;manifest 展示 |
49
+ | `concept_documents` | 2 | `src/world/` | settings | setting_documents 的兼容别名;不重复计算 | 章节装配/兼容输入 → writer;manifest 展示 |
50
+ | `setting_documents` | 2 | `src/world/`、`src/progression/` | settings | 世界规则/术语/时间线 + 本章涉及实体 + 全部 YAML 进阶体系;按文档容量分配、保留开头 | 章节装配/兼容输入 → writer;manifest 展示 |
51
+ | `continuity_documents` | 3 | `data/world/`、`data/foreshadowing/` | 受保护,不截断 | 运行态正典 current_state/ledger/relationships;完整保留 | 章节装配/兼容输入 → writer;manifest 展示 |
52
+ | `style_documents` | 3 | `data/style/`、`craft/` | style | 作品风格与 craft;优先 work.composed/manifest/fingerprint/craft,再按文档容量分配 | 章节装配/兼容输入 → writer;manifest 展示 |
53
+
54
+ ## 渐进摘要与进阶体系
55
+
56
+ `progressive_compressor` 是较早的分节/分篇摘要组件:节摘要目标约 800 字符,篇摘要目标约 2000 字符,优先首尾、关键词和事件,降低对话优先级并在句子边界截断。它不是上表 ChapterAssemblerV2 的逐槽预算器;不要把旧组件的目标长度当成当前每槽固定预算。
57
+
58
+ 作者在资产页创建的进阶体系保存于 `src/progression/<id>.yaml`。本候选实际加载 .yaml/.yml 为 `setting_documents[progression.<id>]`,经过同一设置预算进入 writer,并出现在逐文档用量里;即使没有 world/ 目录也可加载。文件存在不保证预算不足时完整送达,写前应核对预览。
59
+
60
+ 工具参数与修改方式见 [工具参考](TOOLS.md)。
@@ -11,7 +11,7 @@ npm --prefix packages/openwrite-bridge run build
11
11
  node --test packages/openwrite-bridge/scripts/tool-policy.test.mjs
12
12
  ```
13
13
 
14
- `real dsh tool registry isolates 95 tools` 会打印两行 JSON:
14
+ `real dsh tool registry isolates 56 tools` 会打印两行 JSON:
15
15
 
16
16
  | 字段 | 含义 | 不是什么 |
17
17
  |---|---|---|
@@ -20,7 +20,7 @@ node --test packages/openwrite-bridge/scripts/tool-policy.test.mjs
20
20
  | `sdkBytes` | 注入到 system prompt 的 SDK 文本字节 | 不是费用 |
21
21
  | `tokenizer: not-measured` | 本仓库不内置某家 tokenizer | 不得改写成已测 token |
22
22
 
23
- 同一套检查还断言:普通预设 `novel_*` 为 0;创作预设为 95 且不随 PTC 另一 scope 改变。
23
+ 同一套检查还断言:普通预设 `novel_*` 为 0;创作预设为 56 且不随 PTC 另一 scope 改变。
24
24
 
25
25
  要对比「请求大小」,把一次真实 `tools.schemas(agent)` 或 PTC `wireSchemas` 的 JSON 写入文件后对体积做 `wc -c` / SHA-256。这仍是请求体字节,不是 token。
26
26
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  | 路径 | 说明 |
20
20
  |---|---|
21
- | `packages/openwrite-bridge/` | dsh 插件:95 个 `novel_*` 工具,覆盖 Studio HTTP 动作面并提供隔离模型横评与脱敏 trace |
21
+ | `packages/openwrite-bridge/` | dsh 插件:56 个 `novel_*` 工具,覆盖 Studio HTTP 动作面并提供隔离模型横评与脱敏 trace |
22
22
  | `packages/studio-panel/` | dsh web 原生工作台:创作 / 资料 / 任务,含规范章节导航、连续审读、场景双序、正文编辑器、双 DAG、模型测试台与工具卡 |
23
23
  | `presets/openwrite/` | OpenWrite 全流程 agent 预设(规划/资产/写章/评审/修订) |
24
24
  | `scripts/install.sh` | 构建插件、安装预设到 `~/.dsh/.agent-presets/`、插件装进 dsh profile |
@@ -52,14 +52,9 @@ npm run doctor -- --profiles # 只读核对本机 web/headless 是否链接
52
52
  `check:plugin` 不需要服务、小说或模型凭据,GitHub Actions 也执行此门禁。
53
53
  真实系统另跑 `scripts/verify.sh` 和 `npm run test:e2e`;E2E 跳过不算运行时通过。
54
54
 
55
- ## DoG 集成
55
+ ## 评审/交付产物
56
56
 
57
- `scripts/install.sh` 默认自动获取固定的 `dsh-dog v1.2.0`,保存到
58
- `$DSH_HOME/extensions/dsh-dog`,完成构建并只挂载到 web profile;重复运行会复用该目录。
59
- 如需使用已有工作树,可传入 `DSH_DOG_DIR=/path/to/dsh-dog`;明确不安装时设置
60
- `DSH_DOG_AUTO_INSTALL=0`。
61
-
62
- 安装器会在缺少 `dog:` 配置时写入安全兜底值。DoG v1.2 优先使用发起调用的 dsh 会话
63
- Workspace,所以切换作品会自动切换评审/交付图根目录,无需修改 `workspaceRoot` 或重启。
64
- `novel_review_chapter` 和后台章节评审完成时会自动实例化标准章节审稿 DAG;DoG 只查询
65
- 已物化产物,不会重复调用模型。
57
+ `novel_review_chapter` 和后台章节评审完成时会自动实例化标准章节审稿记录,
58
+ 查询技能(`review-artifact-query` / `delivery-artifact-query` / `import-artifact-query`)
59
+ 只读这些已物化产物,不会重复调用模型。0.2.29 起不再内置第三方 DoG 引擎,
60
+ 需要图形化验证可自行安装 `@dsh-external/dsh-dog`。
package/docs/DSH_STORE.md CHANGED
@@ -11,12 +11,22 @@ OpenWrite 是一个完整的小说创作插件套件。商城安装目标是仓
11
11
  - manifestPath:`package.json`
12
12
  - Bundle Patch:`cordis.patch.yml`
13
13
 
14
- 根包统一加载 `openwrite-bundle`、`openwrite-bridge`、`studio-panel`、`openwrite-dog`。这些既有 ID 保持稳定。`packages/openwrite-bridge`、`packages/studio-panel` 是内部开发包,不应和根包一起登记到同一个 Profile,也不需要删除它们或拆成独立商城条目。
14
+ 根包统一加载 `openwrite-bundle`、`openwrite-bridge`、`studio-panel`。这些既有 ID 保持稳定。`packages/openwrite-bridge`、`packages/studio-panel` 是内部开发包,不应和根包一起登记到同一个 Profile,也不需要删除它们或拆成独立商城条目。
15
15
 
16
16
  源码验收必须固定到完整 Commit;`prepare` 会自包含构建三个内部插件,包含 Core wheel、编辑器静态资源、预设和许可证,不依赖相邻源码。构建授权仍遵循用户的 pnpm 设置。普通用户优先使用 npm 预编译包:`dsh plugin --profile web add -w dsh-openwrite@latest`。latest 只在执行安装或升级时解析,运行中不自动更新。市场的版本、兼容和验收字段应记录实际核验的精确版本;不能把已有验收结果自动套用到未来版本。精确 npm 版本及对应 GitHub Release `.tgz` 继续用于复现与回退,见 README。
17
17
 
18
18
  ## 0.2.26
19
19
 
20
+ ### #142:商城仍选择 0.2.25
21
+
22
+ 报告的实际命令是不带版本的 `dsh plugin --profile desktop add dsh-openwrite`,
23
+ 被拒版本为 0.2.25。此版本确实没有声明 DSH 0.2.1-rc.3;0.2.26 起已加入,
24
+ 已发布的 0.2.28 根包与所有内嵌子包继续覆盖该精确宿主。
25
+ 安装入口应显式指定已经验收的版本或 `dsh-openwrite@latest`,避免旧的精确依赖选择被沿用。
26
+ 最新 npm 元数据、profile 的 spec/锁和实际安装版本应分别核对,不能只修改商城展示字段。
27
+ 当前不能仅凭日志认定报告者的具体缓存来源;排查和停机升级步骤见
28
+ [Stale package selection](INSTALL.md#stale-package-selection)。
29
+
20
30
  0.2.26 在根包及全部内嵌子包加入精确 `0.2.1-rc.3` 声明,真实 Web 客户端验收通过。
21
31
  市场请按实际 npm/Release 制品及其验收报告记录版本和兼容信息。
22
32
  验证范围见 [#105–#113 修复说明](ISSUES_105_113.md)。
@@ -29,7 +39,9 @@ OpenWrite 是一个完整的小说创作插件套件。商城安装目标是仓
29
39
 
30
40
  alpha 浏览器验收进一步发现 persona 配置由 `text` 改成了必填 `prefix`;预设使用 YAML 锚点将同一份身份文本提供给两个字段,并以两版实际 Config / apply 验证身份只注册一次。
31
41
 
32
- 构建基线仍是 `0.1.2-rc.1`。兼容声明覆盖精确版本 `0.1.2-rc.1`、`0.1.5-alpha.1`、`0.2.0-rc.2`、`0.2.1-rc.2`、`0.2.1-rc.3`,并分别保留已完成的 Web 客户端验收;`0.1.3-alpha.1`、`0.1.3-alpha.2` 保持未知。这不自动升级用户宿主,也不承诺整个 alpha 或 0.2 范围都兼容。`0.2.23` 已发布到 npm `latest` 与 GitHub Release,完整平台矩阵、源码安装和四份宿主客户端报告见[发布验收](RELEASE_ACCEPTANCE.md#023);本机另复验了 `0.2.1-rc.2` 的安装闸门、客户端激活、预设选择、工作台入口与三页签、DoG 面板及其他插件共存。
42
+ 构建基线仍是 `0.1.2-rc.1`。兼容声明覆盖精确版本 `0.1.2-rc.1`、`0.1.5-alpha.1`、`0.2.0-rc.2`、`0.2.1-rc.2`、`0.2.1-rc.3`、`0.2.1-rc.4`、`0.2.1-rc.5`,并分别保留已完成的 Web 客户端验收;`0.1.3-alpha.1`、`0.1.3-alpha.2` 保持未知。这不自动升级用户宿主,也不承诺整个 alpha 或 0.2 范围都兼容。`0.2.23` 已发布到 npm `latest` 与 GitHub Release,完整平台矩阵、源码安装和四份宿主客户端报告见[发布验收](RELEASE_ACCEPTANCE.md#023);本机另复验了 `0.2.1-rc.2` 的安装闸门、客户端激活、预设选择、工作台入口与三页签及其他插件共存。内置 DoG 引擎已移除(见 README),需要图形化 DoG 验证可自行安装 `@dsh-external/dsh-dog`。
43
+
44
+ `0.2.1-rc.4` 与 `0.2.1-rc.5` 于 0.2.29 候选加入声明:此前 `dsh plugin add dsh-openwrite` 在这两个宿主上直接被版本闸门拒绝([#150](https://github.com/LiPu-jpg/Openwrite/issues/150)/[#151](https://github.com/LiPu-jpg/Openwrite/issues/151)/[#142](https://github.com/LiPu-jpg/Openwrite/issues/142))。两个宿主各用官方 registry 的精确包完成安装闸门、客户端激活、预设选择、工作台三页签及其他插件共存验证,方法与边界见 [#149/#150/#151 修复说明](ISSUES_149_150_151.md)。已发布版本(含 `0.2.28`)不追溯补声明,需要这两个宿主的用户应等 `0.2.29` 正式发布。
33
45
 
34
46
  2026-09-09,从官方 npm Registry 直接安装 `@deepseek-ai/dsh@0.1.5-alpha.1` 时,上游范围依赖选中了正在发布的 alpha.2,其中 `@deepseek-ai/dsh-tool-pwsh-persistent@^0.1.5-alpha.2` 当时缺失,安装失败(ETARGET)。兼容测试使用 npm 的 `--before=2026-09-09T00:00:00Z` 解析 alpha.1 发布时的依赖,并保留解析锁。没有修改官方包源码或用 replacements/overrides 冒充官方组件。此证据仅适用于报告中的宿主依赖图,不代表后续浮动依赖安装也通过。
35
47
 
@@ -0,0 +1,17 @@
1
+ # 正文编辑与审稿选区补修
2
+
3
+ 0.2.28 / Core 5.8.20 已正式发布,见[发布验收](RELEASE_ACCEPTANCE.md)。原先 22 项检查没有覆盖编辑器延迟回调、审稿选区上限与真实 Markdown 序列化;本轮三项均先复现,再修复并增加行为回归。
4
+
5
+ | 缺口 | 修复后行为 | 验证 |
6
+ | --- | --- | --- |
7
+ | 输入后立即保存或离开,最后一段未进入延迟回调 | 首次 DOM 输入立即启用保存;保存、离开和相关操作前同步收集最新正文。切章/切工作区时,只保存到原正文的恢复草稿;明确放弃后不复活旧稿。 | 9 项真实 CreationView/VditorBody 生命周期测试,含首次输入、未 blur 的保存、切工作区/章节、加载失败后重试保护、明确丢弃、未编辑对照。 |
8
+ | “按审稿改这段”扩大到选区外 | 按实际锚点优先选择问题;传递完整原文选区,服务端在生成前验证准确片段、版本和问题范围。问题证据可与选区部分重叠,生成范围始终限定为作者选区。 | 重复句和部分选区,经同步/后台真实 HTTP;重新生成/应用保留上限,选区外问题及不匹配拒绝且零调用。 |
9
+ | Vditor 自动补换行/调整空行后拒绝未编辑的正文 | 加载时记录原文与实际序列化结果,仅对这一对文本支持末尾换行、标题空行和连续换行的范围映射。其余字符、NBSP、后续作者改动、版本变化和不明确边界仍拒绝。 | 真实候选包 Vditor、独立 Studio 编辑器包装、Core 与原生面板映射模块共 9 组浏览器场景;额外 3 项独立 Studio 实际绑定代码测试。 |
10
+
11
+ 正文不会为了通过映射而被静默规范化。批注提示、定位及选区请求使用同一份源范围映射。常规“按所选问题修订”入口不提供 selection 时仍保留原语义;选区入口不能仅凭 original_text 猜重复句位置。
12
+
13
+ `novel_revision_create_from_review` 新增可选 `selection: {start,end,original_text}`,start/end 是保存原文的 Unicode 码点下标,保留原始 CR/LF。传递当前 `expected_document_revision` 与 `expected_review_revision`。旧界面只带 original_text 而没有明确选区时返回 INVALID_SELECTION,请刷新界面重新选择。
14
+
15
+ 本地 Core 1550 passed / 32 skipped,真实 HTTP 14 passed,界面 336 passed,managed 34 passed,完整插件检查通过。Core wheel 的 499 个运行时源文件逐字节一致,163 个应打包 Python 文件无遗漏。原生安装矩阵额外对同一候选 tarball 中的真实 Vditor/独立编辑器和两端映射器运行 9 组场景,结果写入每份原生报告的 editorSerialization 字段。
16
+
17
+ 测试不调用付费模型,不写作者作品或真实 profile。最终跨平台回执见[发布验收](RELEASE_ACCEPTANCE.md)。#123 的宿主正式发布和 Android/Termux 真机验收仍保留,本次发行不将这两项标记完成。
package/docs/INSTALL.md CHANGED
@@ -45,7 +45,7 @@ dsh 对话模型在宿主中配置。小说生成、评审与测试模型在「
45
45
  依赖包要求 Apple Silicon Mac 至少 macOS 14,Intel Mac 至少 macOS 13;
46
46
  其他系统小版本的覆盖范围以 Release 报告为准。
47
47
 
48
- - 插件装在指定 profile。bridge、panel、DoG、技能、编辑器资源和 Core wheel 位于同一包。
48
+ - 插件装在指定 profile。bridge、panel、技能、编辑器资源和 Core wheel 位于同一包。
49
49
  - `$DSH_HOME/openwrite/` 保存下载缓存、Python 环境、管理记录、隔离配置与凭据;未指定 DSH_HOME 时使用 dsh 默认目录。
50
50
  - 作品保存在作者选定目录。受管理 Core 仅监听回环地址,端口自动分配,实例认证只在宿主与 Core 之间传递。
51
51
  - 只启动、停止本插件创建的进程。不修改系统 Python、全局 PATH 或 Shell 配置。
@@ -101,12 +101,52 @@ dsh plugin --profile web remove -w dsh-openwrite
101
101
 
102
102
  ## 自定义预设和高级配置
103
103
 
104
- 自定义预设从官方版本复制,目录 ID 使用 `openwrite-` 前缀以启用创作界面。小说工具行是 `dsh-openwrite/tools`,DoG 工具行是 `dsh-openwrite/dog-tools`;不要再次注册全局 bridge 或 DoG 引擎。工具集合随会话预设保持稳定,不随界面切换。
104
+ 自定义预设从官方版本复制,目录 ID 使用 `openwrite-` 前缀以启用创作界面。小说工具行是 `dsh-openwrite/tools`;不要再次注册全局 bridge。工具集合随会话预设保持稳定,不随界面切换。
105
105
 
106
106
  小说工具支持 `presentation: native`(默认)、`ptc` 或 `both`。只读策略和计划模式独立约束副作用。模型服务商已接收的请求可能无法撤回:取消后停止新调度和重试,保存已完成结果与用量;费用未知时显示未知,不计为零。
107
107
 
108
108
  bridge 的高级 `mode: external` / `baseUrl` 配置继续支持外部 Core,不接管外部进程。默认 `managed` 不需要配置端口。旧显式地址配置仍按外部模式解释。
109
109
 
110
+ ### Bring your own Python
111
+
112
+ 以下配置从 **0.2.29 候选版**提供,尚未发布;0.2.28 及更早版本请使用下节的 external 模式。
113
+
114
+ 已有 Python **3.10 或更高版本**及所需依赖时,可以在当前 profile 的 `cordis.patch.yml`
115
+ 修改已有 `openwrite-bridge` 行的配置:
116
+
117
+ ```yaml
118
+ config:
119
+ mode: managed
120
+ pythonPath: /absolute/path/to/python3
121
+ # 依赖已安装在这个解释器的 site-packages 时,无须此项。
122
+ # Android 手工准备的 pyroot 可显式列出;路径必须是绝对目录。
123
+ pythonModulePaths:
124
+ - /absolute/path/to/pyroot
125
+ ```
126
+
127
+ 也可以在启动 dsh 的进程环境中设置 `OPENWRITE_PYTHON`,值为解释器的绝对路径,不能附带命令参数;
128
+ 显式 `pythonPath` 优先。桌面应用须从继承该变量的环境启动,也可直接使用上面的 profile 配置。
129
+ `pythonModulePaths` 只在选定自备解释器后生效;external 模式继续由作者管理服务端。
130
+
131
+ 此路径不下载 uv 或 python-build-standalone,不执行 pip,也不安装或升级作者的依赖。
132
+ 插件校验随包 Core wheel 后,将其解包到自己的环境目录,使用所选解释器启动这一份 Core,
133
+ 无需作者另外安装相同版本的 `openwrite`。解释器和显式依赖目录加入环境标识,不会误用托管 Python 的缓存。
134
+ 运行时保留 `-I` 隔离和 UTF-8,使用 `-B` 禁止写入依赖目录的字节码;不继承 `PYTHONPATH`,
135
+ 需要额外依赖目录时使用 `pythonModulePaths`。Core 路径排在显式依赖目录之前。
136
+ 共享构建需要的 `LD_LIBRARY_PATH` / `DYLD_LIBRARY_PATH` / `DYLD_FALLBACK_LIBRARY_PATH`
137
+ 在此模式下从宿主传入;应选择可以用 `-I` 正常启动的解释器,不依赖 `PYTHONHOME` 或隐式用户 site。
138
+
139
+ 依赖须与随包 Core 的 wheel `METADATA` 相容,包括 pydantic 及与 Python/系统 ABI 对应的
140
+ pydantic-core、PyYAML、httpx、Markdown-it-py 和需要使用的模型客户端等。
141
+ 桌面 Python 3.12 可在作者自己创建的 venv 中,使用随包的 `release/requirements.lock`
142
+ 与 `release/wheels/` 准备依赖;该锁文件的桌面二进制轮子不能直接套用到 Android Python 3.14。
143
+ Android 的原生依赖由宿主或作者编译、提供,插件不会尝试安装 glibc 轮子来替代 bionic 产物。
144
+
145
+ 每次启动都会在所选解释器中检查 Python 版本、Core 导入和 API 版本;失败给出缺失依赖等诊断,
146
+ 不回退到运行时下载,不替换旧活动记录。健康检查成功后才标记就绪。进程鉴权、随机端口、
147
+ 取消、有限自动重启和卸载清理沿用托管模式;重启不重放写作或其他付费请求。
148
+ 通过启动检查只说明 Studio 启动链可用,各模型及原生依赖功能仍需分别验证。
149
+
110
150
  ### External Studio
111
151
 
112
152
  Android / Termux(bionic)和未列入 runtime manifest 的 ARM Linux 无托管 Python/ONNX 产物。
@@ -127,6 +167,47 @@ config:
127
167
  提供,勿贴入 issue。作品目录必须在 Studio 所在机器上存在,Workspace 路径也须与服务端
128
168
  一致,插件不会同步手机与电脑的文件。重启 dsh 后生效;外部进程由作者管理。
129
169
 
170
+ #### iPhone / iPad
171
+
172
+ iOS 可用浏览器访问电脑托管的 DSH Web 工作台或独立 Studio;电脑保持运行,并提供受信任且有访问控制的网络入口。
173
+ 手机上的 `127.0.0.1` 只访问手机自身,不能沿用电脑的回环地址。本项目没有 iOS 本地 Python 后端。
174
+ 候选 0.2.29 的开发范围、自动回归与待做的真机项目见 [手机验收说明](MOBILE_READINESS.md)。
175
+
176
+ #### Android / Termux
177
+
178
+ 可以连接受信任的电脑,也可以在手机已有 Python 的环境中自行启动 Studio。
179
+ 两者均使用上面的 external 配置,不要求插件下载 Android Python。
180
+ Termux 使用其自身的 Python 包;DSH Mobile 的 Python 扩展应使用该宿主提供的实际解释器路径。
181
+ 不同发行方的路径、Python ABI 和依赖产物不能互换。
182
+
183
+ [#140](https://github.com/LiPu-jpg/Openwrite/issues/140) 的报告者提供了 Android/aarch64/bionic、
184
+ 宿主 Python 3.14.8、pydantic 2.14.1 + 自编译 pydantic-core 2.50.1 的记录:
185
+ 插件 0.2.26 所含 Studio 启动成功,`GET /` 返回 200。
186
+ 这是一份第三方启动验证,不代表 0.2.28 或候选 0.2.29 已通过手机端完整工具验收。
187
+
188
+ 可按以下目录约定准备;命令在解压 Release 后的工作目录执行:
189
+
190
+ 1. 从 `package/release/runtime-manifest.json` 找到 `wheel.file`,用 Python 标准库解压到 `app/`。
191
+ 例如,0.2.28 的 Core 是 `python3 -m zipfile -e package/release/openwrite-5.8.20-py3-none-any.whl app`。
192
+ 2. 在选定 Python 的 site-packages 或独立 `pyroot/` 中准备相容依赖。
193
+ pydantic-core 需要与解释器及 Android ABI 匹配;报告者使用 Rust/clang 本地构建。
194
+ 其他原生依赖也可能需要对应构建,不能将 Linux/glibc 轮子直接改名使用。
195
+ 3. 如果使用独立 `pyroot/`,在手机 shell 中以前台进程启动:
196
+
197
+ ```sh
198
+ PYTHONPATH="$PWD/pyroot:$PWD/app" python3 -m tools.cli studio --port 4567
199
+ ```
200
+
201
+ 4. 确认 `http://127.0.0.1:4567/` 可以打开,再将当前 profile 的已有 bridge 行设为
202
+ `mode: external`、`baseUrl: http://127.0.0.1:4567`。此地址仅适用于 Studio 和 dsh
203
+ 在同一设备的情况;跨设备使用受信任的私网或 SSH 隧道。
204
+ 5. 重启 dsh 后,继续验证 OpenWrite 面板、Workspace 路径绑定、实际文件工具和服务端鉴权。
205
+ `GET /` 返回 200 不能代替这些检查。候选 0.2.29 也可改用上节的自备 Python 模式,
206
+ 把该 `pyroot` 绝对目录放入 `pythonModulePaths`,由插件负责启动和停止。
207
+
208
+ 没有 fastembed/ONNX 等可选语义依赖时,部分检索会降级,不能据此承诺所有模型、
209
+ Embedding 或语义检索功能可用。平台 manifest 仍只列官方托管产物,不宣称提供 Android 原生构建。
210
+
130
211
  ## GitHub 源码安装
131
212
 
132
213
  源码安装使用 dsh 官方 GitHub source 机制:`dsh plugin --profile web add -w github:LiPu-jpg/Openwrite#v0.2.8`。仓库 `prepare` 自行构建三个插件,Core wheel 随固定提交提供,不访问相邻工作区。源码安装需要 Git 和构建依赖;建议普通用户优先使用已验收 Release 包。
@@ -143,12 +224,39 @@ config:
143
224
 
144
225
  反馈请提供宿主版本、系统与架构、Release 版本、安装阶段及脱敏错误。来源、许可证和校验值见 Release 附件及包内 `release/`。不要提交 API Key、浏览器登录 URL 或作品全文。
145
226
 
227
+ ### Stale package selection
228
+
229
+ 如果宿主是 `0.2.1-rc.3`,错误却显示 `dsh-openwrite@0.2.25` 不兼容,先确认实际选择的包版本。
230
+ 0.2.25 未声明该宿主;0.2.26 起根包和全部内嵌子包已声明精确支持,0.2.28 继续包含对应验收。
231
+ 不要给旧包添加版本豁免来掩盖取包问题。
232
+
233
+ ```sh
234
+ npm view dsh-openwrite@latest version peerDependencies --registry=https://registry.npmjs.org
235
+ ```
236
+
237
+ 对照当前 profile 的 `package.json`、`pnpm-lock.yaml` 和已安装包的 `package.json`。
238
+ 不带版本的 `add dsh-openwrite` 可能沿用已有精确依赖;显式 `@latest` 或精确版本才清楚表达升级意图。
239
+ 商城显示的目录版本也不能替代 npm 实际解析结果。仅凭 #142 的报错不能确定用户侧是哪份锁或缓存。
240
+
241
+ 完全退出 dsh/Desktop(含托盘)、备份 profile 后,优先使用已验收 Release 包的停机升级工具:
242
+
243
+ ```sh
244
+ node package/scripts/safe-upgrade.mjs --profile desktop --package dsh-openwrite@0.2.28
245
+ ```
246
+
247
+ 该例固定到已发布的 0.2.28;更新版本须先确认其验收结果。源码安装、tarball 和自定义 registry
248
+ 按各自来源排查,不直接清空整个 pnpm store 或删除 profile。停机升级工具失败会保留旧环境与日志。
249
+ 0.2.29 候选的 `maintenance.mjs doctor --profile desktop` 会另外显示请求 spec、实际已装版本及诊断工具版本,
250
+ 其停机升级工具也会把裸包名规范成 `dsh-openwrite@latest`;指定精确版本和本地 tarball 不受影响。
251
+
146
252
  ## dsh 0.2 客户端兼容排查
147
253
 
148
254
  `dsh-openwrite@0.2.10` 的旧工作台按 0.1 接口构建,不能通过版本豁免获得 0.2.0-rc.2 的客户端兼容性。根包豁免不覆盖内嵌子包:`@dsh-novel/studio-panel@<ver>`、`@dsh-external/dsh-dog@<ver>` 各自经过宿主版本检查。优先升级到包含 #45 修复的包;修复后的精确 `0.2.0-rc.2` 声明覆盖根包和所有子包,不需要手工编辑 `compatibility.json`。
149
255
 
150
256
  `dsh-openwrite@0.2.23` 起,根包和全部内嵌子包的声明同时覆盖精确宿主 `0.2.1-rc.2`,安装和激活不需要版本豁免。宿主判断的是 `package.json` 的 `peerDependencies`(`@deepseek-ai/dsh-*`),不是 `dsh.compatibility` 字段;因此只改 `dsh.compatibility` 字符串并不能让 0.2.22 在 0.2.1-rc.2 上加载。若安装日志出现 `plugin does not support the DSH version in use`,请直接升级到 `0.2.23` 或更高的已验收版本,不要手工改版本号或给旧子包授权。本版已在 `0.2.1-rc.2` 完成 Web 启动、OpenWrite 入口、工作台三页签、DoG 面板与其他插件共存的验证;`0.1.2-rc.1`、`0.2.0-rc.2` 回归通过,Windows Electron 桌面端仍未实机复测。
151
257
 
258
+ `0.2.29` 候选起,声明同时覆盖精确宿主 `0.2.1-rc.4` 与 `0.2.1-rc.5`;这两个宿主上 `0.2.28` 及更早版本会被同一闸门拒绝([#150](https://github.com/LiPu-jpg/Openwrite/issues/150)/[#151](https://github.com/LiPu-jpg/Openwrite/issues/151)/[#142](https://github.com/LiPu-jpg/Openwrite/issues/142))。已发布版本不追溯补声明,遇到该错误请升级到声明覆盖该宿主的版本,方法与边界见 [#149/#150/#151 修复说明](ISSUES_149_150_151.md)。
259
+
152
260
  本修复同时处理 `conversation.chat.turnTail` 从 chain 到 list 的变化,以及 `uiSession.pendingInteractions` 到 `uiSession.sessionStatus` 的变化。客户端初始化或延迟槽位注册失败时,插件回滚对应注册并在浏览器控制台输出 `[OpenWrite/Studio]` / `[OpenWrite/DoG]` 和原始异常,避免让这类插件初始化异常升级为宿主 web boot 失败。此修复不更改桌面端自身的 profile 恢复策略。
153
261
 
154
262
  如果旧版本已经触发桌面端恢复,关闭桌面端后备份整个 profile,找到恢复前的 `cordis.patch.yml.bak-*`,恢复 patch 和原 `package.json` 中的 `dsh.profile.bundles`。这两项需一起核对,才能重新加载其他插件。保留已安装依赖和作品目录,不要用空 profile 替换完整配置。
@@ -162,7 +270,7 @@ node scripts/client-boot-smoke.mjs --host-cli=/absolute/path/to/dsh-0.2.0-rc.2/n
162
270
  node scripts/client-boot-smoke.mjs dsh-openwrite-<version>.tgz --host-cli=/absolute/path/to/dsh-0.2.1-rc.2/node_modules/@deepseek-ai/dsh/lib/bin.js
163
271
  ```
164
272
 
165
- 脚本需要 Playwright Chromium,创建临时 Web profile,检查无豁免版本闸门、两个客户端加载、真实预设选择、会话导航、三个工作台页签出现和创作视图激活、DoG 面板及其他插件共存,后端就绪与未初始化响应由测试夹具提供,不准备 Python 环境、不调用模型;实际安装与后端动作由独立发布验收覆盖。它验证 Web 客户端兼容性;Windows Electron 的原生启动和恢复流程仍须在对应平台完成发布验收。
273
+ 脚本需要 Playwright Chromium,创建临时 Web profile,检查无豁免版本闸门、客户端加载、真实预设选择、会话导航、三个工作台页签出现和创作视图激活、预设选择器不出现重复别名及其他插件共存,后端就绪与未初始化响应由测试夹具提供,不准备 Python 环境、不调用模型;实际安装与后端动作由独立发布验收覆盖。它验证 Web 客户端兼容性;Windows Electron 的原生启动和恢复流程仍须在对应平台完成发布验收。
166
274
 
167
275
  ## 0.2.12 的预设与审读修复
168
276
 
@@ -172,6 +280,6 @@ node scripts/client-boot-smoke.mjs dsh-openwrite-<version>.tgz --host-cli=/absol
172
280
 
173
281
  ## 作品信息与推理模型预算
174
282
 
175
- 在「任务 → 导入与导出 → 编辑作品信息」填写或修改书名、作者署名和语言。旧作品也可补齐作者,无需手工编辑配置文件。保存冲突时保留输入;请取消编辑并重新载入最新信息后再修改。未填写作者仍不能进行交付导出。`novel_project_init` 也支持可选 `author` 与 `language`。
283
+ 在「任务 → 导入与导出 → 编辑作品信息」填写或修改书名、作者署名和语言。旧作品也可补齐作者,无需手工编辑配置文件。保存冲突时保留输入;请取消编辑并重新载入最新信息后再修改。未填写作者仍不能进行交付导出。`novel_project(action="init")` 也支持可选 `author` 与 `language`。
176
284
 
177
285
  写章、事实提取和状态结算(包括重试)统一使用「任务 → 模型」中所选模型的输出 token 预算,不再在非创作阶段偷偷降到 4096/8192。推理模型的隐藏推理通常也占用输出额度:若仍出现截断,请在服务商允许的范围内提高所选模型的输出预算(例如 32768 或 49152),同时核对上下文窗口。正文目标字数与 token 预算是两回事;较高上限不等于一定消耗该数量,也不能保证所有模型都支持它。此次验证使用模型替身,未进行真实模型计费测试。
@@ -0,0 +1,97 @@
1
+ # #121–#123 与 #128 修复验证记录(已合并,随 0.2.28 发布)
2
+
3
+ 本轮按“先修能修的”处理。以下代码已包含于正式 0.2.28(最终 Core 5.8.20);下方早期 Core 5.8.17 产物与验证记录保留为形成过程证据,未单独发行。
4
+ 没有原始复现、没有设备或仍依赖上游的项目继续保留,不能用自动测试代替这些证据。
5
+
6
+ ## 修复范围
7
+
8
+ | 报告条目 | 开发分支中的变更 | 验证方式 |
9
+ | --- | --- | --- |
10
+ | #121 B-18 | JavaScript 验收脚本使用 Electron 的 Node 子进程模式;不再把脚本交给桌面应用模式运行。 | 真实 Electron 44.7.0 执行 ESM;旧实现失败、修复后通过;追加 Linux/macOS/Windows CI。 |
11
+ | B-19 | 区分脚本缺失、启动失败、非零退出、超时、输出超限和输出格式错误;保留退出码、stderr 尾部及前 200 字节完整 UTF-8 输出。 | 真实子进程成功、退出 3、错误输出、缺失文件和取消回归。 |
12
+ | B-20 / #122 F-10 | 生成前被阻止的请求也留下失败运行;保留每次运行的错误。已取消/失败的历史记录不再被后续验收改成运行中。删除章节后的运行继续存在于归档,可显式列出并定位原始产物。 | 三次被阻止的请求留下三份 V1/V2 记录;删除归档后的历史与原始字节读取;取消后再次写作不改写旧运行。 |
13
+ | B-21 / F-13 | 返回结构化 `delivery_diagnostics`,列出未定论检查、未评范围、服务商错误和实际未提供的上下文字段。保留兼容的字符串 `delivery_reason`。不从“正典检查未定论”直接推断一定缺结算;降级后的总分为 null,并给 `score_valid`。 | 正典与部分审稿诊断、评分有效性、持久化和 DoG 消费回归。 |
14
+ | B-23 | 区分流水线执行完成、作者确认和 DoG 交付判定;工作流页提示“审稿执行完成”不代表交付通过。 | 下方映射表;工作流组件回归。 |
15
+ | B-24 | 分别返回 Agent 会话缺失、plan 模式、沙盘策略服务不可用、只读沙盘的具体代码与恢复提示。只读 DoG 查询继续可用。 | 四类拒绝条件及只读放行回归。 |
16
+ | B-25 / F-12 | 工作流页展示作者确认的工具入口、参数及核对顺序;不自动代替作者确认,也不把确认当成补跑结算。 | 组件显示确认提示与执行/交付区别。 |
17
+ | #122 F-01 | 现有异步写作/取消接口接上请求内模型取消;流式接收时检查取消并关闭流,停止后续模型请求。每段更新草稿,而非只保留第一段;恢复部分草稿创建新运行,核对上下文、源文件和项目配置。 | 流关闭及部分正文保留;取消→拒绝变化后的输入且零新增调用→恢复原输入续写→分阶段提交;旧取消记录保持不变。 |
18
+ | F-02 | 每次写作模型请求记录阶段、分段号、重试次数、reasoning token、用量及提供方成本。V2 的 draft/fact_extract/settle 分别保存自己的用量;失败请求和部分稿保留用量记录。 | 分段与失败调用账本、reasoning 明细相加、阶段用量归属、提供方零费用和缺失费用回归。 |
19
+ | F-03 | 项目可选择上一章全文、结尾字符或已核对的章节摘要;摘要缺失/过期会明确报错。 | 两层上下文组装与实际 writer 预览一致。 |
20
+ | F-04 | `novel_review_chapter` 增加 `depth=quick/full` 和域选择。quick 审 coherence/canon/prose 与 safety;已选范围单独报告分数与结论,不冒充完整交付批准。 | 参数透传、非法范围拒绝、部分范围全通过而整章仍未批准。 |
21
+ | F-05 | manifest 按文档记录原始/组装字符数及 compressed/excluded,包含 craft 文档。 | 预算压力下逐份字符数与实际组装文本一致。 |
22
+ | F-06 | `novel_write_chapter(dry_run=true)` 组装所选模型档案下的 writer 输入,包含传入的 guidance/target_words 与文档尺寸,不创建写作任务。 | 工具→HTTP 路由参数测试;Studio dry-run 不调用 writer。 |
23
+ | F-07 | `outline_extra_keys` 允许登记章级扩展字段,解析、缓存、受保护的章节要求和 writer 大纲均保留;未登记字段有解析诊断及警告。 | 大纲源→缓存→双层上下文→writer 预览回归。 |
24
+ | F-09 | 同一来源对同一组章节、同一正文版本重复接纳复用操作,不重复失效化。不同来源(例如历史恢复)仍保留独立操作语义。 | 重复请求无额外写入;正文变化生成新操作;历史恢复既有回归。 |
25
+ | F-11 | 单章和批量工具均明确异步返回 task_id;单章可取消,连续写作以批次任务查询进度。 | 工具描述、任务接口与取消回归;不另造重复的异步入口。 |
26
+ | #128 D-01 / D-02 | 新增作者可查的 [95 项工具参考](TOOLS.md) 与 [上下文槽位参考](CONTEXT_SLOTS.md),README 提供入口。工具参数从注册定义生成;槽位、来源、保护规则和默认配额从固定 Core 源码生成。进阶体系 YAML 实际进入设定上下文,参与原有预算与逐文档用量。 | 95 个运行时注册名称与说明逐项一致;20 个来源条目覆盖,生成物漂移检查纳入 CI;创建真实结构化进阶资产后,验证普通及无 world/ 目录的装配、writer 输入、来源与文档尺寸。 |
27
+
28
+ 成本仅在提供方明确报告时视为已知。`cost_summary.reported_usd` 是已报告部分,`complete=false` 表示存在未知费用;未知值不会伪装成零,也不会把估算当作账单。
29
+ 取消是协作式操作:`requested` 与 `cancelled` 分开,等待提供方响应时不承诺瞬间停止计费;已收到的流内容与已完成段落会保留,后续请求不再调度。
30
+
31
+ CI 额外发现并修复归档路径缺陷:排除规则只判断作品内部相对路径,父目录或作品 ID 为 `tmp`、`cache`、`secrets` 或 `exports` 不会再误删大纲等必需内容。四种父目录及四种作品 ID、内部凭据/缓存排除与正文逐字节恢复均有回归。
32
+
33
+ 真实 OpenCode Go 取消测试发现 LiteLLM 的同步包装流没有 `close()`,原清理逻辑未关闭它持有的 HTTP 流。现在取消和流式总时限耗尽时,沿包装流找到本次请求拥有的底层连接并关闭,不关闭共享客户端。直接流和包装流的取消、包装流超时均有回归;真实 Go 测试只有一次服务商请求,取消后已收到的正文保留、HTTP 响应确认关闭,后续请求在调用服务商前被拒绝,`~/my_novel` 文件未改变。实测源码的文件哈希与冻结 Core 提交核对一致。
34
+
35
+ Windows 全量 CI 又暴露 12 个失败。任务快照读取与写入互斥,并对 Windows 共享冲突做有限重试;正文搜索、工作台、接纳、审稿和历史使用原始 UTF-8 字节计算版本,结构化预览/应用/撤销和场景失败回滚保留行尾。大纲新增内容跟随原有 LF/CRLF。研究进程使用跨平台输出读取和进程树取消,Windows pnpm 脚本通过 Node 入口执行;测试中的 `/bin/echo` 改为真实 Python 子进程。POSIX 权限位断言只适用于 POSIX,凭据不出现在接口的断言在每种系统都运行。新增 20 项专门回归,另将搜索与场景回滚的既有测试扩为 LF/CRLF 两种输入。
36
+
37
+ 字节版本已同步到章节记忆、角色状态索引、导出预检及相关文档接口;搜索检索仍使用规范化行文本,来源版本则保持与原文件一致。旧历史记录缺少格式标记时,兼容其当年的行尾规范化校验,只返回其校验值所代表的文本,不改写旧产物。新记录标为 `source_revision_format=utf8-bytes`,行尾改变也会触发完整性错误。
38
+
39
+ DSH rc.3 的依赖安装时间固定为发布日之后的 `2026-10-24T00:00:00Z`。原来的未来时间边界会让上游正在发布的一批依赖进入验收,已出现依赖声明早于实际包发布六秒的安装失败;历史依赖图已在 npm 官方 registry 成功解析,最终仍以完整宿主验收为准。
40
+
41
+ 安装回归还发现自动恢复的进度更新会清空上一次后端崩溃原因;现在恢复期间保留该诊断,直到进入 ready 或结束恢复。回归会在新后端启动的边界核对诊断,避免靠观察时机碰巧通过。源码校验从固定 Git 提交归档还原字节并关闭行尾转换,再逐文件比较 wheel;CRLF 检出副本已验证可还原匹配,存在本地改动时拒绝覆盖。
42
+
43
+ 任务快照读取只在文件句柄打开期间互斥,YAML 解析在锁外进行,避免观察进度阻塞后台写入。阻塞解析的并发回归在旧实现失败、修复后通过。异步功能测试允许慢速磁盘下的有限等待,降低轮询频率;错误终态立即失败,超时附最后状态,不把超时或失败任务视为成功。
44
+
45
+ ## 使用补充
46
+
47
+ 项目 `novel_config.yaml` 可配置:
48
+
49
+ ```yaml
50
+ previous_chapter_mode: tail # full / tail / summary,默认 full
51
+ previous_chapter_tail_chars: 800
52
+ outline_extra_keys:
53
+ - 故事线
54
+ - 视角人物
55
+ ```
56
+
57
+ 在章纲中按 `> 故事线: 雨钥线` 填写扩展字段。summary 模式要求上一章有与当前正文匹配的有效章节记忆;不能用过期摘要继续写作。
58
+
59
+ 只组装不生成:`novel_write_chapter {chapter_id, dry_run:true, guidance, target_words}`。
60
+ 普通写作立即返回 task_id,用 `novel_task_get` 查询,用 `novel_task_cancel` 请求取消。
61
+ 取消后使用 `resume_from_draft:true` 续写最近可用的部分稿;原上下文或源文件变动时会拒绝自动续写,需先检查草稿。
62
+ 新运行通过 `resumed_from_run_id` 指向旧运行,费用记录分别保留。
63
+
64
+ 历史运行:`novel_chapter_run_action {action:"list", chapter_id, include_archived:true}`。
65
+ 删除章节会把原运行及产物移动到 `data/chapter_deletions/<operation>/`,不会删除这些历史;返回的 `archive_directory` 和 artifact 指向归档位置。
66
+ 当前没有自动清除运行的保留策略。列表默认 20 条、最多 200 条,可按章节和时间筛选;这不是磁盘保留上限。
67
+
68
+ ## 三套阶段的对应关系
69
+
70
+ | 语义 | Chapter Run V2 | 工作流页 | DoG 交付图 |
71
+ | --- | --- | --- | --- |
72
+ | 输入准备 | context / plan | context_assembly | writing 的上游依据 |
73
+ | 草稿生成、事实提取和入库 | draft / fact_extract / settle / validate / commit | writing | writing 检查已入库正文及版本 |
74
+ | 执行一次模型审稿 | review(completed 只表示调用与保存完成) | review | review 检查当前正文对应的审稿结论 |
75
+ | 作者核对验收影响 | 验收台账中的 acknowledge | user_confirm | closure 的交付依据之一 |
76
+ | 文风/压缩诊断 | 上下文与写作产物 | styling / compression | 不直接等于交付通过 |
77
+ | 修订到最终交付 | 修订记录与再次审稿 | 不由单个绿色步骤代表 | revision / application / rereview / closure |
78
+
79
+ `gate_status` 表示硬门禁,`delivery_status` 表示完整交付结论;硬门禁通过仍可能因未评范围、证据不足或质量不足而不能交付。
80
+ 部分审稿使用 `scope_status=partial`、`scope_quality_score`、`scope_passed` 和 `unreviewed_dimensions`;完整章总分保持 null,完整交付仍需全范围检查。
81
+
82
+ ## 验证边界和发布限制
83
+
84
+ 冻结 Core 提交本地全量 1531 passed / 32 skipped,包含新增 20 项定向回归;DoG 64 项(含真实 macOS Electron 二进制)、界面 310 项组件、两项真实 HTTP 路由回归通过。最终 22 项 CI 全部成功,Linux/macOS/Windows 各 1531 passed / 32 skipped、HTTP 各 2 passed、真实 Electron 各 5 passed;32 项为缺失旧样例的既有跳过。修复 PR #126/#127 已合并,最终源码、产物哈希和报告范围见 [候选验收记录](RELEASE_ACCEPTANCE.md#0228-候选未发布)。
85
+
86
+ 本轮 Go 快速审稿先遇到本机 CLI 凭据读取错误,排查后四次流式请求成功、无服务商错误;所选范围通过,整章交付仍按部分审稿保持未定论,作品文件未改变。提供方未返回 token/费用明细,不将零占位计为已知账单。该实测发生于 `61c3f68`,之后完善审稿诊断与 Windows 文件处理,模型请求协议未改动。另一次 Go 取消验收使用的流处理模块与最终冻结提交逐文件哈希一致,已确认 HTTP 连接关闭。
87
+
88
+ #121/#122 的报告条目已修复、验收并合并,现已关闭。代码已随 0.2.28 发行;以下原场景验证与外部依赖继续独立跟踪。
89
+
90
+ [#123](https://github.com/LiPu-jpg/Openwrite/issues/123) 继续跟踪:
91
+
92
+ - #98.1 宿主原生升级补丁正式发布,仍取决于上游;插件停机绕行工具不等于宿主已修。
93
+ - #105 已由报告者补充 Windows Electron 旧会话恢复成功的[实机证据](https://github.com/LiPu-jpg/Openwrite/issues/123#issuecomment-6422870871),本项验收完成。
94
+ - #109 B-13 已由报告者确认行中 `>` 与混合行尾锚点的 [Windows 实测通过](https://github.com/LiPu-jpg/Openwrite/issues/123#issuecomment-6423904648),本项验收完成。
95
+ - #111 Android/Termux 真机及外部 Studio 验收;没有 Android 原生运行时。
96
+
97
+ 此前缺少材料时保留四项;报告者新回复已补齐其中两项,现只保留宿主正式发布及 Android/Termux 实机两项。回复中新发现的代码问题另见 [补修记录](ISSUE_123_FOLLOWUP.md),本阶段候选未单独发行,代码已纳入正式 0.2.28(最终 Core 5.8.20)。