@mokuyoaxis/dsh-iris 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/README.en.md +72 -15
  3. package/README.md +72 -15
  4. package/bin/dsh-iris.js +392 -13
  5. package/docs/AGENT_QUICKSTART.md +35 -0
  6. package/docs/ARCHITECTURE.md +80 -64
  7. package/docs/ARTIFACT_MANIFEST.md +60 -0
  8. package/docs/CORE_RUNTIME_CONTRACT.md +83 -0
  9. package/docs/DSH_CORE_MIGRATION.md +106 -0
  10. package/docs/DSH_RC2_ADAPTATION.md +36 -0
  11. package/docs/HEADLESS_CLI.md +217 -0
  12. package/docs/HOST_ADAPTER_CONTRACT.md +31 -12
  13. package/docs/HOST_DOCTOR.md +2 -0
  14. package/docs/MODEL_PORT_CONTRACT.md +300 -0
  15. package/docs/PROVIDER_ADAPTER_CONTRACT.md +51 -10
  16. package/docs/PROVIDER_RUNTIME_HARNESS.md +33 -0
  17. package/docs/PROVIDER_SUBMISSION_CONTRACT.md +1 -1
  18. package/docs/ROADMAP.md +42 -86
  19. package/docs/SECURITY.md +4 -3
  20. package/docs/assets/logo/README.md +55 -0
  21. package/docs/assets/logo/iris-bubble-concept.svg +67 -0
  22. package/docs/assets/logo/iris-bubble.svg +14 -0
  23. package/docs/assets/logo/iris-interim-flower.png +0 -0
  24. package/docs/assets/logo/iris-logo-mono-inverse.svg +78 -0
  25. package/docs/assets/logo/iris-logo-mono.svg +78 -0
  26. package/docs/assets/logo/iris-logo.svg +78 -0
  27. package/docs/assets/logo/iris-mark-mono-inverse.svg +42 -0
  28. package/docs/assets/logo/iris-mark-mono.svg +42 -0
  29. package/docs/assets/logo/iris-mark.svg +42 -0
  30. package/docs/releases/0.2.0.md +48 -0
  31. package/lib/actions.js +374 -362
  32. package/lib/adapters.js +52 -15
  33. package/lib/api.js +152 -5
  34. package/lib/client.js +763 -48
  35. package/lib/command-service.js +420 -0
  36. package/lib/config.js +56 -43
  37. package/lib/core-artifact-store.js +598 -0
  38. package/lib/core-artifacts.js +4 -0
  39. package/lib/core-attention.js +103 -0
  40. package/lib/core-contract.js +105 -0
  41. package/lib/core-doctor.js +41 -0
  42. package/lib/core-lease-recovery.js +170 -0
  43. package/lib/core-runtime.js +232 -0
  44. package/lib/core-tasks.js +560 -0
  45. package/lib/core-user-projection.js +192 -0
  46. package/lib/doctor.js +92 -33
  47. package/lib/dsh-core-adapter.js +599 -0
  48. package/lib/dsh-host-adapter.js +58 -7
  49. package/lib/generation-input.js +95 -0
  50. package/lib/guard.js +3 -3
  51. package/lib/index.js +159 -54
  52. package/lib/model-invoker.js +218 -0
  53. package/lib/model-port-contract.js +333 -0
  54. package/lib/models.js +97 -11
  55. package/lib/provider-adapter.js +49 -23
  56. package/lib/provider-adapters.js +84 -21
  57. package/lib/provider-catalog.js +171 -0
  58. package/lib/provider-contract.js +72 -3
  59. package/lib/provider-protocol.js +51 -2
  60. package/lib/provider-task-runner.js +328 -0
  61. package/lib/tasks.js +16 -4
  62. package/lib/vision.js +28 -7
  63. package/package.json +8 -8
  64. package/user_guide.md +27 -12
@@ -1,95 +1,111 @@
1
1
  # Iris 架构与边界
2
2
 
3
- 状态:v0.1.3 已发布实现;v0.1.4 已冻结 Host Adapter v0 契约,提供 test-only Local Host consumer,完成 DSH Adapter 消费者迁移与真实 DSH 隔离 canary,并实现 Provider Adapter v0 完整生命周期与 Host Doctor。
3
+ 状态:Iris `0.2.0` 提供可在无 DSH 进程中运行的实例化 Core Runtime、Headless CLI、共享 Provider 生命周期、Core Task/Attempt 与 Artifact Manifest,并让 DSH 逐项消费同一套事实。DSH 插件仅支持 `0.2.0-rc.2`,Node.js 最低为 22.0.0;旧宿主固定使用 npm `0.1.4`。Core 内部 API 尚未冻结为公共 SDK。
4
4
 
5
5
  ## 当前形态
6
6
 
7
- Iris 目前以 DeepSeek Harness 插件运行。DSH 提供 Agent 工具注册、会话附件、浏览器和 Web UI 插槽;Iris 自己负责供应商配置、媒体动作、可信任务、产物落盘、媒体授权路由和工作台投影。
7
+ Iris 仍以一个 npm 包交付,但已有两个执行入口:DSH 插件负责 Agent 工具、会话附件、浏览器、Web UI 和后台观察;Headless CLI 在没有 DSH/Cordis 的进程中显式接收数据根与私有 Provider 配置。两者共用 Core Runtime、Provider Task Runner、Task/Artifact Store 和本地 Command,不能在同一数据根上同时充当写者。
8
8
 
9
9
  ```text
10
- DSH Host / Cordis
11
- ├─ Agent tools ───────────────┐
12
- ├─ Web slots / browser │
13
- └─ attachment/session ports │
14
- ▼
15
- dsh-host-adapter.js
16
- (能力探测 / DTO / 生命周期)
17
- │ Host Adapter v0
18
- ▼
19
- actions.runAction
20
- ├─ provider adapters
21
- ├─ Task / Attempt v2
22
- ├─ media delivery
23
- └─ vision / local media tools
24
- │
25
- ▼
26
- $DSH_HOME/iris/v1
27
- providers.json · tasks.json
28
- artifacts.json · outputs/ · uploads/
10
+ DSH Host / Cordis Headless CLI
11
+ ├─ Agent tools / Web UI ├─ explicit --data-root
12
+ ├─ attachment / browser ports └─ private provider config
13
+ └─ bounded observation timers │
14
+ │ │
15
+ dsh-host-adapter.js bin/dsh-iris.js
16
+ │ │
17
+ dsh-core-adapter.js ────────────────┬───────────┘
18
+ ▼
19
+ Core Runtime v0
20
+ explicit root · reader/writer
21
+ lease · AbortSignal · disposal
22
+ ┌────────────┴────────────┐
23
+ ▼ ▼
24
+ Command Service v0 Provider Task Runner
25
+ crop / diff / frames submit / observe /
26
+ inspect / control cancel / delivery
27
+ └────────────┬────────────┘
28
+ ▼
29
+ Core Task Store + Artifact Manifest
30
+ records · objects · SHA-256 · index
31
+ │
32
+ DSH: $DSH_HOME/iris/v1/core-v0
33
+ CLI: explicit absolute data root
29
34
  ```
30
35
 
31
- `lib/index.js` 是 DSH 插件入口,`lib/dsh-host-adapter.js` 是服务端 DSH/Cordis 对象进入 Iris 的唯一映射边界;`lib/client.js` 内部用最小 client slot adapter 隔离 DSH UI Slot。`lib/api.js` 是工作台 HTTP 投影,不是真相来源。Task 的持久事实由 `lib/tasks.js` 管理。
36
+ `lib/index.js` 是 DSH 插件装配入口,`lib/dsh-host-adapter.js` 是原始 DSH/Cordis 对象进入 Iris 的服务端边界;`lib/dsh-core-adapter.js` 只负责选择 DSH profile 的 Core 数据根、恢复 Provider 配置和投影 Host DTO。`bin/dsh-iris.js` 不启动 DSH,也不推断 profile。`lib/api.js` 与 `lib/client.js` 是 Host 投影,不是真相来源。
32
37
 
33
- ## 已稳定的核心候选
38
+ 未迁移能力仍走 0.1.4 legacy 链。当前主要包括 s2v 数字人视频、视觉理解、长图 OCR、媒体摘要、HTML 渲染和提示词优化;它们不会被伪装成 Core 能力。
39
+
40
+ ## 0.2.0 核心
34
41
 
35
42
  | 模块 | 职责 | DSH 运行时依赖 |
36
43
  |---|---|---:|
37
- | `task-semantics.js` | Task v2 枚举、旧状态与用户状态派生、自洽校验 | 无 |
38
- | `provider-contract.js` | 提交结果、受理边界、错误脱敏、候选调度 | 无 |
39
- | `provider-adapter.js` | Provider v0 生命周期、canonical 结果与统一调用边界 | 无 |
40
- | `provider-adapters.js` | DashScope / OpenAI Images 协议到 v0 的映射 | 无 |
41
- | `tasks.js` | Task/Attempt 持久化、观察、恢复与交付状态 | 无;数据根仍沿用 `DSH_HOME` |
42
- | `artifacts.js` | 作品库 v0 的最小索引、分页、重建、删除与独立媒体授权 | 无;数据根仍沿用 `DSH_HOME` |
43
- | `doctor.js` | 共用诊断结果模型;离线检查环境/数据,Host 模式检查安全能力快照与注册证据 | 无 |
44
- | `host-runtime.js` | 服务端成功注册账本与受限浏览器握手;不保存 live object | 无 |
45
- | `actions.js` | GUI 与 Agent 共用动作 | 只接收 Host Adapter;部分动作声明 Browser/会话端口 |
46
- | `dsh-host-adapter.js` | DSH capability detection、DTO 与生命周期映射 | 有;唯一服务端 DSH 运行时映射边界 |
47
- | `index.js` | DSH 工具、路由、Skill 与生命周期注册 | 有 |
48
- | `client.js` | DSH Web Slot、工作台、泡泡和提示词入口 | 有 |
49
-
50
- 0.1.3 没有完整独立 Core 或 Local Host Adapter。0.1.4 先冻结并验证最小 Host Port、Local Host fixture 和 DSH capability detection;完整 Command Service 与非 DSH Provider 执行入口仍属于 0.2.0。
44
+ | `core-contract.js` / `core-runtime.js` | 显式数据根、reader/writer 权限、单写者租约、取消与释放 | 无 |
45
+ | `command-service.js` | 本地媒体命令、Task 控制面和 Artifact 查询/导出 | 无 |
46
+ | `generation-input.js` | CLI、DSH 与重试共用的生成参数校验和 Provider 字段转换 | 无 |
47
+ | `model-port-contract.js` / `model-invoker.js` | Text/Vision 内部契约、有限调用预算与取消;真实消费者尚未接入 | 无 |
48
+ | `core-tasks.js` | Core Task/Attempt 持久事实、受理与交付状态 | 无 |
49
+ | `core-artifacts.js` / `core-artifact-store.js` | 对象、Manifest、SHA-256、关系边与可重建 Index | 无 |
50
+ | `provider-contract.js` / `provider-adapter.js` | canonical 结果、错误脱敏、受理边界与 Provider v0 操作 | 无 |
51
+ | `provider-adapters.js` | DashScope / OpenAI Images 协议实现和可选输入准备 | 无 |
52
+ | `provider-task-runner.js` | 写前 Attempt、submit/poll/cancel/download 与 Profile 化交付 | 无 |
53
+ | `core-doctor.js` / `core-lease-recovery.js` | 只读完整性诊断与需显式确认的陈旧租约恢复 | 无 |
54
+ | `provider-catalog.js` | 显式 Provider 配置、能力候选和原 Task Adapter 恢复 | 无 |
55
+ | `dsh-core-adapter.js` | DSH 数据根、后台观察与 Core 到 Host 的投影 | 有;DSH 专属边界 |
56
+ | `dsh-host-adapter.js` / `index.js` | Host 能力映射、工具/路由/Skill 与生命周期装配 | 有 |
57
+ | `client.js` | DSH Web Slot、统一任务/作品区、泡泡和提示词入口 | 有 |
58
+
59
+ 完整规则见 [Core Runtime v0](CORE_RUNTIME_CONTRACT.md)、[Artifact Manifest v0](ARTIFACT_MANIFEST.md)、[Provider Adapter v0](PROVIDER_ADAPTER_CONTRACT.md) 与 [DSH → Core 渐进迁移](DSH_CORE_MIGRATION.md)。这些是 rc 候选内部契约,不是第三方 SDK 兼容承诺。
51
60
 
52
61
  ## Task、Attempt 与 Artifact
53
62
 
54
- - 一个用户意图对应一个 Task;每个候选供应商调用对应一个稳定 Attempt。
55
- - Attempt 必须在可能发送计费请求前落盘。只有明确 `not_accepted` 才允许自动 failover。
56
- - 生成结果与本地交付是两类事实。生成成功后下载失败仍保持 `outcome=succeeded`。
57
- - 0.1.4 增加独立作品库 v0:`artifacts.json` 只保存文件、类型、大小、时间和随机令牌,因此清任务历史后仍可浏览作品;它不保存 Prompt、Provider、Model 或任务关系。
58
- - 正式 Artifact Manifest、内容哈希、谱系、收藏、标签和搜索仍属于 0.2.0+;作品库 v0 不是该公共契约。
59
- - 每次 v2 任务变更递增 Task `revision`;完整状态快照另带进程 `stateEpoch/stateRevision`,客户端拒绝同一 epoch 中迟到的旧快照。
63
+ - 一个用户意图对应一个 Core Task;每次候选供应商调用对应一个稳定 Attempt。Attempt 必须在可能发送计费请求前落盘。
64
+ - 只有明确 `not_accepted` 才允许自动切换候选;`accepted` 或 `unknown` 后禁止自动重提。重试会创建新 Task,并要求用户再次提供未持久化的输入和明确确认潜在费用。
65
+ - 生成结果与本地交付是两类事实。远端成功后下载失败仍保持 `outcome=succeeded / deliveryState=failed`,可显式重新交付而不重新生成。
66
+ - 新 Attempt 可选保存阶段时间戳与模型选择来源;旧记录缺少这些字段仍可读取。
67
+ - Artifact Manifest v0 保存内容哈希、媒体类型、中性元数据和关系边;不保存 Prompt、API Key、签名 URL、Provider 端点或宿主绝对路径。
68
+ - Core Task/Artifact 的删除与清理能力在 0.2.0 中保持封闭:DSH 与 CLI 都不提供 delete、clear 或 orphan purge。Doctor 只报告,不自动修复。
60
69
 
61
- 详细状态机见 [Task/Attempt v2 语义契约](TASK_SEMANTICS.md),故障证据见 [故障注入矩阵](FAULT_INJECTION.md)。
70
+ 0.1.4 的 `tasks.json`、`artifacts.json`、`outputs/` 与上传目录继续作为 legacy 数据存在;Core 使用隔离的 `core-v0`。已迁移的新图片、视频、TTS 与转写任务不双写 legacy,回退到 0.1.4 时也不删除或改写 Core 数据。
62
71
 
63
72
  ## Provider 边界
64
73
 
65
- 0.1.4 已实现内部 Provider Adapter v0:`provider-adapter.js` 固定 discovery、submit、poll、cancel、download 与 error mapping 六类操作和 canonical 结果;`provider-adapters.js` 将 DashScope 与 OpenAI Images 映射到契约;`adapters.js` 只保留注入式低层 HTTP transport。动作、恢复、重新交付、模型发现与能力探测不再直接绕过该生命周期边界。
74
+ Provider Adapter v0 固定 discovery、submit、poll、cancel、download 与 error mapping 六类生命周期操作;提交前的临时输入上传是可选准备能力,不自动成为 Core 事实。协议实现只接收显式凭据、模型和媒体端点,Core 保存复合模型身份与非敏感 binding,不保存端点原文。
75
+
76
+ Core Runner 不拥有后台 timer。Headless `task observe` 每次最多 poll 一次;DSH 的有界自动观察属于 Host,插件释放时停止 timer 并中止在途观察,但不会把“停止本地观察”写成“远端已取消”。端点或协议 binding 漂移时恢复在联网前拒绝。
77
+
78
+ 每个操作必须明确声明 supported 或 unsupported。当前 DashScope 与 OpenAI Images 媒体协议没有经过验证的远端取消实现,因此取消请求如实返回 not-supported,而不是伪造 canceled。完整受理与错误规则见 [Provider 提交契约 v0](PROVIDER_SUBMISSION_CONTRACT.md)。
79
+
80
+ ## Text/Vision 共享边界(M1 已实现)
66
81
 
67
- 每个操作必须明确声明 supported 或 unsupported。DashScope 的远端 cancel 尚无经过验证的实现,OpenAI Images 的同步路径没有 poll/cancel,它们均以能力事实公开,而不是在运行时以“方法不存在”失败。完整规则见 [Provider Adapter v0 生命周期契约](PROVIDER_ADAPTER_CONTRACT.md),四态受理规则见 [Provider 提交契约 v0](PROVIDER_SUBMISSION_CONTRACT.md)。
82
+ [Text/Vision Model Port v0](MODEL_PORT_CONTRACT.md) 的纯契约、调用控制与 test-only Fake Port 已实现,尚未接入真实消费者。它以 `describe()` 和单轮 `complete()` 统一文本/视觉输入、正常终态、预算、取消与安全错误;图片以字节和 MIME 进入共享层,模型选择、会话与附件桥接保留在入口/适配器。
68
83
 
69
- Provider 健康事实位于配置层,以 Provider × Model × Capability 为键保存最近成功、决定性认证失败和临时观察。动作层只在真实 Provider 生命周期结果或显式探针后写入;API 投影按当前 failover 候选汇总,客户端只渲染快照,不自行猜测可用性。成功与明确认证失败的有效窗口均为 7 天;429、网络、5xx、内容安全、取消和 unknown 不会推翻窗口内成功。详见 [Provider 与能力健康状态](PROVIDER_HEALTH.md)。
84
+ 提示词优化与视觉理解不创建媒体生成 Task,不进入 Provider Task Runner。提示词优化的功能定位与输入隔离正在讨论,其接入待后续确定;look/relook、定位、OCR 与摘要仍按独立切片迁移。现有 Host 方法、配置与 CLI 均未因 M1 改变;自持文本目录和独立入口需要另行审查。
70
85
 
71
- ## Host Port 清单
86
+ ## Host Port 与 Headless 边界
72
87
 
73
- | 能力 | 当前来源 | 缺失时行为 |
88
+ | 能力 | DSH 来源 | 缺失或 Headless 时行为 |
74
89
  |---|---|---|
75
- | 工具注册与 Fiber 生命周期 | DSH `ctx.tools` / `ctx.effect` | 对应工具不注册;其余能力继续装载 |
76
- | Web 路由 | DSH `webServer` 或 `httpServer` | 工作台 API、媒体链接和 HTML 渲染不可用 |
77
- | UI Slot | DSH Web Client | 不影响 Host 侧任务与离线 Doctor |
78
- | Browser | DSH browser service | 仅 HTML 截图不可用 |
79
- | 会话附件与输入草稿 | DSH session/input ports | 退化为 Iris 自有产物或浏览器上传 |
80
- | Skills registry | DSH skills service | 随包 Skill 不自动注册;核心动作仍可用 |
90
+ | 工具注册与 Fiber 生命周期 | `ctx.tools` / `ctx.effect` | 不注册 DSH 工具;CLI/Core 不受影响 |
91
+ | Web 路由 | `webServer` 或 `httpServer` | 无工作台 API 和同源媒体路由;CLI 直接导出 Artifact |
92
+ | UI Slot | DSH Web Client | 不影响 Core Task、Artifact 与离线 Doctor |
93
+ | Browser | DSH browser service | HTML 渲染不可用;本地媒体命令不受影响 |
94
+ | 会话附件与输入草稿 | session/input ports | CLI 使用显式文件或 JSON 输入,不创建会话对象 |
95
+ | Skills registry | DSH skills service | 随包 Skill 不自动注册;CLI/Core 仍可用 |
81
96
 
82
- 这些依赖由 `dsh-host-adapter.js` 映射为命名端口,`index.js` 只负责 DSH 插件装配和生命周期入口;客户端 Slot 探测留在 client bundle 的最小 adapter 内。Command、API、提示词优化和视觉后端不接收原始 `ctx`。test-only Local Host fixture 使用同一契约验证无 DSH 降级,但不等同于独立宿主。
97
+ Command、Core Store、Provider Runner 和 Headless CLI 不接收原始 `ctx`、会话对象或 Browser 对象。Host URL、attachment 与 UI 文案只在 DSH 投影层产生。
83
98
 
84
- ## 事件与 UI
99
+ ## 事件、UI 与媒体读取
85
100
 
86
- Host Doctor 通过已认证的 `/iris/api/doctor` 返回能力和装载证据;客户端只在 Slot 回调实际执行后向 `/iris/api/host-client` 回报插件版本、协议号和 Slot 名称。诊断不调用端口、Browser、模型或 Provider,详见 [Host Doctor](HOST_DOCTOR.md)。
101
+ DSH 工作台把 Core 与 legacy Task 合并到一个用户任务区,把 Core 图片与旧 `outputs/` 合并到一个作品区。普通投影只有五类用户状态;原始 Attempt 事实留在高级诊断。刷新、展开、关闭、读取作品和查询状态都不得触发 submit、poll 或隐式修复。
87
102
 
88
- 任务、配置和作品索引写入会触发节流 SSE 快照。每份快照都有进程 epoch 与单调序号;慢消费者进入背压后只保留最新快照,重连仍通过持久化全量状态收敛。工作台只展示稳定人类状态,内部事实轴保留在 API 详情中供诊断和人工动作判断。
103
+ Core 媒体路由按随机 Artifact ID 读取并逐次验证 SHA-256;它没有独立 token。浏览器请求还受可信 Host、`Origin`/`Sec-Fetch-Site` 和 `Referrer-Policy: no-referrer` 约束。Artifact ID 是持有者标识,不等于多租户认证;Iris 与 DSH 仍处于同一本机信任域。
89
104
 
90
- ## 非目标
105
+ ## 非目标与发布边界
91
106
 
92
- - 不在 0.1.4 启动独立常驻服务或复制 DSH 聊天界面。
93
- - 不迁移到 SQLite/JSONL,不破坏旧任务读取。
94
- - 0.1.4 不新增 Gemini、Fal 或 Replicate 分支;Provider conformance 完成后仍保持版本范围。
95
- - 不把离线 Doctor 的成功等同于 DSH Host、浏览器或真实供应商已可用。
107
+ - `0.2.0` 不启动独立常驻服务,也不复制 DSH 聊天界面。
108
+ - 不迁移到 SQLite/JSONL,不原地改写 0.1.4 数据,不自动接管不确定的写者租约。
109
+ - 不在本候选新增 Gemini、Fal、Replicate 或本地模型协议;注册表只是后续接入点。
110
+ - 不把离线测试、一次 canary 或 Headless 可运行等同于公开 Core API 已冻结。
111
+ - rc.1 仍须通过最终包审计、仓库外安装、跨平台 CI、Android 目视、回退和机器可读验证摘要后才能发布。
@@ -0,0 +1,60 @@
1
+ # Artifact Manifest v0
2
+
3
+ Artifact Manifest v0 是 Iris 0.2.0 使用的内部格式,尚未作为公开 package API 冻结。它不替换 0.1.4 的 `outputs/` 与 `artifacts.json`;后续 Host 迁移只能显式、逐件复制旧作品,失败时保留原文件。
4
+
5
+ ## 存储与提交顺序
6
+
7
+ ```text
8
+ artifact-store/v0/
9
+ ├── objects/<artifact-id>.<ext>
10
+ ├── manifests/<artifact-id>.json
11
+ ├── records/<artifact-id>.json
12
+ └── index.json
13
+ ```
14
+
15
+ 写入顺序固定为 `object → manifest → record → index`:
16
+
17
+ - object 是受控媒体内容;
18
+ - manifest 保存 SHA-256、媒体类型、大小、中性元数据和关系边;
19
+ - record 是最小提交标记。只有 record、manifest 与 object 一致的 Artifact 才属于已提交事实;
20
+ - index 只是分页查询缓存。它可以损坏或丢失,不影响按稳定 ID 检查已提交 Artifact。
21
+
22
+ Index 更新失败不会撤销已经提交的 Artifact,避免调用方因本地缓存错误重新生成或重复付费。显式 `artifact rebuild` 会从提交记录和旁车 Manifest 重建 Index。
23
+
24
+ ## 内容完整性
25
+
26
+ Manifest 使用小写十六进制 SHA-256,并同时记录字节数。`inspect`、`export`、`list` 和重建都会核验对象;即使文件大小不变,内容被替换也返回 `IRIS_ARTIFACT_DIGEST_MISMATCH`。
27
+
28
+ 哈希通过固定大小分块读取,不把完整视频再次载入内存。Manifest、错误和 CLI 结果不保存输入路径、旧作品文件名、DSH URL 或供应商下载 URL。
29
+
30
+ ## 关系边
31
+
32
+ 关系方向固定为“当前 Artifact 指向既有 Artifact”。v0 支持:
33
+
34
+ - `derived-from`
35
+ - `preview-of`
36
+ - `frame-of`
37
+ - `transcript-of`
38
+ - `audio-for`
39
+
40
+ 创建时目标必须已经存在且通过完整性检查,重复边会被拒绝。目标后续丢失时,来源 Artifact 仍保持可用;重建报告 `danglingRelations`,不会级联删除或猜测修复关系。
41
+
42
+ ## 重建与孤儿
43
+
44
+ `rebuildCoreArtifactIndex()` 属于 writer 的显式 `recover` 操作,reader 不会偷偷修复:
45
+
46
+ - 早期 Core v0 单文件记录:计算真实哈希,生成 Manifest,并将 record 升级为提交标记;
47
+ - object + manifest、缺 record:验证后补写提交标记;
48
+ - 只有命名和媒体扩展合法的 object:计算哈希,以 `kind=recovered`、`metadata.recovered=true` 补全;
49
+ - manifest 缺 object、哈希不匹配、结构损坏或未知文件:不进入 Index、不自动删除,只计入 `invalid` 或 `unresolved`。
50
+
51
+ 原子写入过程中遗留的临时文件也属于 unresolved 现场。自动清理和数据删除需要单独的用户授权,不属于 rebuild。
52
+
53
+ `adoptCoreArtifactFile()` 用于后续渐进接回 0.1.4 作品:来源必须是明确的普通文件,Core 复制内容并计算哈希,既不移动来源,也不在 Manifest 中保存来源路径。批量扫描和旧 ID 映射留给 DSH 消费迁移阶段。
54
+
55
+ ## 当前限制
56
+
57
+ - Manifest 和 record 格式仍是内部候选,版本发布前可能调整;
58
+ - 当前没有删除、去重、垃圾回收或关系编辑 API;
59
+ - 进程崩溃窗口已通过 fixture 验证;突然断电后的持久性仍取决于宿主文件系统,v0 不宣称跨文件系统事务或 `fsync` 级保证;
60
+ - Android 共享存储、网络文件系统和原生 Windows 的恢复行为仍需各自的真实验证。
@@ -0,0 +1,83 @@
1
+ # Core Runtime v0 候选契约
2
+
3
+ 本文定义 0.2.0 的 Core Runtime 内部接口。内部接口在后续版本仍可能调整,npm 包不把它作为公开 API 导出;现有 `config.js`、`tasks.js` 和 `artifacts.js` 也尚未迁移。
4
+
5
+ ## 目标与范围
6
+
7
+ Core Runtime 由调用方显式创建、启动和释放。数据根、操作权限、取消和清理都属于实例;存储缓存与观察器接入后也必须遵守同一归属。Core 不推断 DSH profile,不读取 `ctx`,不启动浏览器或监听端口,也不在启动、Doctor 或能力枚举时触发供应商请求。
8
+
9
+ 0.2.0 包含 Runtime、Task/Attempt、Artifact Manifest、本地与媒体 Command,以及 DSH 对已迁移媒体任务的同源消费。s2v、视觉理解等未迁移能力仍走 legacy Host;完整迁移与公开 Core API 冻结留待后续版本。
10
+
11
+ ## 数据根和进程归属
12
+
13
+ - `dataRoot` 必须由 DSH Host Adapter、CLI 或测试宿主选择后,以绝对路径显式传给 Core。Core 不读取 `DSH_HOME`、`HOME` 或当前工作目录来猜测位置。
14
+ - 每个数据根只允许一个写者。写者必须在读取、初始化、规范化配置、接回旧作品、重建索引或启动任务观察器之前取得数据根租约,并持有到实例完成释放。
15
+ - 其他进程可以用 `reader` 打开同一数据根,但只能执行无副作用的检查。DSH 正在使用该数据根时,CLI 写操作返回 `IRIS_CORE_DATA_ROOT_BUSY`;用户可以停止现有写者,或显式选择另一数据根。
16
+ - 只读不是隐式写入:不得创建缺失文件、修改权限、隔离损坏文件、修复/迁移记录、接回 `outputs/`、更新健康时间或启动任务观察器。
17
+ - 写者冲突必须 fail-fast,普通 Runtime **不得自动夺取**租约。0.2.0 提供独立的 `runtime recover` 显式流程:先由只读 Doctor 报告 owner,再要求用户回显陈旧 PID,并在接管时复核证据、写私有审计;活跃、未知或损坏状态拒绝。PID 不存在本身仍不是跨主机安全证明。
18
+ - 路径别名必须在取得租约前解析为同一物理数据根。不能只依赖字符串规范化或原子 `rename`:后者可以防止半写文件,不能阻止两个带缓存的进程互相覆盖。
19
+
20
+ 初版租约优先使用 Node 标准库和本地文件系统能力,不新增生产依赖。Android 共享存储、网络文件系统和异常退出后的恢复只有拿到真实证据后才声明支持;实现不得假设 systemd 或常驻 daemon 存在。
21
+
22
+ ## 访问模式和操作分类
23
+
24
+ | 模式 | `inspect` | `execute` | `recover` |
25
+ |---|---:|---:|---:|
26
+ | `reader` | 允许 | 拒绝 | 拒绝 |
27
+ | `writer` | 允许 | 允许 | 允许 |
28
+
29
+ `inspect` 只读取已有事实并返回中性的可序列化结果。`execute` 包含本地动作、远端提交和任何持久化变化。`recover` 包含显式迁移、索引重建、损坏隔离和租约恢复;它不是普通读取的自动副作用。
30
+
31
+ 上表是 Core 操作的权限分类。CLI 的 `runtime recover` 是租约外的独立、需人工确认的接管入口;它不能先取得被陈旧 owner 占用的普通 writer 租约,也不能由 reader 或 Doctor 隐式触发。
32
+
33
+ 启动、释放、Doctor、Provider 列表与 capability 列表本身不触发供应商请求、不产生费用,也不偷偷恢复远端任务。真实验证和生成必须由用户显式执行,并继续遵守现有受理、重试、取消和预算规则。
34
+
35
+ ## 生命周期
36
+
37
+ ```text
38
+ created --start--> started --dispose--> disposing --finish-dispose--> disposed
39
+ \----------------dispose---------->/
40
+ ```
41
+
42
+ - 实例只能启动一次;已经释放的实例不能重启。
43
+ - `dispose` 可以重复调用,并返回同一个释放过程。
44
+ - 释放顺序固定为:停止接收新 Command;传播取消信号;等待或保守挂起在途操作;停止任务观察器和 Host 注册;刷写已承诺记录;最后释放数据根租约。
45
+ - 如果仍可能存在写入,或最终刷写失败,不能提前释放租约来伪造“已安全退出”。远端是否取消仍以供应商证据为准,本地释放不得猜测。
46
+ - Host 生命周期只能拥有它创建的 Core 实例和注册资源;不得让模块级缓存、timer 或 listener 泄漏到下一次插件重载。
47
+
48
+ ## 错误与结果边界
49
+
50
+ 候选稳定错误码:
51
+
52
+ - `IRIS_CORE_OPTIONS_INVALID`:选项或显式数据根无效;
53
+ - `IRIS_CORE_STATE_INVALID`:生命周期顺序无效;
54
+ - `IRIS_CORE_OPERATION_INVALID`:未知操作类型;
55
+ - `IRIS_CORE_READ_ONLY`:只读实例收到写操作;
56
+ - `IRIS_CORE_DATA_ROOT_BUSY`:该数据根已有写者;
57
+ - `IRIS_CORE_DATA_ROOT_NOT_FOUND`:reader 指定的数据根不存在,且不会自动创建;
58
+ - `IRIS_CORE_DATA_ROOT_UNAVAILABLE`:无法安全创建、访问或检查数据根;
59
+ - `IRIS_CORE_LEASE_INVALID`:租约证据异常或无法安全释放,保留现场等待显式处理;
60
+ - `IRIS_CORE_LEASE_NOT_FOUND`:显式恢复时没有租约;
61
+ - `IRIS_CORE_LEASE_CONFIRMATION_MISMATCH`:用户回显的 PID 与租约 owner 不一致;
62
+ - `IRIS_CORE_LEASE_OWNER_ALIVE` / `IRIS_CORE_LEASE_OWNER_UNVERIFIED`:owner 仍活跃或无法证明已退出;
63
+ - `IRIS_CORE_LEASE_RECOVERY_FAILED`:恢复或审计未安全完成,现场已保留。
64
+
65
+ 错误、Doctor 证据和 Command 输出不得包含 API Key、授权头、私有签名 URL 或不必要的本机绝对路径。Core 的 Artifact 结果使用稳定 ID 和中性元数据;HTTP/media URL、DSH attachment 与会话展示均由 Host Adapter 投影。
66
+
67
+ ## 当前接口与后续范围
68
+
69
+ 当前候选实现包括:
70
+
71
+ - `normalizeCoreOptions()`:规范化显式数据根和 reader/writer 模式;
72
+ - `createCoreRuntime()`:管理写者租约、状态、`AbortSignal`、在途操作和 cleanup;
73
+ - `createCommandService()`:提供 `crop`、只读 `task.list/task.inspect`、显式单步 `task.observe`/`task.reobserve`(同一份实现,`reobserve` 是人工触发观察的对外命令名)、人工重新交付 `task.redeliver`(只开放 outcome=succeeded / deliveryState=failed,一次带 redelivery 标志的 re-poll + 下载,绝不 submit、绝不重新生成)、人工取消 `task.cancel`(只开放已受理未终态任务,只有 Provider 明确确认才写 canceled,不支持/无法确认保持真实状态)、人工重试为新任务 `task.retry`(只开放终态未成功交付任务;必须显式 confirm_billing 确认重复计费;新 Task 记录单向 retriedFrom 关系,候选链按宿主实况重新解析;Core 不持久化 Prompt,prompt 必须由调用方重新提供),以及 Artifact inspect/list/export/rebuild;Task reader 返回既有安全事实,不读取 Provider 配置,也不创建、修复或迁移记录;`observe/reobserve/redeliver/cancel` 只接受宿主注入的 Adapter resolver,`retry` 只接受宿主注入的候选链 resolver,Core 不读取配置路径;Task capability 现已覆盖 image、video、tts 与 transcribe——交付按 `provider-task-runner.js` 的 DELIVERY_PROFILES 冻结(video:`video/mp4` + `generated-video`;tts:`audio/mpeg`/`audio/wav` + `generated-audio`,同步 completed 同次调用内交付;transcribe:`text/plain` + `transcript`,正文物化为 UTF-8 Artifact),不共用不准确的图片交付语义;
74
+ - Artifact Manifest v0:保存受控对象、SHA-256、关系边和可重建 Index,可跨 CLI 进程检查、导出和显式重建;Doctor 只报告孤立/未解析条目,不自动删除或修复。
75
+
76
+ [Headless CLI](HEADLESS_CLI.md) 记录了当前开发接口,包括只读配置查询、Core Doctor 与陈旧租约显式恢复。FakeProvider 与各媒体 Profile 的离线生命周期测试已经存在;真实 Provider、Android 目视、跨平台 CI 和发布门禁仍须分别举证。未迁移能力保持 legacy 路径,不冒充 Core 事实。
77
+
78
+ ## 非目标
79
+
80
+ - 当前接口尚未作为 package export 或第三方 SDK 发布。0.2.0 的 F 阶段已正式决定:**不新增 `./core` 公开 export**——Root 插件与 `bin/dsh-iris` CLI 承载全部对外能力,内部模块(core-runtime、core-tasks、command-service、provider-task-runner、core-artifact*、core-user-projection)保持私有,可在 minor 版本间调整;冻结为公开 export 的决策顺延到 M2(0.3.0)的 Recipe/Serve 边界定稿后再审。届时一旦公开即写兼容策略与 semver 边界;
81
+ - 不提供 standalone 服务、账号、多租户或额外监听端口;
82
+ - 不包含新 Provider、收藏、标签、搜索或 Flow/Recipe;
83
+ - 不把 0.1.4 的模块级存储包装成实例存储,也不允许 CLI 与 DSH 无租约并发写同一数据根。
@@ -0,0 +1,106 @@
1
+ # DSH → Core 渐进迁移
2
+
3
+ 本文描述 Iris 0.2.0 的实现与迁移边界。迁移逐条切换消费者,不原地改写 0.1.4 数据;未迁移能力继续使用原有实现。
4
+
5
+ ## 已切换的执行链:本地媒体处理与新生成任务
6
+
7
+ - `iris_crop` 和工作台 crop 共用 Command Service 与 Artifact Manifest。attachment 输入先成为 `host-input` Artifact,裁剪结果用 `derived-from` 保存关系;工具名、参数和附件输出不变。
8
+ - 新图片任务的同步、异步与混合候选均使用同一 Core Task/Attempt/Artifact。每个候选先落盘 Attempt,只有明确 `not_accepted` 才允许切换;收到远端 ID 或受理未知后停止候选提交。
9
+ - 新 Attempt 可选记录七个单调 `stageTimestamps` 边界,区分排队、提交、远端执行、下载和本地 Artifact 处理;旧记录缺失该字段仍合法,未发生的阶段不补写。
10
+ - Provider 只收到原始模型 ID;Core 保存 `providerId::modelId` 和非敏感端点 binding,不保存 Prompt、凭据、下载 URL 或 DSH 会话。
11
+ - DSH 边界选择 `$DSH_HOME/iris/v1/core-v0`,与旧 `tasks.json`、`artifacts.json`、`outputs/` 隔离。旧任务仍由旧观察器读取和接管;新图片不双写旧存储。
12
+
13
+ `iris_draw_image` 等待同一 Core Task,ready 后通过命名 Attachment Port 返回图片。等待超时只返回稳定 Task ID,后台观察继续;停止工具等待不等于远端取消。宿主投影失败不会撤销 Core 中已经成功交付的产物。
14
+
15
+ ## 异步观察与重启接管
16
+
17
+ Core runner 不拥有 timer,单次 observe 最多执行一次 poll,绝不 resubmit。DSH Host 在此之上提供有界调度:
18
+
19
+ - 每次观察重新读取 Task,并按原 Provider、模型和 binding 恢复 Adapter;端点/协议漂移、停用、缺凭据或模型不可用时不发送请求。API Key 可以轮换。
20
+ - 每次 submit/observe 使用独立、短生命周期 writer Runtime;同进程操作排队,跨进程 writer 冲突仍 fail-fast。等待下次节拍不占用 writer 租约。
21
+ - 强杀残留租约先由 `doctor --data-root ... --json` 只读确认;仅 owner PID 为 `missing`、用户确认无跨主机写者并用 `--confirm-stale-pid` 回显该 PID 时,`dsh-iris runtime recover` 才接管、写私有审计并释放。活跃/未知/损坏证据全部拒绝,DSH 不自动恢复。
22
+ - 默认间隔 2.5 秒,本轮最多观察 20 分钟;连续 5 次观察错误停止自动等待,保留远端受理与未知事实,不伪造远端失败。
23
+ - 启动扫描全部 Task 页,保守恢复 submitting、active、取消响应和交付中断窗口;仅接管仍有远端受理证据、且在自动窗口内的图片。旧无 binding Task 不猜测恢复配置。
24
+ - timer 使用 unref,随插件 Fiber 清理;在途观察收到取消信号,旧回调不能清掉同一 Task 的新观察器。停止本地观察不宣称已取消远端任务。
25
+
26
+ Headless CLI 使用同一控制面,但不自动循环:`task observe` 每次显式调用只 poll 一次,Provider 配置路径由 CLI 边界提供。
27
+
28
+ DSH 工作台现也开放同一份显式单步观察(D1 reobserve):`POST /iris/api/core/task/:id/reobserve` 经 Command Service 命令 `task.reobserve`(与 `task.observe` 同实现),adapter/binding 恢复与 Host 观察节拍共用同一 resolver。用户任务区的 Core 投影行在服务端的行 DTO 标记 `observable`(已受理、有远端 ID、结果未定论、非终态)时显示「重新观察」按钮,点击后单次调用、禁用期间防重复,完成后复用刷新节拍重拉快照;高级诊断卡对符合同一受理事实门的任务提供同一动作。每次调用至多一次 poll,绝不 submit;终态、未受理、无远端 ID 或 binding 漂移的任务在网络与写入前被拒绝并返回稳定错误码。
29
+
30
+ 人工控制面第二项 redeliver(D2)也已开放:`POST /iris/api/core/task/:id/redeliver` 与 CLI `task redeliver` 经 Command Service 命令 `task.redeliver`,只对 outcome=succeeded / deliveryState=failed 的 Task 开放——一次带 redelivery 标志的 re-poll 拿远端产物清单 → 下载 → 新 Artifact,绝不 submit、绝不重新生成、不新建 Attempt。行 DTO 在五类状态中的 `delivery_failed` 上标记 `redeliverable`,工作台相应投影行与高级诊断卡显示「重新取回作品」;成功即 ready 且门反转(再次调用被拒),下载失败回落 failed 可再次显式执行。
31
+
32
+ 人工控制面第三项 cancel(D3)同样开放:`POST /iris/api/core/task/:id/cancel` 与 CLI `task cancel` 经 Command Service 命令 `task.cancel`,只对已受理、有远端 ID、未终态且未请求过取消的 Task 开放。结果只有三种,且**绝不伪造已取消**:① 供应商明确确认 → outcome=canceled、cancelState=remote_confirmed;② 供应商不支持远端取消(当前 DashScope 与 OpenAI Images 媒体协议均不提供经过验证的取消实现)→ 取消未发生,回落到可继续观察的真实状态(outcome 不变);③ 超时或网络失败 → cancelState=unknown、保持非终态,可显式 reobserve 收敛。竞态下远端先沉淀的成功事实不得被取消覆盖;已请求过取消但未确认的任务拒绝再次取消。工作台按钮「取消任务」需要二次确认,五类用户状态保持不变,三种结果态在高级诊断的「取消状态」字段如实区分(已确认 / 已请求未确认 / 无请求)。
33
+
34
+ 人工控制面最后一项 retry as new task(D4)也已开放,控制面四个动作全部收口:`POST /iris/api/core/task/:id/retry` 与 CLI `task retry` 经 Command Service 命令 `task.retry`。这是唯一产生新的真实计费的动作,三层都强制显式确认——CLI `--confirm-billing`、API 请求体 `confirmBilling:true`、UI 含重复计费警示的确认弹窗,缺一不进且在网络与创建之前拒绝。只对终态且未成功交付的 Task 开放(succeeded+ready 拒绝)。新 Task 有全新 id/attempts/binding,候选链按当前 assignments/池实况重新解析(旧 binding 可能正是失败原因),`model_ref`/`modelRef` 可显式指定;记录单向 `retriedFrom` 关系指向旧 Task,旧 Task 事实零变化,高级诊断以「重试来源」展示该关系。**Core 记录不持久化 Prompt**,生成指令必须由调用方重新提供(CLI `--input` / API `prompt` / 工作台弹窗重新输入),绝不从旧任务"恢复"——这是隐私设计,不是缺陷。同一请求网络重放的幂等键未实现:每次显式确认即一个新任务,属预期语义。
35
+
36
+ ## 作品与只读诊断
37
+
38
+ 工作台只有一个作品库:Core 图片与旧 outputs 作品一起显示,原始输入 Artifact 不进入作品视图。Core 媒体路由 `/iris/api/core/artifact/<artifact_id>/media` 没有独立 token:它按随机 96-bit Artifact ID 读取,每次验证 SHA-256,并由默认回环/显式 trusted Host 与浏览器 `Origin`/`Sec-Fetch-Site` 守卫拒绝明确跨站请求。Artifact ID 持有者在可达受信 Host 时即可读取;Host allowlist 不等于身份认证。Host URL 不写回 Core。
39
+
40
+ 默认收起的“高级诊断 → Core 任务事实”展示同一批作品背后的 Task/Attempt,可展开、复制 ID 和打开图片,不是第二个作品库。`iris_task_status` 可查询同一 Core ID;CLI 指定同一 profile 数据根时可以 inspect/export,反向也成立。重复读取和附件投影不触发生成或修改 Core 事实。
41
+
42
+ 工作台与泡泡的普通任务区现已消费同一快照的 `userTasks` 安全投影:Core 任务与旧版任务合并进同一个运行中/需要处理/历史分区,对外只呈现五类用户状态——`running`、`observation_paused`、`attention`、`delivery_failed`、`succeeded`。观察暂停的文案明确说明远端可能仍在运行,与“已明确失败”严格区分。卡片显示稳定 Task ID、模型、更新时间和关联作品链接;供应商身份、binding、错误原文与路径不进入普通任务区。投影是纯只读:刷新、展开、关闭与历史清理不会 poll、submit、删除或修复 Core 事实;完成提示在会话内只出现一次,刷新页面后从事实快照重新计算,不持久化提醒偏好。单条任务记录损坏或媒体文件丢失只触发局部降级(跳过该条、作品卡片显示占位),快照与其余条目照常可用。Core 的人工恢复四个动作 reobserve/redeliver/cancel/retry 已全部开放(见上节,CLI/API/UI 同一 Command Service);需要处理条目在投影行或高级诊断中有对应动作入口,旧任务继续由 legacy 记录处理。
43
+
44
+ ## 注意力处置(0.2.x 补丁)
45
+
46
+ Core 任务的提醒处置属于 **Host 偏好**(计划铁律:提醒已读/处置不修改远端事实字段)。偏好存 `$DSH_HOME/iris/v1/core-attention.json`(0600、tmp+rename 原子写、损坏降级为无偏好、只存 Task ID 与时间戳),**绝不写入 Core 数据根**;「移除」也只是本机隐藏,任务与产物记录完整保留,高级诊断标注"已隐藏"并可「恢复显示」,CLI 与 reader 照常可查。
47
+
48
+ 工作台 attention 行(失败/取回失败/受理未知)提供「不再提醒」(受理后移出需要处理,历史区仍可见并可「恢复提醒」)与「移除」(本机隐藏,任务区/泡泡全部过滤)。泡泡计数与列表跟随过滤;泡泡亮度仍只由 Provider 健康决定。高级诊断(tasks.recent 全量记录)不受偏好影响,并新增「处置状态」展示 acknowledged/hidden/suppressed 三种口径。
49
+
50
+ 已确认取消的任务仍保留 Core 事实投影 `outcome=canceled → userState=attention` 与原语义校验,但 DSH 安全投影额外标记 `historical:true`:工作台与泡泡将其放入历史,不计「需要处理」或角标,不显示注意力处置按钮。失败、受理未知、结果未知和交付失败仍照常进入 attention。
51
+
52
+ 此外由事实派生的**自动静默**:若任务 X 处于 attention 且存在 `retriedFrom = X` 的后继任务已成功交付,X 自动静默(客户端连同手动处置一起过滤);后继后续失败则静默撤销。该派生每次快照重算,不缓存、不落偏好——这正是 D 阶段 D4 关系字段的用户侧收益,也是计划 §4.D.5(提醒已读/处置属于 Host 偏好,不修改远端事实字段)的落地。
53
+
54
+ ## 视频迁移(E 阶段第一项)
55
+
56
+ t2v/i2v 视频已迁到 Core,与图片共用 Task/Attempt 事实轴但**不共用图片状态机**:交付走冻结的视频 Profile(`lib/provider-task-runner.js` 的 `DELIVERY_PROFILES.video`:媒体白名单 `video/mp4`、Artifact kind `generated-video`、metadata 带 `capability`),观察用视频长轮询档(默认 6s/拍),受理、取消(当前真实协议不支持远端取消,not_supported 如实回落)、redeliver/retry 与 CLI/API/UI 控制面全部对视频生效。Agent 工具与工作台视频动作经 `submitCoreVideo` 落到 Core,**零 legacy 双写**(不再写 `tasks.json`/`outputs/`;旧视频任务继续 legacy 只读兼容)。同源媒体路由按 ID 播放 mp4;视频作品在任务区行内给出链接,不进入图片画廊网格。s2v 数字人(受理边界前需上传首帧与音频到临时存储)暂留 legacy 链路,后续单独迁移。真实 Provider 视频 canary 待验收。
57
+
58
+ ## 语音合成迁移(E 阶段第二项)
59
+
60
+ TTS 是同步完成型,与视频的长轮询不同:一次 submit 内 completed,同一次调用直接交付为 Core Artifact(`DELIVERY_PROFILES.tts`:媒体白名单 `audio/mpeg`/`audio/wav`、kind `generated-audio`;remote-url 走下载,inline base64 直接物化)。Agent 工具 `iris_speak_text`、工作台语音动作与 CLI `run tts` 全部落到 Core,**零 legacy 双写**;同步完成即终态,observe/redeliver/cancel 对终态语音任务全部稳定拒绝,终态失败可用 retry 显式重试为新任务(输入为 `{text, voice?}`,候选链按实况解析)。语义差如实记录:legacy 是"单 Task 多 Attempt、每次尝试独立交付到 outputs/",Core 是"单 Task 多 Attempt、一次 Artifact 交付";候选链共用一个 voice(Core providerInput 静态)。同源媒体路由按 ID 播放音频。真实 Provider 语音 canary 待验收。
61
+
62
+ ## 转写迁移(E 阶段第三项)
63
+
64
+ 转写是上传型异步,Profile 独立:音频在 Host/CLI 边界上传到首选候选 Provider 的临时存储(`oss://` 签名地址只进 providerInput,**绝不落 Core 记录**),经受理边界提交后走 Core 长轮询(默认 2.5s/拍),远端成功后正文物化为 `text/plain` 的 `transcript` Artifact(adapter 在 poll 成功时把正文转为 inline-base64,不依赖签名 URL 生命周期)。CLI `run transcribe` 支持 `audio_url`(公网/oss:// 直达)或 `audio_path`(本地文件经同一上传通道);Agent 工具与工作台转写动作切 Core,完成时结果直接附转写正文。**零 legacy 双写**,旧转写任务继续 legacy 只读兼容。取消沿用 not_supported 如实语义;retry 输入为 `audio_url`(Core 不持久化音频地址,必须由调用方重新提供)。已知边界:临时音频 URL 属于首选候选的账号,failover 到不同账号时该候选会如实失败。真实 Provider 转写 canary 待验收。
65
+
66
+ ## 本地媒体原语
67
+
68
+ Core Command Service 已纳入两项确定性、零 Provider 的本地能力:`media.diff` 用 Sharp 生成指标与 `pixel-diff` 热力图 Artifact;`media.frames` 用本机 ffmpeg/ffprobe 返回视频元数据并生成 `video-frame` Artifact。两者均可读取宿主绝对路径;读取既有 Core Artifact 时分别写入 `derived-from` 或 `frame-of` 关系,Manifest 不保存宿主或临时路径。Headless CLI 的 `media diff` / `media frames` 直接消费同一 Command Service,不读取 Provider 配置、不发起网络请求。
69
+
70
+ DSH 的 `iris_pixel_diff`、`iris_video_frames` 与工作台对应动作也消费上述 Command:Host 只解析图片附件/本地来源,并将已落盘的 Artifact 字节投影为附件或首帧预览。diff 的附件输入先形成 `host-input` Artifact,热力图保存 `derived-from` 关系;本地视频路径不伪造来源关系。结果提供 `artifactIds`,CLI 可从同一 Core 根检查和导出相同字节,DSH 不再为这两项另写 legacy Task 或 `outputs/`。
71
+
72
+ 图片、t2v/i2v 视频、TTS 与转写的正常提交和知情重试共用 `generation-input.js`:统一文本修剪、数量/时长/长度校验,并把 `img_data_url`、`audio_url` 转为 Adapter 的 `imgDataUrl`、`audioUrl`。非法输入在 Provider 提交和新 Task 创建前拒绝;CLI 仍返回 usage 退出码,Command 仍返回 `IRIS_COMMAND_INPUT_INVALID`。工作台清空可选文本框仍由 Host 解释为使用默认值。音频路径与签名地址不落 Core,上传和附件解析仍属于入口;S2V 的 legacy 参数链保持原边界。
73
+
74
+ 依赖视觉模型或 Host Browser 的 `locate`、长图 OCR、媒体摘要和 HTML 渲染不进入这条本地命令链;它们留到中立 Text/Vision Port 冻结后再迁移,避免把网络模型或浏览器对象塞进 Core。
75
+
76
+ ## Text/Vision 下一步(M1 完成,消费者未迁移)
77
+
78
+ [Text/Vision Model Port v0](MODEL_PORT_CONTRACT.md) 固定目标请求、完整结果、错误、取消/预算与 DSH 图片桥接边界。后续顺序为纯契约/Fake Port → 提示词优化 → look/relook → 定位/OCR/拼图摘要,逐个消费者举证。取消后 fallback、缺终态的部分文字成功、OCR 吞取消继续分块均列为待修行为,现有测试通过不能算作新契约已通过。
79
+
80
+ 纯契约、调用控制与 Fake Port 已完成 M1,共用有限调用预算、严格结果验证与取消语义;真实 HTTP/DSH 适配器尚未接入。提示词优化继续讨论主动提示词组装与不可信输入隔离,本轮不迁移该消费者。M1 不增加 Task/Artifact 写入,不修改 v1 配置或公开 export。HTML/Browser、S2V 与自持文本能力目录独立处理;媒体摘要复用 Core 抽帧也需后续单独接线。
81
+
82
+ ## 尚未迁移或开放
83
+
84
+ - s2v 数字人视频的 Core Command/Task 消费;
85
+ - 依赖 Text/Vision Model Port 或 Host Browser 的 locate、长图 OCR、媒体摘要与 HTML 渲染;
86
+ - 旧任务、旧作品 ID 与 Core ID 的显式映射;
87
+ - Core Task/Artifact 删除、清理、孤儿 purge 与完整作品分页(提醒处置和人工控制面 reobserve/redeliver/cancel/retry 已开放);
88
+ - 真实 DSH 对话 attachment、浏览器进度/作品区和异步重启 canary。
89
+
90
+ 旧作品重新索引、删除、清空和孤儿清理仍只操作 legacy `outputs/`;Core Task/Artifact 在 DSH 工作台和 Headless CLI 中都保持只读。Doctor 会报告 Core 孤立对象、未提交 Manifest 与未解析条目,但不会删除或修复它们。Core 删除与清理能力计划在 0.2.x 开放;不要手动移动或删除 `core-v0` 中的 object、Manifest、record 或租约文件。
91
+
92
+ ## 验证证据与限制
93
+
94
+ - 2026-09-30 当前开发工作树已完成仓库外真实 tarball 安装验收:空项目安装当前包和 Sharp,不含 DSH/Cordis,也不复用仓库依赖。安装后的 CLI 实际完成 crop/diff/抽帧和四类 Provider fixture 生成,13 份 Artifact 的导出字节及 SHA-256 一致;跨进程 reader/导出零 Core 写入、零额外 Provider 请求。可在源码仓库执行 `node scripts/verify-headless-package.mjs` 复现,缓存完整时支持 `--offline`。本机为 Linux ARM64/PRoot、Node 22;这项证据不替代真实 Provider、DSH 异步重启或其他平台验收。
95
+ - 完整离线回归为 96 个测试文件,lint 覆盖 151 个 JS/MJS 文件。同步、多产物、混合 failover、受理未知、交付失败、跨进程观察、零 legacy 双写、用户侧只读投影(五类真值表、零写入、局部降级、窄屏断言)与 D1 reobserve、D2 redeliver、D3 cancel、D4 retry(Command 门真值表零网络零写入、幂等矩阵、redelivery 标志、取消三分支如实语义与竞态防护、计费确认三层门、retriedFrom 关系与 prompt 零持久化、失败回落显式收敛、API 状态码/脱敏、CLI↔API 同一 Task 事实连续性、客户端投影门)均有 fixture;E 阶段视频、语音、转写迁移各有独立 conformance(视频长轮询多拍/mp4 Profile、语音同步双产物形态/音频 Profile、转写上传通道/文本物化 Profile)与 CLI/DSH 端到端 fixture。
96
+ - 2026-09-19 最新完整门禁为 113 个测试文件、lint 173 个 JS/MJS 文件;新增证据包括 T-09 七阶段时间戳与旧记录兼容,以及 T-12 本地 diff/抽帧 CLI、Artifact 关系和路径脱敏。上一条 96/151 为早期迁移阶段的历史计数。
97
+ - DSH 异步工具 fixture 实际执行注册后的工具,贯通 submit → poll → download → Core Artifact → attachment;另验证 active 崩溃接管、唯一 Attempt、端点漂移零 poll/零 Task 写入。
98
+ - Headless CLI 与真实 DSH action 已用百炼同步模型完成图片生成,Manifest、同源媒体和 CLI 导出 hash 一致。这些证据不包含真实异步 Provider 或会话附件。
99
+ - 最近一次真实对话验收在进入 Iris 前被 DSH 主模型的 429 限流阻断,未新增 Core Task/Artifact,也未调用媒体 Provider。未改动用户全局模型设置。
100
+ - 早期候选 tarball 已在仓库外、无 DSH 包的临时项目安装并完成 crop/inspect;后续新增代码仍需最终候选重新打包审计。Windows CI 和安卓浏览器目视未以离线测试替代。
101
+
102
+ ## 后续验收
103
+
104
+ Core 任务到工作台进度/提醒的只读安全投影已完成(五类状态、合并任务区、会话内一次性完成提示、损坏/缺媒体局部降级),人工控制面四个动作已全部开放(reobserve/redeliver/cancel/retry,CLI/API/UI 同一 Command Service,retry 三层强制计费确认)。图片、t2v/i2v、TTS、转写以及本地 crop/diff/抽帧已有 Core 执行链;接下来补恢复后真实会话附件、浏览器与异步重启证据,验证停止 DSH 后 CLI 仍可 inspect/observe/export。旧 ID 映射和尚未迁移能力按后续计划单独处理。
105
+
106
+ 发行验证覆盖最终 tarball、无 DSH 安装闭包、Linux/Windows CI 和真实安装的 rc.2 服务隔离检查;这些检查不替代付费 Provider、个人 profile 的停机接管/回退与逐项浏览器验收。上述剩余范围继续跟踪;未验证的宿主版本与 Provider 路径不作为支持声明。
@@ -0,0 +1,36 @@
1
+ # DSH 0.2.0-rc.2 适配
2
+
3
+ 本适配随 Iris `0.2.0` 发布;npm 0.1.4 包不包含这些后续修正。Iris 0.2.0 要求 Node.js `>=22.0.0`,DSH engines、五项客户端 peers 与 Host Doctor 仅放行准确版本 `0.2.0-rc.2`,不再沿用旧版支持窗口,也不推定其他 0.2 预览版或正式版兼容。
4
+
5
+ 旧 DSH `>=0.1.2-rc.1 <0.1.3-0` 或 `0.1.5-rc.1` 按历史验证范围使用稳定包 `@mokuyoaxis/dsh-iris@0.1.4`。安装与 npm tarball 下载方式见 [README](../README.md#最快开始)。保留的旧桥接与 fixture 测试不构成 Iris 0.2.0 的旧宿主支持承诺。
6
+
7
+ ## 宿主边界的修正
8
+
9
+ | 边界 | 问题与修正 |
10
+ |---|---|
11
+ | 加载器与诊断 | rc.2 加载器检查 `peerDependencies`,原旧版客户端范围会被拒绝。当前客户端 peers、DSH engines、锁文件和 Host Doctor 均收敛到准确 rc.2,无需版本豁免。 |
12
+ | 会话附件 | 扫描引用时曾丢弃 `bytes/width/height`,真实 `readImage()` 因完整性不匹配拒绝读取。适配器保留这些已知事实及 `originalDimensions` 的独立副本,不猜测缺失值,不复制额外 Host 字段。 |
13
+ | 宿主视觉 | rc.2 的 `llm.stream()` 需要明确 Provider/模型路由。默认选择仅在精确模型元数据确认接受 `image` 时成为视觉候选;文本模型、未知能力和身份漂移在生成前拒绝,错误事件以及 `finish.reason.kind` 的 `error/aborted` 不再被当作空回答或部分成功。 |
14
+ | 客户端会话 | rc.2 列表没有旧 `current` 字段。适配器使用唯一的 `retainedBy.mainView` 持有者,通知时回读 `getSnapshot()`,卸载时释放订阅;保留旧接口,有歧义或无选择时不取任意列表项。 |
15
+
16
+ 修改位于 DSH Host Adapter、客户端边界、Host Doctor 与兼容元数据。Core Runtime、Command、Provider、Task/Artifact 存储和 CLI 实现不因该宿主升级修改;不迁移用户配置或已有数据。
17
+
18
+ ## 验证方式与证据范围
19
+
20
+ 常规 `npm test` 包含 rc.2 附件/视觉边界、客户端真实附件请求和 Doctor 的准确版本判定;Doctor 对旧 DSH 返回不在当前支持范围,并提示固定 Iris 0.1.4。旧接口 fixture 回归保留,但不作为旧宿主实际验收。
21
+
22
+ 若本机已安装 DSH rc.2,可在仓库运行以下手动验收,无需为 Iris 添加 DSH/React 生产依赖:
23
+
24
+ ```bash
25
+ node scripts/verify-dsh-host.mjs --dsh-root /absolute/path/to/@deepseek-ai/dsh
26
+ ```
27
+
28
+ 脚本在仓库外创建新临时数据根,载入实际安装的 Cordis、加载器兼容检查、附件、工具、Skill、LLM、默认模型、WebServer 与客户端 SlotRegistry。模型使用本地 Fake Adapter,正常流遵循安装包的 `index` 和对象终态格式,并验证真实 Runtime 将异常转换为失败终态;禁止外部请求。会话日志和列表是显式 fixture,宿主进程入口是已核实 DSH bin 的模拟。实际 WebServer 只绑定临时 loopback 端口,退出时卸载所有 Fiber。临时目录与 `report.json` 保留供复核。
29
+
30
+ 它检查 14 个工具、2 项 Skill、Doctor 路由、DSH → Core diff → DSH 附件,以及四个客户端座位的注册和卸载。SlotRegistry 使用安装包中的真实代码,React/DOM 为 stub,因此不证明完整 Web profile 装载、实际组件渲染、点击和草稿写回。另用 `scripts/verify-headless-package.mjs --offline` 验证当前 tarball 在无 DSH/Cordis 安装树中执行 CLI 和 Artifact 导出。
31
+
32
+ ## 当前限制
33
+
34
+ 真实用户 profile 若禁用 Iris,路由不存在属于预期状态,不据此判定适配失败。启用后仍需实机验证工作台、会话附件选择、提示词预览/写回和媒体展示。验证脚本不自动启用、安装、重载或重启用户插件,也不运行付费探针。
35
+
36
+ 这次修正保留现有 `textModel.stream()` / `visionModel.analyze()` 消费链;没有将真实适配器或业务接入 [Model Port M1](MODEL_PORT_CONTRACT.md)。视觉完整终态、统一输出预算、候选控制和 OCR 取消的进一步收口仍按该契约的后续阶段验收,不能把 rc.2 桥接测试当作迁移完成证据。