A workspace represents a multi-file tree as records and artifacts. Agents can create new versions, execute a version in a jail, serve it to a browser and export its history as a Git repository. Workspaces are an extension over Radia's public API.
Code generation often produces a project rather than one source file. The files must persist between iterations, preserve their version history and materialize as a directory for tools that expect a filesystem.
Radia stores each tree version durably while using temporary directories only for execution. The record model remains the source of identity, provenance and authorization.
The runtime has no workspace, file, path or directory abstraction.
The workspace extension combines a manifest record, artifact records for file contents and a latest-version projection. It uses the same public API as an external application.
extensions/. Application-specific behavior stays in
the application, and the runtime remains limited to records, leases, grants and artifacts.
Structural tests prevent extensions from importing runtime internals. Commands such as Git export are therefore ordinary clients, not privileged server operations.
A manifest record contains a name, tree digest, base version and file list. Each file entry contains a validated path, mode, content digest and artifact id.
{ "name": "landing-page",
"treeDigest": "t1:9f2c...ade1",
"basedOn": "01JB2Q7X4KJ8ZN0R5V3M9WPHTC",
"files": [
{ "path": "index.html", "mode": "100644", "digest": "sha256:4b1e...", "artifactId": "01JB2..." },
{ "path": "style.css", "mode": "100644", "digest": "sha256:c70a...", "artifactId": "01JB2..." },
{ "path": "cat.png", "mode": "100644", "digest": "sha256:8ee3...", "artifactId": "01JB2..." }
] }
Editing writes a new manifest linked to its base version. File bytes are content-addressed, so unchanged files are shared across versions. Concurrent edits from the same base create visible successor branches.
Existing artifacts can be attached without copying their bytes. Attached artifacts become data parents of the manifest, propagating their provenance labels.
NAME FILES VERSIONS TREE OWNER
landing-page 3 7 t1:9f2cade1a4… human:alice
scraper 9 22 t1:07b3e5c918… human:alice
Paths are validated when a manifest is written and again during materialization. The materializer verifies that every resolved file remains within the destination directory.
Radia ships a Deno permission jail for JavaScript and a bubblewrap backend for available host interpreters. Sandbox records describe the guarantees of each backend.
A worker probes a sandbox before advertising it. A backend is available only when the probe confirms the guarantees claimed by its record.
Successful probes determine which execution tools the worker publishes. A host that cannot provide the required isolation does not advertise that runner.
A run writes files into a separate output directory. When execution finishes, the host captures that directory as a new workspace version. The input tree remains immutable and may be shared by concurrent runs.
A binding record associates an agent with a workspace digest. The generic host materializes that version, executes it in the selected jail and claims work through the agent's run.
Promotion rotates grants that are pinned to the workspace digest. The claim permission and executable code version are therefore checked together.
$ radia promote t1:07b3e5c918… --tier prod --pin agent:scraper:take,ack
$ radia pins agent:scraper --tier prod
agent:scraper on 'prod': t1:07b3e5c918…
A host refuses a binding whose digest disagrees with the active grant pin. Rollback promotes a previous digest through the same mechanism. The jail bounds host access, the binding selects code and the grant limits the records that code may process and produce.
Bindings declare which request fields identify input artifacts. The host fetches those artifacts under the agent's authority and places them in the run directory. Outputs name the inputs as parents so their labels propagate.
The analysis example uses promoted workspace stages through one generic host. View the analysis example →
The extension converts a manifest into a path-to-artifact index and mints a short-lived capability over the complete tree. Scriptable content is served from an isolated origin.
Requests match entries in the fixed index and never resolve against a filesystem. Artifact access is authorized when the capability is minted, and the URL expires with that capability.
$ radia workspace-git landing-page --dir /tmp/landing.git
landing-page: 7 versions, 34 objects -> /tmp/landing.git
$ git clone /tmp/landing.git && cd landing && git log --oneline
9c1e4a2 attempt 7: fix the header overlap
04b7f30 attempt 6: add the illustration
…
The same projection can be served over read-only Git HTTP:
$ radia git-serve
git server on http://127.0.0.1:7790 (reading http://127.0.0.1:7788)
$ git clone http://you:<token>@127.0.0.1:7790/landing-page.git
Git authentication uses a mint-only credential and applies the caller's Radia permissions. Revocation stops subsequent fetches. Push is explicitly unsupported.
Each manifest version becomes a commit, version links become commit parents and trailers refer back to the source record. The exporter writes Git objects directly without invoking Git.
Export is one-way. Git object identity and rewritable history are not accepted as workspace identity; Radia records and SHA-256 tree digests remain authoritative.
Anyone who has purged a leaked credential from a repository knows what it costs: every downstream hash changes, every fork force-pushes, every clone is invalidated, signed tags die. Here a file is an artifact, so one payload can be destroyed while the tree digest still verifies and the history still reads. The blast radius is gone.
credentials/prod-db.txt outlives its own contents, and anyone
holding a candidate secret can hash it and confirm that exact value was in that tree. A
destroyed build output or document is gone in every practical sense. A destroyed credential is
unreadable and still confirmable, and its filename is plaintext forever. What this removes is
the blast radius, not the disclosure.
Past that: every file version is attributable to a specific run, the dependency set is inside
the record rather than claimed by a lockfile, a grant can scope which workspace an agent may
touch at all, and labels track whether a file descends from something untrusted. Branch
protection has been approximating that last set for years, and a git hook dies to
--no-verify.
What it does not buy: incremental builds, editor feedback, merge, blame. Git does the storage model better and has thirty years of tooling around it. This is not a better git. It is a working tree whose every state is a record the runtime can authorize, attest and erase.