Run from source
Build Steadmesh from this repository and run the example organisation on a local kind cluster with deterministic fakes. No accounts or API keys needed.
To install a published release into your own cluster without cloning the repository, use the Quickstart instead. This page is for working on Steadmesh itself, or for trying it with no accounts at all.
This walkthrough deploys the example organisation to a local kind cluster: two human representatives and an engineering team of three. Slack and Linear are replaced by deterministic fake servers from the repository, and seats run the fake harness. That harness executes scripted commands instead of calling a model, so it needs no accounts or API keys.
Every command pins the kubectl context kind-steadmesh. Nothing here uses or changes your current kubectl context.
Prerequisites
| Tool | Version | Notes |
|---|---|---|
| Go | 1.27 | Builds the binaries, the provider and the images. |
| Docker | any recent | Docker Desktop or Colima, running. Give it at least 4 CPUs and 8 GB of memory. |
| kind | 0.24 or later | brew install kind. Its default CNI enforces NetworkPolicy, which the platform checks before it starts any seat. |
| kubectl, Helm | kubectl 1.30+, Helm 3 | |
| Terraform | 1.5 or later | Tested with 1.5.7. terraform init needs network access for the kubernetes, helm and random providers. |
Run it
-
Build the tools and binaries. This installs
controller-genandsetup-envtestinto./bin, then builds every command, including the Terraform provider andorgctl.make tools build -
Create the cluster and load the images. The first image build takes a few minutes; the Claude Code image is the largest.
make kind-up kind-load -
Apply the foundation stage. This creates the namespaces
steadmesh-systemandsteadmesh-example, Postgres, and the credential Secrets. The Secrets hold placeholder values, which the fakes accept.make -C examples apply-foundation -
Start the fake Slack and Linear servers.
kubectl --context kind-steadmesh apply -f tests/e2e/manifests/fakes.yaml kubectl --context kind-steadmesh -n steadmesh-system rollout status deploy/steadmesh-fakes -
Point the organisation at the fakes and apply everything else.
make applyinstalls the platform chart, applies the organisation through thesteadmeshprovider, waits for readiness, then runs a fresh verification. Setting a 1-minute idle timeout lets you watch seats go to sleep.export TF_VAR_slack_endpoint_ref=http://steadmesh-fakes.steadmesh-system.svc:8090 export TF_VAR_linear_endpoint_ref=http://steadmesh-fakes.steadmesh-system.svc:8091 export TF_VAR_seat_idle_timeout=1m make -C examples applyThe run ends with a readiness report like this:
CONDITION STATUS REASON MESSAGE Configured True Compiled 5 seats resolved; defaults version 1 IdentitiesReady True Synced 5 seat identities active ConnectionsAuthenticated True Verified 2 connection verified IngressReady True Verified 1 ingress verified BindingsValid True Verified 2 binding verified StorageReady True Ready 5 seat workspaces provisioned HarnessCompatible True Ready harness profiles compatible SandboxEnforced True Ready sandbox restrictions verified RoutesExecutable True Ready ... OperationalReady True Ready ... HUMAN REPRESENTATIVE CHANNEL USER alex representative_alex slack (slack) U0ALEX sean representative_sean slack (slack) U0SEAN -
Message your representative. The fake Slack server has test endpoints that inject a direct message from a user and list what the bot posted. Forward its port, then send a message as Sean:
kubectl --context kind-steadmesh -n steadmesh-system port-forward svc/steadmesh-fakes 8090:8090 & curl -s localhost:8090/_test/dm -d '{"user":"U0SEAN","text":"hello from sean"}' sleep 20 # a sleeping seat takes a few seconds to wake curl -s localhost:8090/_test/posted | jq -r '.[] | "\(.channel): \(.text)"'D0SEAN: ack: hello from seanThat reply went from the message, through the platform's durable inbox, to Sean's representative seat, which woke up, ran a turn and replied through the outbox to Slack. No manual command was involved.
-
Or chat from a terminal. A human can reach their representative from a terminal instead of Slack. Put Sean on the terminal connection, which generates his token in the Secret
terminal-credentials, and re-apply:export TF_VAR_terminal_users='["sean"]' export TF_VAR_humans='{"sean":{"channel":"terminal","display_name":"Sean'"'"'s representative"},"alex":{"slack_user_id":"U0ALEX"}}' make -C examples apply bin/orgctl chat --context kind-steadmesh --user seanChatting with sean's representative over terminal. you 14:02 hello from sean representative 14:02 ack: hello from sean › Message your representative enter send · alt+enter new line · ↑ history · ctrl+c quitorgctl chatport-forwards to the platform and reads the token from the connection's Secret; pass--tokenfor a Vault reference. The representative's replies are rendered as markdown, in colour matched to a light or dark terminal. When input or output is not a terminal, for example when piping a message in, it falls back to plain lines. The representative can message you at any time withmessages.reply. Anything it sends while no terminal is open waits in the platform's memory, up to 200 messages, and appears when you next connect. Those queued messages are lost if the platform restarts. -
Delegate work and create a tracker project. The fake harness runs lines that start with
/as commands (see the script language). This message asks the representative to delegate to the engineering lead. The lead creates a Linear project and the result comes back to Sean:curl -s localhost:8090/_test/dm -d @- <<'JSON' {"user":"U0SEAN","text":"/delegate eng_lead /task\n/tool connections.invoke {\"connection\":\"linear\",\"operation\":\"project.create\",\"params\":{\"name\":\"Onboarding checklist\"}}"} JSON sleep 30 curl -s localhost:8090/_test/posted | jq -r '.[-1].text'Update from eng_lead: task result from eng_lead: tool connections.invoke: {"id":"…","connection":"linear","operation":"project.create","status":"succeeded","external_receipt":"proj-…"}Confirm the project exists in the fake tracker:
kubectl --context kind-steadmesh -n steadmesh-system port-forward svc/steadmesh-fakes 8091:8091 & curl -s localhost:8091/_test/state | jq '.projects[].name' -
Watch the seats. After a minute without work, seats scale to zero and keep their workspace and memory. The next message wakes them.
make -C examples status kubectl --context kind-steadmesh -n steadmesh-example get agentseats -w
Clean up
make -C examples teardown # destroy organisation, platform and foundation
make kind-down # delete the kind cluster
The same flow, with many more checks, is automated by make e2e. That suite covers replayed events, lost API responses, Pod kills, sleeping seats, control-plane restarts and credential leaks. See Acceptance status.
Next steps
- Learn what each part of the declaration does in the tutorial.
- Use real Slack, Linear and Claude: Connect real services.