Merge remote-tracking branch 'origin/master' into feature/workspace-picker-composer
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-26-task-registry-seam.md
|
||||
2026-07-26-task-registry-seam.md: 45801505f1729ec6094900acf94b4c17ed92c3b1
|
||||
2026-07-26-task-registry-seam.zh.md: 8dd90b34d2da1d22caba13fe8c388dab4a29be0d
|
||||
2026-07-26-task-registry-seam.md: 4487bd9c53595fa8b4eed588b294ceafe3ab58dc
|
||||
2026-07-26-task-registry-seam.zh.md: 6195dc809e84852c7e0f63ac101ba0ed6a46853e
|
||||
|
||||
@@ -12,7 +12,7 @@ The [background-task runtime](2026-06-20-generic-long-running-tool-runtime.md) s
|
||||
|
||||
`tasks/` is now a three-package capability family in the bash-trio shape:
|
||||
|
||||
- **`@deepseek-ai/dsh-tasks` (Service Definition)** — the abstract `TaskService extends Service` owning `ctx.tasks`, the eight-method contract (`start`, `list`, `get`, `read`, `kill`, `wait`, `onTaskDone`, `attachSurface`), all vocabulary types (`TaskId`, `TaskKindMap`, `TaskStart`, `TaskHooks`, `TaskOutcome`, `TaskSnapshot`, `TaskRead`, `TaskDoneListener`), and the snapshot invariant companion. The class-level JSDoc states the semantics every Service provider owes: registrations outlive producer and surface fibers, owned access is session-fenced, settlement is first-wins with contained listeners, and `start` refuses work while no control surface is attached.
|
||||
- **`@deepseek-ai/dsh-tasks` (Service Definition)** — the abstract `TaskService extends Service` owning `ctx.tasks`, the eight-method contract (`start`, `list`, `get`, `read`, `kill`, `wait`, `onTaskDone`, `attachSurface`), all vocabulary types (`TaskId`, `TaskKindMap`, `TaskStart`, `TaskHooks`, `TaskOutcome`, `TaskSnapshot`, `TaskRead`, `TaskDoneListener`), and the snapshot invariant companion. The class-level JSDoc states the semantics every Service provider owes: registrations outlive producer and surface fibers, owned access is session-fenced, settlement is first-wins with contained listeners, and `start` refuses work while no attached control surface serves the spec's owner (surfaces and listeners are scope-layered, so one process-wide registry answers both questions per owner).
|
||||
- **`@deepseek-ai/dsh-tasks-local` (Service provider)** — `LocalTaskService`, the process-local registry moved verbatim: the in-memory store, per-kind counters, waiter bookkeeping, `TASK_WAIT_TIMEOUT` deadline code, owner-cleanup effects, and force-fail teardown. The `dsh-timeout` dependency moves here with it; the Service Definition package has no provider dependencies.
|
||||
- **`@deepseek-ai/dsh-tool-tasks` (Consumer)** — unchanged; it injects `'tasks'` and never imports provider types.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Status: implemented
|
||||
|
||||
`tasks/` 如今是一个 bash 三件套形态的三包能力家族:
|
||||
|
||||
- **`@deepseek-ai/dsh-tasks`(Service Definition)**——抽象的 `TaskService extends Service`,拥有 `ctx.tasks`、八个方法的约定(`start`、`list`、`get`、`read`、`kill`、`wait`、`onTaskDone`、`attachSurface`)、全部词汇类型(`TaskId`、`TaskKindMap`、`TaskStart`、`TaskHooks`、`TaskOutcome`、`TaskSnapshot`、`TaskRead`、`TaskDoneListener`),以及快照不变式配套插件。类级 JSDoc 陈述了每个 Service provider 都必须兑现的语义:注册的存续期长于生产方与控制接口的 fiber,有所有者的访问以会话为界,结算遵循首次结果优先且监听器错误被隔离,并且在没有附加任何控制接口时 `start` 拒绝启动工作。
|
||||
- **`@deepseek-ai/dsh-tasks`(Service Definition)**——抽象的 `TaskService extends Service`,拥有 `ctx.tasks`、八个方法的约定(`start`、`list`、`get`、`read`、`kill`、`wait`、`onTaskDone`、`attachSurface`)、全部词汇类型(`TaskId`、`TaskKindMap`、`TaskStart`、`TaskHooks`、`TaskOutcome`、`TaskSnapshot`、`TaskRead`、`TaskDoneListener`),以及快照不变式配套插件。类级 JSDoc 陈述了每个 Service provider 都必须兑现的语义:注册的存续期长于生产方与控制接口的 fiber,有所有者的访问以会话为界,结算遵循首次结果优先且监听器错误被隔离,并且当没有任何已附加的控制接口服务于 spec 的所有者时 `start` 拒绝启动工作(控制接口与监听器按 scope 分层,因此一个进程级注册表能逐所有者地回答这两个问题)。
|
||||
- **`@deepseek-ai/dsh-tasks-local`(Service provider)**——`LocalTaskService`,即原样迁移的进程内注册表:内存存储、按 kind 划分的计数器、等待方簿记、`TASK_WAIT_TIMEOUT` deadline 代码、所有者清理 effect,以及强制失败的拆除。`dsh-timeout` 依赖随之迁入此包;Service Definition 包不含任何提供方依赖。
|
||||
- **`@deepseek-ai/dsh-tool-tasks`(Consumer)**——保持不变;它注入 `'tasks'`,从不导入提供方类型。
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-08-per-preset-standing-mounts.md
|
||||
2026-08-08-per-preset-standing-mounts.md: 834d645f5f293a2e137b8faf662e301f1e8bb971
|
||||
2026-08-08-per-preset-standing-mounts.zh.md: 45ce0f4e7dec28e5bf807898dc9cdbf32b8e4eb5
|
||||
2026-08-08-per-preset-standing-mounts.md: c2792454f90a88cd6fba36eed8e36104e5fffea4
|
||||
2026-08-08-per-preset-standing-mounts.zh.md: 47668c8c2c424eb188aa14bf55986d27bcfb8ee0
|
||||
|
||||
@@ -16,7 +16,7 @@ A preset is one composition per PROCESS, not one per session. The roster mounts
|
||||
|
||||
Standing mounts fix the class, not the instances: the registrations a reader needs exist for the process lifetime, keyed by preset id, no agent required. What made it cheap
|
||||
|
||||
- The stateful preset plugins (`plan-mode`, `token-meter`, `compact-basic`, `tasks-local`) already key state by `Session`/`Agent` — they predate presets. Sharing one instance is a return to their design, not a rewrite.
|
||||
- The stateful preset plugins (`plan-mode`, `token-meter`, `compact-basic`) already key state by `Session`/`Agent` — they predate presets. Sharing one instance is a return to their design, not a rewrite. `tasks-local` shared that property and has since left the preset plane entirely: producers outside its realm (`tool-bash`, `tool-pty`, a non-continuable `tool-subagent`) resolve the registry with `ctx.get`, which an entry-local realm hides from them, so it is composed on the host plane and only the model-facing `tool-tasks` row stays per preset.
|
||||
- Preset ymls are unchanged: one mount per preset = one Entry per preset, whose entry-local realms (`isolate: <name>: true`) keep two presets' same-named services apart exactly as they kept two sessions' apart.
|
||||
- A shared realm label was NOT an option: `provide()` throws on a second registration under the same realm symbol, so labels pool the REALM, never the instance — a per-session world sharing a label crashes the second mount.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Status: implemented
|
||||
|
||||
常驻挂载修的是这一类问题而非其中的个例:读取方需要的注册在进程生命周期内始终存在,按 preset id 索引,不需要任何 agent。让它便宜的原因:
|
||||
|
||||
- 有状态的 preset 插件(`plan-mode`、`token-meter`、`compact-basic`、`tasks-local`)本就按 `Session`/`Agent` 分键存状态——它们早于 preset 存在。共享一份实例是回归其设计,不是改写。
|
||||
- 有状态的 preset 插件(`plan-mode`、`token-meter`、`compact-basic`)本就按 `Session`/`Agent` 分键存状态——它们早于 preset 存在。共享一份实例是回归其设计,不是改写。`tasks-local` 同样具备该性质,且此后已完全离开 preset 平面:realm 之外的生产方(`tool-bash`、`tool-pty`、非 continuable 的 `tool-subagent`)以 `ctx.get` 解析该注册表,而 entry-local realm 对它们不可见,因此它组合在宿主平面,只有面向模型的 `tool-tasks` 行仍留在各 preset 中。
|
||||
- preset 的 yml 不变:每 preset 挂一次 = 每 preset 一个 Entry,其 entry 本地 realm(`isolate: <name>: true`)让两个 preset 的同名服务互不相干,正如它从前隔开两个会话。
|
||||
- 共享 realm label **不是**选项:`provide()` 对同一 realm 符号下的第二次注册直接抛错,label 池化的是 REALM 而非实例——按会话挂载的世界里共享 label 会让第二次挂载崩溃。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user