@zaalipro/dsh-workflows 0.1.0-rc.3

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 (229) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +224 -0
  3. package/README.i18n.yaml +4 -0
  4. package/README.md +109 -0
  5. package/README.zh.md +109 -0
  6. package/cordis.patch.yml +10 -0
  7. package/docs/architecture.i18n.yaml +4 -0
  8. package/docs/architecture.md +177 -0
  9. package/docs/architecture.zh.md +177 -0
  10. package/docs/testing.i18n.yaml +4 -0
  11. package/docs/testing.md +125 -0
  12. package/docs/testing.zh.md +125 -0
  13. package/docs/user-guide.i18n.yaml +4 -0
  14. package/docs/user-guide.md +351 -0
  15. package/docs/user-guide.zh.md +351 -0
  16. package/lib/client-types/WorkflowMemberInspector.d.ts +28 -0
  17. package/lib/client-types/WorkflowMemberInspector.d.ts.map +1 -0
  18. package/lib/client-types/WorkflowMemberInspector.js +181 -0
  19. package/lib/client-types/WorkflowMemberInspector.js.map +1 -0
  20. package/lib/client-types/WorkflowRunPanel.d.ts +43 -0
  21. package/lib/client-types/WorkflowRunPanel.d.ts.map +1 -0
  22. package/lib/client-types/WorkflowRunPanel.js +130 -0
  23. package/lib/client-types/WorkflowRunPanel.js.map +1 -0
  24. package/lib/client-types/WorkflowsDashboard.d.ts +49 -0
  25. package/lib/client-types/WorkflowsDashboard.d.ts.map +1 -0
  26. package/lib/client-types/WorkflowsDashboard.js +942 -0
  27. package/lib/client-types/WorkflowsDashboard.js.map +1 -0
  28. package/lib/client-types/adapter.d.ts +60 -0
  29. package/lib/client-types/adapter.d.ts.map +1 -0
  30. package/lib/client-types/adapter.js +117 -0
  31. package/lib/client-types/adapter.js.map +1 -0
  32. package/lib/client-types/chat-renderer.d.ts +10 -0
  33. package/lib/client-types/chat-renderer.d.ts.map +1 -0
  34. package/lib/client-types/chat-renderer.js +11 -0
  35. package/lib/client-types/chat-renderer.js.map +1 -0
  36. package/lib/client-types/contract.d.ts +210 -0
  37. package/lib/client-types/contract.d.ts.map +1 -0
  38. package/lib/client-types/contract.js +37 -0
  39. package/lib/client-types/contract.js.map +1 -0
  40. package/lib/client-types/controller.d.ts +83 -0
  41. package/lib/client-types/controller.d.ts.map +1 -0
  42. package/lib/client-types/controller.js +705 -0
  43. package/lib/client-types/controller.js.map +1 -0
  44. package/lib/client-types/index.d.ts +19 -0
  45. package/lib/client-types/index.d.ts.map +1 -0
  46. package/lib/client-types/index.js +730 -0
  47. package/lib/client-types/index.js.map +1 -0
  48. package/lib/client-types/locales.d.ts +257 -0
  49. package/lib/client-types/locales.d.ts.map +1 -0
  50. package/lib/client-types/locales.js +270 -0
  51. package/lib/client-types/locales.js.map +1 -0
  52. package/lib/client-types/slot-components.d.ts +38 -0
  53. package/lib/client-types/slot-components.d.ts.map +1 -0
  54. package/lib/client-types/slot-components.js +22 -0
  55. package/lib/client-types/slot-components.js.map +1 -0
  56. package/lib/client-types/store.d.ts +69 -0
  57. package/lib/client-types/store.d.ts.map +1 -0
  58. package/lib/client-types/store.js +135 -0
  59. package/lib/client-types/store.js.map +1 -0
  60. package/lib/client-types/workflow-definition.d.ts +52 -0
  61. package/lib/client-types/workflow-definition.d.ts.map +1 -0
  62. package/lib/client-types/workflow-definition.js +135 -0
  63. package/lib/client-types/workflow-definition.js.map +1 -0
  64. package/lib/client.js +11064 -0
  65. package/lib/client.js.map +1 -0
  66. package/lib/compat-engine/index.js +1926 -0
  67. package/lib/compat-engine/index.js.map +1 -0
  68. package/lib/compat-engine/worker.cjs +1500 -0
  69. package/lib/compat-engine/worker.cjs.map +1 -0
  70. package/lib/typert.host.d.ts +3 -0
  71. package/lib/typert.host.js +1709 -0
  72. package/lib/typert.remote-client.d.ts +57 -0
  73. package/lib/typert.remote-client.js +1662 -0
  74. package/lib/types/commands/aliases.d.ts +4 -0
  75. package/lib/types/commands/aliases.d.ts.map +1 -0
  76. package/lib/types/commands/aliases.js +25 -0
  77. package/lib/types/commands/aliases.js.map +1 -0
  78. package/lib/types/commands/index.d.ts +66 -0
  79. package/lib/types/commands/index.d.ts.map +1 -0
  80. package/lib/types/commands/index.js +550 -0
  81. package/lib/types/commands/index.js.map +1 -0
  82. package/lib/types/commands/parser.d.ts +17 -0
  83. package/lib/types/commands/parser.d.ts.map +1 -0
  84. package/lib/types/commands/parser.js +45 -0
  85. package/lib/types/commands/parser.js.map +1 -0
  86. package/lib/types/config.d.ts +71 -0
  87. package/lib/types/config.d.ts.map +1 -0
  88. package/lib/types/config.js +109 -0
  89. package/lib/types/config.js.map +1 -0
  90. package/lib/types/index.d.ts +41 -0
  91. package/lib/types/index.d.ts.map +1 -0
  92. package/lib/types/index.js +483 -0
  93. package/lib/types/index.js.map +1 -0
  94. package/lib/types/invariant.d.ts +21 -0
  95. package/lib/types/invariant.d.ts.map +1 -0
  96. package/lib/types/invariant.js +85 -0
  97. package/lib/types/invariant.js.map +1 -0
  98. package/lib/types/registry/definition.d.ts +24 -0
  99. package/lib/types/registry/definition.d.ts.map +1 -0
  100. package/lib/types/registry/definition.js +189 -0
  101. package/lib/types/registry/definition.js.map +1 -0
  102. package/lib/types/registry/index.d.ts +100 -0
  103. package/lib/types/registry/index.d.ts.map +1 -0
  104. package/lib/types/registry/index.js +899 -0
  105. package/lib/types/registry/index.js.map +1 -0
  106. package/lib/types/registry/names.d.ts +19 -0
  107. package/lib/types/registry/names.d.ts.map +1 -0
  108. package/lib/types/registry/names.js +69 -0
  109. package/lib/types/registry/names.js.map +1 -0
  110. package/lib/types/registry/remote.d.ts +15 -0
  111. package/lib/types/registry/remote.d.ts.map +1 -0
  112. package/lib/types/registry/remote.js +128 -0
  113. package/lib/types/registry/remote.js.map +1 -0
  114. package/lib/types/registry/roots.d.ts +44 -0
  115. package/lib/types/registry/roots.d.ts.map +1 -0
  116. package/lib/types/registry/roots.js +118 -0
  117. package/lib/types/registry/roots.js.map +1 -0
  118. package/lib/types/registry/types.d.ts +62 -0
  119. package/lib/types/registry/types.d.ts.map +1 -0
  120. package/lib/types/registry/types.js +2 -0
  121. package/lib/types/registry/types.js.map +1 -0
  122. package/lib/types/registry/watchers.d.ts +70 -0
  123. package/lib/types/registry/watchers.d.ts.map +1 -0
  124. package/lib/types/registry/watchers.js +152 -0
  125. package/lib/types/registry/watchers.js.map +1 -0
  126. package/lib/types/remote-events.d.ts +42 -0
  127. package/lib/types/remote-events.d.ts.map +1 -0
  128. package/lib/types/remote-events.js +21 -0
  129. package/lib/types/remote-events.js.map +1 -0
  130. package/lib/types/run-recorder.d.ts +44 -0
  131. package/lib/types/run-recorder.d.ts.map +1 -0
  132. package/lib/types/run-recorder.js +356 -0
  133. package/lib/types/run-recorder.js.map +1 -0
  134. package/lib/types/supervisor/canned-validate.d.ts +25 -0
  135. package/lib/types/supervisor/canned-validate.d.ts.map +1 -0
  136. package/lib/types/supervisor/canned-validate.js +122 -0
  137. package/lib/types/supervisor/canned-validate.js.map +1 -0
  138. package/lib/types/supervisor/completion-notice.d.ts +49 -0
  139. package/lib/types/supervisor/completion-notice.d.ts.map +1 -0
  140. package/lib/types/supervisor/completion-notice.js +281 -0
  141. package/lib/types/supervisor/completion-notice.js.map +1 -0
  142. package/lib/types/supervisor/cursors.d.ts +68 -0
  143. package/lib/types/supervisor/cursors.d.ts.map +1 -0
  144. package/lib/types/supervisor/cursors.js +158 -0
  145. package/lib/types/supervisor/cursors.js.map +1 -0
  146. package/lib/types/supervisor/engine-compat.d.ts +48 -0
  147. package/lib/types/supervisor/engine-compat.d.ts.map +1 -0
  148. package/lib/types/supervisor/engine-compat.js +116 -0
  149. package/lib/types/supervisor/engine-compat.js.map +1 -0
  150. package/lib/types/supervisor/index.d.ts +183 -0
  151. package/lib/types/supervisor/index.d.ts.map +1 -0
  152. package/lib/types/supervisor/index.js +2040 -0
  153. package/lib/types/supervisor/index.js.map +1 -0
  154. package/lib/types/supervisor/parallel-compat.d.ts +36 -0
  155. package/lib/types/supervisor/parallel-compat.d.ts.map +1 -0
  156. package/lib/types/supervisor/parallel-compat.js +180 -0
  157. package/lib/types/supervisor/parallel-compat.js.map +1 -0
  158. package/lib/types/supervisor/remote.d.ts +25 -0
  159. package/lib/types/supervisor/remote.d.ts.map +1 -0
  160. package/lib/types/supervisor/remote.js +478 -0
  161. package/lib/types/supervisor/remote.js.map +1 -0
  162. package/lib/types/supervisor/storage/bounded-file.d.ts +41 -0
  163. package/lib/types/supervisor/storage/bounded-file.d.ts.map +1 -0
  164. package/lib/types/supervisor/storage/bounded-file.js +186 -0
  165. package/lib/types/supervisor/storage/bounded-file.js.map +1 -0
  166. package/lib/types/supervisor/storage/details-codec.d.ts +14 -0
  167. package/lib/types/supervisor/storage/details-codec.d.ts.map +1 -0
  168. package/lib/types/supervisor/storage/details-codec.js +359 -0
  169. package/lib/types/supervisor/storage/details-codec.js.map +1 -0
  170. package/lib/types/supervisor/storage/index.d.ts +26 -0
  171. package/lib/types/supervisor/storage/index.d.ts.map +1 -0
  172. package/lib/types/supervisor/storage/index.js +100 -0
  173. package/lib/types/supervisor/storage/index.js.map +1 -0
  174. package/lib/types/supervisor/storage/lease.d.ts +34 -0
  175. package/lib/types/supervisor/storage/lease.d.ts.map +1 -0
  176. package/lib/types/supervisor/storage/lease.js +289 -0
  177. package/lib/types/supervisor/storage/lease.js.map +1 -0
  178. package/lib/types/supervisor/storage/manifest-codec.d.ts +10 -0
  179. package/lib/types/supervisor/storage/manifest-codec.d.ts.map +1 -0
  180. package/lib/types/supervisor/storage/manifest-codec.js +335 -0
  181. package/lib/types/supervisor/storage/manifest-codec.js.map +1 -0
  182. package/lib/types/supervisor/storage/manifest-store.d.ts +99 -0
  183. package/lib/types/supervisor/storage/manifest-store.d.ts.map +1 -0
  184. package/lib/types/supervisor/storage/manifest-store.js +1606 -0
  185. package/lib/types/supervisor/storage/manifest-store.js.map +1 -0
  186. package/lib/types/supervisor/storage/manifest-types.d.ts +269 -0
  187. package/lib/types/supervisor/storage/manifest-types.d.ts.map +1 -0
  188. package/lib/types/supervisor/storage/manifest-types.js +2 -0
  189. package/lib/types/supervisor/storage/manifest-types.js.map +1 -0
  190. package/lib/types/supervisor/storage/private-root.d.ts +143 -0
  191. package/lib/types/supervisor/storage/private-root.d.ts.map +1 -0
  192. package/lib/types/supervisor/storage/private-root.js +860 -0
  193. package/lib/types/supervisor/storage/private-root.js.map +1 -0
  194. package/lib/types/supervisor/storage/recovery.d.ts +14 -0
  195. package/lib/types/supervisor/storage/recovery.d.ts.map +1 -0
  196. package/lib/types/supervisor/storage/recovery.js +126 -0
  197. package/lib/types/supervisor/storage/recovery.js.map +1 -0
  198. package/lib/types/supervisor/storage/run-files.d.ts +67 -0
  199. package/lib/types/supervisor/storage/run-files.d.ts.map +1 -0
  200. package/lib/types/supervisor/storage/run-files.js +346 -0
  201. package/lib/types/supervisor/storage/run-files.js.map +1 -0
  202. package/lib/types/supervisor/types.d.ts +295 -0
  203. package/lib/types/supervisor/types.d.ts.map +1 -0
  204. package/lib/types/supervisor/types.js +3 -0
  205. package/lib/types/supervisor/types.js.map +1 -0
  206. package/lib/types/supervisor/value-view.d.ts +19 -0
  207. package/lib/types/supervisor/value-view.d.ts.map +1 -0
  208. package/lib/types/supervisor/value-view.js +183 -0
  209. package/lib/types/supervisor/value-view.js.map +1 -0
  210. package/lib/types/tool/index.d.ts +86 -0
  211. package/lib/types/tool/index.d.ts.map +1 -0
  212. package/lib/types/tool/index.js +810 -0
  213. package/lib/types/tool/index.js.map +1 -0
  214. package/lib/types/tool/schema.d.ts +158 -0
  215. package/lib/types/tool/schema.d.ts.map +1 -0
  216. package/lib/types/tool/schema.js +137 -0
  217. package/lib/types/tool/schema.js.map +1 -0
  218. package/lib/types/types.d.ts +9 -0
  219. package/lib/types/types.d.ts.map +1 -0
  220. package/lib/types/types.js +3 -0
  221. package/lib/types/types.js.map +1 -0
  222. package/lib/types/user-questions.d.ts +9 -0
  223. package/lib/types/user-questions.d.ts.map +1 -0
  224. package/lib/types/user-questions.js +91 -0
  225. package/lib/types/user-questions.js.map +1 -0
  226. package/package.json +273 -0
  227. package/skills/create-workflow/SKILL.md +166 -0
  228. package/vendor/workflow-engine/LICENSE +21 -0
  229. package/vendor/workflow-engine/README.md +1 -0
@@ -0,0 +1,177 @@
1
+ # Package architecture
2
+
3
+ English | [中文](architecture.zh.md)
4
+
5
+ This reference describes the installed architecture of `@zaalipro/dsh-workflows`: one Host/Client bundle for official DeepSeek Harness `0.1.1-rc.2`, with a package-owned MIT compatibility evaluator. The [user guide](user-guide.md) owns operating procedures, the [testing reference](testing.md) owns release evidence, and the [architecture decision](../.agents/notes/implemented/architecture/2026-08-20-installable-workflows-package.md) owns rationale and rejected alternatives.
6
+
7
+ ## Scope and invariants
8
+
9
+ The package owns definition discovery, logical-run supervision, retained storage, completion delivery, commands, Agent-scoped model-tool replacement, authorized Remote reads, the Web dashboard, and the private JavaScript compatibility evaluator. Official `0.1.1-rc.2` owns the Host, Agent, Session, provider, and Client services. A Headless install evaluates no browser module. A Web install adds the Client aggregate without changing Host execution authority.
10
+
11
+ Current state: plugin `0.1.0-rc.3` is verified against official `0.1.1-rc.2`. The plugin adapts the public Agent-scoped tool/prompt, filesystem, command, Remote, and provider faces and does not modify the stock `ctx.workflowEngine`.
12
+
13
+ Four invariants organize every component:
14
+
15
+ 1. A start is durable before it is visible, and a deferred private evaluator attempt has an owner before it can execute.
16
+ 2. A same-process resume uses only the quiescent engine checkpoint; observe-only events never become replay authority.
17
+ 3. Protected run data moves through Agent-authorized, bounded Remote pages; broadcast events carry invalidation only.
18
+ 4. Teardown closes admission and drains owned work to a fixed point before releasing the storage lease.
19
+
20
+ ## Package topology
21
+
22
+ ### Web composition
23
+
24
+ ```mermaid
25
+ flowchart LR
26
+ subgraph H[Official Harness 0.1.1-rc.2]
27
+ Loader[Profile loader]
28
+ Engine[Stock workflow service]
29
+ Agent[Exact Agent context]
30
+ Session[Session log]
31
+ Gateway[Typert Gateway and ApiProxy]
32
+ Slots[Client slots and shell overlay]
33
+ end
34
+ subgraph Package[One installed package]
35
+ Host[Host aggregate]
36
+ Registry[Definition registry]
37
+ Supervisor[Logical-run supervisor]
38
+ Store[Version-2 store]
39
+ Recorder[Durable recorder]
40
+ Remote[Generated Remote services]
41
+ Client[Client aggregate]
42
+ Controller[Revisioned controller]
43
+ Dashboard[Dashboard and inspector]
44
+ Chat[Durable Chat renderer]
45
+ end
46
+ Loader --> Host
47
+ Host --> Registry
48
+ Host --> Supervisor
49
+ Supervisor --> Engine
50
+ Supervisor --> Store
51
+ Agent --> Host
52
+ Supervisor --> Recorder --> Session
53
+ Registry --> Remote
54
+ Supervisor --> Remote --> Gateway --> Controller
55
+ Loader --> Client --> Controller
56
+ Client --> Dashboard --> Slots
57
+ Client --> Chat --> Slots
58
+ ```
59
+
60
+ The package's bundle patch mounts exactly one Host aggregate, advertises `lib/client.js`, and disables the stock workflow Chat renderer only where the package renderer consumes the same official durable vocabulary. It does not edit an official profile file.
61
+
62
+ ### Headless composition
63
+
64
+ ```mermaid
65
+ flowchart LR
66
+ Loader[Official 0.1.1-rc.2 profile loader] --> Host[Package Host aggregate]
67
+ Host --> Registry[Definition registry]
68
+ Host --> Supervisor[Logical-run supervisor]
69
+ Host --> Commands[Commands and tool shadow]
70
+ Supervisor --> Engine[Package compatibility evaluator]
71
+ Supervisor --> Store[Version-2 retained store]
72
+ Supervisor --> Recorder[Durable Session recorder]
73
+ Host --> Remote[Generated Host Remote services]
74
+ Browser[Client aggregate]:::absent
75
+ classDef absent stroke-dasharray: 5 5,opacity:0.45
76
+ ```
77
+
78
+ The headless bundle has no import path to `./client`; commands, saved aliases, the model tool, gates, supervision, persistence, and durable Session recording remain available.
79
+
80
+ ## Component and event ownership
81
+
82
+ ### Host components
83
+
84
+ - **Aggregate and configuration** validate official `0.1.1-rc.2` faces before filesystem access, resolve every Schemastery default, load assets relative to `import.meta.url`, and mount children under effect ownership.
85
+ - **Definition registry (`ctx.workflows`)** observes bundled, project, and user roots; re-reads authoritative bytes; publishes only coalesced `workflows/change` hints; and owns safe save publication.
86
+ - **Run store and native lease** own manifests, immutable detail sidecars, scripts, scratch files, retention, recovery, and one process-lifetime advisory lock.
87
+ - **Supervisor (`ctx.workflowSupervisor`)** owns exact Agent/Session authorization, logical identities, attempts, status transitions, budgets, checkpoints, gates, controls, and lifecycle events.
88
+ - **Completion notifier** owns the `none -> claimed -> delivered|abandoned` outbox and bounded direct Session-surface append cohorts. It never wakes the Agent or writes either inbox lane.
89
+ - **Run recorder (`ctx.workflowRunRecorder`)** projects explicitly attributed top-level runs into the official Session vocabulary.
90
+ - **Question bridge** maps an exact fenced `workflows/gate-request` to `ctx.userQuestions` and acknowledges only the current Agent/run/execution/gate tuple.
91
+ - **Commands and trusted skill** own `/workflow`, `/create-workflow`, dynamic aliases, and the protected packaged `create-workflow` definition. The Client input-trigger source exclusively owns bare `/workflows` and its overlay.
92
+ - **Tool adapter** temporarily replaces the official `workflow` tool and `tool:workflow` prompt section only in the exact Agent context where both official identities match.
93
+ - **Remote services** expose definition lists and paged run detail, members, logs, result, artifacts, chunks, and revision-checked controls.
94
+
95
+ The supervisor emits package-local `workflows/run-start`, `workflows/member-start`, `workflows/member-end`, `workflows/run-end`, `workflows/run-change`, and `workflows/gate-request`. These events are process lifecycle and invalidation signals, not durable replay authority. The recorder writes only `tool-workflow/run-start`, `tool-workflow/agent-start`, `tool-workflow/agent-end`, and `tool-workflow/run-end`; the package invents no durable phase or log event.
96
+
97
+ ### Client components
98
+
99
+ - **Generated Remote mount** installs `lib/typert.remote-client.js` before any Remote consumer and unmounts it after reads and controllers abort.
100
+ - **WorkflowRunsController** keeps one lazy revisioned source per observed Session, handles paging and reconnect generations, and never recreates removed state from a late response.
101
+ - **Dashboard navigator** opens as a client-owned centered overlay modal (conversation remains visible behind dimmed chrome) and owns wide, two-pane, and mobile drill-down navigation.
102
+ - **Member inspector** distinguishes pending, JSON (including `null`), text, primitive, truncated, not-produced, evicted, unavailable-transcript, and request-error states.
103
+ - **Durable Chat renderer** folds only the four official Session events and never observes package-private run heads.
104
+
105
+ Browser HMR disposes controllers, actions, overlays, generated Remote mounts, and CSS ownership before mounting the new Client generation. A Host HMR cycle follows the full teardown sequence; it never carries a live attempt into a replacement plugin generation.
106
+
107
+ ## Public subpaths and build faces
108
+
109
+ The public export map is closed: `.`, `./registry`, `./supervisor`, `./run-recorder`, `./user-questions`, `./commands`, `./tool`, `./client`, `./types`, `./invariant`, `./typert`, `./remote`, `./cordis.patch.yml`, `./skills/create-workflow/SKILL.md`, and `./package.json`. No `./src/*` path is public.
110
+
111
+ The package root owns three compiler faces: solution `tsconfig.json`, Host `tsconfig.host.json`, and Client `tsconfig.client.json`. Build order is **Host TSC -> Typert -> Client TSC -> classic lazy CJS**. A temporary copied mini-workspace provides one staging-root Host aggregate and one copied-package staging `tsconfig.json`; it has no nested Host/Client aggregate files. Focused `WorkspaceTypertGenerator.generate()` returns artifacts, and the build writes exactly `lib/typert.host.js`, `lib/typert.host.d.ts`, `lib/typert.remote-client.js`, and `lib/typert.remote-client.d.ts`, plus a map only when returned.
112
+
113
+ The final `lib/client.js` must call `window.__ModuleLoader__.load({ id: "@zaalipro/dsh-workflows", factory: (require) => ... })` with a non-empty factory. Optional-chaining `?.load` and `factory: () => ({})` placeholders fail the build and package verifier. The bundle keeps baseline Client dependencies external, inlines package Remote and `clsx` code, and lets Lightning CSS own module names and lifecycle. Skill, patch, and Client asset paths derive from `import.meta.url`, never the process cwd. The private evaluator is emitted from `vendor/workflow-engine` as `lib/compat-engine/index.js` and `worker.cjs`; it is instantiated only for the supervisor and never replaces stock `ctx.workflowEngine`. Published and Git installs ship those prebuilt artifacts; `dsh plugin add` must not run a build.
114
+
115
+ ## Lifecycle authority
116
+
117
+ ### Boot and startup recovery
118
+
119
+ Activation first verifies the supported official `0.1.1-rc.2` service faces. Storage then validates or creates only the owner-only runs root and permanent lock anchor, opens the anchor without following links, validates its stable identity, and acquires a nonblocking `fs-native-extensions` lifetime lease. Only the lease holder creates or validates the four store directories and performs one complete, bounded recovery before Session admission.
120
+
121
+ Recovery validates every manifest and referenced sidecar before publishing any row. Persisted active rows become terminal `interrupted`, running member heads become `cancelled`, and orphaned notice claims become `abandoned`. Recovery keeps inspection facts and display ordinals but reconstructs no execution authority.
122
+
123
+ ### Durable-before-visible launch
124
+
125
+ Start validates ownership, source, args, budget, and capacity before reserving a display ordinal or path. It stages `script.js`, `scratch/`, and `details/`, publishes the single-component run directory, and commits the initial version-2 manifest row. That manifest transaction is durable admission. The supervisor then installs private starting authority, attaches all observers and a deferred evaluator attempt, publishes the in-memory row and package lifecycle, releases execution once, and returns `started` without awaiting settlement.
126
+
127
+ A caller abort before durable admission rolls back without a run directory or ordinal. After admission, the supervisor owns the detached run. A later attachment or execution failure terminalizes retained history instead of deleting it.
128
+
129
+ ### Pause, resume, and gates
130
+
131
+ Pause commits `pausing`, closes new engine work, cancels the attempt, awaits its result, awaits idempotent disposal and child/scratch drainage, then reads `checkpoint()` synchronously. The supervisor commits and publishes `paused` only after that quiescent checkpoint exists.
132
+
133
+ Ordinary Resume starts a new attempt over the immutable admitted script and args plus the retained in-memory checkpoint. An `await_user` acknowledgement continues the exact live attempt and commits the satisfied gate; a `pause` acknowledgement disposes the parked attempt and replays, so an unchanged pause condition emits again. Every answer is fenced by exact Agent identity, Session, logical run, engine execution, gate id, and generation. A budget-limited run accepts only model resume with a strictly higher absolute cap up to 1,024.
134
+
135
+ ### Stop and completion notice
136
+
137
+ Stop closes admission, commits `stopping`, cancels the attempt and every admitted child/scratch operation, awaits paired member endings and disposal, discards resume authority, then atomically commits terminal `cancelled` and its notice claim. A clean or failed settlement follows the same dispose-before-terminal discipline.
138
+
139
+ The terminal transaction changes `completionNotice` from `none` to `claimed` before the head becomes visible. One bounded append attempt finalizes that claim as `delivered` or `abandoned`; neither state retries. Cohorts carry at most 20 notices and 262,144 UTF-8 bytes. They append a plugin-sourced `user/message` directly to the owner Session with `surfaceOp: "append"`, making it durable and visible without opening a completion-driven model turn.
140
+
141
+ ### Remote reconnect and HMR
142
+
143
+ `workflows/run-change` carries only `{ kind: 'invalidate', sessionId, revision }` or `{ kind: 'invalidate-all' }`. ApiProxy keeps keyed-latest hints for at most 256 Session keys and collapses overflow to the global form. On connection loss the Client aborts reads and marks existing sources reconnecting. After `connection/reset`, it fetches a new Agent-authorized epoch baseline before accepting later invalidations. Page, selection, Session, and connection generations suppress late responses.
144
+
145
+ ### Fixed-point teardown
146
+
147
+ Host teardown closes global start admission, aborts and awaits pre-admission starts, stops and disposes published attempts, drains child/scratch operations, commits terminal rows, completes recorder prefixes, withdraws questions, and delivers or abandons notices. It repeats until completion-driven work cannot add another owner. Only then do the registry and storage close; the native lease unlock and descriptor close are last. This sequence leaves no worker, child, timer, watcher, request, or lock owner behind.
148
+
149
+ ## Manifest version 2 and secure storage
150
+
151
+ The default root is `$DSH_HOME/workflow-runs` with permanent `.workflow-storage.lock`, Session manifests at `sessions/<sha256(sessionId)>/manifest.json`, and one safe 32-lowercase-hex directory per run under `runs/`. Each run directory owns `script.js`, `scratch/`, and immutable `details/<detail-id>.json` snapshots. `staging/` and `quarantine/` are separate root children.
152
+
153
+ The at-most-8-MiB manifest is a Session head/index: ownership, display ordinal high-water marks, bounded run heads, revisions, one-component directory ids, sidecar references, and notice state. It never carries absolute paths, full outputs, args, journals, gates, or Agent references. One fully fsynced detail snapshot holds bounded members, logs, result, and artifact indexes; each run has at most 32 MiB of referenced detail. Terminal retention keeps at most 256 rows per Session, and total committed storage is at most 512 MiB. Oldest eligible terminal rows evict deterministically; active and claimed-notice rows never evict, and display ordinal history remains.
154
+
155
+ Every run-storage directory walk uses the plugin-owned, fail-closed local descriptor implementation; the official filesystem service remains authoritative for definition discovery. A `script_path` read prefers a Host `readBytesNoFollow` capability. Published stock RC2 lacks that method, so only for its verified local filesystem shape the plugin authorizes and normalizes through the public Host `lstat`/`resolve`/`processPath` methods, then performs its own bounded `O_NOFOLLOW` descriptor read; unknown and remote providers fail closed. Root and components must have the current owner, restrictive `0700`/`0600` modes, expected type, one link for regular files, no symlink or junction, and stable device/inode identity. Cleanup never recurses after identity changes. The permanent kernel lock has no PID, heartbeat, stale age, retry, takeover, or deletion protocol. It coordinates cooperating same-user processes, not a malicious same-UID actor that ignores the lease.
156
+
157
+ ## Replay and script containment
158
+
159
+ The journal addresses committed hooks with positive-safe-integer tuples in numeric lexicographic order and fingerprints each effective operation with lowercase SHA-256. Replay validates id, kind, and fingerprint before any new effect. Cumulative `agentSpend` and member sequence continue across attempts; replay and schema-correction calls cost no additional logical agent. An uncommitted effect may run again, so the system does not claim exactly-once external effects.
160
+
161
+ Replay-capable runs remove `Date`, `Math.random`, `Atomics`, `SharedArrayBuffer`, `WeakRef`, and `FinalizationRegistry` while preserving deterministic Math functions. `node:vm` shapes that API and keeps synchronous script work off the Host event loop; it is not a security sandbox for hostile code. Scripts retain the same trust premise as existing model shell access.
162
+
163
+ ## Bounded Remote and browser presentation
164
+
165
+ Every direct Remote method receives an explicit resolved Agent first and a required `AbortSignal` last; none combines that root with `@RemoteScope`. The exact Agent and its Session authorize every run, member, artifact, cursor, and control before protected data is read. List limits default to 50 and cap at 200. Only heads are eager; detail, members, outcomes, logs, result, artifacts, and UTF-8-safe artifact chunks load after selection.
166
+
167
+ The dashboard has three panes at 1,200 px and wider, two-pane navigation below 1,200 px, and explicit runs-to-execution-to-inspector drill-down below 768 px, including 320 px. It traps and restores focus, uses real selection controls, preserves prior successful pages on errors, exposes labelled Retry actions, supports Escape and guarded P/R/X/S shortcuts, respects reduced motion, and keeps narrow actions at least 44 px.
168
+
169
+ ## Compatibility provenance
170
+
171
+ Official `0.1.1-rc.2` integration uses Agent-scoped `tools.register` and `systemPrompt.section` only when the stock workflow contribution is identified; custom same-name contributions remain untouched. The package owns deferred execution, replay journal, checkpoints, gates, budget accounting, and scratch in its private compatibility evaluator.
172
+
173
+ Official `0.1.1-rc.2` is the only verified installed Host for plugin `0.1.0-rc.3`; `0.1.0-rc.8` is unsupported and later Hosts require re-verification. The compatibility evaluator is package-owned MIT source derived narrowly from the maintained workflow behavior, not a replacement for the process-global stock workflow service.
174
+
175
+ ## Capacity bounds
176
+
177
+ Defaults and hard ceilings keep every path bounded: 128 agents per run by default and 1,024 maximum; deployment live concurrency; 8 MiB Host protocol frames; 64 MiB journals; 1 MiB prompts and definition/projection files; 64 KiB events; 8 MiB manifests; 32 MiB detail per run; 512 MiB committed store; 4,096 startup entries; 64 active runs per Session and 1,024 globally; 200 rows per Remote page; and 256 pending Session invalidation keys. Scratch allows at most 4,096 operations, 64 pending operations, 64 files, 1 MiB per file, and 8 MiB total unless configuration lowers a limit.
@@ -0,0 +1,177 @@
1
+ # 包架构
2
+
3
+ [English](architecture.md) | 中文
4
+
5
+ 本参考说明 `@zaalipro/dsh-workflows` 的已安装架构:它是面向官方 DeepSeek Harness `0.1.1-rc.2` 的单一 Host/Client bundle,并包含 private compatibility evaluator(package-owned MIT source)。[用户指南](user-guide.zh.md)负责操作步骤,[测试参考](testing.zh.md)负责发布证据,[架构决策](../.agents/notes/implemented/architecture/2026-08-20-installable-workflows-package.zh.md)负责理由和被拒绝的替代方案。
6
+
7
+ ## 范围与不变量
8
+
9
+ 本包拥有 definition discovery、logical-run supervision、retained storage、completion delivery、命令、Agent-scoped model-tool replacement、授权 Remote read、Web dashboard 与 private JavaScript compatibility evaluator。官方 `0.1.1-rc.2` 拥有 Host、Agent、Session、provider 与 Client service。Headless 安装不求值任何浏览器模块;Web 安装增加 Client aggregate,但不改变 Host execution authority。
10
+
11
+ 当前状态:plugin `0.1.0-rc.3` 已针对官方 `0.1.1-rc.2` 验证。Plugin 适配 public Agent-scoped tool/prompt、filesystem、command、Remote 与 provider face,不修改 stock `ctx.workflowEngine`。
12
+
13
+ 四条不变量组织所有组件:
14
+
15
+ 1. start 在可见前持久化,而且 deferred private evaluator attempt 在执行前已经有 owner。
16
+ 2. same-process resume 只使用 quiescent engine checkpoint;observe-only event 绝不成为 replay authority。
17
+ 3. 受保护的 run data 通过 Agent-authorized、bounded Remote page 传输;broadcast event 只携带 invalidation。
18
+ 4. teardown 先关闭 admission 并把 owned work 排空到 fixed point,最后才释放 storage lease。
19
+
20
+ ## 包拓扑
21
+
22
+ ### Web composition
23
+
24
+ ```mermaid
25
+ flowchart LR
26
+ subgraph H[Official Harness 0.1.1-rc.2]
27
+ Loader[Profile loader]
28
+ Engine[Stock workflow service]
29
+ Agent[Exact Agent context]
30
+ Session[Session log]
31
+ Gateway[Typert Gateway and ApiProxy]
32
+ Slots[Client slots and shell overlay]
33
+ end
34
+ subgraph Package[One installed package]
35
+ Host[Host aggregate]
36
+ Registry[Definition registry]
37
+ Supervisor[Logical-run supervisor]
38
+ Store[Version-2 store]
39
+ Recorder[Durable recorder]
40
+ Remote[Generated Remote services]
41
+ Client[Client aggregate]
42
+ Controller[Revisioned controller]
43
+ Dashboard[Dashboard and inspector]
44
+ Chat[Durable Chat renderer]
45
+ end
46
+ Loader --> Host
47
+ Host --> Registry
48
+ Host --> Supervisor
49
+ Supervisor --> Engine
50
+ Supervisor --> Store
51
+ Agent --> Host
52
+ Supervisor --> Recorder --> Session
53
+ Registry --> Remote
54
+ Supervisor --> Remote --> Gateway --> Controller
55
+ Loader --> Client --> Controller
56
+ Client --> Dashboard --> Slots
57
+ Client --> Chat --> Slots
58
+ ```
59
+
60
+ 本包的 bundle patch 只挂载一个 Host aggregate,公布 `lib/client.js`,并且只在本包 renderer 消费相同官方 durable vocabulary 的位置禁用 stock workflow Chat renderer。它不会修改官方 profile 文件。
61
+
62
+ ### Headless composition
63
+
64
+ ```mermaid
65
+ flowchart LR
66
+ Loader[Official 0.1.1-rc.2 profile loader] --> Host[Package Host aggregate]
67
+ Host --> Registry[Definition registry]
68
+ Host --> Supervisor[Logical-run supervisor]
69
+ Host --> Commands[Commands and tool shadow]
70
+ Supervisor --> Engine[Package compatibility evaluator]
71
+ Supervisor --> Store[Version-2 retained store]
72
+ Supervisor --> Recorder[Durable Session recorder]
73
+ Host --> Remote[Generated Host Remote services]
74
+ Browser[Client aggregate]:::absent
75
+ classDef absent stroke-dasharray: 5 5,opacity:0.45
76
+ ```
77
+
78
+ headless bundle 没有通往 `./client` 的 import path;命令、保存的 alias、model tool、gate、supervision、persistence 和 durable Session recording 仍然可用。
79
+
80
+ ## 组件与事件归属
81
+
82
+ ### Host 组件
83
+
84
+ - **Aggregate 与配置**在访问 filesystem 前验证官方 `0.1.1-rc.2` 的 package version 与 service face,解析每个 Schemastery default,通过 `import.meta.url` 相对路径加载资产,并在 effect ownership 下挂载 child。
85
+ - **Definition registry (`ctx.workflows`)** 观察 bundled、project 和 user root;重新读取 authoritative byte;只发布合并后的 `workflows/change` hint;并拥有 safe save publication。
86
+ - **Run store 与 native lease** 拥有 manifest、immutable detail sidecar、script、scratch file、retention、recovery 和一个 process-lifetime advisory lock。
87
+ - **Supervisor (`ctx.workflowSupervisor`)** 拥有 exact Agent/Session authorization、logical identity、attempt、status transition、budget、checkpoint、gate、control 和 lifecycle event。
88
+ - **Completion notifier** 拥有 `none -> claimed -> delivered|abandoned` outbox 和 bounded direct Session-surface append cohort;它不会唤醒 Agent,也不会写入任何 inbox lane。
89
+ - **Run recorder (`ctx.workflowRunRecorder`)** 把明确归属的 top-level run 投影到官方 Session vocabulary。
90
+ - **Question bridge** 把 exact fenced `workflows/gate-request` 映射到 `ctx.userQuestions`,只确认当前 Agent/run/execution/gate tuple。
91
+ - **命令与 trusted skill** 拥有 `/workflow`、`/create-workflow`、dynamic alias 以及受保护的 packaged `create-workflow` definition。Client input-trigger source 独占裸 `/workflows` 及其 overlay。
92
+ - **Tool adapter** 只在两个官方 identity 都匹配的 exact Agent context 中临时替换官方 `workflow` tool 和 `tool:workflow` prompt section。
93
+ - **Remote service** 提供 definition list 以及分页的 run detail、member、log、result、artifact、chunk 和 revision-checked control。
94
+
95
+ Supervisor 发出 package-local `workflows/run-start`、`workflows/member-start`、`workflows/member-end`、`workflows/run-end`、`workflows/run-change` 和 `workflows/gate-request`。这些 event 是 process lifecycle 与 invalidation signal,不是 durable replay authority。Recorder 只写入 `tool-workflow/run-start`、`tool-workflow/agent-start`、`tool-workflow/agent-end` 和 `tool-workflow/run-end`;本包不发明 durable phase 或 log event。
96
+
97
+ ### Client 组件
98
+
99
+ - **Generated Remote mount** 在任何 Remote consumer 前安装 `lib/typert.remote-client.js`,并在 read 和 controller abort 后卸载。
100
+ - **WorkflowRunsController** 为每个 observed Session 保存一个 lazy revisioned source,处理 paging 与 reconnect generation,绝不让 late response 重建已移除状态。
101
+ - **Dashboard navigator** 作为 client-owned 居中 overlay modal 打开(conversation 在 dimmed chrome 后仍可见),拥有宽屏、双 pane 和 mobile drill-down navigation。
102
+ - **Member inspector** 区分 pending、JSON(包括 `null`)、text、primitive、truncated、not-produced、evicted、unavailable-transcript 和 request-error 状态。
103
+ - **Durable Chat renderer** 只 fold 四个官方 Session event,绝不观察 package-private run head。
104
+
105
+ 浏览器 HMR 会依次 dispose controller、action、overlay、generated Remote mount 和 CSS ownership,然后挂载新的 Client generation。Host HMR cycle 遵循完整 teardown sequence;它不会把 live attempt 带入替换后的 plugin generation。
106
+
107
+ ## Public subpath 与 build face
108
+
109
+ public export map 是闭集:`.`、`./registry`、`./supervisor`、`./run-recorder`、`./user-questions`、`./commands`、`./tool`、`./client`、`./types`、`./invariant`、`./typert`、`./remote`、`./cordis.patch.yml`、`./skills/create-workflow/SKILL.md` 和 `./package.json`。没有公开的 `./src/*` path。
110
+
111
+ package root 拥有三个 compiler face:solution `tsconfig.json`、Host `tsconfig.host.json` 和 Client `tsconfig.client.json`。Build 顺序为 **Host TSC -> Typert -> Client TSC -> classic lazy CJS**。临时复制的 mini-workspace 提供一个 staging-root Host aggregate 和一个 copied-package staging `tsconfig.json`;其中没有嵌套 Host/Client aggregate file。Focused `WorkspaceTypertGenerator.generate()` 返回 artifact,build 会准确写入 `lib/typert.host.js`、`lib/typert.host.d.ts`、`lib/typert.remote-client.js` 和 `lib/typert.remote-client.d.ts`,并且只在返回值包含 map 时写 map。
112
+
113
+ 最终的 `lib/client.js` 必须调用 `window.__ModuleLoader__.load({ id: "@zaalipro/dsh-workflows", factory: (require) => ... })`,且 factory 非空。Optional-chaining `?.load` 与 `factory: () => ({})` 占位符会使 build 与 package verifier 失败。bundle 保持 baseline Client dependency 为 external,内联 package Remote 与 `clsx` code,并由 Lightning CSS 拥有 module name 和 lifecycle。Skill、patch 与 Client asset path 来自 `import.meta.url`,绝不来自 process cwd。Private evaluator 由 `vendor/workflow-engine` 构建为 tarball 中的 `lib/compat-engine/index.js` 与 `worker.cjs`,只供 supervisor 实例化,绝不替换 stock `ctx.workflowEngine`。发布物与 Git install 带上这些预构建 artifact;`dsh plugin add` 不得在安装时构建。
114
+
115
+ ## Lifecycle authority
116
+
117
+ ### 启动与 startup recovery
118
+
119
+ Activation 首先验证受支持的官方 `0.1.1-rc.2` service face。Storage 随后只验证或创建 owner-only runs root 和永久 lock anchor,以 no-follow 方式打开 anchor,验证稳定 identity,并取得非阻塞 `fs-native-extensions` lifetime lease。只有 lease holder 能创建或验证四个 store directory,并在 Session admission 前完成一次完整且有界的 recovery。
120
+
121
+ Recovery 会在发布任何 row 前验证所有 manifest 和引用的 sidecar。持久化的 active row 变成 terminal `interrupted`,running member head 变成 `cancelled`,orphaned notice claim 变成 `abandoned`。Recovery 保留 inspection fact 和 display ordinal,但不重建 execution authority。
122
+
123
+ ### Durable-before-visible launch
124
+
125
+ Start 在预留 display ordinal 或 path 前验证 ownership、source、args、budget 和 capacity。它 stage `script.js`、`scratch/` 和 `details/`,发布单 component run directory,然后提交 initial version-2 manifest row。该 manifest transaction 是 durable admission。Supervisor 随后安装 private starting authority,附加所有 observer 和一个 deferred evaluator attempt,发布 in-memory row 和 package lifecycle,仅 release execution 一次,并在不等待 settlement 的情况下返回 `started`。
126
+
127
+ Durable admission 前的 caller abort 会 rollback,不留下 run directory 或 ordinal。Admission 后由 supervisor 拥有 detached run。之后的 attachment 或 execution failure 会 terminalize retained history,而不是删除它。
128
+
129
+ ### Pause、resume 与 gate
130
+
131
+ Pause 提交 `pausing`,关闭新的 engine work,取消 attempt,等待 result,等待 idempotent disposal 与 child/scratch drainage,然后同步读取 `checkpoint()`。Supervisor 只在该 quiescent checkpoint 存在后提交并发布 `paused`。
132
+
133
+ 普通 Resume 用 immutable admitted script、args 和 retained in-memory checkpoint 启动新 attempt。`await_user` acknowledgement 会继续 exact live attempt 并提交 satisfied gate;`pause` acknowledgement 会 dispose parked attempt 并 replay,因此未改变的 pause condition 会再次 emit。每个 answer 都由 exact Agent identity、Session、logical run、engine execution、gate id 和 generation fence 保护。Budget-limited run 只接受 model resume,且绝对 cap 必须严格提高并不超过 1,024。
134
+
135
+ ### Stop 与 completion notice
136
+
137
+ Stop 关闭 admission,提交 `stopping`,取消 attempt 和所有 admitted child/scratch operation,等待 paired member ending 与 disposal,丢弃 resume authority,最后原子提交 terminal `cancelled` 及其 notice claim。Clean 或 failed settlement 遵循相同的 dispose-before-terminal discipline。
138
+
139
+ Terminal transaction 在 head 可见前把 `completionNotice` 从 `none` 变成 `claimed`。一次 bounded append attempt 会把 claim finalize 为 `delivered` 或 `abandoned`;两者都不会重试。每个 cohort 最多携带 20 个 notice 和 262,144 UTF-8 byte。它通过 `surfaceOp: "append"` 把 plugin-sourced `user/message` 直接追加到 owner Session,使 notice durable 且立即可见,同时不会打开 completion-driven model turn。
140
+
141
+ ### Remote reconnect 与 HMR
142
+
143
+ `workflows/run-change` 只携带 `{ kind: 'invalidate', sessionId, revision }` 或 `{ kind: 'invalidate-all' }`。ApiProxy 为最多 256 个 Session key 保留 keyed-latest hint,并把 overflow 合并成 global form。Connection loss 时 Client abort read,并把已有 source 标记为 reconnecting。`connection/reset` 后,它先获取新的 Agent-authorized epoch baseline,再接受后续 invalidation。Page、selection、Session 和 connection generation 会抑制 late response。
144
+
145
+ ### Fixed-point teardown
146
+
147
+ Host teardown 关闭 global start admission,abort 并等待 pre-admission start,停止和 dispose 已发布 attempt,排空 child/scratch operation,提交 terminal row,完成 recorder prefix,withdraw question,并 deliver 或 abandon notice。它重复检查,直到 completion-driven work 无法再增加 owner。随后才关闭 registry 和 storage;native lease unlock 与 descriptor close 最后执行。该顺序不会遗留 worker、child、timer、watcher、request 或 lock owner。
148
+
149
+ ## Manifest version 2 与安全存储
150
+
151
+ 默认 root 是 `$DSH_HOME/workflow-runs`,其中包含永久 `.workflow-storage.lock`、位于 `sessions/<sha256(sessionId)>/manifest.json` 的 Session manifest,以及 `runs/` 下每个 run 独有的安全 32 位小写十六进制 directory。每个 run directory 拥有 `script.js`、`scratch/` 和 immutable `details/<detail-id>.json` snapshot。`staging/` 与 `quarantine/` 是独立的 root child。
152
+
153
+ 最大 8 MiB 的 manifest 是 Session head/index:ownership、display ordinal high-water mark、bounded run head、revision、单 component directory id、sidecar reference 和 notice state。它从不携带 absolute path、完整 output、args、journal、gate 或 Agent reference。一个 fully fsynced detail snapshot 保存 bounded member、log、result 和 artifact index;每个 run 最多引用 32 MiB detail。Terminal retention 每个 Session 最多保留 256 row,全部 committed storage 最多 512 MiB。最旧且符合条件的 terminal row 会确定性 evict;active 与 claimed-notice row 绝不 evict,display ordinal history 保留。
154
+
155
+ 每次 run-storage directory walk 都使用 plugin-owned、fail-closed local descriptor implementation;官方 filesystem service 仍负责 definition discovery。`script_path` read 优先使用 Host `readBytesNoFollow` capability。已发布的 stock RC2 没有该方法,因此 plugin 仅在验证为其 local filesystem shape 后,先通过 public Host `lstat`/`resolve`/`processPath` method 完成授权与规范化,再自行执行 bounded `O_NOFOLLOW` descriptor read;unknown 与 remote provider 会 fail closed。Root 与 component 必须属于当前 owner,具有严格 `0700`/`0600` mode、预期 type、regular file 单 link、无 symlink 或 junction,以及稳定 device/inode identity。Identity 改变后 cleanup 不会 recurse。永久 kernel lock 没有 PID、heartbeat、stale age、retry、takeover 或 deletion protocol。它协调同一用户下合作的 process,而不是忽略 lease 的 malicious same-UID actor。
156
+
157
+ ## Replay 与 script containment
158
+
159
+ Journal 使用按 numeric lexicographic order 排列的 positive-safe-integer tuple 寻址 committed hook,并用小写 SHA-256 fingerprint 标识每个 effective operation。Replay 会在任何新 effect 前验证 id、kind 和 fingerprint。Cumulative `agentSpend` 和 member sequence 跨 attempt 延续;replay 与 schema-correction call 不增加 logical agent 消耗。Uncommitted effect 可能再次执行,因此系统不声称 exactly-once external effect。
160
+
161
+ Replay-capable run 移除 `Date`、`Math.random`、`Atomics`、`SharedArrayBuffer`、`WeakRef` 和 `FinalizationRegistry`,同时保留 deterministic Math function。`node:vm` 塑造该 API,并使 synchronous script work 不阻塞 Host event loop;它不是 hostile-code security sandbox。Script 与现有 model shell access 保持相同 trust premise。
162
+
163
+ ## Bounded Remote 与浏览器展示
164
+
165
+ 每个 direct Remote method 的首个参数都是显式 resolved Agent,最后一个参数是必需的 `AbortSignal`;没有方法把该 root 与 `@RemoteScope` 组合。Exact Agent 及其 Session 会在读取受保护数据前授权每个 run、member、artifact、cursor 和 control。List limit 默认 50,最大 200。只有 head eager load;detail、member、outcome、log、result、artifact 和 UTF-8-safe artifact chunk 都在 selection 后加载。
166
+
167
+ Dashboard 在 1,200 px 及以上使用三 pane,低于 1,200 px 使用双 pane,低于 768 px(包括 320 px)使用明确的 runs-to-execution-to-inspector drill-down。它 trap 并恢复 focus,使用真实 selection control,在 error 后保留先前成功 page,提供有 label 的 Retry action,支持 Escape 和受保护的 P/R/X/S shortcut,尊重 reduced motion,并让窄屏 action 至少为 44 px。
168
+
169
+ ## 兼容性来源
170
+
171
+ 官方 `0.1.1-rc.2` integration 只在识别出 stock workflow contribution 时使用 Agent-scoped `tools.register` 与 `systemPrompt.section`;同名 custom contribution 保持不变。Deferred execution、replay journal、checkpoint、gate、budget accounting 与 scratch 由 package private compatibility evaluator 提供。
172
+
173
+ 官方 `0.1.1-rc.2` 是 plugin `0.1.0-rc.3` 唯一已验证的 installed Host;`0.1.0-rc.8` 不受支持,更高 Host 必须重新验证。Compatibility evaluator 是 package-owned MIT source,只窄范围承载 maintained workflow behavior,绝不替换 stock `ctx.workflowEngine` 或 process-global stock workflow service。
174
+
175
+ ## Capacity bound
176
+
177
+ Default 与 hard ceiling 使所有 path 有界:每个 run 默认 128 个 agent、最多 1,024;deployment live concurrency;8 MiB Host protocol frame;64 MiB journal;1 MiB prompt 与 definition/projection file;64 KiB event;8 MiB manifest;每个 run 32 MiB detail;512 MiB committed store;4,096 个 startup entry;每个 Session 64 个 active run、全局 1,024;每个 Remote page 200 row;以及 256 个 pending Session invalidation key。Scratch 最多允许 4,096 次 operation、64 个 pending operation、64 个 file、每个 file 1 MiB、合计 8 MiB,除非 configuration 下调限制。
@@ -0,0 +1,4 @@
1
+ # Bilingual-pair consistency record: git blob hash of each side at the last
2
+ # confirmed-consistent state. Both languages carry equal authority.
3
+ testing.md: 6c3bb3f89939ed2aae75a6ab812203b841d95bca
4
+ testing.zh.md: 25edde0ab27df71ec0b34b5fe8e91fa6840b7591
@@ -0,0 +1,125 @@
1
+ # Testing and release acceptance
2
+
3
+ English | [中文](testing.zh.md)
4
+
5
+ This reference separates automated proof from the final human release decision. A green unit suite never substitutes for the official-prerequisite, assembled, packed-consumer, browser, race, provider, or manual boundaries below.
6
+
7
+ ## Automated gates
8
+
9
+ Run package commands from the package checkout with a frozen `pnpm@11.7.0` install. Each command exits nonzero at its first failure; the text after it is the success marker a CI or release log must retain.
10
+
11
+ ### Build, type, lint, coverage, and docs
12
+
13
+ ```sh
14
+ pnpm run build && printf 'package build PASS\n'
15
+ pnpm run typecheck && printf 'package typecheck PASS\n'
16
+ pnpm run lint && printf 'package lint PASS\n'
17
+ pnpm run test:coverage && printf 'package coverage PASS\n'
18
+ node scripts/verify-docs.mjs
19
+ ```
20
+
21
+ The documentation command prints exactly `documentation verification passed`. It checks complete English/Chinese pairs and their recorded blob hashes, local files and heading fragments, one trailing LF, current compatibility prose, and the required installation, architecture, testing, user, and Agent Note coverage.
22
+
23
+ ### Keyless assembled snapshots
24
+
25
+ ```sh
26
+ pnpm exec vitest run tests/keyless-snapshot.spec.ts --reporter=dot && printf 'RD5 keyless snapshot PASS\n'
27
+ pnpm exec vitest run tests/dashboard-snapshot.client.spec.tsx --reporter=dot && printf 'RD6 dashboard snapshots PASS\n'
28
+ ```
29
+
30
+ `tests/keyless-snapshot.spec.ts` is a source-resolved fixture: it feeds official `tool-workflow/*` events through `ConversationNodeAssembler`, proves append/prepend/full-replay parity, maps Interrupted Chat nodes to cancelled, and checks the completion-notice footer. It does not boot the official assembled snapshot harness or compare reviewed Session/stdout JSONL files; those `examples/workflows-keyless/` inputs remain a later assembled gate. The dashboard snapshot locks accessible empty, live, terminal, interrupted, disclosure, and member-outcome semantics rather than CSS hashes.
31
+
32
+ ### Package policy and exact packed consumer
33
+
34
+ ```sh
35
+ pnpm exec vitest run tests/verify-package.spec.ts --reporter=dot && printf 'RD3 package policy PASS\n'
36
+ pnpm exec vitest run tests/packed-consumer.spec.ts --reporter=dot && printf 'RD8 packed consumer PASS\n'
37
+ ```
38
+
39
+ The standalone packed-consumer test performs one `pnpm pack --json`, records SHA-256, and sends that unchanged absolute tarball to `scripts/verify-package.mjs --tarball`. During a release, `scripts/check-release.mjs` is the sole pack owner and calls `scripts/packed-consumer.mjs` with that same artifact instead; generic unit commands exclude the self-packing spec. Missing skill, client bundle, evaluator, or required peer assets fail before any consumer Session starts. The runner installs the bytes with scripts disabled, installs pinned consumer-only TypeScript/Node types and the exact prebuilt official CLI, imports every JavaScript and strict NodeNext export, and loads `lib/client.js` through the lazy-CJS seam. Every declared Host, Client, Cordis, and React peer remains an exact compatibility declaration but is marked optional: an isolated `autoInstallPeers: true` probe must not materialize one, while the standalone import/type probe supplies peers explicitly. The real Web and headless profile cycles must retain official `autoInstallPeers: false`, contain no profile-local peer package, resolve those peers through the healed official fallback, and resolve `dsh-scope` to one realpath from both agent-loop and agent-presets. Each profile then receives two bounded activation/teardown sentinel boots (the second proves lease release), remove, and manifest restoration. Source-tree runtime fallback, `--help` as activation evidence, a split Host graph, or a second release pack is a failure.
40
+
41
+ ### Automated Chromium
42
+
43
+ ```sh
44
+ pnpm exec vitest run tests/browser-smoke.spec.ts --reporter=dot && printf 'RD10 browser automation PASS\n'
45
+ ```
46
+
47
+ `tests/browser-smoke.spec.ts` currently gates the `scripts/browser-smoke.mjs` helper boundary: absolute arguments, loopback readiness JSON, stdin teardown, and isolation from the caller's workspace. It does not drive Chromium through slash discovery, disclosures, or 1,199/767/320 px layouts. That product journey is the final Ego Lite checklist below, not a substitute this helper already covers.
48
+
49
+ ### Lifecycle, storage, and Client stress
50
+
51
+ ```sh
52
+ pnpm exec vitest run tests/race-stress.spec.ts --reporter=dot && printf 'RD11 host race stress PASS\n'
53
+ pnpm exec vitest run tests/storage-stress.spec.ts --reporter=dot && printf 'RD12 storage stress PASS\n'
54
+ pnpm exec vitest run tests/client-race-stress.client.spec.ts --reporter=dot && printf 'RD13 client race stress PASS\n'
55
+ ```
56
+
57
+ These deterministic repeated suites cover aggregate cancellation, pending durable admission, pause/stop/teardown, worker death, completion cohorts, advisory-lease contention, link/inode substitution, interrupted publication, stale gate/control/page responses, reconnect generations, invalidation overflow, and cross-Agent authorization. They assert zero orphan worker, child, scratch operation, timer, watcher, controller, request, cursor, selection, or unhandled rejection. The donor aggregate-cancellation scenario must pass alone and inside the aggregate suite repeatedly; one passing rerun never excuses a failure.
58
+
59
+ ### Opt-in real provider
60
+
61
+ ```sh
62
+ pnpm exec vitest run tests/real-provider.spec.ts --reporter=dot && printf 'RD14 real provider gate PASS\n'
63
+ ```
64
+
65
+ With `DEEPSEEK_API_KEY`, the file starts exactly two logical children labelled `alpha` and `beta`, verifies the independent bytes `alpha` in `alpha.txt` and `beta` in `beta.txt`, verifies final result `{"alpha":"alpha","beta":"beta"}`, and disposes every child, worker, Agent, Host, lease, and temporary directory in `finally`. It reads `DEEPSEEK_BASE_URL` only through official provider configuration. Neither value, any credential, nor a model transcript enters logs or artifacts.
66
+
67
+ Without the key, this file alone registers exactly one skipped test with reason `DEEPSEEK_API_KEY is not set`. No other package, platform, workflow, or storage lane may self-skip.
68
+
69
+ ### Exact official Host checkout
70
+
71
+ The packed consumer and CI checkout official DeepSeek Harness `0.1.1-rc.2` at commit `b150a551b8d465e31e418e1b2eaf5e79bbb7d28e`. The package build and tests compile against `0.1.1-rc.2` development dependencies; no Harness source patch or fork checkout participates. The package-owned evaluator build, strict NodeNext consumer, add/boot/remove profile cycle, and stock boot after removal are blocking release evidence.
72
+
73
+ ### Final automated aggregate
74
+
75
+ ```sh
76
+ pnpm run check:release
77
+ ```
78
+
79
+ Success ends exactly `release checks passed`. The orchestrator runs clean/frozen-install verification, build, typecheck, lint, owned-source aggregate coverage, snapshots, documentation, package policy, one immutable pack and packed consumer (`official-host-probe` plus real Web/headless add/boot/remove), the browser helper boundary, all three stress suites, and the opt-in provider file in order. It does not publish, launch Ego Lite, or record a GIF. The packed profile cycle is blocking against official `0.1.1-rc.2`; the Chromium product journey remains the final Ego Lite acceptance.
80
+
81
+ ## Coverage policy
82
+
83
+ `pnpm run test:coverage` enforces truthful aggregate floors of **80% statements, 80% branches, 80% functions, and 80% lines** across owned package integration source. Its explicit instrumentation include is `src/**/*.{ts,tsx}` with type-only declarations excluded, so unimported owned source still counts while generated `lib/` and release helpers under `scripts/` cannot enter the denominator accidentally. Per-file 100% is not claimed: the August 23 baseline was 85.35% statements/lines, 80.69% branches, and 84.98% functions. That command excludes packed-consumer, browser-smoke, snapshot, stress, and real-provider lanes. The stored `coverage-all` report is not 100% of generated `lib/` plus dependencies (~57% last captured); it is not a substitute for the owned-source aggregate gate. Tests exercise deterministic clocks and barriers, every error and cancellation branch, effect disposal, HMR registration, authorization, and external world state rather than self-reported success.
84
+
85
+ The only non-instrumented artifacts are generated or browser-delivery products rather than an exception for handwritten Host behavior:
86
+
87
+ | Exclusion | Why it is not instrumented as owned runtime source | Required evidence |
88
+ |---|---|---|
89
+ | `vendor/workflow-engine/*.ts` and emitted `lib/compat-engine/*` | Attributed MIT compatibility evaluator with a separate process/worker protocol gate | `tests/compat-engine.spec.ts`, supervisor replay/gate/budget/scratch suites, packed artifact verification, and live profile smoke |
90
+ | `lib/typert.host.*` and `lib/typert.remote-client.*` | Generated from decorated Host source | `tests/build-artifacts.spec.ts`, Remote API tests, packed imports, and browser mount smoke |
91
+ | `lib/client.js`, emitted Client declarations/maps, and Lightning CSS output | Generated bundle products | Client component/controller specs, dashboard semantic snapshots, packed serving, and `tests/browser-smoke.spec.ts` |
92
+ | `src/client/css-modules.d.ts` | Type-only generated-facing declaration with no executable statements | Client TSC plus source assertion in the build suite |
93
+ | CSS module visual branches | Styles do not enter JavaScript statement coverage | source token assertions, jsdom semantic snapshots, and the final Ego Lite real-flow GIF when GUI behavior changes. Automated Chromium in CI only gates `scripts/browser-smoke.mjs`; layout, light/dark, and reduced-motion remain manual Ego Lite. |
94
+
95
+ Handwritten Client TypeScript remains covered by its Client test project; generated outputs do not create a parallel coverage denominator. Adding another exclusion requires corresponding real-browser evidence and an explicit testing-policy change.
96
+
97
+ ## CI platform matrix
98
+
99
+ Blocking Ubuntu 24.04 jobs run Node `22.19.0`, `24`, and `26`; each uses a frozen lockfile and covers build, typecheck, lint, docs, package policy, and its assigned unit/coverage/snapshot gates. Node 24 additionally owns macOS 14, Windows Server 2022, Chromium helper, race-stress, and release-pack/packed-consumer jobs. The packed lane checks out official `0.1.1-rc.2` commit `b150a551b8d465e31e418e1b2eaf5e79bbb7d28e`; it applies no Harness patch, packs once, preserves one digest and artifact path, and requires live add/boot/remove for Web and headless.
100
+
101
+ Windows runs every supported definition, manifest, scratch, retention, recovery, and subprocess case. It explicitly asserts junction/hard-link behavior and either working native advisory locking or the documented `WORKFLOW_STORAGE_UNSUPPORTED` result; it never silently skips the workflow, marks the job `continue-on-error`, or treats a platform limitation as success without asserting its exact branch.
102
+
103
+ CI may upload reviewed snapshot, browser, stress, and pack diagnostics only after failure. It never uploads a DSH home, credential, secret-lane model transcript, or unrestricted scratch store. Actions are pinned to full commit SHAs, permissions default read-only, jobs have timeouts, and only the real-provider file may skip for an absent key.
104
+
105
+ ## Real-provider secret and cleanup policy
106
+
107
+ CI passes `DEEPSEEK_API_KEY` only to the isolated provider job when available. The test never prints the key or base URL and never copies them into child prompts, session logs, screenshots, archives, or failure diagnostics. A provider error may name the display handle and provider failure, never the internal run UUID or credential material.
108
+
109
+ All live resources are created inside an isolated workspace and DSH home. `finally` stops or settles the run, disposes child catalog entries, worker handles, the Agent and Host, releases the permanent-anchor lease, and removes the temporary directories even after provider failure or timeout.
110
+
111
+ ## Final manual Web acceptance
112
+
113
+ This is a release checklist, not a coding task, CI step, or substitute for automated Chromium. Perform it only after every automated gate passes, using the exact tested tarball installed into a real official `0.1.1-rc.2` Web profile and a real server/model flow.
114
+
115
+ - [ ] Start the tarball-installed real server and confirm the package activates without a source checkout fallback.
116
+ - [ ] Use **Ego Lite** for the smoke journey. Reuse its task space across the journey; never wipe or reset any user session, cookies, browser storage, or daily-browser state.
117
+ - [ ] Confirm `/create-workflow`, `/workflow`, `/workflows`, and a saved alias appear; launch two runs and observe immediate acknowledgements, display-name numbering, live phase/member/progress updates, and a usable composer.
118
+ - [ ] Open and close the run disclosure and `Inspect · N members`; inspect real text/Markdown and JSON outcomes, logs, result, and a scratch artifact. Verify no internal UUID appears in user-visible or accessible text.
119
+ - [ ] Exercise a resumable gate, Pause, Resume, Stop, and an eligible Save; confirm stale-revision and budget-limited errors remain visible and actionable.
120
+ - [ ] Check focus restoration, keyboard controls, screen-reader labels, light/dark/reduced-motion behavior, and the narrow mobile drill-down without horizontal overflow.
121
+ - [ ] Confirm exactly one completion notice per eligible run and no duplicate `workflows · Completed` row merely from opening the dashboard.
122
+ - [ ] For any product-visible GUI change, record and retain a GIF from this **real PR server/model flow** showing launch, live updates, member outcome inspection, controls, and narrow layout. A mocked or source-only GIF is not release evidence.
123
+ - [ ] When verification is complete, close **only the Ego Lite task space**. Do not wipe sessions, cookies, storage, or unrelated tabs/spaces.
124
+
125
+ Record the tested tarball SHA-256, official Host build identity, platform, automated aggregate log, manual result, and GIF location in the release evidence. A failed manual item blocks release even when the automated suite is green.