Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/substrate/issues/002-concurrent-turn-context-race.md
Fimeg e480809c70 docs: rescue the agent-substrate tree out of a gitignored directory
219 files, 2.0 MB, untracked in souveraine/docs and existing nowhere else.
The volume is at 100% with no snapshots.
2026-07-26 12:11:50 -04:00

2.1 KiB

id title status priority created area
002 Concurrent turns race on the global Sensorium open medium 2026-05-08 tool-substrate

Problem

If two turns execute concurrently (e.g. HTTP server handling two agent conversations, or a subconscious N+1 pass running alongside a primary turn), both would share the global Sensorium including its ToolContext. This means:

  1. Turn A sets ToolContext to agent A's memory root
  2. Turn B sets ToolContext to agent B's memory root
  3. Turn A's tool executes — checks agent B's boundary → false positive or false negative

Current architecture constraints

  • Sensorium is a OnceLock at src/core/tools/mod.rs:164 — globally shared
  • The bash BashState (cwd, env, background tasks) lives inside the shared Sensorium as Arc<Mutex<BashState>>
  • Two agents running simultaneously would also share bash state — cwd from one leaks into the other

Consideration: is this actually a problem today?

Currently:

  • LocalBackend::send() spawns a single run_turn() per conversation — sequential per conversation
  • The HTTP server may handle multiple conversations but each streams via its own SSE channel
  • N+1 subconscious is synchronous (no LLM call, just heuristic) — can't race with primary

If/when N+1 becomes an async LLM call with tool access, or when the HTTP server dispatches concurrent turns, this race becomes real.

Possible approaches

  • Pass agent context through execute_tool() parameter (resolves the ToolContext race)
  • But bash state is still shared — would need per-agent BashState or explicit isolation
  • Or defer bash state isolation until concurrent turns are actually wired

References

  • src/backend/local.rs:98-328 — single-threaded run_turn()
  • src/core/tools/mod.rs:62-75Sensorium::new() creates shared Bash
  • src/core/tools/bash.rsBashState in Arc<Mutex<>>

Status

This is not actionable today — no concurrent turns exist. It becomes actionable when: a) HTTP server dispatches concurrent turns, OR b) Async N+1 runs alongside primary turn with tool access