{"content":"Dev journal — DSH Phase 1 M5 cutover core delivered (feat/dsh-phase1, 103b0ec2): real cowork sessions can now run on the DSH kernel behind app_config.dshKernelEnabled. coworkKernelRouting decides per turn (flag + OpenAI-compatible eligibility + dsh: handle stickiness so an existing session never switches kernels mid-conversation); coworkDshTurn's DshTurnHub multiplexes one runtime subprocess across sessions; coworkRunner gained runDshSessionLocal wired into the executionMode dispatch — native steer via a trySubmitSteer branch (no interrupt-and-resubmit), abort maps to the runtime's turn cancel, and tool approvals ride the existing pendingPermissions machinery verbatim so the renderer permission dialog works unchanged. Provider resolution is direct-upstream via resolveDshProviderRoute — the DSH path speaks the provider's native protocol through pi-ai and bypasses the OpenAICompatProxy entirely. Proven end-to-end: an integration test drives a real CoworkRunner through four turns (plain reply with streaming + finalize, mid-turn steer consumed as a durable user message, approval allow executing the gated tool, abort closing the turn) against a mock gateway on the real pi-ai path. Hardening during the hunt: the notification pump now contains per-event handler failures (one bad callback previously killed the whole event stream), and streaming assertions must read store mutations, not the emitted snapshot. Remaining under M5: sandbox-mode decision, Electron packaging, real-model behavior comparison, compaction quality. Full suite: 11 app-side + 33 runtime checks green.","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}