This pull request lands the tool; switching the shipped defaults is a
separate pull request stacked on it. Every shipped `tool-fs` row states
`applyPatch: false`, the `fs-observation-policy` row stays mounted, the
write, edit, and apply_patch guidance names the policy, and every recorded
expectation outside the apply-patch scenarios returns to the master
baseline. The upgrade guide, the parity exception, and the optional
classification of the policy package move to the stacked change.
The SDK/Desktop parity check requires the `standard` tool sets to match, so
the base row enables apply_patch like the Web standard preset; the SDK PTC
overlay keeps that row while the Desktop PTC preset lists its own, which the
parity exceptions now record. fs-observation-policy, no longer mounted by
default, is classified as an optional product package.
Every headless, SDK, and ACP recording follows: sidecars and recorded headers
gain the apply_patch schema, the fixed-budget compaction scenarios pin
`applyPatch: false` so their recorded thresholds hold (model-switch-notice and
session-resume own their schema sidecars again), the parent presets that
borrow the default pin mirror the base row, and the pwsh and Python PTC pins
carry the schema and guidance.
Keeps the apply_patch toolview registration with master's file-menu inject,
takes master's shortened slot JSDoc, re-adds the seven filesystem type-equiv
manifest entries, regenerates the event matrix and client catalogs, moves the
fs-observation-policy upgrade guide under v0.2.2-alpha.2 with the matching
fs-patch version, and refreshes the two SDK scenarios master added for the
write and edit guidance change.
Evaluation on the shipped Web composition decided the defaults: the
`fs-observation-policy` row in dsh-base ships `disabled: true`, so write,
edit, and apply_patch mutate unconditionally in every profile; the Web
`standard` preset lists apply_patch; and the tool-fs `applyPatchGuard` switch
is gone, apply_patch always consulting the fs/* intent waterfalls like the
other mutating tools.
The write and edit guidance stops citing the policy as the default, and the
apply_patch guidance asks for enough hunk context instead of a prior read.
The two recordings that capture a policy refusal (fs-policy-reject and
apply-patch-rejected) re-enable the row through a per-scenario
runtime.cordis.yml; every other sidecar follows the prompt change, and the
Web standard-preset recordings gain the apply_patch schema. An upgrade guide
records the default change.
The guidance described only the commit phase ("stop at the first failure,
not rolled back"), so a model inferred that an invalid hunk would leave
earlier operations applied. The sentence now says the whole patch is checked
first and a rejected patch changes nothing before describing commit order.
`tool-fs.applyPatchGuard` selects the mutation guards of apply_patch:
`observation` consults the mounted observation policy per operation like
write and edit; `none`, the default, applies hunks unconditionally on
context match alone as the Codex tool does, keeps publishing fs/observed,
and replaces the read-first guidance with a context-matching reminder.
In 2,226 recorded DS-Bench and DeepSWE rollouts with the policy on, read-first
and stale-version refusals were 29–41% of apply_patch failures although hunk
context matching already rejects a divergent file. The recorded apply-patch
scenarios pin `observation`, under which they were captured.
Across 2,226 recorded DS-Bench and DeepSWE rollouts, 14% of apply_patch
calls arrived as {"input": ...} and were rejected for the missing `patch`
property: models trained on the Codex tool send its parameter name
unprompted. The schema now uses `input`; the executor request keeps its
internal `patch` field. Recorded apply-patch sessions, the schema sidecar,
and the catalogs follow.
Takes master's re-measured npm install-layout budget, which covers this
branch's graph, and regenerates the Cordis API, event matrix, client slot,
and tool catalogs on the merged tree.
Resolves the headless snapshot runner (keeps both the readonly-patch-directory
and cua-script-guidance workspace setups), regenerates the client slot and tool
catalogs with their pairing record, adds the apply_patch tool title to the five
locales master introduced, and refreshes the apply-patch system-prompt pin for
master's subagent guidance change.
`tool-fs.applyPatch` now defaults to false instead of deriving from
`write && edit`, so every shipped composition keeps the model request it
had before the tool existed. The `tool-fs` rows that enable `edit`
(dsh-base and the Web standard, ptc, and cordis presets) state
`applyPatch: false` explicitly; changing that one line adds the tool.
The apply-patch snapshot composition enables the switch, the tool catalog
mounts tool-fs with it on so the schema stays documented, and every other
recorded expectation returns to the master baseline.
Master replaced the creation and plugin recommendation bundles with one
personalized recommendations bundle.
- The CLI manifest keeps master's bundle and the forge bundle.
- The plugin page expectation ranks the forge bundle before the held-back
personalized recommendations bundle.
- The experimental README pairing is recorded again.
The blocking ask_user_question description did not explain that an answer
item with empty selected and no custom is a user skip, so models re-asked
the same question after the user clicked Skip.
Refs #7134
The parent branch now carries master through #6426 again.
- Master moved the optional, experimental, and plugin page bundle lists
into @deepseek-ai/dsh-official-bundles; the forge bundle joins the
optional and experimental lists there.
- The CLI manifest, release families, and plugin page expectations keep
both sides; the forge bundle ranks before the held-back recommendation
bundles.
- The lockfile, the event matrix, and the experimental persistence
catalog are regenerated, and the capability-seams and experimental
README pairings are recorded again.
Add an authored headless scenario that appends a changed prompt and then replaces a surface node before the third step. The unchanged-rendering series start must keep both prompt versions and write no system/message event; the scenario fails against the pre-fix projection. Also tighten the tool-series-start assertions and make the prefix premise explicit.
Replace the literal "Approval policy: ask." runtime-context sentence
with a statement parallel to the never-policy sentence, and refresh the
current-generation fixtures that persist it.
Co-authored-by: Tianyi Cui <[email protected]>
The parent branch now carries master through #6426, including the
agent-controller revert.
- Package manifests keep both sides: the ./types and ./locale/*.json
exports of the forge packages, and the Web app's forge bundle and
message quotes dependencies.
- The type manifest drops the removed agent-controller entries and keeps
the forge panel entries.
- The event matrix and the capability-seams pairing are regenerated.
- The forge bundle stays on the main plugin list and now ranks before the
held-back developer tools; the plugin page expectations follow.
The branch merge from master brought four scenarios added after the prompt
refresh (background-wait-steer, session-resume, model-switch-compaction,
web-search-unconfigured); their system-prompt sidecars still show the
guidance without the restored sentence, so the keyless replay fails. Apply
the same sentence to those six expected lines.
The DeepSeek search and Search/Fetch API providers now report readiness
from credential presence alone, on any model route: the account token
first on the deepseek-account route, then a literal apiKey or a
configured apiKeyEnv reference. A conversation on another provider's
model keeps web_search and web_fetch while a DeepSeek key is configured,
as on master, so the route refusal WEB_PROVIDER_ROUTE_DISABLED and its
upgrade guide are removed.
The pi-ai-conversation-updates and deepseek-messages-system-prompt
snapshots replay their master recordings again, the headless keyless
smoke points its search key reference at an unset variable, and the
readiness Agent Note records the rejected route and endpoint rules.
web-search-unconfigured declares exactly the tool catalog that web-fetch
already pins, so it names web-fetch as its toolSchemasSource instead of
committing a second copy.
Master declares exit_plan_mode only in plan mode, so this branch's own tool
schema sidecars for web-search-unconfigured and pi-ai-conversation-updates
drop it. The merge took master's pi-ai-conversation-updates session, whose
request headers still listed web_search; the refresh records the moonshotai
route without it again.
- tool-jobs: inline a completion notice only when the complete text fits inlineOutputBytes and the producer cap; otherwise point at job_output, whose result the spill policy bounds
- subagent: drop toolCallsThisStep; omit the closing text while the child's last logged tool call is its message to the parent