Identities for entities did.bot
agent llm did
README.md

didbot-setup #

Says what this machine's didbot stack is, and what is wrong with one.

didbot-setup            # what is wrong here
didbot-setup show       # services, profiles, bindings
didbot-setup env        # the exports the dev scripts read
didbot-setup disk       # where the disk went

What it is for #

The stack comes up from a checkout: a handful of scripts, each finding the others by default. What does not come up from a checkout is the description of which services this machine runs, which profile a directory is bound to, and whether any of it is answering.

That is the whole subject, and it is the part that differs on every machine.

Probing, not acting #

check walks the description and asks the machine about it: is the configuration internally consistent, does the profile this directory resolves to exist, and is each service it names answering. Read-only, so it is safe to run at any moment.

Idempotence and resumability are not features here, they are consequences: every question is asked afresh, so running twice changes nothing. There is no checkpoint file, because the machine's own state is the checkpoint and a file would go stale the moment somebody edited a setting by hand.

Describing a second stack #

The three tables are hand-editable and always were, but a flag at a time is harder to get wrong than a TOML table at a time — and nothing here writes a configuration that check would then report as broken.

didbot-setup service add pds pds-beta --port 3500 --zone beta.agents.localhost
didbot-setup profile new beta --pds pds-beta
didbot-setup bind beta            # this directory, or --dir another
didbot-setup show

A service given no --port lands just above whichever upstream it names, so a second stack reads as a block rather than as numbers scattered above whatever happened to be highest.

profile new --from default --pds pds-b is the two-stacks case: copy everything and replace one role.

Writing the file discards comments — it is machine-written from here on. show prints what it holds and what the current directory resolves to.

The development scripts read this too #

didbot-setup env prints the profile as shell assignments, and scripts/dev-profile.sh — sourced by each dev-*.sh — evaluates them. So a worktree bound to a second profile runs ./scripts/dev-pds.sh and gets that profile's ports with nothing edited.

Each assignment is export NAME="${NAME-value}", so a variable already in the environment wins: DIDBOT_PDS_PORT=3100 ./scripts/dev-pds.sh still means 3100. A profile is a default, not an override. Set to nothing counts as set, which is how DIDBOT_PDS_DATA= ./scripts/dev-pds.sh asks that server for a store in memory. A machine with no configuration file is unaffected, because the builtin profile is the ports and the state directory those scripts already defaulted to, and a checkout with no setup binary built yet is unaffected too, because the helper is silent when it cannot find one.

One switch for the log filter #

didbot-setup debug on     # every component, one switch
didbot-setup debug        # what it is now

debug on writes debug = true into stack.toml, and env turns that into a RUST_LOG the development scripts export. A running process keeps the filter it started with, so the terminals need restarting.

Where the disk went #

A target/ in this workspace is between eight and twenty gigabytes and there is one per worktree. Four live worktrees have filled a machine mid-link more than once, and the failure does not look like a full disk — it looks like the linker crashing, which sends a developer reading a compiler bug tracker.

didbot-setup disk
didbot-setup disk --clean   # orphans only
    22.3G  this worktree   …/.claude/worktrees/dev-setup/target
    10.1G  in use          …/.claude/worktrees/mst-diff-suite/target
     8.6G  idle            …/didbot/target

    41.0G  in total

--clean removes exactly one category: a build directory whose worktree no longer exists, which belongs to nothing and which nobody is building in. This machine is shared between people and agents, so a directory touched in the last hour is reported as in use and never offered, and one that is merely idle is somebody else's to clear with cargo clean in it.

What it will not do #

Restart a service, install a certificate authority, or bind a privileged port. Each is named as a step and stopped on, with the command to run, rather than attempted quietly.