dsh-doctor
asdf17128
Find what your DeepSeek Harness (dsh) patches silently broke — dead patches, config fields dropped by whole-config repla…
PROJECT TOPICS
PROJECT README
Durable, workspace-owned long-running processes for DeepSeek Harness, plus a Runtime Center that keeps DSH Session Jobs and Workspace Workloads visible without conflating their lifecycles.
Current status: public installable profile bundle with a Windows local-process Provider, validated against DSH
0.1.0-rc.6. The Service/API contract remains pre-1.0.
| DSH Job | DSH Workload | |
|---|---|---|
| Owner | Agent/Session | Canonical workspace |
| Lifetime | Bounded operation | Long-running service |
| Disposal | Cancel with owner | Explicit stop |
| Storage | In-memory registry | Durable records and logs |
| Restart identity | New Job | Stable workloadId, new runId/generation |
| Readiness | Producer-specific | Log/TCP/localhost HTTP evidence |
Typical Workloads include dev servers, watchers, debuggers, proxies, local middleware, and long-running event consumers. Builds, tests, installs, and other bounded operations should remain DSH Jobs.
. — Host plugin that provides ctx.workloads, the local-process provider, and a session-authorized Web API../client — Web Client plugin that registers the 运行中心 entry in conversation.view../tools — opt-in Agent-preset consumer exposing seven workload_* tools and optional proc_* compatibility aliases.The Host plugin provides one process-wide ctx.workloads service:
list(workspaceRoot, options)
start(workspaceRoot, spec, existing?, control?)
wait(workspaceRoot, workloadId, readiness, signal?)
logs(workspaceRoot, workloadId, maxBytes?)
stop(workspaceRoot, workloadId, control?)
stopAll(workspaceRoot, control?)
restart(workspaceRoot, workloadId, control?)
subscribe(listener)
Records are stored outside business repositories:
${DSH_HOME}/runtime/workloads/<canonical-workspace-sha256-prefix>/
Each Workload has a stable workloadId, a new runId and incremented generation per start/restart, orthogonal lifecycle phase and readiness health, process identity, timestamps, last outcome, bounded run history, readiness evidence, action audit metadata, and rotating logs.
The detached runner checks currentRunId before each metadata write, preventing a stopped older generation from overwriting a newer restart.
Browser calls include the current sessionId, but neither the browser nor the model chooses the authoritative workspace boundary. The Host resolves:
sessions.get(sessionId)
→ sandboxPolicy.resolve({ session })
→ canonical workspaceRoot
A request whose cwd does not match that root is rejected. Agent tools use the same policy from exec.agent.session.
The Client registers a session-scoped conversation.view entry with ID runtime-center and label 运行中心.
useSessions(state => state.jobsBySession[sessionId]); they are not polled or copied into a second state owner.Stop button is available in every phase (idempotent for already-terminated services); Restart keeps its original behavior.工作区长期服务 section header shows a Stop all button only while at least one service is active; like stop/restart it needs a second-click confirmation and is re-authorized on the Host.A future DSH-native version should replace Workload polling with an apiProxy domain and Client snapshot mirror. Session Jobs already use the native push mirror.
Load ./tools from an Agent preset to expose:
workload_list
workload_start
workload_wait
workload_logs
workload_stop
workload_stop_all
workload_restart
Set enableProcAliases: false to omit the seven legacy proc_* aliases (including proc_stop_all). The tool layer is a consumer only; it must not publish or isolate the shared Host workloads service.
Install the tagged GitHub package into the Web profile:
dsh plugin --profile web add github:yewenyell-lang/dsh-workloads#v0.3.0
The package declares dsh.bundle.patch, so dsh plugin automatically adds it to dsh.profile.bundles. Its cordis.patch.yml mounts the Host Registry, local-process Provider, Web API, and Runtime Center with legacy migration disabled by default. Restart the existing DSH Web process and refresh the browser after installation.
Verify the composed profile without starting another server:
dsh --profile web --dump-config
To remove the bundle:
dsh plugin --profile web remove dsh-workloads-local-ui1
Add the tool consumer only to Agent presets that should control Workloads:
- id: tool-workloads
name: dsh-workloads-local-ui1/tools
config:
enableProcAliases: true
The Registry belongs in the Host plane because it crosses Sessions. Only the tool consumer belongs in an Agent preset; do not isolate the shared workloads service there.
To opt into legacy migration, override the bundle row in the Web profile's later cordis.patch.yml layer and restate its complete config:
- id: dsh-workloads-local-ui1
config:
legacyProcessRoots:
- C:\\absolute\\legacy-process-root
DSH_* and common credential variable names.127.0.0.1 TCP, and credential-free localhost http:// URLs.taskkill /T first, /F only after the grace period.legacyProcessRoots accepts absolute directories whose children are workspace-hash directories containing the earlier jobId/status/logPath record shape.
Migration is opt-in, copy-only, idempotent per target workspace, non-destructive to sources, and marked with migratedFrom: legacy-process-v1. No product-, preset-, user-, or machine-specific migration root is compiled into the package.
No dependency installation is required for the current source and smoke tests.
npm run check
npm test
The suite uses temporary DSH_HOME and workspace directories and covers Client registration, optional legacy migration, start, combined readiness, redaction, stable restart identity, stop, stop-all, action audit metadata, seven workload_* tools, optional aliases, and cleanup.
DSH_HOME is the supported coordination model. Shared multi-Host operation needs storage CAS/lease fencing.apiProxy domain/mux.connection/reset and consume Host change events.attachController(), desired state, and reconciliation leases before a stable 1.0 release.MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。