feat(qrypt): qrypt.chat anonymous-invite issuer

AgentBBS becomes a trusted Ed25519 issuer for qrypt.chat anonymous
accounts. Members mint a signed, single-use qci1 token (per the shared
invite contract) that qrypt.chat verifies and redeems.

- internal/qryptinvite: Mint / GenerateIssuerKey / ParsePrivateKey +
  Config (AGENTBBS_QRYPT_* env) with unit tests (independent verify,
  payload assertions, jti uniqueness, tamper rejection, seed/full key).
- store: qrypt_invites table + QryptInviteCount / RecordQryptInvite
  (per-member quota, enforced in a tx; ErrQuotaExceeded) + test.
- plugins/qryptinvite: hub plugin (members only) — checks quota, mints,
  records, prints token + redeem URL.
- cmd/agentbbs: `qrypt-invite <user>` and `qrypt-issuer-keygen`
  subcommands wired into dispatch.
- setup.sh env template + docs/qrypt-invites.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Anthony Ettinger 2026-06-14 11:35:05 +00:00
parent 8adafaf515
commit 97da723c5c
10 changed files with 855 additions and 1 deletions

View file

@ -264,6 +264,16 @@ AGENTBBS_HTTP_ADDR=${HTTP_ADDR}
# Agent chat backend (agent@), stdin->stdout, e.g. "claude -p":
# AGENTBBS_AGENT_CMD=
# qrypt.chat anonymous-invite issuer (docs/qrypt-invites.md). Members mint a
# signed single-use token here that qrypt.chat redeems into an anon account.
# Run \`agentbbs qrypt-issuer-keygen\` once: paste the seed below, register the
# public key in qrypt.chat's invite_issuers row. Without the key, minting is off.
# AGENTBBS_QRYPT_ISSUER_KEY=<base64 ed25519 seed from qrypt-issuer-keygen>
# AGENTBBS_QRYPT_ISSUER_ID=agentbbs
# AGENTBBS_QRYPT_INVITE_TTL=168h
# AGENTBBS_QRYPT_REDEEM_URL=https://qrypt.chat/anon?invite=
# AGENTBBS_QRYPT_INVITE_QUOTA=5
ENV
chmod 0640 "$ENV_DIR/agentbbs.env"
fi