openstation

Guides

Notes agent example

Run the complete notes agent and inspect its files.

An agent that keeps this workspace's written record: it files notes under okf/issues/, searches them to answer questions, and every change it makes is a git commit you can revert. No Slack, Telegram, or email credentials — just Claude auth.

Run it

# 1. Claude auth (either one)
claude login            # or: export ANTHROPIC_API_KEY=...

# 2. Copy the example into the workspaces home and make it a repo
mkdir -p ~/openstation && cp -r examples/notes-agent ~/openstation/notes
git -C ~/openstation/notes init -q .

# 3. Talk to it — a bare name resolves under ~/openstation
openstation notes dev

Then try:

you> we decided to use interval schedules instead of cron — write that down
you> what did we decide about scheduling?
you> run the stats tool

git log shows what it wrote — each turn that changes okf/ becomes a commit — and git revert HEAD undoes it. Platform state under var/ is never committed, even though the event log is written there during the same turn.

What each file is for

Path Whose file Why it's here
.openstation/openstation.yaml ours management overlay: identity, executor, which settings file enforces it, channel membership. It references the Claude-native files and never restates their contents.
.openstation/profiles/{member,admin}.md ours per-role addendum layered on the charter. A role with no file here is refused, not silently downgraded.
.claude/agents/notes.md Claude Code's the charter. Deliberately carries no tools: field — the settings gate below is the sole narrowing; a curated list here would have to be hand-synced forever or silently void a grant.
.claude/settings.notes.json Claude Code's the enforced gate. Writes are scoped to Edit(okf/**)/Write(okf/**); var/ is denied so the agent can't read the platform's own state.
.claude/skills/note/SKILL.md Claude Code's teaches the note format. Claude discovers skills itself; the platform never reads this.
tools/stats.py yours proof that agent tools are any language: the platform is TypeScript, this is Python, reached as a subprocess.
okf/issues/, okf/index.md the agent's the artifact zone — the only place it may write.

Things worth noticing

The gate is Claude's, not ours. Ask it to read .env and it refuses, citing settings.notes.json — not because the platform filtered a list. One enforcement source of truth. Worth knowing exactly how strong that is: enforcement happens inside Claude's decision loop, so a deny entry is a strong default, not a hard boundary. Anything that must never happen needs a PreToolUse hook or OS-level permissions behind it. (This agent worked that out and filed it as a note on its first run.)

Writes are reversible by construction. Turn on autoCommit and every turn that changes okf/ becomes a commit. Nothing outside the artifact zone is ever staged, even when it isn't gitignored.

Add a second agent with no code:

openstation notes agents add reviewer --channel review

That writes a manifest entry plus its own .claude/agents/reviewer.md and settings.reviewer.json. Note the current limit: agent selection resolves once at startup, so one process serves one agent — per-message channel routing is not wired yet (see docs/internal/roadmap.md, "Known gaps to v1").

Making it answer on Slack or Telegram

export SLACK_BOT_TOKEN=... SLACK_APP_TOKEN=...   # or TELEGRAM_BOT_TOKEN=...
openstation notes serve

Connectors start from credential presence — secrets stay in the environment and never enter openstation.yaml. Both transports are verified against fakes; neither has been run against a live workspace yet.

View Markdown source on GitHub ↗