Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions docs/architecture/rfcs/harness-selection-dsh-pi-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,22 @@ passivity is a property of the selected adapter and its loaded dependencies.

The two LoopX surfaces that depend on dsh do not move together. The bounded Turn
host uses the Python SDK/runtime pin recorded above (`0.1.5rc1`, the released
channel). The dsh-side plugin (`packages/dsh-loopx-plugin`) still builds its
development and client surfaces against `0.1.1-rc.2` while its clean-Docker smoke
already asserts `dsh --version == 0.1.5-rc.1`, and the 0.1.5 line no longer
publishes `@deepseek-ai/dsh-client-runtime` (last released 0.1.1-rc.2), moving
the client runner to `@deepseek-ai/dsh-cordis-client-runner`. That upgrade is
tracked as its own pin item and does not change the L1 observer contract above.
channel). The dsh-side plugin (`packages/dsh-loopx-plugin`) now builds its
development, host, and client surfaces on the same released `0.1.5-rc.2` line
instead of the retired `0.1.1-rc.2` one, and its npm peer ranges admit only
`>=0.1.5-rc.1`. Three upstream moves forced that, so it is a new release line
rather than a patch: the 0.1.5 line no longer publishes
`@deepseek-ai/dsh-client-runtime` (last released 0.1.1-rc.2), which moves the
`slots` service seat to `@deepseek-ai/dsh-client-ui-renderer` — the package this
manifest now names in `dsh.client.inject`; `Session.events` became
`Session.snapshotEvents()` and `Inbox.hasPending` became the two pending queues;
and the shared `/api` bridge addresses Remote methods as `<namespace>/<method>`
with a single `args` payload field. One `dsh.client.inject` list cannot order
boot rows for both generations at once, so the plugin cannot claim both. The L1
observer contract above is unchanged: the observer still consumes only
`session/created`, `session/event`, and `session/disposed`, and now treats
token-level `assistant/chunk` rows as retired input replayed from older durable
logs instead of a live event type.

## Data and Authority Flow

Expand Down
17 changes: 12 additions & 5 deletions docs/architecture/rfcs/harness-selection-dsh-pi-v0.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,18 @@ tag:PyPI 上的 `deepseek-harness-sdk==0.1.5rc1` /

依赖 dsh 的两个 LoopX 面并不一起移动:有界 Turn 宿主使用上文记录的 Python
SDK/runtime 固定版本(`0.1.5rc1`,已发布通道);而 dsh 侧插件
(`packages/dsh-loopx-plugin`)的开发与客户端面仍构建在 `0.1.1-rc.2` 上,尽管其
clean-Docker smoke 已断言 `dsh --version == 0.1.5-rc.1`。0.1.5 线不再发布
`@deepseek-ai/dsh-client-runtime`(最后发布版本为 `0.1.1-rc.2`),客户端 runner 改为
`@deepseek-ai/dsh-cordis-client-runner`。该升级作为独立的 pin 项跟踪,不改变上文的
L1 observer 契约。
(`packages/dsh-loopx-plugin`)的开发、宿主与客户端面现已统一构建在同一已发布的
`0.1.5-rc.2` 线上,不再停留在 `0.1.1-rc.2`,其 npm peer 范围只接受
`>=0.1.5-rc.1`。这是上游三处变化逼出来的,因此它是一条新的发布线而不是原地补丁:
0.1.5 线不再发布 `@deepseek-ai/dsh-client-runtime`(最后发布版本为 `0.1.1-rc.2`),
`slots` service 座位随之移到 `@deepseek-ai/dsh-client-ui-renderer`,也就是本 manifest
现在写入 `dsh.client.inject` 的包;`Session.events` 变为 `Session.snapshotEvents()`,
`Inbox.hasPending` 变为两个 pending 队列;共享 `/api` bridge 用
`<namespace>/<method>` 寻址 Remote 方法,并只接受一个 `args` payload 字段。一份
`dsh.client.inject` 无法同时为两代排序 boot row,所以插件不能同时声明两代。上文的
L1 observer 契约不变:observer 仍只消费 `session/created`、`session/event`、
`session/disposed`,只是把 token 级 `assistant/chunk` 行视为旧 durable 日志重放出来的
已退场输入,而不是现存事件类型。

## 数据流与权限

Expand Down
3 changes: 2 additions & 1 deletion loopx/capabilities/reliability_diagnostics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ hooks and writes no files (feature-off parity). When enabled, `observer.ts`
observes only `session/created`, `session/event`, and `session/disposed`.
Events from any other session are rejected as `identity_invalid`, so they can
never be silently attributed to the configured goal. Token-level
`assistant/chunk` events are not consumed.
`assistant/chunk` events — a retired type that only older durable logs still
replay — are not consumed.

## Validation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ ingest 是透明拷贝。任何损坏或被拒绝的输入都会追加持久化
三个必需变量未全部有效时,observer 行不注册任何 hook、不写任何文件(feature-off
parity)。启用后,`observer.ts` 只观察 `session/created`、`session/event`、
`session/disposed`。其它 session 的事件一律以 `identity_invalid` 拒绝,因此不会静默归属
到配置的 goal。token 级 `assistant/chunk` 不被消费。
到配置的 goal。token 级 `assistant/chunk`(已退场类型,只有旧 durable 日志还会重放)
不被消费。

## 验证

Expand Down
41 changes: 26 additions & 15 deletions packages/dsh-loopx-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ separate Loader rows:
Session successfully invokes the exact `loopx` skill. It then asks LoopX
whether another turn may run and queues the authoritative heartbeat task
into that live DSH Agent.
- the package-root Host registers a loopback-only `/loopx` Connection channel,
and its web Client contributes a compact GoalBar between DSH's native GoalBar
and Queue dock rows. It renders only for one exact live
`(goalId, loopxAgentId)` binding.
- the package-root Host registers GoalBar at the authenticated
`/api/loopx.goalbar` route required by DSH 0.1.5. Its web Client adds a compact
GoalBar between DSH's native GoalBar and Queue dock rows, visible only for one
exact live `(goalId, loopxAgentId)` binding.

Installing the plugin and starting DSH load and prepare these capabilities;
neither creates a binding nor activates the Driver. The GoalBar
Expand Down Expand Up @@ -61,7 +61,12 @@ dsh plugin --profile web add \
"https://github.com/huangruiteng/loopx/releases/download/dsh-loopx-plugin-v0.1.1-beta.5/dsh-loopx-plugin-0.1.1-beta.5.tgz"
```

For a source checkout, the equivalent build-and-install path is:
The prebuilt release above retains its original DSH compatibility. This source
checkout targets DSH 0.1.5-rc.1 or newer within the 0.1.x line; it does not
publish a new plugin release. The exported legacy RPC registration remains
available to explicit callers, but plugin startup always uses the shared API.

For the DSH 0.1.5 source build, use:

```bash
cd packages/dsh-loopx-plugin
Expand Down Expand Up @@ -129,7 +134,7 @@ Start/Pause. Focused Client tests cover Session-generation replacement and old
request cancellation without duplicating that matrix in the packed smoke.
The Docker smoke packs the current plugin and builds the current LoopX
release-candidate wheel, then starts both in a clean Debian container with the
DSH 0.1.5 release candidate. It proves PEP 668-compatible private installation,
DSH 0.1.5-rc.2 release candidate. It proves PEP 668-compatible private installation,
the managed launcher, startup readiness, installed `loopx` skill files, launch-
token authentication, and an authenticated GoalBar read through DSH's shared
API carrier. It requires Docker, `uv`, and network access for base images and
Expand Down Expand Up @@ -198,9 +203,10 @@ loopx reliability-diagnostics status --goal-id <goal-id> --format json

Unless all required variables are valid, the independent observer row
registers no hook and writes no file. When enabled, it consumes only
`session/created`, `session/event`, and `session/disposed`; it skips
`assistant/chunk` and records tool names, turn and step numbers, typed end
reasons, and ids only, never arguments, outputs, prompts, or paths. Events for
`session/created`, `session/event`, and `session/disposed`; it skips the retired
token-level `assistant/chunk` rows older logs still replay, and records tool
names, turn and step numbers, typed end reasons, and ids only, never arguments,
outputs, prompts, or paths. Events for
any session other than the exact configured session are rejected as
`identity_invalid`. The stats record pins worker/model/task/environment/tools/
budget plus adapter and observer revisions, declares source coverage, and
Expand All @@ -214,12 +220,17 @@ C1 run, and measured observer overhead remain separate evidence gates.

## GoalBar authority and privacy boundary

`/loopx` is registered with Connection authority `loopback`. Loopback is a
network reachability fence, not user authentication, and Phase 1 does not
support LAN or remote browsers. The browser supplies only its injected DSH
Session id and, for an action, the last validated Goal/Agent pair. The Host
re-derives cwd and thread identity from the live DSH Agent, freshly resolves
the binding, and executes only fixed LoopX argv.
The GoalBar carrier uses Connection's authenticated `/api/loopx.goalbar`
Fetch route. Explicit callers of the deprecated RPC registration can still
register `/loopx`; plugin startup does not select it automatically. Both pass
Connection's Host/Origin trust fence and browser authentication, and this
package adds no second credential of its own. The deployment's reachability
policy — loopback by default, or declared `trustedHosts` — decides which
browsers can reach the host at all; Phase 1 does not support LAN or remote
browsers. The browser supplies only its injected DSH Session id and, for an
action, the last validated Goal/Agent pair. The Host re-derives cwd and thread
identity from the live DSH Agent, freshly resolves the binding, and executes
only fixed LoopX argv.

The wire allowlist contains ids, activation, live Agent status, full-lane
counts, cursors, opaque source revisions, and fixed error codes. It excludes
Expand Down
46 changes: 23 additions & 23 deletions packages/dsh-loopx-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,47 +59,47 @@
"inject": [
"@deepseek-ai/dsh-client-connection",
"@deepseek-ai/dsh-client-locale",
"@deepseek-ai/dsh-client-runtime",
"@deepseek-ai/dsh-client-ui-conversation"
"@deepseek-ai/dsh-client-ui-conversation",
"@deepseek-ai/dsh-client-ui-renderer"
],
"platform": "web"
}
},
"peerDependencies": {
"@deepseek-ai/cordis": "^4.0.1",
"@deepseek-ai/dsh": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.7 <0.1.1 || >=0.1.1-rc.1 <0.2.0-0",
"@deepseek-ai/cordis": "^4.0.2",
"@deepseek-ai/dsh": ">=0.1.5-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-connection": ">=0.1.5-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.1 <0.2.0-0",
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.1 <0.2.0-0",
"react": "^18.2.0"
},
"peerDependenciesMeta": {
"@deepseek-ai/cordis": { "optional": true },
"@deepseek-ai/dsh": { "optional": true },
"@deepseek-ai/dsh-client-connection": { "optional": true },
"@deepseek-ai/dsh-client-locale": { "optional": true },
"@deepseek-ai/dsh-client-runtime": { "optional": true },
"@deepseek-ai/dsh-client-ui-conversation": { "optional": true },
"@deepseek-ai/dsh-client-ui-primitives": { "optional": true },
"@deepseek-ai/dsh-client-ui-renderer": { "optional": true },
"@deepseek-ai/dsh-client-ui-slots": { "optional": true },
"react": { "optional": true }
},
"devDependencies": {
"@deepseek-ai/cordis": "4.0.1",
"@deepseek-ai/dsh": "0.1.1-rc.2",
"@deepseek-ai/dsh-agent": "0.1.1-rc.2",
"@deepseek-ai/dsh-client-connection": "0.1.1-rc.2",
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
"@deepseek-ai/dsh-client-ui-conversation": "0.1.1-rc.2",
"@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
"@deepseek-ai/dsh-commands": "0.1.1-rc.2",
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
"@deepseek-ai/dsh-session": "0.1.1-rc.2",
"@deepseek-ai/cordis": "4.0.2",
"@deepseek-ai/dsh": "0.1.5-rc.2",
"@deepseek-ai/dsh-agent": "0.1.5-rc.2",
"@deepseek-ai/dsh-client-connection": "0.1.5-rc.2",
"@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
"@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
"@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
"@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2",
"@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
"@deepseek-ai/dsh-commands": "0.1.5-rc.2",
"@deepseek-ai/dsh-llm": "0.1.5-rc.2",
"@deepseek-ai/dsh-session": "0.1.5-rc.2",
"@types/node": "^22.19.0",
"@types/react": "~18.3.1",
"@types/react-dom": "~18.3.1",
Expand Down
Loading
Loading