Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
Teach the profile installation fallback to use normal symlinks under Node and real ESM proxy packages under pkg. Each proxy records the source package version, mirrors its explicit runtime subpath exports, and re-exports the virtual /snapshot URLs, so built-in Loader rows and external plugin peers resolve one shared Cordis/module instance from an on-disk profile.
Keep proxy healing idempotent, reject foreign real directories, cover root and subpath imports in packaged mode, and expand AggregateError startup diagnostics so concurrent Loader failures retain their individual import causes. This is the reusable packaged-profile mechanism; Python-specific artifact wiring remains in the next commit.
Delete @deepseek-ai/dsh-sdk-python-runtime and its packaged-bin entry now that Python uses the repository's dsh application launcher. Remove the package's project reference, Knip entry, workspace-policy exception, executable allowlist entry, and README-model classification together so no tooling preserves the old exception.
This commit is deliberately mechanical: it removes the obsolete package and gate accommodations without introducing the replacement launch behavior. The following commits add the packaged dsh runtime and Python profile API, keeping the architecture change separate from deletion noise.
The Landlock packed-install rehearsal packed a hand-maintained list of
workspace tarballs. When dsh-llm gained the dsh-util-crypto runtime
dependency, the list stayed stale and npm tried to fetch the unpublished
release candidate from the public registry, failing both Linux master jobs
with E404 before confinement ran.
Read the current pnpm workspace inventory and traverse dependencies,
optionalDependencies, and required peerDependencies from the packed test
roots. Verify package identities, fail loudly on unresolved workspace names,
sort the closure deterministically, and leave native-family packages to the
existing mode-preserving native packer.
Cover runtime traversal, optional-peer exclusion, native filtering, and
invalid workspace metadata. Remove the obsolete vendoring exact edit for the
deleted manual list so future runtime workspace additions are included by
their manifests instead of becoming post-merge CI failures.
Unix PowerShell emits cursor-position requests while PSReadLine starts and
redraws prompts. The subprocess PTY is only a transport, so those requests
went unanswered. Startup could then accept the dsh> literal echoed from its
setup source as a rendered prompt, and later sends were lost or clipped.
Feed raw PTY output into a zero-scrollback @xterm/headless state machine and
write generated replies through the provider-owned terminal handle. Drain
replies before caller input, repeat foreground inspection when terminal
activity races the sample, and retain send ownership until parser and reply
work quiesce. Coalesce raw chunks behind one active parser write so large
Windows output cannot create thousands of queued parse callbacks.
Publish pwsh only from backend stdin_read evidence and start one timeoutMs
deadline before the complete startup retry loop, so inferred-idle follow-ups
cannot reset the bound. Dispose the emulator when the
terminal or cleanup fails. Document the fail-loud ConstrainedLanguage path
and add focused coverage for split queries, reply ordering, foreground
resampling, failure containment, batching, timeout, and disposal.
* test(python): exercise installed wheels as black boxes
Add an installed-wheel mode that refuses source/editable imports, repository working directories, mismatched SDK/runtime versions, unpinned runtime dependencies, and executables outside the installed runtime distribution. The mode resolves the wheel-owned executable itself, so callers cannot accidentally prove an explicit checkout artifact.
Add a real-API scenario that drives two tool-using turns through the public synchronous SDK, verifies the file bytes outside the agent, checks completed turn/tool events and persistence, and projects provider failures without retaining credential-bearing error text. The existing deterministic scenario set remains the keyless behavior oracle.
Refs #2952.
* ci(python): require installed-wheel checks on every release target
Move the complete deterministic runtime scenarios behind construction and clean installation of the SDK and matching runtime wheels. Each native leg runs outside the checkout with source-resolution environment variables removed; Linux manylinux smokes assert the same installed provenance.
Expand the required pull-request call from Linux x64 to Linux x64, Linux arm64, and macOS arm64. Trusted heads receive only DEEPSEEK_API_KEY_EXTERNAL for a fail-loud live two-turn smoke on each carrier, while fork and Dependabot heads retain the full keyless path without exposing secrets.
Pin the reusable secret declaration, matrix call, aggregate dependency, untrusted-head condition, and live/keyless commands in the workflow contract test.
Refs #2952.
* docs(testing): make installed wheels the Python CI authority
Record the clean-wheel provenance boundary, complete keyless scenario set, trusted real-API contract, secret handling, and three-target required topology in a new implemented testing decision. Update the SEA distribution and portable-CI authorities plus the Python contributor reference to describe the same current state.
Archive the fully superseded Linux-x64-only decision after consolidating its rationale and alternatives into the new owner. Preserve its bilingual triplet as a sealed historical snapshot and redirect every active current-state reference.
Refs #2952.
Move the shared module-reload policy into dsh-base by inserting its HMR row disabled, then remove the redundant disabled overrides from Web, headless, SDK, and ACP. No shipped profile enables server module reload; live profile patch watching continues through the launcher-owned config-only fallback, and browser client HMR remains a separate mechanism.
A later profile layer can opt into source-module reload explicitly with disabled: false while retaining the base root configuration. Composition tests cover every shipped mode and the explicit enable path, and the bundle references plus launcher Agent Notes document the resulting ownership and safety rationale.
Set DSH_E2E_MAX_WORKERS=4 for the credentialed e2e workflow and pin that environment contract in the workflow test. Profile-launched SDK and ACP scenarios each boot a complete subprocess tree, so the previous file-level fan-out could multiply process and provider pressure far beyond the runner's useful concurrency.
The bound changes scheduling only: every e2e file still runs, the Vitest configuration retains its explicit override knob, and local callers can choose a different positive worker count when their resources allow it.
Regenerate the configuration catalog and module graph after replacing standalone application packages with dsh profile bundles and renaming the private Python carrier. Update built-bin coverage to launch the shipped sdk and acp profiles, assert retired bins stay absent, and keep the Web golden text aligned with the same assembled runtime.
Clarify that headless is a startup profile whose patches freeze after boot. This commit is projection and verification work: it contains no application implementation, and every generated document is produced from source committed earlier in the series.
Update workspace manifests, the lockfile, Host project references, Knip inputs, package constraints, vendoring rewrites, and Python runtime build/smoke scripts for sdk-app, acp-app, and @deepseek-ai/dsh-sdk-python-runtime. Add the ACP hook packages to the dsh dependency closure so installed profile materialization resolves the same plugins as source workspaces.
Keep Python distribution outputs deliberately unchanged: the wheel modules, executable names, and smoke targets retain their public identities even though their private npm carrier moved. Constraint fixtures pin the new package locations and catch missing application dependencies on every platform.
Add verify-application-entrypoints to the top-level gate graph. It inventories executable sources and package bins across apps, packages, and examples; rejects unclassified launchers including root-level js/mjs/cjs/ts files; and permits only the dsh CLI plus the explicitly private Python runtime carrier exception.
Update repository, architecture, CLI, and naming records to state the same rule: Node consumers select a dsh profile instead of invoking application-package bins, and no compatibility aliases remain. Fixtures prove both allowed classifications and representative escape attempts, making the architectural rule mechanically enforceable.
Rename the relocated npm workspace to @deepseek-ai/dsh-sdk-python-runtime and the runnable example to python-sdk-agent, then update every owning English/Chinese document, test, and packaged-runtime reference. Remove the obsolete standalone bin while retaining the carrier entrypoints used to assemble the wheel runtime.
This is intentionally a naming and ownership change, not a Python SDK migration. The public deepseek_harness_sdk and deepseek_harness_runtime module, wheel, executable, environment, and wire behavior remain unchanged. Documentation records that this private carrier is the temporary sole non-dsh application exception and will move to profile launch later.
Regenerate the four TypeScript SDK replay scenarios after switching their subprocess to dsh --profile sdk. The fixtures now project profile-owned runtime context, tool composition, nested-child persistence, and the opt-in DeepSeek session-log acceptance event while preserving each scenario's final response and file assertions.
This commit contains only committed snapshot outputs. Separating them from the SDK implementation keeps protocol/API review focused and makes the model-visible consequences auditable as generated evidence.
Replace the TypeScript SDK's public arbitrary command/argv launch surface with the same-version dsh CLI, a named profile, ordered per-launch patches, optional process cwd, and explicit Harness home selection. Installed consumers use the built CLI; clean source checkouts use the package's src/bin.ts through an absolute tsx/esm loader and a source-only patch that omits build-generated Typert loading.
Materialize explicit or inherited environments at spawn time, keep profile-internal patches below caller patches, and resolve every caller-relative path before the child starts. The SDK subagent provider validates its optional CLI and patch files at plugin load and requires an isolated absolute child home.
Treat JSON-RPC initialize as the Loader-owned readiness point: Loader settlement joins entry imports, fiber lifecycle work, and synchronous effect registration, so the server needs no scheduler tick. A delayed profile entry registers a private adapter before initialize resolves, proving caller-supplied plugin routes are visible without fallback.
Update sdk-app ownership, server diagnostics, TypeScript SDK examples, nested-loader coverage, and session-upload replay layering together. The following commit contains only the regenerated SDK transcripts, keeping this API and lifecycle change directly reviewable.
Move examples/jsonrpc-agent to examples/python-sdk-agent and packages/examples/jsonrpc-demo to packages/sdk/python-runtime while preserving every file byte-for-byte. The directory placement now reflects the example's Python-distribution role and the private runtime carrier's SDK ownership.
This commit deliberately keeps the old package names, commands, configuration, and snapshots inside their new directories. All 42 files are 100% renames; API/profile migration and naming changes follow separately so reviewers do not have to disentangle behavior from filesystem movement.
Regenerate the ACP composition graph and committed replay outputs from the assembled dsh base plus acp-app profile. The updated logs, system prompts, tool schemas, and stdout projections capture the same scenarios after shared plugins move out of the retired demo package and into profile-owned composition.
There is no runtime source in this commit. Keeping generator-owned artifacts separate lets reviewers validate the behavioral migration first, then inspect expected wire/model-visible consequences as a mechanical projection update.
Replace the standalone @deepseek-ai/dsh-acp-demo application with dsh --profile acp plus ordered example patches. The shipped acp-app bundle owns only the protocol bridge; every example overlay now targets shared dsh-base rows instead of copying a complete application tree.
Move launcher responsibilities into the ACP snapshot harness: it materializes profile patches, links required packages, reserves stdout for JSON-RPC, observes spawn and drain failures, and escalates process teardown deterministically. The relocated control-surface fixture and the ACP/subagent integration tests now exercise the real CLI/profile path.
This commit contains authored runtime, configuration, and test changes only. Generated transcript and projection churn is deliberately left for the next commit so reviewers can inspect the migration logic without hundreds of expected-output edits.
Move the ACP control-surface e2e, scripted LLM, and Cordis fixture out of the application package that later commits retire and into the runnable examples/acp-agent test tree. This gives the assembled dsh profile example ownership of its integration fixture.
This commit is intentionally mechanical: all three files retain their exact blobs and appear as 100% renames. Imports and launch behavior are updated only in the subsequent ACP migration commit, keeping reviewer-visible code changes separate from file movement.
Introduce @deepseek-ai/dsh-acp-app as the thin application layer for the built-in acp profile. It contributes only the ACP protocol bridge and profile metadata; dsh-base remains the single owner of shared agent composition, providers, persistence, permissions, and tools.
Wire the bundle into CLI resolution, catalogs, workspace configuration, and built-bin coverage. The focused bundle and startup tests prove that base plus acp-app exposes automation sessions while keeping stdout reserved for ACP JSON-RPC.
Introduce @deepseek-ai/dsh-sdk-app as the thin application layer for the built-in sdk profile. The bundle contributes the JSON-RPC server and startup-only profile metadata, while dsh-base continues to own the shared agent, provider, persistence, and tool composition.
Publish ctx.appReady from the launcher only after the Loader tree and launcher-owned setup succeed. The stdio lifetime binding leaves stdin unread until the protocol transport claims it and defers EOF exit 0 until readiness commits, so early protocol frames remain buffered and a racing startup failure remains the nonzero process outcome. Fiber disposal cancels both pending lifecycle listeners.
Register the bundle in the CLI resolver closure, generated configuration catalog, workspace graph, and built-bin smoke. Startup tests prove that base plus sdk-app exposes the SDK server without taking ownership of shared runtime plugins; focused and built-bin regressions cover early input, EOF readiness, and startup-error precedence.
Add a patchReload field to built-in profile metadata and carry it through CLI profile resolution into app boot. Live profiles install the existing patch watcher; startup profiles freeze every layer after boot and apply later edits only on the next launch. Missing or invalid metadata fails before the plugin tree starts.
The implementation keeps reload policy with the profile that owns it instead of inferring behavior from an entrypoint. Unit tests cover metadata validation and both lifecycle modes, while the CLI and app-boot references document which built-ins are live versus startup.
Record the final architecture before any runtime or file-layout changes. The decision makes named dsh profiles the only supported Node application launch path, gives TypeScript SDK callers ordered profile patches for per-launch customization, and retains the packaged Python runtime as an explicitly temporary exception with a later migration obligation.
Keeping this decision in a documentation-only commit gives every following commit one stable naming, lifecycle, and compatibility reference. The English and Chinese notes and their pairing record enter together.
- stop attributing the 45-case helper/Node divergence to the path port spec,
which pins only the Node-facing port to Node
- keep the divergence measurement as provenance, without a dead owner
- fix the path corpus comment so it does not claim divergence from the spec
that asserts equality
- drop the v2 generation stamp from the cordis mount fallback test
- restate the watcher refusal rationale in current-state terms
- re-record the ui-workspace bilingual pair after rebase
Remove dead design-session citations, change narration, indexical
stamps, and review-adjacent justification found by the
dsh-trim-cot-leakage recall batteries in prose that landed after the
last purge. Bilingual README pairs are re-recorded.