Daimond Daimond Guide

Your computer

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 takes two commands at a terminal, and it is Linux only. Read the warning first, before you type either command.

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 this is the first thing you will meet, and on Ubuntu the default Chromium is a snap. Why, and what to install instead.

What it gives you

With the hand installed, a daimon can run a build, a test suite, a linter or a script against the folder you granted, and read the result. Nothing else on the machine is in reach.

The tools it uses are named in the Tools panel, and four of them are worth knowing by name.

A refusal names the path, the cause and the fix, so there is no code to look up. The turn then ends the way any turn does, as Answered, Stopped or Step limit reached, so a refused command never reads as one that worked.

Before you start

Three things decide whether any of this will work. Checking them takes a minute, and 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 keeps its journal at ~/.local/share/daimond/hand/journal/, behind one of them. The hand 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. That sentence gives you nothing to act on, and the confinement is what a snap is for. Moving the journal does not help, because the browser hands the program its own environment.

You need not work this out yourself. The installer writes into the profiles that can use it and names the ones that cannot, and where every browser it finds is confined it stops, so you are not left with an install that appears to have worked. --check flags a confined browser even with a usable one beside it, because the browser 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 puts you in the same place. Install 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 and 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 built from Landlock, which fences files, and seccomp, which filters system calls, and both are Linux kernel features. Landlock arrived in Linux 5.13, and Unconventional systems sets out what older and unusual machines get. The hand builds and runs on macOS and Windows, but reports that it can fence nothing, and Daimond then refuses every command instead of running one unfenced. The refusal names what is missing. Neither platform’s fence 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 More than one device and Safety & fixes.
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. They are two separate grants, made separately. Operations does need the workspace, because a command runs against a real folder, so the workspace has to be one, and the same one.

Installing it

Installing takes 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. The install leaves nothing listening on a port, no daemon running, and no secret to steal.

  1. Build the hand

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

    Use --manifest-path and not -p, because 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. That folder 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. The folder 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 the folder, and it never guesses, because a guessed folder is 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 default permissions 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, so 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, because 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.

    The extension 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. Its manifest names a single origin, https://daimond.oxedyne.com, as the only page allowed to speak to it, so no other page in your browser can reach it at all.

  4. Restart the browser

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

Then check it

hand/install/install.sh --check

The 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

None of the steps above made a decision for you. 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 the two. 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. That is also what makes it revocable, because 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, which is 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 here in order and stops at the first thing that is wrong. The three steps it automates are useful on their own, and they are 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

This 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. There are three answers.

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

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

This prints what the compartment can enforce on this kernel and, at greater length, what it cannot. Read the second list closely, because on a kernel below Linux 7.1 it includes a route out of the compartment that Landlock leaves open and the hand closes itself, by refusing unix sockets. 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

The journal holds one JSON object per line, in the order things happened: the handshake, every command, and every refusal with its reason. If the hand started at all it wrote something here. An empty directory after a failed attempt means the hand 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()

The extension answers with JSON saying 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. Daimond shows the model that same sentence, so the JSON explains what the daimon has been told.

What it actually is

A command is an ordinary process, owned by you, on your own kernel, against your own files, with capabilities removed first. There is no virtual machine, no container and no emulation, so nothing is simulated and nothing copied in. Four parts each do 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, 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 under the system directories is reachable, because the compartment adds them to the grant 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, because 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, because it reads the first result before choosing the second.

What a command can and cannot do

Files

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

Named local sockets are refused, always

A command cannot create a unix socket, whatever else it was allowed. That costs a local database over a socket file, docker, anything wanting X11, and ssh-agent. socketpair, the paired socket a build uses to talk to its own child processes, is untouched, so cargo build is unaffected.

Below Landlock ABI 9 (Linux 7.1) the compartment does not govern connecting to a socket file at all. We measured it. With the fence in force and the network refused, one message to the desktop's session bus starts a process that was never fenced and reads a file the fence denies. That is a way out of the compartment, and no leak at its edge, so it is closed unconditionally.

ssh does not work

Two independent reasons stop it, and closing either alone would not be enough. ~/.ssh is not in the compartment, because every path is built from the folder you granted. And the agent socket is a unix socket, refused above. git push over SSH fails for both reasons at once. Granting your home directory would remove the first reason and most of the point of the compartment, which is why the installer refuses it.

Operations that touch only the repository do 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, because ~/.cargo and ~/.rustup sit under your home directory, and your home directory is not in the compartment.

Git is the odd one out. git is already in the read-only base, which is why git status and a local commit work with no grant. The button adds your own configuration, read-only, meaning your name, your email, and the hooks core.hooksPath names. Your stored passwords and ~/.ssh are denied by name.

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, and it surprises people. Reading an ordinary file in your own workspace does not count, and 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

The system-call filter is compiled for one architecture and checks the architecture first, because 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 that declares a different architecture 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 has 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. Choose it 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, apart from a click an unattended agent wants to make on a page, which is always put to you. 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.

The rung 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 list 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 exists because some programs ask their questions of a terminal and not of standard input. Keystrokes are not written to the journal. It needs a hand paired, like everything else here.

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 reason to run it. Every entry in it was measured on a running kernel and not inferred, and it changes with your kernel, so read your own. The entries fall into a few groups.

Taking it back

Three different things can be taken back, and all three come up.