v2.6.0: pluggable workspace backend + S3-compatible storage#31
Merged
Conversation
Introduces a workspace capability abstraction so built-in tools (read,
write, edit, patch, ls, bash, grep, glob, git, git_stash, git_worktree)
route through trait-based providers instead of hard-coded local
filesystem calls. The default LocalWorkspaceBackend preserves existing
behavior; future remote/browser/DFS/container backends can plug in via
WorkspaceServicesBuilder without changing tool schemas.
Key changes:
- Split workspace.rs into workspace/{mod.rs, local.rs}: trait definitions
+ LocalWorkspaceBackend in separate files (CLAUDE.md file-size rule).
- New traits: WorkspaceFileSystem, WorkspaceCommandRunner, WorkspaceSearch,
WorkspaceGit (slim core) + optional WorkspaceGitStashProvider and
WorkspaceGitWorktreeProvider, CommandOutputObserver.
- WorkspaceServices: assembled via WorkspaceServicesBuilder; auto-downgrades
capabilities when matching providers are missing; carries an optional
per-operation timeout enforced by run_with_timeout helper.
- Capability gating: register_builtins(registry, &capabilities) only
registers tools whose required capability is provided — bash, grep,
glob, git can be hidden from the model when the backend lacks them.
- Local backend now implements WorkspaceCommandRunner (no more
bash-specific local fallback in the tool).
- CommandRequest carries Arc<dyn CommandOutputObserver> instead of leaking
ToolEventSender into the abstraction.
- ChildRunContext propagates workspace_services to child runs.
- New Session direct-tool APIs: write_file, ls, edit_file, patch_file.
- WorkspaceFileSystemExt policy: future trait extensions go to a
separate extension trait (additive only).
- Removed dead WorkspaceCapabilities flags (watch, atomic_write),
unreachable bash fallback branch, set_workspace_services mutation
hazard, redundant ToolExecutor private constructors.
- Deprecated ToolContext::resolve_path / resolve_path_for_write under
non-local backends.
Tests:
- 17 new unit + integration tests in workspace + tools modules.
- All 1553 lib tests + integration tests pass.
- cargo clippy --all-targets --all-features -D warnings clean.
Adds S3WorkspaceBackend behind the new `s3` Cargo feature. The backend implements WorkspaceFileSystem against any S3-compatible endpoint (AWS S3, MinIO, RustFS, Cloudflare R2, Backblaze B2, ...) via the AWS Rust SDK. It deliberately does NOT implement WorkspaceCommandRunner, WorkspaceSearch, or any git provider trait — capability gating then prevents bash/grep/glob/git from being registered when the backend is in use, so the model never sees tools the backend cannot service. Includes: - core/src/workspace/s3.rs: S3WorkspaceBackend + S3BackendConfig builder (endpoint / region / session_token / force_path_style / request_timeout), with_client() injection for tests. - WorkspaceServices::s3(config) and WorkspaceServices::from_s3_backend() factories with a 60s default per-operation timeout. - 11 unit tests covering key/prefix derivation, list prefix handling, capability matrix, and config builder. - core/tests/test_s3_backend.rs: env-gated end-to-end integration test that exercises the full session executor (read/write/edit/patch/ls, asserting bash/git/grep/glob are not registered) against a real S3-compatible endpoint; auto-cleans the per-run UUID prefix. - Node and Python SDKs expose S3WorkspaceBackend alongside LocalWorkspaceBackend via the same workspaceBackend / workspace_backend option surface; both SDK Rust crates depend on a3s-code-core with the s3 feature enabled. - README documents the new backend with cross-language usage examples. The new feature is fully optional: building a3s-code-core without `--features s3` keeps the dependency tree slim and excludes the AWS SDK.
Aligns the release surface for v2.6.0:
- core/Cargo.toml, sdk/node/Cargo.toml, sdk/python/Cargo.toml: package
version + a3s-code-core dependency version.
- sdk/python/pyproject.toml: project version.
- sdk/node/package.json: root version + all 6 optionalDependencies
(@a3s-lab/code-{darwin-arm64,linux-{x64,arm64}-{gnu,musl},win32-x64-msvc}).
- sdk/node/package-lock.json and sdk/node/examples/package-lock.json.
- Cargo.lock: a3s-code-core / a3s-code-node / a3s-code-py entries.
- CHANGELOG.md: v2.6.0 entry covering the workspace abstraction refactor
and the new S3WorkspaceBackend feature.
scripts/check_release_versions.sh 2.6.0 → pass.
ZhiXiao-Lin
added a commit
that referenced
this pull request
May 29, 2026
…nt versions (#31) (#49) Adds core/tests/test_persisted_schema_roundtrip.rs — a dependency-free, seeded round-trip fuzz over the persisted graph (LoopCheckpoint, RunRecord incl. all three 3.3.0 AgentEvent variants, SubagentTaskSnapshot, TraceEvent, VerificationReport, Message/ContentBlock, and the largest root SessionData), asserting serialize→deserialize→re-serialize stability. Plus cross-version coverage: backward-compat (pre-3.3.0 payloads missing schema_version / identity fields / using the `todos` alias load with defaults), forward-compat (unknown fields ignored — guards rolling cluster upgrades against a stray deny_unknown_fields), the untagged ToolResultContentField and the persisted untagged PermissionRule dual-form hazards. Closes a real gap surfaced while writing it: LoopCheckpoint documented that loads from a future schema version must be rejected, but no impl enforced it. Adds LoopCheckpoint::ensure_loadable() and calls it in both the file and memory store load paths, so resume_run surfaces the error and the live-run sink starts fresh rather than misinterpreting an incompatible checkpoint. Co-authored-by: Claude <claude@anthropic.com>
ZhiXiao-Lin
added a commit
that referenced
this pull request
May 29, 2026
Closes the coverage gaps surfaced by an adversarial coverage audit across the new orchestration layer. +21 unit tests, +4 real-LLM integration tests (all run green against .a3s/config.acl), plus a small fix and a de-flake. Unit: - combinators: empty inputs, zero concurrency_hint (\.max(1) clamp), first-stage None, resumable ignores checkpointed-but-dropped specs, and resumable re-runs all when the checkpoint is unreadable (future version). - store: FileSessionStore workflow-checkpoint round-trip, crash-atomic no-temp-leftovers, and future-version rejection through both stores. - schema coercion FAILURE path (previously untested): demote-to-failure with the marker, isolation from a sibling in a fan-out, and failed-run-skips-coercion. - #31 persisted-schema fuzz extended to AgentStepSpec / StepOutcome / WorkflowCheckpoint (round-trip stability + forward-compat unknown-field tolerance) — the cross-node-migration types were previously excluded. - Python SDK conversion helpers (py_to_step_spec / step_outcome_to_py) and the PythonPipelineStage bridge (None-stops, raise-fails-closed, snake_case ctx['previous']) — previously zero coverage. Real-LLM (#[ignore], .a3s/config.acl): pure parallel fan-out of distinct agents (order + per-branch sentinels), multi-item pipeline (no-barrier shape with >1 item), the actual RESUME path (completed step served from checkpoint, only the rest run live), and a nested/array output_schema. Fix: the resumable combinator now distinguishes Ok(None) from a load Err and logs a warning before re-running from scratch (was a silent swallow). De-flake: the pipeline real-LLM tests no longer assert on stage-2 output *content* (some models return an empty final turn for a one-word instruction); chaining is proven by reaching stage 2 + the deterministic mock test. Co-authored-by: Claude <claude@anthropic.com>
ZhiXiao-Lin
added a commit
that referenced
this pull request
May 30, 2026
Programmable orchestration (AgentExecutor seam, parallel/pipeline/resumable combinators, WorkflowCheckpoint, Node + Python SDK grammar) + the #31/#32/#43 hardening since v3.3.0. Backward-compatible feature additions → minor bump. Bumps the full version-sync surface (core/sdk Cargo.toml + core-dep pins, package.json + optionalDeps, pyproject + bootstrap __version__, Cargo.lock, npm lockfiles); scripts/check_release_versions.sh passes at 3.4.0. Adds the [3.4.0] CHANGELOG entry. No source changes — prep only. Co-authored-by: Claude <claude@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release v2.6.0 of a3s-code: introduces a pluggable workspace backend
abstraction, ships a native S3-compatible backend behind an optional Cargo
feature, and bundles 16 architectural refinements to the surrounding
workspace / capability-gating subsystem.
Built-in file tools (
read,write,edit,patch,ls,bash,grep,glob,git) now route through trait-based capability providers insteadof hard-coded local filesystem calls. Local behaviour is unchanged.
DFS / browser / container / remote backends become drop-in extensions.
Commits
refactor(workspace): pluggable backend abstraction + 16 optimizationsworkspace.rsintoworkspace/{mod.rs, local.rs}(CLAUDE.mdfile-size rule).
WorkspaceFileSystem,WorkspaceCommandRunner,WorkspaceSearch,WorkspaceGit(slim core) + optionalWorkspaceGitStashProvider/WorkspaceGitWorktreeProvider+CommandOutputObserver.WorkspaceServicesbuilder, capability auto-downgrade, defaultoperation_timeout+run_with_timeouthelper.bash/grep/glob/gitare hidden from the model unless the backend declaresmatching capability.
LocalWorkspaceBackendnow implementsWorkspaceCommandRunner(no bash-specific fallback in the tool).
CommandRequestcarriesArc<dyn CommandOutputObserver>, droppingthe previous
ToolEventSenderleak from the abstraction.ChildRunContextpropagatesworkspace_servicesto child runs.Session:write_file,ls,edit_file,patch_file.WorkspaceCapabilitiesflags(
watch/atomic_write), unreachable bash fallback branch,unused
Registry::set_workspace_services, redundantToolExecutorprivate constructors.ToolContext::resolve_path/resolve_path_for_writeunder non-local backends (fail-closed when called against a
virtual backend).
feat(workspace): S3-compatible workspace backendcore/src/workspace/s3.rsbehind thes3Cargo feature.S3WorkspaceBackend+S3BackendConfigbuilder(endpoint / region / session_token / force_path_style /
request_timeout);
with_client()for test injection.WorkspaceServices::s3(cfg)+from_s3_backend(arc)factorieswith 60s default per-operation timeout.
matrix); env-gated end-to-end integration test exercising the
full session executor.
S3WorkspaceBackendalongsideLocalWorkspaceBackendvia the sameworkspaceBackend/workspace_backendoption surface.Backblaze B2 / RustFS interchangeably.
chore: bump all SDK versions to 2.6.0 + CHANGELOGcore/Cargo.toml,sdk/node/Cargo.toml,sdk/python/Cargo.toml,sdk/python/pyproject.toml,sdk/node/package.json(+ 6 optionalDependencies),two
package-lock.jsonfiles, andCargo.lock.scripts/check_release_versions.sh 2.6.0→ pass.Test plan
cargo fmt -p a3s-code-core --check— cleancargo clippy -p a3s-code-core --all-targets -- -D warnings— cleancargo clippy -p a3s-code-core --all-targets --features s3 -- -D warnings— cleancargo test -p a3s-code-core --lib(no s3) — 1553 passed / 0 failedcargo test -p a3s-code-core --lib --features s3— 1564 passed / 0 failedcargo test -p a3s-code-core --tests --features s3— all green (env-gated S3 e2e ignored by default)cargo test— 16 passed / 0 failed (+2 new for S3 dispatch)cargo test— 9 passed / 0 failed (+1 new for S3 dispatch)bash scripts/check_release_versions.sh 2.6.0— versions consistentAfter merge, push tag
v2.6.0to triggerrelease.yml.