Expose a live goals/get read plus goal/activation-changed for the Web strip, reject model resume of durable paused goals, refresh snapshot and generated documentation surfaces, and record the follow-up decision.
The new keyless sdk-spawn-node scenario drives the platform shell tool
through a command starting with node and requires the machine's own Node
version in the tool result with no PKG_EXECPATH in the child environment,
so a pkg upgrade that re-records the child-process patch cannot silently
restore the hijack. Runs on every target through --scenario all.
@yao-pkg/pkg's SEA bootstrap rewrites child_process commands named node --
including the string after a -c flag, exactly the Bash tool's bash -c form --
to the executable itself and stamps PKG_EXECPATH into every child
environment, so a model-issued 'node --version' silently booted the dsh CLI
instead of the machine's Node. Pin the packager as an exact root
devDependency invoked through pnpm exec and patch out the single
patchChildProcess call from the SEA bootstrap bundle; packaged children now
resolve node through PATH like any other process. The third-party notices
drop the build-time tools section: the packager is now a declared, patched
devDependency, so the manifest and patch tiers disclose it.
The persistence seam is now create/open/stat/list returning per-session
SessionHandles (read/append/flush/close); every log read and write flows
through the owning handle. The seam package exports only the service and
handle contracts, consumer-visible errors, and pure durable-data
validation helpers; each backend owns its complete storage runtime, and
the shared contract suites pin equivalent observable behavior. The
backend routes published sessions' live events by id into the active
write handle; agent-loop only acquires, seeds, and closes the handle.
Resume appends interruptedTurnClosers through its write handle;
session-query owns the revision-keyed cold cache. Legacy-only surfaces
are removed in the same swap: locate/readRaw/supportsRawArtifacts, the
legacy event-shape read migration, zstd torn-frame salvage,
DSH_SESSION_JSONL, and hook transcript_path population; a torn final
zstd frame is discarded whole; the session-list cold blank probe returns
on stat metadata (eventCount derived from the last physical row,
sizeBytes). The WebUI ZIP export serializes the logical log from a read
handle, so both backends export identically.
Refs #3245
The package exported six functions, four of them shaped by one SDK's
transport each: a dispatcher factory, a `node:http` agent factory, a
proxy-URL lookup, and a policy accessor. Review asked whether the call
sites could converge instead of the package growing an export per SDK.
They could, and each removal took a whole shape with it:
- The OTLP exporter moves to the SDK's `fetch` delegate, retiring
`createNodeHttpAgent`. Its Node-version floor goes too: `proxyEnv` on
an `http.Agent` needs 22.21 or 24.5, inside the engines range, so
telemetry was direct on 22.19, 22.20, and 24.0-24.4. The cost is
`compression`, a Node-transport option; the plugin now refuses it,
`keepAlive`, and `httpAgentOptions` at load instead of ignoring them.
- `web-fetch-http` builds its own address-pinning agent under an
annotated `proxy-exempt:` exemption, retiring `createDispatcher`.
Pinning is per-request state a process-wide dispatcher cannot hold.
- E2B reads `route.proxy`, retiring `proxyUrlFor`.
What remains is `installProxyFromEnvironment`, `proxyRouteFor`,
`proxyEnvironmentForChild`, and `clearedProxyEnv` — one per way a caller
can need the policy. Installation absorbs resolution and diagnostic
reporting, which no caller needed apart.
`proxyRouteFor` also closes a defect the old accessor made expressible:
`web-fetch-http` read the policy to decide whether to pin, then read it
again to build a transport, so an unmount between the two returned a
direct, unpinned agent for a URL the first read had cleared as proxied.
A route carries the answer and the transport that answer assumed.
Every egress spec now installs through `installProxyFromEnvironment`, so
no test asserts a policy object a real launch could not produce.
Master moved 212 commits. Conflicts were eight `package.json` and nine
`tsconfig.json` files, all dependency-and-reference unions: master dropped the
`runtime-diagnostics/invariants` reference across packages while this branch
added `util/http-proxy`. The lockfile, `tsconfig.base.json`, and the module
graph were regenerated rather than merged by hand.
Master also brought `verify-package-invariants`, which rejects an empty
invariant companion. This package's companion was empty by design, so it is
gone with its publication wiring — the export, the `files` entry, the project
reference, the `dsh-invariants` peer, and the test. Master did the same across
`util/`. The README carries the reason sentence that gate requires.
Carried in the same commit, because the review arrived while the merge was open:
`e2bApiUrl` moves out of the `dsh-e2b` entry into `src/api-url.ts`. Code Entropy
flagged it as a public name with no consumer outside its own package; the seam
keeps its URL-precedence test, which is worth having directly — getting that
order wrong hands a proxy the control-plane traffic and its API key.
Review asked why this is a plugin and why it exports so much. The design note
this branch shipped answered the second question itself — "a pure resolution
function plus an installation function" — and the code drifted to seventeen
exports and a Cordis plugin nobody approved or mounted.
The plugin is gone. Transport policy has one answer per process: nothing to
swap, and no scope narrower than the process to give one. Its `Config` was also
the only supplier of a configuration branch, so resolution now reads the
environment and nothing else — `mode`, the config-sourced fields, and the
`config` policy source were unreachable the moment the plugin left.
Four exports nothing outside the package used are internal again, and
`currentProxyPolicy` answers with the direct policy instead of `undefined`, so
`DIRECT_POLICY` no longer needs a public face. Nine functions remain, one per
way a caller can need the policy; two is not reachable with six consumer seams.
The package moves to `util/`. The note claimed a dependency on `undici`
disqualified it from that group; the charter governs harness dependencies, not
external ones, and the process note that says so predates this branch. The real
blocker was the harness dependency: resolution needed one method of
`LaunchEnvironmentSnapshot`, so it names a structural `EnvLookup` and the
launcher passes its snapshot unchanged. `net/` is dissolved.
Dropping the group's line from the repository layout also returns `AGENTS.md`
to its original ceiling, so the raise the merge needed is reverted.
New turnOutline projection unit serving every started turn's number,
turn/start seq, and bounded first-prompt preview through the
session-projection seam, mounted in the web-app bundle for the chat
turn rail. Entries stay strictly increasing; previews mirror the rail's
loaded-turn preview budget.
render() loaded the workspace manifests once per external dependency
name through workspaceLinkedManifest, an O(names x manifests) file
read on the cold path; on the loaded self-hosted Windows host with
coverage instrumentation the freshness spec crossed Vitest's default
5000ms budget and failed the serial-windows standby gate four times in
a week. Load the manifests once in render() and thread the map through
the collectors instead.
The serial-windows lane also ran the coverage inventory at the strictest
budget of any lane: add DSH_COVERAGE_TEST_TIMEOUT_MS=90000 to match the
pull-request windows-coverage lane, pinned by ci-workflow.spec.ts.
The capability-seams graph derives its implementation lists from
SERVICE_ROLES in scripts/gen-doc-graphs.ts, which still listed only the
worker-thread backend. Add experimental-code-runtime-python so the
generated graph and table match the registered ctx.codeRuntime
implementations; regenerate docs/capability-seams.md, sync the zh pair,
and re-record the i18n pairing.
The CPython code runtime's complete public contract is experimental, so it
moves to packages/experimental per the experimental-packages rules: npm name
@deepseek-ai/dsh-experimental-code-runtime-python, private: true, no
publishConfig. All references updated (code-runtime READMEs, config-catalog
and module-graph regenerated with zh alignment, tsconfig paths, doc-standard
and workspace-constraints scripts, the fd-3 and settlement Agent Notes, and
the package README links); md-links and translation pairing pass, and the
suite still runs green.
The audited library registry still listed dsh-code-runtime-python as a plain
protocol library, but the shipped package's src/index.ts has a plugin default
export; the entry is removed from PACKAGE_LIBRARIES and both READMEs declare
kind: package-reference. The zh README heading is 概述 per the standard.
Land the PythonCodeRuntime implementation on top of the fd-3 protocol
seam: python3 -I per run, binding namespace over fd 3, RLIMIT_CPU/AS,
wall-clock timer, and SIGTERM->grace->SIGKILL process-group teardown,
with the real-subprocess integration suite.
Fixes three defects surfaced on the source PR's review before they ship:
- boot-write failure resolved a worker-exit through finish()/settle()
that read wallTimer/onAbort/live in their TDZ, rejecting run() instead;
the boot write now runs after those bindings and the v8-ignore that hid
the branch is removed.
- log capture serialized against settlement with no lock while model
daemon threads keep writing; LogBuffer now owns one shared re-entrant
lock taken by write/flush_line/push.
- the fd-3 line residual was a subarray view pinning the whole joined
frame; it is copied into a right-sized Buffer via detachResidual so
pendingBytes measures what is retained.
Resolve the 08-08 note conflict (keep the zero-build rewrite, drop the
SQLite busy-journal sentence removed with the SQLite backend) and drop the
now-removed session-persistence-sqlite built-package suite from the
lib-consuming self-skip inventory in the ci.yml comment, the
ci-workflow.spec.ts comment, and the partitioned-coverage note; the
inventory is now image-loadable, transform-corpus, and client-bundle.
`AGENTS.md` sat at exactly its 1950-word ceiling on master, so the one line this
branch adds to the repository layout — a new top-level package group — cannot
fit at any length: even a one-word description overflows. The description is
condensed to five words and the ceiling raised by ten, the smallest change that
keeps every package group listed. Omitting only `net/` from a list that names
every other group was the alternative.
One new test drove an IPv4-mapped literal through a full fetch. An IPv6 literal
sends `resolvePublicAddresses` looking for a NAT64 prefix before it refuses
anything, and that is a real DNS query — 5s under load, 6ms here, which is why
it passed alone and timed out in the full suite. The three IPv4 cases already
prove the branch end to end without touching the network, so the mapped form is
asserted on the predicate instead.
client-bundle.client.spec.ts reads packages/client/ui-trajectory/lib/client.js
and skips all three cases when the bundle is absent, so it is a fourth
lib-consuming suite in the instrumented corpus. List it beside built-package
in the ci.yml comment, the ci-workflow.spec.ts comment, and the
partitioned-coverage note (both languages).
Strengthen the ci-workflow.spec.ts guard to match any 'pnpm run build'
spelling (corepack prefix, multi-line run blocks) instead of one exact
string, and complete the lib-consuming self-skip inventory with the
webworker-runtime transform-corpus import sweep alongside the packer
image assertions and the built-package check. Update the ci.yml comment
and the partitioned-coverage note (both languages) to match, and drop the
stale 'post-build' phase wording and the native-Windows build-wait
rationale from the coverage-exempt comment.