DSH / Atlas
2026-07-30implementedfeature

Current sandbox policy context

当前沙箱策略上下文

The sandbox policy already enforced and logged each session's file-effect mode, but a fresh model request did not contain that state. In a Web session under `read-only`, write and edit schemas remained visible, so the model claimed it could write and learned otherwise only after a denied call. After `/permission danger-full-access`, the next request carried the approval-policy change but still omitted the sandbox mod

English

Problem

The sandbox policy already enforced and logged each session's file-effect mode, but a fresh model request did not contain that state. In a Web session under read-only, write and edit schemas remained visible, so the model claimed it could write and learned otherwise only after a denied call. After /permission danger-full-access, the next request carried the approval-policy change but still omitted the sandbox mode. Denial results were therefore the first model-visible policy source even when the user asked about capability before any operation.

Decision

dsh-sandbox-policy, the owner of mode and workspace-root resolution, registers one sandbox:policy cache-safe context contribution. Every agent request resolves the active session directly through ctx.sandboxPolicy.resolve({ session }); there is no denial-history scan or process-local “last told” state.

The policy contribution is capability-neutral and available to every agent session by default. A composition may suppress the complete runtime-context channel when its model interface intentionally excludes dynamic context; this does not disable policy enforcement. The contribution does not maintain a second inventory of mounted backends or tools; model-visible schemas remain the authority for available operations, while the context conditions its claims on any available operation that the DSH file sandbox enforces. The capability-neutral policy context decision supersedes the earlier family-registration mechanism while retaining this note's cache-safe delivery and durable snapshot design.

The contribution states only facts shared by every enforcement dialect. read-only says an available sandbox-enforced operation cannot modify files in the standing mode and directs the model to try an available tool normally, then follow any denial and escalation guidance that tool returns. workspace-write states the canonical session workspace with non-exclusive wording and summarizes, without enumerating, that some platform temporary areas may also be writable. danger-full-access says the DSH file sandbox does not restrict file modifications by available operations. Backend-selected temporary paths, /dev/null, runner readiness, exact tool availability, and other policy domains are absent because resolve() cannot establish them at request assembly.

The existing dsh-system-prompt assembly now has ordered dynamic contexts alongside stable system sections and tool schemas. After assembling one step, agent-loop renders all active contexts as one full snapshot with an explicit supersession statement. It appends a sourced user/message only when no retained snapshot exists, the bytes changed, compaction removed the retained message, or the final contribution disappeared and needs one clearing snapshot. The snapshot is appended after existing history and before step/start, so a changed policy preserves the preceding system-and-conversation cache prefix. The session event itself reconstructs the exact model input; request/header remains byte-identical when only policy context changes.

Ownership stays narrow. Approval policy contributes its complete current ask or never fact to the same full snapshot; migrating sandbox alone would not preserve cache because /permission changes both owners. Plan mode remains plan:policy, and tool plugins continue to own schemas plus attempt, denial, and escalation guidance. Context states standing policy; filesystem, one-shot bash, and terminal backends remain the enforcement boundaries.

The cache decision follows current source rather than analogy alone. Codex models permissions as a developer-role WorldState section with a persisted fingerprint, emits it only when state changes or retained history lost the fragment, and records the snapshot transition. Hermes keeps its system prompt fixed for a session and explicitly prepends changing skill, model, and voice notices to the next user message to avoid invalidating prompt cache. Pi has no comparable built-in sandbox state, and Claude Code's current native implementation is not publicly inspectable; Anthropic's public cache guidance nevertheless places changing per-request context after the stable cached prefix.

The earlier real-provider Web fixture quantified the defect in the system-section version. The first danger-full-access and workspace-write requests each reported only 256 cache-read tokens against 14,691 and 14,782 uncached input tokens. Later steps under an unchanged policy reported approximately 14.7k–15.5k cache-read tokens. Moving only the sandbox sentence would not fix those misses because the same preset switch also rewrote the approval-policy system section.

Wording evidence

The wording experiment pre-registered preemptive refusal as its primary endpoint and required the old standing sentence to produce at least one refusal in twelve fresh sessions before any replacement could be judged. On 2026-07-30, commit 2bf41990401b194bd8637f07bbd90c67a9eeac75 ran deepseek-v4-flash through the shipped Web composition with the exact positive-control sentence Bash commands run under the "read-only" file sandbox. and the current tool-owned attempt guidance. The control produced zero preemptive refusals and zero speculative escalations; all twelve sessions made an ordinary bash call, observed a denial, escalated in the same turn, received approval, and landed the requested file. No sample was excluded.

After the cache-safe delivery change, commit 10d4e0ff7b68d38fc4403403b644aac442b97a00 repeated the same twelve-session positive control through the new tail-context channel. It again produced zero preemptive refusals and zero speculative escalations; all twelve sessions made an ordinary first call, observed denial, escalated in the same turn, and received approval. Eight landed the exact requested file, and no sample was excluded.

Both positive controls therefore failed the pre-registered sensitivity gate. The formal twelve-session Candidate A and B arms were not run, and these experiments do not select or validate the current wording. They establish that the earlier five-of-twelve result is not reproducible under this task and current tool guidance, and that a stronger positive control or different task distribution is required before making model-behavior rate claims. Deterministic tests below establish truthful request construction and replay only.

The cache-safe delivery rework then supplied a separate, non-statistical acceptance comparison over the neutral Web task Create the relative path policy-neutral.txt ...; it does not replace the pre-registered twelve-session experiment. Candidate A's categorical read-only statement produced a text refusal with zero tool calls. Candidate B added one composition-conditioned sentence only for enforced families whose tools expose escalation. A fresh real-provider run then issued an ordinary write, observed the read-only denial, retried the same operation in the same turn with sandbox_permissions: "workspace-write", received approval, read the file back, and verified the exact contents. It made no speculative escalation. Across the permission switches and four mutation steps, cache reads were 14,848–15,872 tokens while uncached input was 59–306 tokens per request, directly demonstrating the stable-prefix benefit.

Alternatives considered

Narrate only mode changes. Rejected because it leaves a fresh session uninformed and makes the first denied operation the policy-discovery mechanism. It also requires a baseline definition that is unnecessary when current state can be rendered directly.

Scan denial history or remember the last narrated mode. Rejected because denial events describe attempted operations, not authoritative current state, while process-local bookkeeping does not survive resume. The owner can fold the durable policy directly on every request.

Put current policy in a dynamic system section. Rejected after real provider evidence showed that a first-time permission switch reduced cache reads to 256 tokens while roughly 14.7k input tokens missed. DeepSeek matches complete prefixes; changing the first wire message prevents reuse of the longer system-plus-history prefix.

Call agent.inject() independently from each policy owner. Rejected because sibling listener order would define model order, separate messages could expose mismatched intermediate snapshots, and every owner would need its own compaction-retention scan. The existing assembly owner can order contributions and materialize one atomic full snapshot.

A generic runtime-facts package. Rejected because the existing system-prompt assembly already owns sections, schemas, variables, scope, and the authoritative per-step waterfall. Extending that owner with ordered contexts adds no package or second registry service.

Repeat tool schemas or plan guidance in the context. Rejected because those surfaces already have owners and independent lifecycles. Approval current state joins the snapshot only because the same /permission switch changes it and leaving its system section would retain the cache defect.

Keep Candidate A after the cache-safe move. Rejected by the neutral real-provider task: the model returned a pure text refusal and made no tool call despite the existing bash attempt guidance. The surviving anti-refusal principle states no escalation mechanics itself; it tells the model not to infer impossibility from the standing label, then delegates denial and escalation behavior back to the available tool.

Keep sandbox mode absent because a standing mode label once caused preemptive refusal. Rejected because a fresh Web request otherwise exposes mutation tools while withholding their standing policy, producing false capability claims before the first operation. The earlier live measurement remains a required counter-test: five of twelve turns ended without a tool call under Bash commands run under the "read-only" file sandbox. The committed tool-owned attempt guidance postdates that measurement, so the replacement is selected through a new positive-control experiment under the current tool contract rather than assuming the old and current conditions match.

A separate model-context package. Rejected because the policy owner can resolve current session state directly and the existing assembly service can order it. A new package would add a shallow composition layer and documentation/gate surface around the same request boundary.

Enumerate writable temporary roots. Rejected because the backend is selected later at confine(): bwrap, Landlock, Seatbelt, and the in-process filesystem fence do not grant one common temporary-path set. Host-specific paths in a standing request would be both unstable and overclaimed.

Consequences

A model receives the standing file policy before probing a tool, and the next request after /permission reflects the committed mode. The stable system prompt no longer changes for sandbox or approval state; a changed full context snapshot is append-only after retained history, and unchanged state adds no message. Older snapshots remain in history but are explicitly superseded by the latest full snapshot. The statement is guidance, not an enforcement guard: runtime safety still comes from filesystem, one-shot bash, and terminal backends consuming the same resolved policy.

Focused tests pin all modes, canonical roots, switch timing, service disposal, context ordering, clearing, stable request headers, resume, and byte stability across different TMPDIR values. Keyless assembled snapshots pin the durable context message through real Loader compositions. Keyless replay owns the neutral denial-to-escalation trajectory; it is a structural regression proof, not wording-selection evidence.

中文

问题

沙箱策略已经强制执行并记录每个会话的文件操作模式,但新的模型请求并不包含这一状态。在 read-only 下的 Web 会话中,write 与 edit schema 仍然可见,因此模型会声称自己能够写入,直到一次被拒绝的调用后才发现事实并非如此。执行 /permission danger-full-access 后,下一个请求带有批准策略变更,却仍省略沙箱模式。因此,即使用户在任何操作前询问能力,拒绝结果也是模型可见的首个策略来源。

决策

dsh-sandbox-policy 负责解析模式与工作区根目录,并注册一项缓存安全的 sandbox:policy 上下文贡献。每次 agent(智能体)请求都通过 ctx.sandboxPolicy.resolve({ session }) 直接解析当前会话;不存在拒绝历史扫描或进程本地的「上次告知」状态。

该策略贡献不依赖具体能力,并默认可用于每个 agent 会话。当模型接口有意排除动态上下文时,组合可以抑制完整的 runtime-context 通道;这不会禁用策略强制机制。该贡献不会另行维护一份已挂载后端或工具清单;模型可见的 schema 仍是可用操作的权威来源,而上下文会将其声明限定在 DSH 文件沙箱所强制执行的任何可用操作上。不依赖具体能力的策略上下文决策取代了较早的家族注册机制,同时保留本 Agent Note 的缓存安全交付与持久快照设计。

该贡献只说明所有强制执行方言所共有的事实。read-only 表明受沙箱强制执行的可用操作在常驻模式下无法修改文件,并指示模型正常尝试可用工具,随后遵循该工具返回的任何拒绝与升权引导。workspace-write 用非排他措辞说明规范化的会话工作区,并概述某些平台临时区域可能也可写,而不逐一列举。danger-full-access 表明 DSH 文件沙箱不会限制可用操作修改文件。后端选择的临时路径、/dev/null、runner 就绪状态、确切的工具可用情况和其他策略领域都不会出现,因为 resolve() 无法在请求组装时确定它们。

现有 dsh-system-prompt 组装在稳定系统段与工具 schema 之外,还包含有序的动态上下文。组装一个步骤后,agent loop(智能体循环)会将所有活动上下文渲染成一份带显式取代声明的完整快照。仅当不存在保留快照、字节发生变化、压缩(compaction)移除了保留消息,或最后一项贡献消失而需要一份清除快照时,它才会追加一条带来源的 user/message。快照追加在现有历史之后、step/start 之前,因此策略变化时仍会保留此前的系统与对话缓存前缀。会话事件本身可以重建确切的模型输入;当变化的只有策略上下文时,request/header 仍保持逐字节相同。

归属范围仍然有限。批准策略会将其完整的当前 asknever 事实贡献给同一份完整快照;只迁移沙箱无法保留缓存,因为 /permission 会同时改变两方。计划模式仍由 plan:policy 负责,工具插件也继续负责各自的 schema,以及尝试、拒绝与升权引导。上下文负责说明常驻策略;文件系统、一次性 bash 与终端后端仍是强制执行边界。

缓存决策依据当前源码,而不只依靠类比。Codex 将权限建模为 developer 角色的 WorldState 段并保存其指纹;只有状态变化或保留的历史丢失该片段时才发出它,同时记录快照转换。Hermes 在会话期间保持系统提示词不变,并明确将不断变化的 skill(技能)、模型与语音通知前置到下一条用户消息,以免提示词缓存失效。Pi 没有可比的内置沙箱状态,Claude Code 当前的原生实现也无法公开检视;不过,Anthropic 的公开缓存指南仍将不断变化的逐请求上下文放在稳定缓存前缀之后。

先前接入真实提供方的 Web fixture(测试前置数据)量化了系统段版本的缺陷。首次 danger-full-accessworkspace-write 请求分别只有 256 个缓存读取 token,而未缓存输入 token 为 14,691 和 14,782 个。相同策略下的后续步骤报告约 14.7k–15.5k 个缓存读取 token。只移动沙箱语句无法修复这些未命中,因为同一次 preset 切换还会改写批准策略系统段。

措辞证据

措辞实验预先登记「预防性拒绝」为主要终点,并要求旧常驻句子在十二个新会话中至少产生一次拒绝,之后才能评判任何替代措辞。2026-07-30,commit 2bf41990401b194bd8637f07bbd90c67a9eeac75 通过已交付的 Web 组合运行 deepseek-v4-flash,使用精确的阳性对照句子 Bash commands run under the "read-only" file sandbox. 与当前工具归属方的尝试引导。对照组产生零次预防性拒绝和零次推测性升权;十二个会话全部先发起普通 bash 调用、观察到拒绝、在同一轮次升权、获得批准,并让所请求文件实际落盘。没有样本被排除。

缓存安全交付变更后,commit 10d4e0ff7b68d38fc4403403b644aac442b97a00 通过新的尾部上下文通道重复了同一项十二会话阳性对照。结果再次为零次预防性拒绝和零次推测性升权;十二个会话的首次调用均为普通调用,随后观察到拒绝、在同一轮次升权并获得批准。其中八个会话让所请求文件按确切要求落盘,没有样本被排除。

因此,两项阳性对照均未通过预先登记的灵敏度门槛。Candidate A 与 B 的正式十二会话实验组均未运行,这些实验不选择也不验证当前措辞。它们说明先前十二次中五次的结果无法在本任务与当前工具引导下复现;在声明模型行为率之前,需要更强的阳性对照或不同的任务分布。下述确定性测试只能证明请求构造如实反映状态,并验证其可回放性。

随后,缓存安全交付重做针对中性 Web 任务 Create the relative path policy-neutral.txt ... 提供了一次独立的非统计验收对比;它不取代预先登记的十二会话实验。Candidate A 的绝对化只读声明导致模型以纯文本拒绝,工具调用为零。Candidate B 只针对受强制执行、且其工具公开升权能力的家族增加一句按组合条件化的文案。随后一次全新的真实提供方运行先发出普通 write,观察到只读拒绝,再在同一轮次用 sandbox_permissions: "workspace-write" 重试同一操作,获得批准、读回文件并核验确切内容。它没有进行推测性升权。在权限切换和四个变更步骤中,每个请求的缓存读取为 14,848–15,872 个 token,未缓存输入为 59–306 个 token,直接证明了稳定前缀的收益。

曾考虑的替代方案

仅叙述模式变更。 不予采用,因为这会让新会话不了解策略,并把首次被拒绝的操作变成策略发现机制。如果可以直接渲染当前状态,也就无需额外定义基线。

扫描拒绝历史或记住上次叙述的模式。 不予采用,因为拒绝事件描述的是尝试过的操作,而不是权威的当前状态;进程本地的簿记也无法跨恢复保留。归属方可以在每次请求时直接折叠持久策略。

把当前策略放入动态系统段。 不予采用,因为真实提供方证据显示,首次权限切换后缓存读取降至 256 个 token,而约 14.7k 个输入 token 未命中缓存。DeepSeek 匹配完整前缀;改变第一条协议消息会阻止复用更长的系统与历史前缀。

由每个策略归属方独立调用 agent.inject() 不予采用,因为同级监听器的顺序会决定模型所见顺序,分开的消息可能暴露不匹配的中间快照,并且每个归属方都需要各自扫描压缩后的保留状态。现有组装归属方可以对贡献排序,并生成一份原子化的完整快照。

通用运行时事实包。 不予采用,因为现有系统提示词组装已经拥有段、schema、变量、作用域和权威的逐步骤 waterfall(瀑布式事件)。为该归属方增加有序上下文,无需新增包或第二个注册表服务。

在上下文中重复工具 schema 或计划引导。 不予采用,因为这些接口已有各自归属方和独立生命周期。批准的当前状态加入快照,仅仅是因为同一个 /permission 切换会改变它,而把它留在系统段会保留缓存缺陷。

缓存安全迁移后仍保留 Candidate A。 不予采用,因为中性的真实提供方任务中,尽管已有 bash 尝试引导,模型仍以纯文本拒绝,且没有调用工具。保留下来的反预防性拒绝原则本身不说明任何升权机制;它告诉模型不要从常驻标签推断操作不可能完成,然后把拒绝与升权行为交还给可用工具。

继续省略沙箱模式,因为常驻模式标签曾引发预防性拒绝。 不予采用,因为新的 Web 请求否则会暴露变更工具,却隐去这些工具的常驻策略,导致模型在首次操作前错误声称自身能力。先前的线上测量仍是必须执行的反证测试:使用 Bash commands run under the "read-only" file sandbox. 时,十二个轮次中有五个没有调用工具。已提交的工具归属方尝试引导晚于该测量,因此应通过当前工具约定下的新阳性对照实验选择替代文案,而不能假设旧条件与当前条件相同。

独立的模型上下文包。 不予采用,因为策略归属方可以直接解析当前会话状态,现有组装服务也可以对其排序。新包只会围绕同一个请求边界引入浅层组合层,并增加额外的文档与门禁维护工作。

枚举可写临时根目录。 不予采用,因为后端要到稍后的 confine() 才会选定:bwrap、Landlock、Seatbelt 和进程内文件系统围栏并不授予一套共同的临时路径。常驻请求中的主机特定路径既不稳定,也会作出过度承诺。

后果

模型在试探工具前就会收到常驻文件策略,且 /permission 后的下一个请求会反映已提交的模式。稳定的系统提示词不再随沙箱或批准状态变化;变化后的完整上下文快照会在保留的历史之后仅追加,状态不变时不增加消息。较旧的快照仍保留在历史中,但最新的完整快照会明确取代它们。该声明是引导,而不是强制执行护栏:运行时安全仍来自文件系统、一次性 bash 与终端后端消费同一项解析完成的策略。

聚焦测试固定了所有模式、规范化根目录、切换时机、服务 dispose(资源释放)、上下文顺序、清除、稳定的请求 header、恢复,以及不同 TMPDIR 值下的字节稳定性。无密钥的组装快照通过真实 Loader 组合固定持久上下文消息。无密钥回放负责固定中性的拒绝到升权轨迹;它是结构回归证明,而不是措辞选型证据。