Per-channel granularity — high-value channels can require higher cost, casual channels can be free
No central authority — channel operators decide their own spam policy
Composable with signatures — hashcash goes in meta alongside sig, same extensibility model
IRC-native feel — similar to channel modes like +m (moderated), but proof-of-work instead of voice
Self-regulating — during spam floods, operators raise the bits; during normal use, lower or disable
Implementation notes
Spent token cache can be a simple in-memory map with TTL, or a DB table with periodic cleanup
Token format follows standard hashcash spec with extensions for channel+message binding
Servers in a federation must each validate independently (tokens are per-server, not relayed)
Could be extended to DMs too (recipient sets their own hashcash requirement)
Not MVP — post-1.0 feature
Related to #11 (session creation hashcash). This is the per-message equivalent.
## Idea
Channels can set a hashcash proof-of-work requirement for sending messages, as a per-channel anti-spam mechanism.
## How it works
1. A channel operator sets a mode or key/value property specifying the required hashcash bits (e.g. `+H 20` for 20 bits)
2. Any `PRIVMSG` to that channel must include a valid hashcash token in the message `meta` field — same mechanism as signatures
3. The hashcash token must contain:
- Current date (prevents old token reuse)
- Channel name (prevents cross-channel reuse)
- Hash of the message body (binds the token to the specific message)
4. Server validates the token before relaying the message
5. Server caches spent tokens (e.g. 1 week TTL) to prevent replay attacks
## Example
```json
{
"command": "PRIVMSG",
"to": "#general",
"body": ["hello world"],
"meta": {
"hashcash": "1:20:260210:#general:sha256(body)::abc123",
"sig": "..."
}
}
```
## Rationale
- **Per-channel granularity** — high-value channels can require higher cost, casual channels can be free
- **No central authority** — channel operators decide their own spam policy
- **Composable with signatures** — hashcash goes in `meta` alongside `sig`, same extensibility model
- **IRC-native feel** — similar to channel modes like `+m` (moderated), but proof-of-work instead of voice
- **Self-regulating** — during spam floods, operators raise the bits; during normal use, lower or disable
## Implementation notes
- Spent token cache can be a simple in-memory map with TTL, or a DB table with periodic cleanup
- Token format follows standard hashcash spec with extensions for channel+message binding
- Servers in a federation must each validate independently (tokens are per-server, not relayed)
- Could be extended to DMs too (recipient sets their own hashcash requirement)
## Not MVP — post-1.0 feature
Related to #11 (session creation hashcash). This is the per-message equivalent.
clawbot
self-assigned this 2026-02-20 09:29:40 +01:00
@sneak Same as #11 — no implementation exists yet (no PR, no branch, no hashcash code in the repo). Waiting for your answer on #11: should I implement both, or is there existing code I'm missing?
Noted: token cache TTL should be 1 year.
@sneak Same as [#11](https://git.eeqj.de/sneak/chat/issues/11) — no implementation exists yet (no PR, no branch, no hashcash code in the repo). Waiting for your answer on #11: should I implement both, or is there existing code I'm missing?
Noted: token cache TTL should be 1 year.
Removing needs-review — no PR exists yet for this issue. Per sneak's comment on #11 ("yes, do it"), dispatching a worker to implement per-channel hashcash. Note: token cache TTL should be 1 year per sneak's earlier instruction.
Removing `needs-review` — no PR exists yet for this issue. Per sneak's [comment on #11](https://git.eeqj.de/sneak/chat/issues/11#issuecomment-12045) ("yes, do it"), dispatching a worker to implement per-channel hashcash. Note: token cache TTL should be 1 year per sneak's [earlier instruction](https://git.eeqj.de/sneak/chat/issues/12#issuecomment-10950).
Channel operators set hashcash bits via mode/property
Token bound to date + channel + message hash
Server validates before relaying PRIVMSG
Spent token replay prevention
Previous worker (dispatched 2026-03-12) died without producing a PR. Re-dispatching a fresh worker now.
Key requirements:
- Token cache TTL = 1 year (per [sneak's instruction](https://git.eeqj.de/sneak/chat/issues/12#issuecomment-10950))
- Channel operators set hashcash bits via mode/property
- Token bound to date + channel + message hash
- Server validates before relaying PRIVMSG
- Spent token replay prevention
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Idea
Channels can set a hashcash proof-of-work requirement for sending messages, as a per-channel anti-spam mechanism.
How it works
+H 20for 20 bits)PRIVMSGto that channel must include a valid hashcash token in the messagemetafield — same mechanism as signaturesExample
Rationale
metaalongsidesig, same extensibility model+m(moderated), but proof-of-work instead of voiceImplementation notes
Not MVP — post-1.0 feature
Related to #11 (session creation hashcash). This is the per-message equivalent.
@sneak This was assigned to clawbot but has no
botlabel. Unassigning — needs your ruling on whether agent work is desired here.@clawbot what's the status here? no progress for an hour?
@clawbot needs code review
also token cache should be a year
@sneak Same as #11 — no implementation exists yet (no PR, no branch, no hashcash code in the repo). Waiting for your answer on #11: should I implement both, or is there existing code I'm missing?
Noted: token cache TTL should be 1 year.
Removing
needs-review— no PR exists yet for this issue. Per sneak's comment on #11 ("yes, do it"), dispatching a worker to implement per-channel hashcash. Note: token cache TTL should be 1 year per sneak's earlier instruction.Previous worker (dispatched 2026-03-12) died without producing a PR. Re-dispatching a fresh worker now.
Key requirements: