refactor(mode): modes are collaboration states — drop the access cap; enforcement axes stay independent

Review follow-up (tianyicui): plan mode and the sandbox are orthogonal
AXES, not just orthogonal state — entering plan must not change what the
sandbox enforces, matching Codex's separation of Plan/Default
collaboration presets from sandbox and approval settings.

ModeDefinition.access, the bash/resolve-mode clamp, and both cap-derived
guards are removed; a ModeDefinition is exactly { section }, and a mode
now carries only its guidance section plus the exit_plan_mode review.
The bash seam's resolveMode + waterfall go with their only listener:
dsh-bash and dsh-tool-bash revert to master byte-for-byte, and the
dsh-mode → dsh-bash dependency edge is gone. A deployment that wants
kernel-enforced read-only planning pairs the mode picker with the
independent sandbox-mode option, in either order.

The RFC archives this as the second removed enforcement shape (after
the interim allowlist) with the same restart trigger — effects
self-declaration; the orthogonality FAQ now answers with the two-axis
rule. The plan example demonstrates the axes side by side, and the
re-recorded fixtures pin the guidance-only section.
This commit is contained in:
kingwl
2026-07-20 13:34:30 +08:00
parent b47b2ba794
commit c0146b9c4a
38 changed files with 1432 additions and 2082 deletions

View File

@@ -2,9 +2,11 @@
# Client Protocol WITH session modes composed — the plan-mode RFC's live
# composition. The editor's mode picker (session/set_mode) switches the
# session between `default` and `plan`; in plan mode the model works under
# the plan guidance section with bash clamped to a read-only sandbox by plan
# mode's `access` cap, and leaves through the user-reviewed exit_plan_mode
# tool (the review rides the same elicitation flow as ask_user_question).
# the plan guidance section and leaves through the user-reviewed
# exit_plan_mode tool (the review rides the same elicitation flow as
# ask_user_question). The mode never touches the sandbox or approval knobs —
# collaboration mode and enforcement are independent axes, switched
# separately and in any order.
#
# CRITICAL: this tree loads NO stdout logger and NO hmr — stdout is reserved
# for the ACP JSON-RPC protocol (a property of @deepseek-ai/dsh-acp-demo,
@@ -41,23 +43,20 @@
Verify your work by running the code or tests. Keep answers brief and factual.
# Session modes (ctx.modes — the shipped `plan` definition, no overrides):
# the mode/set vocabulary, the mode section, the exit_plan_mode tool, and
# plan's read-only `access` cap on the sandbox stack below. The ACP bridge
# above reads it opportunistically and advertises the picker.
# the mode/set vocabulary, the mode section, and the exit_plan_mode tool.
# The ACP bridge above reads it opportunistically and advertises the picker.
- id: mode
name: '@deepseek-ai/dsh-mode'
# The sandbox stack: the platform-runner provider (bwrap → per-platform
# Landlock launcher → Seatbelt, functionally probed), then the confined bash
# executor. workspace-write is the day-to-day default; plan mode's `access`
# cap clamps every call to read-only while it is in force — which is exactly
# what keeps the bash tools AVAILABLE in plan mode: exploration commands run,
# a write is denied by the sandbox. The cap and the session's own
# sandbox-mode knob compose at read time (neither writes the other), so a
# knob switched during plan re-emerges intact on exit. NOTE: the workspace
# root is CONFIG-FIXED for the executor's lifetime (the launch dir here),
# while each ACP session has its own cwd — a per-session root is config-phase
# future work in the sandbox RFC.
# executor. workspace-write is the day-to-day default; it applies identically
# in every mode — plan mode does not change it. A user who wants a hard
# read-only floor while planning switches the sandbox-mode option to
# read-only, independently of the mode picker, in either order. NOTE: the
# workspace root is CONFIG-FIXED for the executor's lifetime (the launch dir
# here), while each ACP session has its own cwd — a per-session root is
# config-phase future work in the sandbox RFC.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
- id: bash
@@ -69,8 +68,7 @@
# The approval seam (ctx.approval — mechanism only, no config): the confined
# executor makes tool-bash advertise the escalation fields, and this seam is
# what lets an escalating retry actually reach the editor as a
# session/request_permission prompt. In plan mode the `access` cap denies
# escalation outright — the widened step belongs in the plan.
# session/request_permission prompt — in plan mode exactly as in default.
- id: approval
name: '@deepseek-ai/dsh-user-approval'
@@ -82,8 +80,7 @@
# Filesystem capability stack: local provider, read-before-write/edit policy
# gate, then the model-facing read/write/edit tools. Plan mode restrains
# these by guidance only (the section says changes belong in the plan) — the
# enforced boundary in plan is the bash sandbox clamp above.
# these by guidance only — the section says changes belong in the plan.
- id: fs-local
name: '@deepseek-ai/dsh-fs-local'
config: