Engineering and security learning path
The preceding lessons answered “How does nanobot complete one Turn?” This section changes perspective: when requests arrive concurrently, a user stops midway, a Provider fails temporarily, the process shuts down, or the model tries to access outside the workspace, how does the system avoid disorder and data damage?
Corresponding source
| Risk topic | Source |
|---|---|
| Concurrency, cancellation, and Turn resources | nanobot/agent/loop.py, nanobot/agent/runner.py |
| Provider, Tool, and persistence failures | nanobot/providers/base.py, nanobot/agent/tools/, nanobot/session/manager.py |
| Observability and tests | nanobot/bus/runtime_events.py, nanobot/agent/hook.py, tests/ |
| Workspace, Shell, and SSRF | nanobot/security/, nanobot/agent/tools/shell.py, sandbox.py |
| Packaging and frontend build | pyproject.toml, hatch_build.py, webui/, nanobot/web/ |
Learning objectives
After this section, you should be able to:
- draw nanobot’s primary concurrency boundaries;
- distinguish timeout, cancellation, recoverable failure, and unrecoverable failure;
- choose an observation point from logs, state traces, runtime events, and persisted files;
- explain what the workspace guard, Shell sandbox, and SSRF guard each protect;
- understand how the Python package, WebUI assets, and Bridge enter a release artifact.
Prerequisites
- Complete the One Turn learning path.
- Complete State and Long-Running Work.
- Know the basic meanings of
asyncio.Task,Lock,Semaphore, andCancelledError. If needed, revisit Python and asyncio minimum.
Recommended order
| Order | Lesson | Core question |
|---|---|---|
| 1 | asyncio concurrency, cancellation, and cleanup | Which work can run concurrently, and which must be serialized? |
| 2 | Errors, retries, and data consistency | After failure, should the system retry, fall back, persist, or stop? |
| 3 | Logging, runtime events, and testing | Which evidence layer should you observe? |
| 4 | Workspace, Shell, and SSRF security boundaries | What does “restricted to the workspace” actually guarantee? |
| 5 | Packaging, WebUI build, and cross-platform behavior | How does source become an installable, runnable product? |
Engineering risk map
flowchart LR A["Concurrent requests"] --> A1["Session Lock"] A --> A2["Global Semaphore"] A --> A3["Tool concurrency_safe"] B["Interruption and shutdown"] --> B1["Task.cancel"] B --> B2["Restore runtime checkpoint"] B --> B3["Close MCP / Channel"] B --> B4["Session flush_all"] C["External failure"] --> C1["Provider retry"] C --> C2["Fallback"] C --> C3["Convert error to visible result"] D["Untrusted input"] --> D1["Tool schema"] D --> D2["Workspace guard"] D --> D3["SSRF guard"] D --> D4["Shell sandbox"] E["Process crash"] --> E1["Temporary file"] E --> E2["os.replace"] E --> E3["fsync when required"]
These mechanisms are not one “security layer.” A Session Lock prevents concurrent writes to one conversation but cannot stop the model from reading a private file. The SSRF guard blocks private-network targets but does not constrain the content of an ordinary public request.
Fact boundaries for this section
An application-level guard is not operating-system isolation
When
restrictToWorkspaceis enabled without a system sandbox, nanobot applies path resolution and command checks at the application layer. The source explicitly reports this state asapplicationwithenforced=False. Do not present it as an unbypassable OS security boundary.
There is no universal transaction layer
Session, Cron, Memory, configuration, and WebUI state use separate write strategies. One file using
os.replacedoes not prove equal durability for all state.
Primary source entry points
nanobot/agent/loop.pynanobot/agent/runner.pynanobot/providers/base.pynanobot/session/manager.pynanobot/cron/service.pynanobot/agent/tools/shell.pynanobot/agent/tools/sandbox.pynanobot/security/workspace_access.pynanobot/security/workspace_policy.pynanobot/security/network.pynanobot/cli/commands.pypyproject.tomlwebui/vite.config.ts