Daimond Daimond Guide

Machine Operations

Daimond can run programs on your computer (a build, a test suite, a linter, a script) inside a compartment the kernel enforces. It is free, it is two commands at a terminal, and it is Linux only. Read the box below before you type either of them.

A snap or flatpak browser cannot do this, and cannot be made to. The installer detects one and refuses rather than writing into it, so you will meet this before you meet anything else, and on Ubuntu the default Chromium is a snap. Why, and what to install instead.

Before you start

Three things decide whether any of this will work. Checking them takes a minute; discovering them afterwards takes an hour, because the error the browser reports names none of them.

1. A browser installed from a .deb

A snap or flatpak browser confines the programs it starts, and that confinement reaches Daimond's hand. The home interface a snap gets does not grant the hidden directories at the top of your home directory, and the hand's journal lives at ~/.local/share/daimond/hand/journal/, behind one of them. It cannot open the file it would have recorded its reason in, so it exits without a word and Chrome reports only Native host has exited. There is nothing in that sentence to act on and nothing to configure: the confinement is what a snap is for. Moving the journal does not help either, because the browser hands the program its own environment and DAIMOND_HAND_JOURNAL_DIR never reaches it.

You need not work this out yourself. The installer looks at every browser profile on the machine, writes into the ones that can use it and names the ones that cannot; where every browser it finds is confined it stops, rather than leaving you an install that appears to have worked. --check reports the same, and flags a confined browser even with a usable one installed beside it, because the one you are actually using decides.

To see what you have before you start:

snap list 2>/dev/null | grep -Ei 'chrom|brave|vivaldi|edge'
flatpak list 2>/dev/null | grep -Ei 'chrom|brave|vivaldi|edge'

Anything either command names is confined. What works is Chrome, Brave, Vivaldi or Edge installed as a .deb, or a Chromium .deb from somewhere other than Ubuntu's archive.

apt install chromium-browser gives you the snap. Ubuntu's chromium-browser package has been a stub that installs the snap since 20.04, so the usual way of getting a browser without the Software app lands you in the same place. Reach for one of the four .debs above instead.

2. Run that browser once before you install

The installer writes one small file into the browser's profile directory, and that directory is created the first time the browser starts. Install a browser, never open it, and install.sh reports finding nothing (correctly, because there is nothing there yet).

3. Linux, with Landlock in the kernel

The compartment is Landlock and seccomp, and both are Linux. Landlock arrived in Linux 5.13; Unconventional systems sets out what older and unusual machines get. The hand does build and run on macOS and Windows and will introduce itself to the page, but it reports that it can fence nothing, and Daimond then refuses every command rather than run one unfenced. The refusal names what is missing: macOS wants a sandbox profile applied through sandbox_exec, or App Sandbox entitlements if the hand ever ships in a bundle; Windows wants a Job Object to bound the process tree and an AppContainer SID to bound what it may open. Neither is built.

Installing a different browser? Your account does not come with you. Your account is a signing key held in the browser you made it in. The passphrase does not recreate that key, it only decrypts the copy already stored there, so the same passphrase in a fresh browser starts a different account, with its own credits and no Pro. The key has to travel, so before you retire the old browser do one of these in it: Link another device, then type the code in the new browser; add a passkey; or Export a backup, which writes the chats, Diamonds and workspace files together with the key, still wrapped under your passphrase, for a browser that has no account of its own yet. See Cross-device sync and Accounts.
Not the same thing as the Machine workspace. The Machine chip in the Workspace panel gives Daimond read and write access to a real folder on your disk. Machine Operations lets it run programs. Two separate grants, made separately. Operations does need the workspace: a command runs against a real folder, so the workspace has to be one, and the same one.

Installing it

Two commands at a terminal, from the top of the Daimond repository, then two things in the browser. They add up to one small JSON file per browser profile plus a binary you built: nothing listens on a port, no daemon runs, and there is no secret to steal.

  1. Build the hand

    cargo build --release --manifest-path hand/Cargo.toml

    --manifest-path, not -p: the hand is a cargo workspace of its own, so -p reports no such package and builds nothing.

  2. Grant a folder, and register the hand

    hand/install/install.sh --workspace ~/work

    Put your own folder in place of ~/work. It bounds everything any command can read or write, so choose one for the work: the script refuses your home directory and / outright, since granting either grants everything. It has to exist already.

    That one run does three things, each with a failure you would otherwise meet later:

    • Writes your folder into root.txt, at ~/.local/share/daimond/hand/journal/root.txt. The hand will not serve a page until it has been told, and it never guesses, a guessed folder being a guess about what a command may touch. To change it later, run the same command with a different folder.
    • Creates that journal directory at mode 700. It holds the record of every command every Diamond has run, so the hand refuses to write it anywhere other users can read; a directory made under the usual umask is 755, and the hand would not start.
    • Writes the registration into every usable browser profile, and prints which. That file is what lets the browser start the hand at all. It is JSON and nothing else: the script builds nothing, downloads nothing, starts nothing and needs no root.
    DAIMOND_HAND_ROOT is a trap. The environment variable does the same job as root.txt and takes precedence, and it will not work: your browser starts the hand with its own environment, and yours is not in it. Use the file.
  3. Load the extension

    The previous step printed the path. Open chrome://extensions, turn on Developer mode, choose Load unpacked, and select the ext/ directory.

    It carries a fixed public key, so its id is the same on every machine (which is how the registration written a moment ago can already name it), and the manifest names a single origin, https://daimond.oxedyne.com, as the only page allowed to speak to it. No other page in your browser can reach it at all.

  4. Restart the browser

    It reads those profile directories only when it starts, so a file that appeared while it was running is invisible until then. This is the commonest reason a correct install looks broken.

Then check it

hand/install/install.sh --check

Changes nothing, and prints one line per thing that has to be true: a usable browser, the registration, the binary, the journal directory and its mode, root.txt, the journal sitting outside the granted folder, and the extension. A failing line carries its fix on the line below it. Work from the top, since a later line often fails only because an earlier one did.

The last two steps are yours

Nothing above chose anything on your behalf. The two things left are the two that are decisions.

Open the same folder in Daimond. On the Workspace panel, use the Machine chip to open the folder you granted. It has to be the same one: the hand writes a token into <folder>/.daimond/workspace.id and names it when it introduces itself, and the page reads that file through the handle it already holds and compares. A workspace that is the browser's own storage, or a different folder from the one in root.txt, has its commands refused with a line saying which. The token lives inside .daimond because the compartment always denies that directory, so a command cannot read the token and cannot answer for a folder it is not in.

Allow the first command. The first time Daimond wants to run something, a Daimond Hands window opens and asks. No browser permission covers “may run programs on this computer”, so that window is the approval and the extension records your answer itself, which is also what makes it revocable: the browser has nothing to take away. Until you allow it, nothing runs.

The window names the folder and the page that asked, and says in one line how far a command can reach on this machine. What this covers, and what it does not opens the rest: what the compartment stops, what it does not, and how to withdraw the permission.

When it does not work

Start with install.sh --check again: it walks every check below in order and stops at the first thing that is wrong. The three steps it automates are useful anyway, being what to reach for when --check passes and Daimond still says the hand is not there.

Run the hand yourself

hand/target/release/daimond-hand < /dev/null

starts the hand exactly the way your browser will, with no browser at the other end, so whatever it would have said to the browser it says to you. Three answers:

Anything else is a whole sentence naming the path, the cause and the fix, the hand having nowhere to print a code anyone could look up.

hand/target/release/daimond-hand --report

prints what the compartment can enforce on this kernel and, at greater length, what it cannot. Read the second list rather than skimming it: on a kernel below Linux 7.1 it includes a way out of the compartment entirely. It also names the folder from root.txt, so a stale one shows up here and not at the first command.

Read the journal

tail -n 5 ~/.local/share/daimond/hand/journal/hand-*.jsonl

One JSON object per line, in the order things happened: the handshake, every command, every refusal with its reason. If the hand started at all it wrote something here. An empty directory after a failed attempt means it never got far enough, which on Ubuntu almost always means the confined browser at the top of this page.

Ask the extension

In the browser, on the Daimond tab, open the developer console and run:

await DaimondHand.status()

It answers with JSON: whether a hand is paired, which folder it says it was granted, what it can enforce, and, where the answer is no, a reason written as a whole sentence and not a code. Daimond shows the model that same sentence, so it explains what the daimon has been told.

What it actually is

Not a virtual machine, not a container, not emulation. A command starts as an ordinary process, owned by you, on your own kernel, against your own files, with capabilities removed first. Nothing is simulated and nothing copied in, so a build here does the work the same build does in your own terminal. Four parts, each doing one job:

It is free, and it is not part of Pro. Nothing about a command touches Daimond's gateway: the request goes from the page to an extension to a program on your own disk and back. There is nothing to meter, so nothing is metered. A command costs what the model thinking about it costs, like any other turn.

Daimond implements no tools

There is no built-in ls, no built-in grep, no bundled toolbox and no shell. ls is /usr/bin/ls, the one already on your machine, at the version you installed.

Every program on the computer is reachable, the compartment adding the system to it read-only: /usr, /bin, /sbin, /lib, /lib32, /lib64, /libx32, /etc, /opt, and the harmless devices /dev/null, /dev/zero, /dev/full, /dev/random and /dev/urandom. Without them nothing starts, not even cat: the loader has to read the shared objects, and the process has to open something for the standard streams.

A bare name is looked up on PATH, which is /usr/local/bin:/usr/bin:/bin unless a granted toolchain has added to it. What that finds is resolved to an absolute path and checked against the compartment like anything else, so finding is not permission: a PATH pointing outside finds a program the command may not run, and the refusal names it.

There is no shell, so there is no shell syntax. A command is a list (["cargo", "test", "--lib"]) and a semicolon, pipe, redirection, backtick, $(…) or && arrives at the program as a literal argument. To chain two commands the daimon runs the tool twice, which is better anyway: it reads the first result before choosing the second.

What a command can and cannot do

Files

One consequence to learn before it looks like a broken tool. Where the whole granted folder is writable (a chat not scoped to a Diamond), that folder itself cannot be listed, and a file cannot be created directly in it. Landlock cannot grant a directory and withhold part of it, so the children are granted one by one and the directory is not. Everything one level down works normally.

Named local sockets are refused, always

A command cannot create a unix socket, whatever else it was allowed. The cost is not small: a local database reached over a socket file, docker, anything wanting X11, and ssh-agent. socketpair is untouched, which is what builds actually use, so a from-scratch cargo build is unaffected.

Below Landlock ABI 9 (Linux 7.1), connecting to a socket file is not governed by the compartment at all. Measured: with the whole fence in force and the network refused, one message to the session bus starts a process that was never fenced, and that process reads a file the fence denies. That is no leak at the edge of the compartment but a way out of it, so it is closed unconditionally: reaching the session bus has nothing to do with whether a build was allowed to fetch a crate.

ssh does not work

Two independent reasons, and closing either alone would not be enough. ~/.ssh is not in the compartment: every path in one is built from the folder you granted, so nothing outside that folder can be named, and the app cannot add one. And the agent socket is a unix socket, refused by the paragraph above. git push over SSH fails for both reasons at once. Granting your home directory would remove the first reason along with most of the point of the compartment, which is why the installer refuses it.

Everything that touches only the repository does work: git status, diff, log, add and a local commit are ordinary file operations inside the folder you granted.

A toolchain needs a grant

Open a Diamond and the Workspace panel shows a Toolchains row with five buttons: Rust, Node, Python, Go, Git. All five start off, so cargo is refused until you turn Rust on: ~/.cargo and ~/.rustup sit under your home directory, and your home directory is not in the compartment.

Git is the odd one out, because it puts no program within reach: git is already in the hand's read-only base, which is why git status and a local commit work with no grant at all. What the button adds is your own configuration, read-only: your name, your email, and the hooks core.hooksPath names, so a commit is attributed to you and a pre-commit hook actually runs. Your stored passwords and ~/.ssh are denied by name, even though the compartment would not reach them anyway.

Three things about that are deliberate:

The network

Whether a command may reach the network depends on the permission mode and on what the turn has already read. Under Ask and Guarded, once a turn has taken in content from outside (a web page it read or fetched, an email, the output of an earlier command), every command in that turn runs with TCP refused, and the daimon is told why, so it reports the cause instead of a broken project. Under Bypass the network is kept whatever the turn has read.

A command's own output counts as content from outside. So the first command in a turn has the network and a second one, in the same turn, does not. A build log is written by whatever the build ran, so this is deliberate, but it surprises people. Reading an ordinary file in your own workspace does not count; a message in your mail does. If something needs to fetch, ask for it in a fresh message, which starts a fresh turn.

What is refused is TCP bind and connect, which is what Landlock governs. UDP and raw sockets are outside it.

32-bit binaries are killed, not filtered

The system-call filter is compiled for one architecture and checks the architecture first: the compatibility ABI numbers its calls differently, and a filter built for the wrong table would refuse the wrong things and report success. A program with a different personality is therefore killed outright instead of filtered. That fails closed, and a build that execs a 32-bit helper will not work here.

The permission ladder

One setting, three rungs, and the axis is what Daimond does without asking. It starts on Guarded.

Ask every time

Every command is put to you before it runs, with the command and the directory on the prompt, and Daimond asks once in each conversation before it reaches the web. For watching each step, and for a machine holding something you cannot lose.

Guarded

The default. Commands run without asking. A turn that has read outside content loses the network, and Daimond asks once, in that conversation, before reaching anywhere the model chose. One yes covers every site until the conversation ends; a new chat or a fresh daimon asks again, and an unusually long address is always put to you on its own.

Bypass

Nothing is asked. Commands run, pages are fetched, and a build needing the network still has it on the turn's tenth command as well as its first. Chosen once, deliberately, then quiet.

A rung never changes what is possible. The compartment a command runs inside, the system-call filter under it, the folders a Diamond is scoped to, a granted toolchain, the marking on content from outside, and the journal are identical on all three. A rung changes only what you are asked.

It is a word in the chat header beside the model, because a mode you have to remember is one you will be wrong about. Click it to change it, or press Ctrl K (Cmd K on a Mac) and type the rung's name.

Unconventional systems

The compartment is built out of a fixed list of absolute paths, and that is what decides whether a given machine works. Run --report on yours before assuming either way.

Will not work

Partly

Fine

A terminal, too

The Terminal panel opens a real terminal on the same machine, inside the same compartment, and you type into it. It is separate from a command run by the daimon, and it exists because some programs ask their questions of a terminal and not of standard input. Keystrokes are never written to the journal, for that same reason. It needs a hand paired, like everything else on this page.

What is recorded

Every run (what was asked, what it was refused, what it returned) is appended to the journal in ~/.local/share/daimond/hand/journal/, as ordinary JSON lines you can read. The entries are hash-chained, and the journal sits outside every compartment, because the hand refuses a fence that would reach it. So a command cannot rewrite the record of itself, and no permission mode turns this off.

What is not protected

--report prints two lists, and the second is the point of running it. Every entry in it was measured on a running kernel rather than inferred, and it changes with your kernel, so read your own. The entries fall into a few groups:

Taking it back

Three different things, and all three come up.