dsh-jailbreak
Verifieddsh-jailbreak Β· v0.1.0 Β· MIT Β· Web UI
Native jailbreak control for DeepSeek Harness: an openable composer-bar mode switch (off / lowered / full) that drives the content-handling system-prompt section and synthetic-history priming.
Install
dsh plugin add dsh-jailbreak Confirm the layer applied with dsh --profile default --dump-config β see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
dsh-jailbreak
Native jailbreak control for DeepSeek Harness β an openable three-mode switch in the composer bar, sitting next to the Access (permission) seat.
Unofficial. This is a third-party plugin. It is not made, endorsed, reviewed, or supported by DeepSeek. "DeepSeek Harness" is named only to say what the plugin plugs into.
Ported from the Codex CLI jailbreak implementation in
codex-cli-main (old, with jailbreak functionality).
| Mode | Chip label | System-prompt section | Synthetic-history priming |
|---|---|---|---|
off |
Disabled | none | none |
lowered |
Lowered | content_handling_lowered.md |
none |
full |
Full | content_handling_full.md |
32-message Q/A priming |
full is the default, matching upstream (JailbreakLevel is a process-global
atomic initialized to Full / 2).
Using it
The chip. A padlock control appears in the composer tool row, to the left of
the message box. It shows the current mode (padlock closed = off, half-open =
lowered, open = full). Click it for a menu of the three modes; the current
one is marked. Choosing Full opens the same acknowledgement gate the shipped
Access seat uses for danger-full-access. The change is applied by the host and
the pushed projection frame is what the chip reflects β there is no optimistic
local state.
The command. /jailbreak works from the composer too:
/jailbreak β reports the current level and the valid options
/jailbreak off β Codex "Disabled"
/jailbreak lowered
/jailbreak full
/jailbreak disabled β accepted alias (the upstream spelling)
An unrecognised argument is an error listing the valid options, with the ported
wording from apply_jailbreak_inline.
Scope. The level is per session, not process-global. The choice is
recorded in that session's own log, so two sessions cannot fight, and resume and
fork restore the choice for free. A session with no explicit choice uses the
configured default. /jailbreak in one session does not touch another.
Configuration
The deployment-wide default for sessions with no explicit choice:
# C:\Users\Leo\.dsh\profiles\desktop\cordis.patch.yml
- id: jailbreak
config:
defaultLevel: off # off | lowered | full (default: full)
What is installed where
The plugin is registered as a profile bundle by the plugin manager:
C:\Users\Leo\.dsh\profiles\desktop\package.jsonβdependencies["dsh-jailbreak"]anddsh.profile.bundlesboth list it.- The running copy lives at
C:\Users\Leo\.dsh\profiles\desktop\node_modules\dsh-jailbreak\.
This directory is the source of truth; that one is what runs.
pnpmmaterialises afile:dependency as a copy, not a symlink. Editing the source does not change the running plugin until you re-sync.
Re-sync after an edit (then reload the page for client-half changes):
powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\sync.ps1
Remove it entirely with
plugin_manager β remove_bundle β dsh-jailbreak.
Sharing it
The plugin is plain JavaScript with no build step and no runtime
dependencies (@deepseek-ai/schemastery is a peer that resolves from the
recipient's own harness). So sharing it is just shipping these files.
Publish to npm (best for a general audience)
The name dsh-jailbreak is unclaimed on npm as of writing.
cd Plugins\Jailbreak
npm publish # add --access public if you scope it
Recipients then install it the same way any harness plugin is installed:
dsh plugin --profile web add dsh-jailbreak
The
desktopprofile is app-managed βdsh --profile desktop β¦refuses with "profile desktop is managed exclusively by the Electron application". Desktop users install through Settings β Plugins in the GUI instead, by name or byfile:path.
Hand over a tarball (no registry needed)
cd Plugins\Jailbreak
npm pack --pack-destination dist
That produces dist\dsh-jailbreak-0.1.0.tgz (~47 kB, 15 files). Send it, and the
recipient runs:
dsh plugin --profile web add file:./dsh-jailbreak-0.1.0.tgz
Verified: this installs cleanly, adds both the dependencies entry and the
dsh.profile.bundles row, materialises the package under the profile's
node_modules, and the composed tree resolves the plugin row.
Share a git repo
git init; git add -A; git commit -m "dsh-jailbreak"
Recipients clone it and install from the path (git: and github: specs work
with pnpm too):
dsh plugin --profile web add file:C:/path/to/clone
dist/ and node_modules/ are gitignored.
What actually ships
npm pack includes exactly index.js, client.js, cordis.patch.yml,
package.json, src/, plus README.md (npm always adds it). Both halves'
verification harnesses ship too β note they re-derive their port proof from the
original Codex source tree and the DSH checkout, which a recipient will not
have, so expect the port-proof assertions to fail outside this machine. The
runtime code has no such dependency.
tools/sync.ps1 is deliberately not shipped: it is an author-side helper for
pushing this source directory into the local profile copy, which is meaningless
for someone who installed a package.
Layout
index.js host half entry: Config + apply(ctx, config)
src/host/levels.js the three levels (ported vocabulary, labels, descriptions)
src/host/prompts.js the content-handling prompt texts (byte-identical port)
src/host/synthetic-history.js the 32-message priming transcript (ported)
src/host/content.js section/context names and orders; level -> text
src/host/projection.js the `jailbreak` session projection + wire value
src/host/config.js schemastery Config (defaultLevel)
src/host/verify/verify.mjs 59-assertion host harness (incl. sha256 port proof)
client.js browser half: the composer chip (classic script)
src/client/verify-client.mjs 29-assertion DOM harness
src/client/README.md client-half notes: slot ids, tokens, fallback
CONTRACT.md the build contract both halves were written against
How it works
Two halves, wired the way the shipped Access seat is wired.
Host. ctx.systemPrompt.section(...) contributes the content-handling
section and ctx.systemPrompt.context(...) contributes the priming; both read
the level through a function, so a switch applies to the next assembly without
re-registering. A sessionProjections unit keyed jailbreak folds the level
out of the session log and publishes the JailbreakSelect wire value
{ currentValue, options: [{ value, name, description }] }. A /jailbreak
command is the single write path.
Client. A classic-script bundle (window.__ModuleLoader__.load) registers
one entry into conversation.input.left, reads useProjection('jailbreak'),
and submits /jailbreak <value> on the live session. Absent projection β
renders nothing, exactly like the shipped chip. UI primitives (Menu,
RiskConfirmation, IconChevronDownOutline14) are used when present, with a
hand-rolled fallback that keeps the same interaction contract.
Write path. The level is recorded by the command's own command/run log
event, which the projection folds β it is not a bespoke event type. A
plugin-owned event type was rejected: out-of-repo event types sit outside
KNOWN_SESSION_EVENT_TYPES and Session.append cannot set the ignorable
marker that stored-log validation needs. command/run is already in the known
vocabulary, and folding it gives durable, replay-safe, fork-safe per-session
state for free.
Two deliberate deviations from the Codex original
Synthetic history is a user-role context snapshot, not alternating user/assistant turns. Codex prepends real user-role and assistant-role
ResponseItems to every request. DSH has no assistant-role injection seam: theagent/pre-stepwaterfall carriesUserMessage[]only. The sanctioned, cache-safe home for model-visible non-tool material isctx.systemPrompt.context(...)β "dynamic model context materialized as a durable user-role snapshot". The same 32 messages, in source order, with the source text, are rendered as one labelled transcript. The content is the ported content; the carrier differs.Per-session instead of process-global. Upstream is one global atomic. Per-session is strictly better here and matches how the harness scopes everything else; the configured
defaultLevelcovers the global case.
Verification
Both halves ship runnable harnesses.
node src/host/verify/verify.mjs β 59 passed, 0 failed
node src/client/verify-client.mjs β 29 passed
The host harness proves, among other things, that both prompt texts are
byte-identical to the Codex sources by sha256
(ad1c51c2β¦ lowered / 5792 B, d4c10a77β¦ full / 15586 B), that the longest
source line (2101 chars) survived, that get_synthetic_history() re-extracts to
32 alternating messages, that the priming really materialises through the
checkout's own RuntimeContextProjection, that an unchanged assembly does not
re-emit it (cache-safe), that unloading removes both contributions and the
command (HMR-safe), and that the plugin mounts on an empty context without
throwing.
Verified live in the running desktop app after install:
- plugin fiber active β
{"entryId":"include:jailbreak","moduleName":"dsh-jailbreak","enabled":true,"fiberPhase":"active"} - client entry mounted β
conversation.input.leftoccupant{ id: "jailbreak", order: 50, active: true } - the content-handling section and the priming both reached a live session's model context
Attribution
The jailbreak content-handling prompts and the synthetic-history transcript are
ported verbatim from the Codex CLI tree at
C:\Users\Leo\Desktop\Stuff\src\agents\Apps\codex-cli-main (old, with jailbreak functionality)
(codex-rs/core/src/prompts/*.md, codex-rs/core/src/jailbreak.rs,
codex-rs/protocol/src/jailbreak.rs). Prompt text is reproduced from material
the operator supplied; the operator is responsible for its use.
MIT.