arizuko › products › Company brain — setup
Company brain — setup
Design your folder tree, wire intake sources, populate
facts/, schedule briefs. One team at a time.
prerequisites
- A host with Docker, ports 80/443 reachable behind a TLS terminator.
- The
arizukobinary andarizuko-antagent image (make build,sudo make images,sudo make agent). - Anthropic API access.
- At least one channel adapter token: Slack (
SLACK_BOT_TOKEN+SLACK_SIGNING_SECRET) and/or email (emaid). Webhooks need no adapter — just a hook token.
1. create the instance
arizuko create corp
cd /srv/data/arizuko_corp
$EDITOR .env
ASSISTANT_NAME=corp-brain
WEB_HOST=brain.example.com
ANTHROPIC_API_KEY=sk-ant-…
# Slack (recommended primary channel)
SLACK_BOT_TOKEN=xoxb-…
SLACK_SIGNING_SECRET=…
arizuko create already generated AUTH_SECRET
and SECRETS_KEY in .env — leave those
alone.
2. design the folder tree
Sketch the org chart first — it becomes the folder tree. Start with two levels max. Add depth when you hit a real coordination problem (e.g. the SRE oncall rotation needs its own diary, separate from the SRE team). Don’t pre-build folders “just in case.” An empty folder adds nothing and costs a route rule.
Example for a 40-person eng company:
corp/ # root intake triage desk
corp/eng/ # engineering channel + PR review ingest
corp/eng/sre/ # SRE runbooks + Sentry ingest
corp/pm/ # roadmap + Linear ingest
corp/sales/ # deal notes + CRM webhook
3. create the folders and route rules
Create each group folder with arizuko group corp add <jid> <folder>.
The <jid> is the source chat that should land in
this folder; the route row is written for you.
# create folders (jid first, then folder)
arizuko group corp add 'slack:T-acme/channel/C0ONCALL' corp/eng/sre/oncall
arizuko group corp add 'slack:T-acme/channel/C0ENG' corp/eng
arizuko group corp add 'slack:T-acme/channel/C0PM' corp/pm
arizuko group corp add 'slack:T-acme/channel/C0SALES' corp/sales
arizuko group corp add 'web:corp/intake' corp/intake
Then the catch-all: an empty match expression matches every message, so anything no other rule claims lands in the intake folder. Hook routes come in step 5, once the tokens exist:
arizuko route corp add '' corp/intake --seq 10
For bulk or GitOps-style edits, declare the same rows in a YAML
manifest and arizuko apply corp corp-routes.yaml instead.
Route priority: more specific rules (lower seq) win.
The catch-all at corp/intake handles anything that
doesn’t match a more specific rule — handy for new
webhook sources while you’re still wiring them up.
4. populate each team's facts/
facts/ is the team’s knowledge base. The agent
reads it on every relevant turn. Start with what teams actually use:
runbooks, decision logs, reference docs. Don’t dump everything
— curated, short files beat a wall of stale text.
Three ways to populate:
-
Directly on disk. Write markdown files under
/srv/data/arizuko_corp/groups/corp/eng/sre/facts/. Fast for initial seeding. -
WebDAV. Mount
https://brain.example.com/dav/corp/eng/sre/in Finder orrclone. Edit as a normal file system; changes are live immediately. -
Webhook-triggered agent write. Wire a GitHub PR
merge webhook to
corp/eng/review; the agent reads the PR diff + description and writes a summary tofacts/decisions/<YYYY-MM-DD>-<pr>.md. The knowledge base grows as work happens, not as a separate documentation effort.
5. wire webhook sources
Mint a hook token for each external source, then route the
token’s JID (hook:<folder>/<label>)
to the folder that should handle it:
# Sentry alerts
arizuko token corp issue webhook corp/eng/sre/oncall sentry
# webhook URL: https://brain.example.com/hook/<token>
# Paste into Sentry: Organization Settings → Integrations → Webhooks
arizuko route corp add 'chat_jid=hook:corp/eng/sre/oncall/sentry' corp/eng/sre/oncall --seq -10
# GitHub
arizuko token corp issue webhook corp/eng github
# Paste into GitHub repo → Settings → Webhooks
arizuko route corp add 'chat_jid=hook:corp/eng/github' corp/eng --seq -5
The body arrives verbatim in the target folder; parsing is skill work on the agent side. See webhooks for signature verification and security model.
6. schedule briefs
Scheduled tasks fire a Turn in a target folder on a cron schedule
— no host cron, no systemd timer. The scheduler
(timed) is part of the stack. There is no dedicated CLI
subcommand for tasks; add them in the
dashd tasks admin at /dash/, declare
scheduled_tasks rows in a manifest for
arizuko apply, or ask the agent:
/new schedule briefs
@corp-brain schedule a recurring task:
folder: corp/eng cron: "0 9 * * 1-5"
task: write daily standup summary to facts/briefs/today.md and send to #eng-standup
The agent writes the task row via the schedule_task MCP
tool; timed picks it up and fires the prompt on
schedule. Examples:
| folder | cadence (cron) | task |
|---|---|---|
| corp/eng | 0 9 * * 1-5 | write daily standup summary to facts/briefs/today.md and send to #eng-standup |
| corp/pm | 0 8 * * 1 | write weekly roadmap digest to facts/briefs/week.md and send to #pm-digest |
| corp/eng/sre | 0 18 * * 5 | write on-call handoff brief and send to #eng-oncall |
Keep the task instruction specific: what to produce, where to write it, where to send it.
7. run
arizuko run corp
Install the systemd unit for production; see getting started for the template.
8. verify
- Send a test Sentry webhook to the hook URL; check
sudo journalctl -u arizuko_corp | grep sentryfor the ingest log line. - Post a message in the wired Slack channel; the agent should reply or observe (depending on your route).
- Test a brief without waiting for cron: ask the agent in chat to run the brief prompt once now, or temporarily set the task’s cron to the next minute in
/dash/→ Tasks. - Check
/dash/→ Groups to see each folder with its route and timed tasks listed.
9. per-folder grants
By default, each folder’s agent can read its own
facts/, write its diary, and reply on the
configured channel; nothing crosses folders. The CLI grant is
admin-scoped — it gives a person admin over a folder subtree
('**' makes them an operator):
arizuko group corp grant google:cto@acme.com 'corp/**'
Finer rules — who may interact in a folder, which
MCP tools an agent may call, deny effects, cross-folder read —
are grant rows managed from /dash/ → Grants.
Full rule syntax: grants.
10. observe-mode ingest
For Slack channels where you want context but not replies —
general chatter, off-topic channels — route to
<folder>#observe. The agent indexes the messages;
no Turn fires; nothing gets sent to the channel.
Add the observe route (the #observe fragment on the
target makes the agent watch without replying):
arizuko route corp add 'chat_jid=slack:*/channel/C0GENERAL' 'corp/eng#observe' --seq 5
You can also add it in the dashd routes admin UI at
/dash/, or declare it in a YAML manifest and
arizuko apply.
When the agent in corp/eng is answering a question, it
can surface context from the observed #general channel via
find_messages without the channel ever knowing.
common issues
- Webhook arrives but no Turn fires.
- Check the route table matches the hook JID exactly
(
hook:corp/eng/sre/oncall/sentryfor a token issued tocorp/eng/sre/oncallwith labelsentry). Runarizuko get corp routesand compare against thechat_jidin the journalctl ingest log line. - Timed brief fires but the agent sends nothing.
- The task instruction probably doesn’t include a send
instruction. Edit the task body (in dashd tasks admin) to include
“send to #<channel>” or the agent will write the
brief to
facts/and stay silent (correct behavior if that’s all you asked). - Agent replies in the wrong folder.
- Route priority. Run
arizuko get corp routesand checkseqvalues — lower wins. Add a more specific rule with a lowerseqviaarizuko route corp addto override the catch-all.
go deeper
- Company brain — intro — system shape, example, honest constraints
- routing — route table, observe mode, delegation
- grants — per-folder and cross-folder ACL
- timed — scheduled tasks, cron format
- davd — WebDAV for facts/ population
- webhooks — hook tokens, ingest recipes
- crackbox — per-folder egress
- CLI reference