Exponentiation, modulo, HTTP API for chats, per-chat webhooks #2

Open
opened 2026-09-28 10:13:39 +02:00 by clawbot · 6 comments
Collaborator

sneak's order, 08:11 UTC 2026-09-28, verbatim:

update simplex bot to do exponentiation and modulo, and make the repo public, and add an http api to allow an external app to enumerate the list of chat connections it has, to fetch their recent history, and to send a message to one of the chats.

oh and add an api for that external app to register a webhook for any conversation, to which any incoming new messages for that conversation will be posted

Definition of done:

  • The repo is public. (Done by the top manager at 08:1x UTC.)
  • The bot computes exponentiation and modulo, with the usual precedence, alongside what it does now; tests cover both; the README says how to write them.
  • An HTTP API lets an external app:
    • list the bot's chats;
    • fetch a chat's recent messages;
    • send a message to a chat;
    • register a webhook on a chat, list them, and remove one. Every new incoming message in that chat is POSTed to each of its webhooks as JSON.
  • The API refuses a request without valid credentials. With no credentials configured, it refuses every request.
  • Webhook registrations survive a restart.
  • The README documents every endpoint with a curl example.
  • make check is green, and every unit is reviewed and merged to next. The next to main PR is open, mergeable and assigned to sneak.
  • The running simplexcalc container runs the new code on the same simplexcalc-data volume, so the address does not change. Its API is reachable from this host. sneak is told the API address and where to find the credential.

Facts for the repo-manager:

  • internal/calc parses with go/parser. In Go, ^ is XOR at the precedence of +, and ** does not parse, so exponentiation needs a different parser. Check ~/.claude/GO_PACKAGE_DEFAULTS.md before adding any dependency. Keep results exact where the answer is exact. Bound the exponent so one message cannot make the bot do unbounded work, as MaxInputLength does now.
  • The simplex-chat WebSocket at 127.0.0.1:5225 inside the container has no authentication, and it stays unexposed. The new HTTP API is the only way in.
  • Never remove the simplexcalc-data volume: it holds the bot's address.
  • Decide reversible details yourself and record them here (memory dont-block-on-reversible-decisions).
  • PRs target next, never main.

Model: opus-5-5

sneak's order, 08:11 UTC 2026-09-28, verbatim: > update simplex bot to do exponentiation and modulo, and make the repo public, and add an http api to allow an external app to enumerate the list of chat connections it has, to fetch their recent history, and to send a message to one of the chats. > > oh and add an api for that external app to register a webhook for any conversation, to which any incoming new messages for that conversation will be posted Definition of done: - The repo is public. (Done by the top manager at 08:1x UTC.) - The bot computes exponentiation and modulo, with the usual precedence, alongside what it does now; tests cover both; the README says how to write them. - An HTTP API lets an external app: - list the bot's chats; - fetch a chat's recent messages; - send a message to a chat; - register a webhook on a chat, list them, and remove one. Every new incoming message in that chat is POSTed to each of its webhooks as JSON. - The API refuses a request without valid credentials. With no credentials configured, it refuses every request. - Webhook registrations survive a restart. - The README documents every endpoint with a `curl` example. - `make check` is green, and every unit is reviewed and merged to `next`. The `next` to `main` PR is open, mergeable and assigned to sneak. - The running `simplexcalc` container runs the new code on the same `simplexcalc-data` volume, so the address does not change. Its API is reachable from this host. sneak is told the API address and where to find the credential. Facts for the repo-manager: - `internal/calc` parses with `go/parser`. In Go, `^` is XOR at the precedence of `+`, and `**` does not parse, so exponentiation needs a different parser. Check `~/.claude/GO_PACKAGE_DEFAULTS.md` before adding any dependency. Keep results exact where the answer is exact. Bound the exponent so one message cannot make the bot do unbounded work, as `MaxInputLength` does now. - The `simplex-chat` WebSocket at `127.0.0.1:5225` inside the container has no authentication, and it stays unexposed. The new HTTP API is the only way in. - Never remove the `simplexcalc-data` volume: it holds the bot's address. - Decide reversible details yourself and record them here (memory `dont-block-on-reversible-decisions`). - PRs target `next`, never `main`. Model: opus-5-5
clawbot added a new dependency 2026-09-28 11:10:29 +02:00
clawbot added a new dependency 2026-09-28 11:10:29 +02:00
clawbot added a new dependency 2026-09-28 11:10:29 +02:00
clawbot added a new dependency 2026-09-28 11:10:29 +02:00
clawbot self-assigned this 2026-09-28 11:10:30 +02:00
Author
Collaborator

Plan. Five units, each one PR to next with an independent review. The API units start after #8 lands: it moves the command setup out of cmd/simplexcalc/ into internal/cli, and they build on that layout. Unit 1 touches only the calculator and starts at once.

  1. #3 — exponentiation and modulo. Runs alongside 2.
  2. #4 — the API server, its credential, the list of chats.
  3. #5 — a chat's recent messages; sending a message.
  4. #6 — register, list and remove webhooks, kept in the data directory.
  5. #7 — posting each new incoming message to the chat's webhooks.

Units 2 to 5 share the API package and the README's API section, so they run one after another.

Decisions (reversible; details in each unit):

  • ^ and ** are exponentiation, grouping to the right and binding tighter than a sign on the left (-2^2 is -4); % takes the sign of the divisor (-7 % 3 is 2). A small parser of our own replaces go/parser; go/constant still computes.
  • The API listens on PORT (default 8080) and takes its credential, a bearer token, from the file named by API_TOKEN_FILE. Without one it refuses every request. No path is exempt.
  • A chat is a direct chat with one of the bot's contacts; the bot never joins groups.
  • Webhooks: one POST per incoming message, no retries, never blocking the bot's replies.

Deploy, after the last merge: rebuild the image from next; write a random credential to /var/lib/simplexcalc/api-token on the simplexcalc-data volume; recreate simplexcalc on the same volume with -p 127.0.0.1:8080:8080, so the API is reachable on this host only and the chat client's WebSocket stays inside the container; check end to end with a throwaway second client.

Model: opus-5-5

**Plan.** Five units, each one PR to `next` with an independent review. The API units start after https://git.eeqj.de/sneak/simplexcalc/issues/8 lands: it moves the command setup out of `cmd/simplexcalc/` into `internal/cli`, and they build on that layout. Unit 1 touches only the calculator and starts at once. 1. https://git.eeqj.de/sneak/simplexcalc/issues/3 — exponentiation and modulo. Runs alongside 2. 2. https://git.eeqj.de/sneak/simplexcalc/issues/4 — the API server, its credential, the list of chats. 3. https://git.eeqj.de/sneak/simplexcalc/issues/5 — a chat's recent messages; sending a message. 4. https://git.eeqj.de/sneak/simplexcalc/issues/6 — register, list and remove webhooks, kept in the data directory. 5. https://git.eeqj.de/sneak/simplexcalc/issues/7 — posting each new incoming message to the chat's webhooks. Units 2 to 5 share the API package and the README's API section, so they run one after another. **Decisions** (reversible; details in each unit): - `^` and `**` are exponentiation, grouping to the right and binding tighter than a sign on the left (`-2^2` is `-4`); `%` takes the sign of the divisor (`-7 % 3` is `2`). A small parser of our own replaces `go/parser`; `go/constant` still computes. - The API listens on `PORT` (default `8080`) and takes its credential, a bearer token, from the file named by `API_TOKEN_FILE`. Without one it refuses every request. No path is exempt. - A chat is a direct chat with one of the bot's contacts; the bot never joins groups. - Webhooks: one POST per incoming message, no retries, never blocking the bot's replies. **Deploy**, after the last merge: rebuild the image from `next`; write a random credential to `/var/lib/simplexcalc/api-token` on the `simplexcalc-data` volume; recreate `simplexcalc` on the same volume with `-p 127.0.0.1:8080:8080`, so the API is reachable on this host only and the chat client's WebSocket stays inside the container; check end to end with a throwaway second client. Model: opus-5-5
Author
Collaborator

sneak asked at 09:19 UTC for this repo to move to his account. The transfer to sneak is requested and waits for him to accept it. Once he does, the repo is sneak/simplexcalc. clawbot can then write to it only after he adds clawbot as a collaborator with write access.

For the repo-manager: once https://git.eeqj.de/sneak/simplexcalc exists, point your remotes, briefs and links there. If a push or merge is refused after the move, stop starting new workers and wait for the top manager: do not work around it. The running simplexcalc container and its volume are not affected.

Model: opus-5-5

sneak asked at 09:19 UTC for this repo to move to his account. The transfer to `sneak` is requested and waits for him to accept it. Once he does, the repo is `sneak/simplexcalc`. clawbot can then write to it only after he adds clawbot as a collaborator with write access. For the repo-manager: once `https://git.eeqj.de/sneak/simplexcalc` exists, point your remotes, briefs and links there. If a push or merge is refused after the move, stop starting new workers and wait for the top manager: do not work around it. The running `simplexcalc` container and its volume are not affected. Model: opus-5-5
Author
Collaborator

The running bot on sandcastle now runs next at ac72139, with exponentiation and modulo (#3). The container simplexcalc was recreated on the same simplexcalc-data volume, and its address is unchanged: https://smp5.simplex.im/a#MAO56qlZNoeCVWMvDXK4qsnRhduwVCVDkbw8r24zx0Q, so existing chats keep working.

Checked from a throwaway second client: 2^10 answers 1024 and -7 % 3 answers 2.

The HTTP API is not deployed yet; it follows once its units are merged.

Model: opus-5-5

The running bot on sandcastle now runs `next` at `ac72139`, with exponentiation and modulo (https://git.eeqj.de/sneak/simplexcalc/issues/3). The container `simplexcalc` was recreated on the same `simplexcalc-data` volume, and its address is unchanged: `https://smp5.simplex.im/a#MAO56qlZNoeCVWMvDXK4qsnRhduwVCVDkbw8r24zx0Q`, so existing chats keep working. Checked from a throwaway second client: `2^10` answers `1024` and `-7 % 3` answers `2`. The HTTP API is not deployed yet; it follows once its units are merged. Model: opus-5-5
Author
Collaborator

The running bot on sandcastle now runs next at 0b9121a, which adds the fix for #16. It was recreated on the same simplexcalc-data volume, and its address is unchanged.

Checked from a throwaway second client: 2^1200 answers 1.7218479456385751e+361 and -7 % 3 answers 2.

The HTTP API is in this build but not yet published or given a credential, so it refuses every request; that follows once webhook delivery (#7) lands.

Model: opus-5-5

The running bot on sandcastle now runs `next` at `0b9121a`, which adds the fix for https://git.eeqj.de/sneak/simplexcalc/issues/16. It was recreated on the same `simplexcalc-data` volume, and its address is unchanged. Checked from a throwaway second client: `2^1200` answers `1.7218479456385751e+361` and `-7 % 3` answers `2`. The HTTP API is in this build but not yet published or given a credential, so it refuses every request; that follows once webhook delivery (https://git.eeqj.de/sneak/simplexcalc/issues/7) lands. Model: opus-5-5
Author
Collaborator

All parts are on next, and the running bot on sandcastle runs next at fa2aa09. The container simplexcalc was recreated on the same simplexcalc-data volume, and its address is unchanged: https://smp5.simplex.im/a#MAO56qlZNoeCVWMvDXK4qsnRhduwVCVDkbw8r24zx0Q.

API address: http://127.0.0.1:8080 on sandcastle, published on loopback only. The chat client's WebSocket stays inside the container.

Credential: a bearer credential in /var/lib/simplexcalc/api-token inside the container, which is /var/lib/docker/volumes/simplexcalc-data/_data/api-token on the host. Read it with docker exec simplexcalc cat /var/lib/simplexcalc/api-token and send it as Authorization: Bearer .... It is on the volume, so it survives recreating the container; the README's Backup paragraph names it.

Checked end to end with a throwaway second client:

  • no credential or a wrong one gets 401;
  • the chats list, a chat's recent messages, and sending a message all work, and the sent message arrived;
  • a webhook registered on the client's chat received the client's next message as a JSON POST, and was then removed;
  • 2^1200 answers 1.7218479456385751e+361 and 6 * 7 answers 42.

The chats list includes throwaway test contacts from these checks (ids 3, 5, 6, 7 and 8); there is no API endpoint to delete a chat.

Model: opus-5-5

All parts are on `next`, and the running bot on sandcastle runs `next` at `fa2aa09`. The container `simplexcalc` was recreated on the same `simplexcalc-data` volume, and its address is unchanged: `https://smp5.simplex.im/a#MAO56qlZNoeCVWMvDXK4qsnRhduwVCVDkbw8r24zx0Q`. **API address:** `http://127.0.0.1:8080` on sandcastle, published on loopback only. The chat client's WebSocket stays inside the container. **Credential:** a bearer credential in `/var/lib/simplexcalc/api-token` inside the container, which is `/var/lib/docker/volumes/simplexcalc-data/_data/api-token` on the host. Read it with `docker exec simplexcalc cat /var/lib/simplexcalc/api-token` and send it as `Authorization: Bearer ...`. It is on the volume, so it survives recreating the container; the README's Backup paragraph names it. Checked end to end with a throwaway second client: - no credential or a wrong one gets `401`; - the chats list, a chat's recent messages, and sending a message all work, and the sent message arrived; - a webhook registered on the client's chat received the client's next message as a JSON POST, and was then removed; - `2^1200` answers `1.7218479456385751e+361` and `6 * 7` answers `42`. The chats list includes throwaway test contacts from these checks (ids 3, 5, 6, 7 and 8); there is no API endpoint to delete a chat. Model: opus-5-5
Author
Collaborator

Direction from sneak (chat, 2026-10-05 ~23:14 UTC), recorded here for whoever works on this repo next: simplexcalc is a proof of concept for an agent integration with SimpleX Chat. The calculator bot is the basis for a send/receive API that can be made into a plugin for an LLM code-agent harness. No manager is assigned to it for now.

Model: opus-5-5

Direction from sneak (chat, 2026-10-05 ~23:14 UTC), recorded here for whoever works on this repo next: simplexcalc is a proof of concept for an agent integration with SimpleX Chat. The calculator bot is the basis for a send/receive API that can be made into a plugin for an LLM code-agent harness. No manager is assigned to it for now. Model: opus-5-5
Sign in to join this conversation.