Skip to content

Commit e5e92ce

Browse files
RoyLinRoyLin
authored andcommitted
fix(sandbox): tolerate transient workspace removals
1 parent 3b9293b commit e5e92ce

6 files changed

Lines changed: 38 additions & 15 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ env:
1818
A3S_WEB_SOURCE_REF: 6e894ce4f0921c89329a7cba30397ff5ac8b6f9a
1919
# Exact companion prerequisite; preflight rejects an absent or incomplete release.
2020
A3S_WEBVIEW_VERSION: 0.1.5
21-
A3S_CODE_CORE_VERSION: 6.4.0
21+
A3S_CODE_CORE_VERSION: 6.4.1
2222
A3S_SEARCH_VERSION: 2.1.0
2323
A3S_TUI_VERSION: 0.1.13
2424
A3S_USE_EXTENSION_VERSION: 0.2.0

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.10.3] - 2026-07-23
11+
1012
### Fixed
1113

1214
- Trusted the official A3S tap before release smoke installation so current
1315
Homebrew versions can resolve the tap-owned `a3s-webview` dependency.
16+
- Updated Core so the managed SRT capability handshake tolerates files and
17+
directories removed concurrently by other workspace processes.
18+
- Included the complete causal error chain in local-sandbox startup warnings
19+
instead of hiding the actionable workspace or platform failure.
1420

1521
## [0.10.2] - 2026-07-23
1622

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "a3s"
3-
version = "0.10.2"
3+
version = "0.10.3"
44
edition = "2021"
55
description = "a3s — A3S coding agent CLI; `a3s code` launches the interactive TUI"
66
license = "MIT"
@@ -14,7 +14,7 @@ name = "a3s"
1414
path = "src/main.rs"
1515

1616
[dependencies]
17-
a3s-code-core = "=6.4.0"
17+
a3s-code-core = "=6.4.1"
1818
a3s-boot = { version = "=0.1.3", features = ["ilink"] }
1919
a3s-lane = "=0.5.1"
2020
# Long-term memory store (same crate/version a3s-code-core uses) — the `/ctx save`

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,8 @@ Offline mode and `A3S_NO_AUTO_INSTALL=1` can use either verified state or the
12861286
verified release payload but forbid registry bootstrap. Setup failure remains
12871287
non-fatal: Default can ask for one exact host Bash invocation and Auto denies
12881288
Bash. There is no silent unsandboxed fallback.
1289+
Startup warnings include the complete causal error chain so a workspace scan,
1290+
runtime verification, or platform failure remains actionable.
12891291

12901292
The local sandbox denies command network egress, local binding, and Unix
12911293
sockets; allows writes only in the active workspace and a private per-run
@@ -1296,7 +1298,8 @@ process-group cancellation, bounded output, and streaming deltas use the same
12961298
contract as the normal Bash tool. Existing `.env*` files are denied at every
12971299
governed source-tree depth, and pre-existing multi-link source files are masked
12981300
for both reads and writes so a workspace hardlink cannot expose an outside
1299-
inode.
1301+
inode. Workspace policy scans tolerate an entry removed concurrently after
1302+
enumeration while permission and other I/O failures remain fatal.
13001303

13011304
The TUI also enables Core's local workspace credential policy for in-process
13021305
tools. `read`, range reads, `grep`, `write`, `edit`, and `patch` therefore

src/tui/app/launch.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ const CODE_INTELLIGENCE_SHUTDOWN_GRACE: Duration = Duration::from_secs(5);
88
const CODE_INTELLIGENCE_SHUTDOWN_SETTLE: Duration = Duration::from_secs(1);
99
const CODE_INTELLIGENCE_ABORT_SETTLE: Duration = Duration::from_millis(250);
1010

11+
fn sandbox_load_warning(error: &anyhow::Error) -> String {
12+
format!(
13+
"Local command sandbox failed its bounded OS capability probe: {error:#}. \
14+
Default mode will ask before exact host Bash execution; Auto mode will deny \
15+
Bash. Repair the reported platform prerequisite and restart `a3s code`"
16+
)
17+
}
18+
1119
fn with_tui_prompt_context(
1220
options: SessionOptions,
1321
instructions: Option<&str>,
@@ -688,14 +696,7 @@ pub(crate) async fn run_in(
688696
Some(Arc::new(sandbox) as Arc<dyn a3s_code_core::sandbox::BashSandbox>),
689697
None,
690698
),
691-
Err(error) => (
692-
None,
693-
Some(format!(
694-
"Local command sandbox failed its bounded OS capability probe: {error}. \
695-
Default mode will ask before exact host Bash execution; Auto mode will deny \
696-
Bash. Repair the reported platform prerequisite and restart `a3s code`"
697-
)),
698-
),
699+
Err(error) => (None, Some(sandbox_load_warning(&error))),
699700
},
700701
None => (None, managed_srt.warning),
701702
};
@@ -1380,6 +1381,19 @@ mod tests {
13801381
assert!(rendered.contains("a3s code resume session-42"));
13811382
}
13821383

1384+
#[test]
1385+
fn sandbox_warning_includes_the_complete_error_chain() {
1386+
let error = anyhow::anyhow!("No such file or directory (os error 2)")
1387+
.context("failed to scan SRT workspace /workspace/transient")
1388+
.context("managed SRT failed its Core capability handshake");
1389+
1390+
let warning = sandbox_load_warning(&error);
1391+
1392+
assert!(warning.contains("managed SRT failed its Core capability handshake"));
1393+
assert!(warning.contains("failed to scan SRT workspace /workspace/transient"));
1394+
assert!(warning.contains("No such file or directory (os error 2)"));
1395+
}
1396+
13831397
#[tokio::test]
13841398
async fn initial_tui_options_inject_and_remove_materialized_preferences() {
13851399
let temp = tempfile::tempdir().unwrap();

0 commit comments

Comments
 (0)