Commit Graph
14 Commits
Author SHA1 Message Date
sjw1231 ea4837abb1 feat(fs): keep apply_patch opt-in and the observation policy mounted
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.
2026-10-29 18:36:31 +08:00
sjw1231 fe5450b152 feat(fs): ship without the observation policy and enable apply_patch in the Web standard preset
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.
2026-10-29 16:38:42 +08:00
sjw1231 5711d3aae7 docs(tool-fs): state apply_patch's whole-patch preflight in the model guidance
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.
2026-10-28 15:37:36 +08:00
sjw1231 1f1a9cda72 feat(tool-fs): add applyPatchGuard to run apply_patch without observation guards
`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.
2026-10-28 15:26:21 +08:00
sjw1231 64d04a4916 feat(tool-fs): name the apply_patch argument input as Codex does
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.
2026-10-27 22:26:39 +08:00
sjw1231 d37b2ba52b Merge branch 'master' into feat/apply-patch
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.
2026-10-26 18:01:46 +08:00
sjw1231 81b0bcf3ef feat(tool-fs): make apply_patch an opt-in switch, default off
`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.
2026-10-26 17:12:36 +08:00
sjw1231 cdd7c76f2a Merge branch 'master' into feat/apply-patch
# Conflicts:
#	apps/cli/tests/profiles/headless/tests/expected/subagent-inheritance/parent.expected.jsonl
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	packages/fs/tool-fs/README.i18n.yaml
#	scripts/verify-package-readme-model-experience.ts
#	snapshots/sdk/dynamic-tool-updates/notifications.expected.jsonl
#	snapshots/sdk/dynamic-tool-updates/session.v4.jsonl
#	snapshots/sdk/tool-error-details/notifications.expected.jsonl
#	snapshots/sdk/tool-error-details/session.v4.jsonl
#	snapshots/session/advanced-toolchain/session.v4.jsonl
#	snapshots/session/dynamic-tool-prompt-updates/session.v4.jsonl
#	snapshots/session/dynamic-tool-updates/session.v4.jsonl
#	snapshots/session/pi-ai-conversation-updates/session.v4.jsonl
#	snapshots/session/plugin-manager-mcp/session.v4.jsonl
#	snapshots/web/collapse-timing/next-message.expected.md
#	snapshots/web/collapse-timing/verbose.expected.md
2026-10-22 16:23:14 +08:00
sjw1231 8f798da97d fix(tool-fs): leave sandbox decisions to providers and bound patch diffs
Drop the preflight sandbox fence. It derived writable roots in the local
process, so under the SSH provider it threw on remote additionalWritableRoots
and compared remote targets against local temp roots; write and edit never
fenced in the tool layer. The provider now refuses a denied operation at
commit, and a commit whose first operation failed without any change rejects
like a preflight refusal so the sandbox escalation path keeps its error code.

Classify FS_ABORTED as unknown: a cancelled remote request rejects while the
provider may still be writing, so no stat comparison can settle it. Document
that a cancelled call receives the registry's abort result like every tool.

Store no diff for creations, matching write, and bound the move source basis
by diffBasisMaxBytes so persisted metadata never holds whole files;
FsMoveOutcome.sourceBefore becomes nullable. Omit deletions from the call
preview and from result diffs without a basis instead of rendering them as
empty creations, and count distinct files in the preview title.

Reject a NUL byte beyond the read sampling window in preflight, name targets
by display path in atomic-write diagnostics, align the apply_patch guidance
with the edit wording and mention delete and move, read the stopped flag and
applied diffs tool-agnostically in the client models, skip the permission-bit
snapshot under root, list fs/delete-intent in the tool catalog, and refresh
the fs-patch description, group README, fs-sandbox summary, and ui-tool README.
2026-10-21 17:21:01 +08:00
sjw1231 8834433444 Merge branch 'master' into feat/apply-patch 2026-10-20 20:25:24 +08:00
sjw1231 10fd0f806c feat(fs): enable apply_patch by default 2026-10-16 16:40:58 +08:00
sjw1231 42958baa8c test(fs): record apply_patch success rejection and partial execution 2026-10-16 12:03:35 +08:00
sjw1231 7ab485156e fix(tool-fs): report move destinations and remove unrecorded scenes 2026-10-15 15:29:21 +08:00
sjw1231 f7dae57fda test(snapshot): prepare apply-patch scenes and document tool activation 2026-10-15 03:51:09 +08:00