Every shell I've used treats authority as implicit. The current working directory is ambient. Environment variables bleed across boundaries. Secrets injected at the start of a script are still visible in the last command. When something goes wrong, you reconstruct what happened from logs that were never designed to be read by a machine.
0sh is an attempt to build a shell where this is not the case. It's in early design — the contracts are being frozen and the parser is being built. This post is about what it's trying to become.
The core idea: execution as evidence
The more accurate framing is: 0sh is a constrained execution language whose primary output is evidence.
Most shells output text. 0sh outputs an execution graph. Every command in a script produces a typed node in that graph. Every data flow between commands is an explicit edge. The graph is a first-class artifact — inspectable before execution, verifiable after, and structured enough for agents to consume deterministically.
The goal is that after a 0sh script runs, you can answer: what did it do, what did it read, what did it write, what secrets did it touch, and what was the causal chain? Not from reconstructed logs, but from the execution graph itself.
No ambient authority
The authority model is the most opinionated part of the design. There is no ambient current working directory. There is no environment bleed. Every effect a script may have is declared before it runs.
| Effect | What it covers |
|---|---|
| reads_filesystem | Reads from files or directories — requires an explicit scope |
| writes_filesystem | Creates or modifies files — scope-bounded, temporary |
| uses_secrets | Accesses secret material via tsafe — secret.resolved → injected → revoked → destroyed |
| network_access | Makes network calls — declared per-host allowlist |
| emits_events | Produces lifecycle or audit events — always on for CellOS integration |
File access requires an explicit scope block that names the path. Access cannot escape the declared scope — ../ is rejected. The scope is revoked when the block exits. Secrets follow the same pattern: resolved, injected, revoked, memory zeroized.
You can inspect what a script will do before it does it. The plan command shows the execution graph with all effect declarations for every node. This is intended to make 0sh safe for agent-driven automation — an agent can read the plan, verify the declared authority, and decide whether to proceed.
Language heritage
0sh is a synthesis. The design draws deliberately from existing languages, keeping what works and redesigning what doesn't.
| Language | What to keep | What to reject |
|---|---|---|
| PowerShell | Object-first pipeline thinking, operational ergonomics | Verbosity and ceremony-heavy constructs |
| zsh | Command-line fluidity, composability, quick interactive workflows | Hidden state and implicit expansion surprises |
| Rust | Explicitness at boundaries, strong correctness defaults, safety mindset | Syntactic overhead for routine scripting tasks |
| Go | Straightforward concurrency model, practical operational tooling style | Limitations that reduce expressiveness in script contexts |
| Python | Readability, expressive scripting flow, low-friction automation | Ambiguity that harms determinism and auditability |
The synthesis rule: if a borrowed feature makes common ops workflows clearer and safer, keep it. If it increases ceremony or ambiguity, redesign it.
Three levels of progressive disclosure
The language should feel good at three levels without changing core semantics.
| Level | Who it's for | What it looks like |
|---|---|---|
| Quick scripting | Daily interactive use | Minimal ceremony, intuitive defaults, short feedback loops — feels like a fast shell |
| Robust automation | Scripts and pipelines | Typed values where they prevent real mistakes, reusable functions, deterministic plans |
| High-assurance execution | CI, agent workflows, compliance contexts | Policy-aware constraints, strict authority declarations, audit-grade execution graph |
The same language at all three levels. The difference is how much of the authority and lifecycle machinery you engage with.
Where it fits in the stack
0sh is being built as the execution language for CellOS — the typed authoring and orchestration surface for cells, plans, and operator workflows. The authority model is designed to compose directly with CellOS cell specs: a 0sh script running inside a cell inherits the cell's declared authority and cannot exceed it.
| Layer | Role |
|---|---|
| taudit | Scans pipeline YAML — before 0sh, when you're still using standard CI workflows |
| tsafe | Secret broker — 0sh resolves secrets through tsafe; lifecycle events track every access |
| CellOS | Execution host — 0sh scripts run inside cells; cell authority bounds what the script can do |
| 0sh | The authoring language — typed, authority-aware, evidence-producing |
The long-term aim is that writing a 0sh script inside a CellOS cell is the normal way to express automation that needs to be auditable, agent-safe, and least-authority by default. Not a special mode — the default.
What exists today
The contracts are being frozen: AST schema, IR schema, execution graph node and edge types, lifecycle states, event emission points. The parser is being built. The design is in active development.
This is early. The post is about the design goals, not a shipping product. But the contracts-first approach means the shape of the language is being locked down before the implementation — which is the right order for something that needs to be machine-readable and stable.
Language tenets
- — fast startup, tight feedback loops, no ceremony tax on simple tasks
- — the same constructs work at every level of the stack
- — no ambient access, no hidden state mutation for authority-sensitive operations
- — source ranges, intent-aware suggestions, stable formatting and linting
- — the execution graph is the product, text output is secondary