Skip to content

Commit 46745fc

Browse files
Add a command-by-command Slack walkthrough to the docs (#25)
Drawn from the first real session of driving grapharc from Slack, refusals and mistakes included: one message is one command, name every trace and run id, what the spend-free default refuses and why, and what a planner's honest negative answer looks like when the registry has no node kind that can do the job. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 88bf104 commit 46745fc

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

docs/cookbook/07-slack.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ is enough. A workspace member types `/grapharc metrics t.jsonl r1` (or
77
mentions the bot in a channel); the bot runs the command on the host and posts
88
the output back in the thread.
99

10+
Setup lives here; what a real session looks like, exchange by exchange, is
11+
[08-slack-walkthrough.md](08-slack-walkthrough.md).
12+
1013
Nothing in this page is byte-compared by the test suite — Slack is on the
1114
other end of every interesting command. What *is* tested, in
1215
`tests/test_slack_gateway.py`, is everything short of Slack itself: the gate
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# A Slack session, command by command
2+
3+
[07-slack.md](07-slack.md) covers setting the bot up; this page is what using
4+
it actually looks like. Every exchange below is from a real session — the
5+
first hour of driving `grapharc` from Slack — including the refusals and the
6+
mistakes, because those teach the model of the tool faster than the successes.
7+
8+
One rule carries the whole page: **one message is one command.** The bot
9+
treats the entire message as a single command line; pasting three commands in
10+
one message glues them into one argv and the CLI rejects it (exit 2). Send
11+
commands one at a time, and wait for a long one to answer before reading its
12+
trace.
13+
14+
## First contact
15+
16+
```
17+
/grapharc models
18+
```
19+
20+
Instant, offline, spend-free — the right first ping. You get the backend
21+
table and which specs need a key. `/grapharc` with nothing after it returns
22+
the allowed-command list.
23+
24+
If the slash command says *not a valid command*, the app needs a reinstall
25+
after the command was registered; mentions (`@grapharc models`) work as soon
26+
as the bot is invited to the channel.
27+
28+
## The run → read loop
29+
30+
The shape of everything else: run something with a **named trace and run id**,
31+
then read that trace back.
32+
33+
```
34+
@grapharc demo stage2 --trace demo.jsonl --run-id first-demo
35+
@grapharc trace demo.jsonl
36+
@grapharc metrics demo.jsonl first-demo
37+
@grapharc viz demo.jsonl first-demo
38+
```
39+
40+
Name both, always. An unnamed run mints a random id you then have to fish out
41+
of the trace, and two runs pointed at the same `--trace` file interleave their
42+
events in one JSONL — legal, but confusing to read. Fresh file, explicit id,
43+
every run.
44+
45+
`trace` is the audit log — every event, verbatim. `metrics` is the summary:
46+
tokens, durations, per-node counts, termination reason. `viz` prints the
47+
executed path as Mermaid, and the reply ends with a *render this diagram*
48+
link that draws it in your browser (the diagram travels compressed inside the
49+
URL fragment, which a browser sends to no server).
50+
51+
## Planning with a real model
52+
53+
The bot's default is spend-free: `--model` is refused until the operator
54+
restarts the bot with `GRAPHARC_SLACK_ALLOW_MODEL=1` — a decision made in the
55+
shell that starts the bot, deliberately not from Slack. Once it's on:
56+
57+
```
58+
@grapharc plan "investigate improvements for the readme file" --model claude-cli/claude-sonnet-5 --trace plan.jsonl --run-id readme-1
59+
```
60+
61+
A scripted `plan` answers in under a second; a real one takes tens of
62+
seconds, and the mention reply arrives only when it finishes. Reading the
63+
trace afterwards is where the governance becomes visible: rounds where the
64+
model's reply had no parseable proposal, a structurally valid proposal
65+
rejected by the edge policy (`policy/edge_denied`), and finally an admitted
66+
round that executed. Every model failure contained, every decision recorded.
67+
68+
## What a refusal looks like, and why
69+
70+
Two refusals from the same session, both correct:
71+
72+
- `@grapharc agent "do something"`*not a command this bot runs*. `agent`
73+
executes tools on the host on behalf of anyone in the workspace, so it is
74+
excluded at the gate, not hidden.
75+
- `plan "make a new file for the docs" --model …`**ran; the answer was
76+
negative**. The planner may only propose node kinds from its registry —
77+
the incident-response demo set — and none of them can create a file. The
78+
model found no admissible work and said so, which is exit 1 doing its job:
79+
a weaker loop would have executed three irrelevant nodes and called it
80+
success. File-creation belongs to `grapharc agent`, on the host.
81+
82+
## The paths rule
83+
84+
Every path in a command must resolve inside the bot's working directory —
85+
`trace ../somewhere-else.jsonl` is refused before a process spawns. The
86+
corollary: tools that default their output *outside* the workdir (a bare
87+
`plan` writes its trace to a temp directory) leave you with a file Slack
88+
cannot read back. Passing `--trace <name>.jsonl` keeps the whole
89+
run-then-read loop inside the bot's world, which is the point of it.

0 commit comments

Comments
 (0)