Hand notes to an agent
A note already says what an AI coding agent needs to fix something: the words, the exact element, the page, the device, the build, and a link that opens that spot. So a note can go to an agent the way it goes to a person. The agent makes the change and shows it to you, you say yes, and the note on the page closes itself.
People stay in charge. The agent works on a branch or on staging, never on what your customers use, and nothing counts as fixed until a person has merged it.
There are two ways to do it:
What an agent gets#
Every note sent anywhere carries the same thing. This is a real one, as the agent reads it:
The pay button is too faint on the dark theme.
| | |
| --- | --- |
| **Noted by** | Ben |
| **Screen** | Checkout |
| **Device** | Desktop |
| **Element** | “Pay CHF 48.00” button |
| **Screenshots** | 1 on the note |
[Open this note on the page](https://shop.example/checkout?note=k3x9)
<details><summary>For developers</summary>
- **Hook:** `pay-button`
- **Selector:** `main > form > button.pay`
- **Route:** `/checkout`
- **Build:** `5cd0764`
</details>
<!-- notefix:k3x9 -->- The element is what makes it actionable. The selector points to exactly one element on the page, and the hook, when your page has one, is a name you can search for in your code.
- The link opens the page with the note showing, on the same screen, so an agent that can drive a browser sees what the reviewer saw.
- The build says which version of the page the note was left on.
- The marker at the end is the note's id.
Through your tracker#
The simplest way. Nothing about Notefix changes: it files issues, and an agent picks them up.
- Connect GitHub. In Notefix Cloud, on the project's Connections tab. On your own server, with the GitHub connector. Give new issues a label, such as
notefix. - Point your agent at the repository. Use any coding agent that works from GitHub issues and opens pull requests. Tell it to take issues with that label.
- Ask for a pull request that says
Fixes #214. When a person merges it, GitHub closes the issue, and within a minute the note on the page turns green.
If the pull request is closed without merging, the issue stays open and so does the note.
Straight to your agent#
For an agent your team runs itself, in its own chat channel or on its own server. This is how John works: he is the agent that helps build Notefix, and he lives in the team's channel on Buzz, a chat server we run ourselves.
It needs your own Notefix server, because a connector on your network hands the note over, and it holds the key to reach your agent.
Before starting, do steps 1 and 2 of How connections work: data-issues="queue" on the tag, and a secret on the store.
1Write the hand-over command
The agent connector runs a program you write. It gets the note on its input, sends it to your agent, and prints one id for what it made: a message, an issue, a job.
This is John's. It files the note as an issue in the team's channel, then says his name, because an agent notices a message that mentions it:
#!/bin/sh
# /opt/notefix/send-to-john.sh
set -eu
id=$(buzz issues create --repo-owner "$BUZZ_REPO_OWNER" --repo-id notefix \
--title "$NOTEFIX_TITLE" --label notefix --content - \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("id") or d.get("event_id") or d["event"]["id"])')
buzz messages send --channel "$BUZZ_CHANNEL" --mention "$JOHN_PUBKEY" \
--content "@John new note: $NOTEFIX_TITLE $NOTEFIX_LINK" >/dev/null || true
echo "$id"| It gets | |
|---|---|
| input | The note, exactly as shown in What an agent gets |
NOTEFIX_TITLE | The first line of the note |
NOTEFIX_LINK | The link that opens the note on the page |
NOTEFIX_NOTE_ID | The note's id, the same as the marker at the end of the input |
It must print the id as its last line (letters, digits, -, _, ., : or #) and exit with 0. Anything else counts as a failed try, and the connector tries again later.
sudo install -m 755 send-to-john.sh /opt/notefix/send-to-john.sh2Write the settings file
sudo install -m 600 -o notefix /dev/null /etc/notefix/agent.env
sudoedit /etc/notefix/agent.envNOTEFIX_API=http://127.0.0.1:8097
NOTEFIX_BOARD=staging
NOTEFIX_SECRET=the-secret-you-gave-the-store
NOTEFIX_SITE=https://staging.acme.com
AGENT_COMMAND=/opt/notefix/send-to-john.sh
AGENT_NAME=John
# What the command itself needs, for John:
BUZZ_RELAY_URL=wss://buzz.example.com
BUZZ_PRIVATE_KEY=the-connector-s-own-key
BUZZ_REPO_OWNER=...
BUZZ_CHANNEL=...
JOHN_PUBKEY=...| Setting | |
|---|---|
AGENT_COMMAND | The command from step 1 |
AGENT_NAME | Shown on each note it has, and in Settings |
AGENT_TIMEOUT | Optional. Seconds the command may take, 120 by default |
The command runs with these settings, except NOTEFIX_SECRET, which it never sees.
Give the connector its own key to reach your agent, never the agent's key. With the agent's key, every note would arrive as if the agent had sent it to itself.
3Try it
set -a; . /etc/notefix/agent.env; set +a
python3 connectors/runner.py agentPress Create an issue on a note. Within about 15 seconds the note shows John 9f2c41d0, and your agent has it. In Settings, under Connected tools, Agent shows John and Working.
Then run it as a service, with agent.env and runner.py agent.
4Let the agent close the note
A tracker can be asked whether a ticket is closed. A chat channel cannot, so the agent closes the note itself, once its change is merged. The note's id is the marker at the end of what it was given, notefix:k3x9:
curl -sS -X POST "$NOTEFIX_API/staging/notes/k3x9/done" \
-H "Authorization: Bearer $NOTEFIX_SECRET" \
-H 'Content-Type: application/json' \
-d '{"by": "John"}'- Use the agent's own name in
by, neveragent. A note closed under the connector's own name counts as the connector's, and the connector would open it again. - The agent needs the store's address and secret for this, in its own settings.
It is the same secret your connectors use, for every board on the store. Whoever holds it can file, close and reopen notes, and read the email addresses people gave for notifications. Give it only to an agent running on a server you trust as much as the store's own.
What to tell your agent#
The hand-over delivers the note; the agent's instructions decide whether what comes back is any good. These are the ones that made the difference for John:
- Open the link before judging. The note makes sense on the page, with the element in front of you.
- Group duplicates. The same rough edge gets noted three times. Say so once.
- Push back. A note that cannot be acted on yet is worth saying so about, rather than guessing.
- Never touch what customers use. Work on a branch or on staging, and let a person merge.
- Show the change. Post the diff, and a screenshot of the page for anything a person can see. Before and after, when the look changed.
- A merged change is the only evidence. An open pull request is not a fix. Close the note after the merge, not before.
- Expect a note twice. If the connector restarts at the wrong moment, it hands the same note over again. Same marker, same work.
Good to know#
- Anyone who can press Create an issue can give your agent work. On your own server, that is anyone who can open the page. Your agent's channel is where a person decides what is worth doing.
- A note can go to a tracker or to an agent. With both running, Create an issue asks where each one goes. See More than one tracker.
- Screenshots stay on the note. The agent reaches them through the link.