Swival 1.0.25 loves nono
Swival 1.0.25 is out.

Swival 1.0.25 loves nono
Swival 1.0.25 is out.
With a new first-class way to run Swival under nono.
It is this:
swival --sandbox nono "Fix the failing tests" --yolo
That runs Swival inside a nono sandbox.
This is one of those features that looks like plumbing until you use it. Then it feels obvious.
nono is a really nice fit for Swival. Swival wants to let an agent do real work. nono gives that work an operating-system boundary. Put them together and you get a coding agent that can move quickly inside the project without inheriting your entire user account by default.
AI coding agents are useful because they can do things. They can read files, run commands, edit code, inspect failures, and try again.
That is also exactly why they pair so well with a real boundary.
What nono is
nono is a capability-based sandbox for AI agents.
The short version: you give a process explicit access to the paths and network destinations it needs, and the operating system enforces that policy.
On Linux, nono uses Landlock. On macOS, it uses Seatbelt. These are kernel-level mechanisms, not a polite request in the agent framework. If the sandbox says the process cannot write to /etc, read your SSH keys, or wander into another project, the kernel denies the operation.
That matters.
An application-level sandbox can be very useful. Swival has one. It validates paths, controls which tools are exposed, restricts file access by base directory, and can require command approval. Those are good guardrails.
But they are still implemented by the application.
nono works underneath that. It constrains the Swival process and every child process Swival starts. If the agent runs a shell command, that command inherits the same boundary. If a test runner spawns another process, that process inherits it too.
This is the security model I want for agent work: let the agent be effective inside the workspace, and make everything outside the workspace structurally unavailable.
nono already has the right shape
nono is already pleasant to use directly. The basic shape is explicit and readable:
nono run --allow "$PWD" --profile swival -- \
swival "Fix the failing tests" --yolo
That works, and it is still available when you want to drive nono yourself.
Swival 1.0.25 simply makes that relationship native.
The Swival CLI already knows the current project, the configured provider, the installation layout, the extra directories you passed with --add-dir, and whether it is already running inside nono. So it can translate the Swival session into the right nono launch.
The normal case becomes one flag:
swival --sandbox nono "Fix the failing tests" --yolo
Swival finds the nono binary, builds the right nono run command, and re-executes itself inside the sandbox early in startup.
Your current project is granted read and write access. Any directories passed with --add-dir are granted too. The platform temp directory is writable, because compilers, package managers, and test runners like to scratch there. The Python runtime and Swival's install paths are granted read-only so the re-executed process can still import and run.
Everything else is denied unless the profile or command line grants it.
That is the whole trick. Swival carries the Swival-specific context. nono enforces the boundary it was designed to enforce.
A practical example
Imagine a normal situation: you have a project with a failing test suite, and you want the agent to investigate and fix the smallest thing it can.
You want the agent to be useful. So you are willing to give it shell access inside the repository. It can run pytest, edit files, inspect failures, and iterate.
You do not want it reading ~/.ssh, touching another checkout, modifying shell history, or following some prompt-injected instruction in a README that says to upload secrets somewhere.
That is a good use for nono.
From the project directory:
swival --sandbox nono --nono-rollback --yolo \
"Run the test suite, fix the smallest failing bug, and summarize the change."
The --sandbox nono flag is the important part. It selects nono as the sandbox backend.
The --nono-rollback flag tells nono to snapshot touched files so you can undo the session afterwards.
The --yolo flag gives the agent broad Swival-level permissions inside the sandbox. That may sound reckless, but this is exactly where the combination is useful. The agent can move quickly within the workspace, while nono keeps the operating-system boundary in place.
In other words, --yolo decides how much Swival should let the agent do. --sandbox nono decides what the process is physically capable of doing.
Those are different layers.
What happens when it starts
At startup, Swival sees --sandbox nono.
If it is not already inside nono, it launches itself again under nono run. Conceptually, the command becomes something like this:
nono run --allow <workspace> --allow <tmp> --read <python-runtime> \
--profile swival -- swival ...
The actual command includes the paths for your installation and any provider-specific grants Swival knows about.
For example, if you use the chatgpt provider, Swival grants the LiteLLM token cache directory read and write access, because that provider may need to refresh OAuth state. For Google Vertex or AWS Bedrock, Swival grants the relevant credential directories read-only where possible.
This is a nice detail. The sandbox should not break normal authentication. It also should not blindly expose every credential on the machine.
Once the child Swival process starts, nono prints the active capabilities. In a small test run here, the sandbox showed the temporary workspace as read and write, Swival’s config as read and write, the Swival install and Python runtime as read-only, and outbound network allowed. Then Swival ran normally and created the requested file inside the workspace.
That is the ideal experience for this kind of feature: visible enough to audit, boring enough to use.
What the agent can and cannot do
Inside the sandbox, the agent can edit your project. It can run tests. It can create files. It can use the model provider you configured.
If it tries to write outside the granted paths, the write fails.
I tested the lower-level nono behavior directly with a command that tried to write to /etc. The shell got:
Operation not permitted
That denial did not depend on the model being well-behaved. There was no prompt to ignore, no instruction to reinterpret, no clever encoding to catch. The process tried to write somewhere it was not allowed to write, and the operating system refused.
That is why this is cool.
The useful part is not that nono makes bad behavior visible after the fact. It prevents a large class of bad behavior from succeeding in the first place.
Rollback makes risky edits less dramatic
nono can also keep rollback snapshots.
With:
swival --sandbox nono --nono-rollback --yolo \
"Modernize this package layout and fix the tests."
nono records the file state around the session. After the run, Swival prints the review hint:
nono rollback
That gives you a separate way to inspect and restore the session’s touched files.
This is not a replacement for git. You should still use git. But it is a very useful safety net for the messy middle of agent work, especially when the agent may edit generated files, config files, or several parts of the tree before it finds the real fix.
Let the agent work. Inspect the result. Keep it, edit it, or roll it back.
That is a much calmer loop.
Network access can be tightened too
By default, nono allows outbound network so Swival can reach your model provider.
For a lot of local coding work, that is the right default. The model call has to go somewhere.
But if network egress matters, Swival exposes the nono controls directly:
swival --sandbox nono \
--nono-network-profile developer \
--nono-allow-domain openrouter.ai \
"Refactor the parser" --yolo
You can also use --nono-block-net for fully offline work, but be careful: that also blocks hosted model providers and local network services. It is mostly useful when the model path itself does not need the network.
The important thing is that network policy stays part of the same launch surface. Swival does not hide nono. It exposes the common nono controls where you already start the agent.
The boundary is composable
nono does not replace Swival’s own controls.
You can still restrict Swival’s file tools and commands:
swival --sandbox nono --files some --commands ls,git,python3 \
"Audit this repository for obvious security issues."
That gives you two layers.
Swival decides what tools the model sees and how those tools validate requests. nono decides what the process and its children can actually reach at the OS level.
Defense in depth is usually a phrase people use when they are trying to sell you a box. Here it is more literal: one layer makes normal agent behavior safer and more legible, the other makes escapes and accidents fail at the kernel boundary.
When to use it
Use --sandbox nono when you want Swival to work on something real but you do not want to hand the agent your entire user account.
That includes:
- untrusted repositories
- large refactors
- dependency updates
- tasks that run project scripts
- tasks where network egress should be limited
- anything where rollback would make you more comfortable
For small edits in a trusted project, Swival’s default sandbox may be enough. For copy-on-write filesystem experiments, AgentFS is still useful. But when you want OS-enforced path and network capabilities, nono is the better tool.
And now the Swival version of that is delightfully direct:
swival --sandbox nono "Do the thing" --yolo
That is the right amount of interface for a serious safety feature.
nono already gives agents a real OS boundary.
Swival 1.0.25 says: yes, please, make that a first-class mode.
nono brings the kernel boundary. Swival brings the agent harness. They fit.
Upgrading
If you installed Swival with uv, upgrade with:
uv tool upgrade swival
On macOS with Homebrew:
brew upgrade swival/tap/swival
Install nono from nono.sh and run nono setup once.
The Swival documentation is at swival.dev, including the new Using Swival With nono guide.
메타데이터
- post_id
- 2ef88933c311
- slug
- swival-1-0-25-loves-nono-2ef88933c311
- url
- https://medium.com/@swival/swival-1-0-25-loves-nono-2ef88933c311
- canonical_url
- https://medium.com/@swival/swival-1-0-25-loves-nono-2ef88933c311
- author_url
- https://medium.com/@swival
- status
- ok
- fetched_at
- 2026-06-12 07:40:50