Mirrors keisei-marketplace/src/lib/crypto-box.ts::sealBoxToVps.
Two new subcommands on kei-buddy bin:
- genkeys --key <path> → writes PKCS#8 PEM x25519 priv,
prints standard-base64 pub (44 char)
- decrypt-and-export --vps-key <pem> --blob <json> --env-out <env>
→ ECDH(vps_priv, ephPub) → HKDF-SHA256
info=keibuddy-token-v1 → XChaCha20-Poly1305
decrypt → append BOT_TOKEN/TELEGRAM_BOT_TOKEN
to env file (replaces stale, keeps other lines)
Cloud-init in hetzner.ts already calls these. Without this commit the
VPS could decode its own pubkey but had no way to recover the sealed
bot-token blob — the bot would never log into Telegram.
Crypto stack (mirror of @noble in TS):
- x25519-dalek 2 (static_secrets feature)
- chacha20poly1305 0.10 (XChaCha20Poly1305)
- hkdf 0.12, sha2 0.10
- base64 0.22 (accepts URL_SAFE_NO_PAD + STANDARD)
- zeroize 1 for priv-key wipe
Tests (6/6 pass):
- roundtrip_seal_then_decrypt — re-implement marketplace sealing in Rust,
verify our decryption recovers plaintext
- decrypt_and_export_writes_env_file — full e2e through CLI surface
- decrypt_and_export_replaces_existing_token — stale BOT_TOKEN replaced,
other env lines preserved
- decrypt_rejects_wrong_key — XChaCha20 AEAD tag fails on wrong key
- pem_roundtrip — write_pkcs8 + parse_pkcs8 round-trip
- b64decode_accepts_urlsafe_and_standard — handles both encodings
Cross-verified end-to-end:
$ node marketplace_seal.mjs <pub> <token> → /tmp/blob.json
$ kei-buddy decrypt-and-export --vps-key ... → BOT_TOKEN matches input
Constructor Pattern: 1 file (provision_decrypt.rs, 344 LOC), 1 module,
1 responsibility (token-blob decryption + key generation).
=== STATUS-TRUTH MARKER ===
shipped: functional
stubs: 0
cargo-check: PASS
behaviour-verified: yes (e2e marketplace-seal → kei-buddy-decrypt round-trip)
follow-up-required:
- none
|
||
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| Cargo.toml | ||
| README.md | ||
kei-buddy
Maturity: concept / scaffold — no business logic yet.
Purpose
kei-buddy is the runtime crate that composes existing KeiSeiKit
primitives (kei-pet, kei-memory-sqlite, kei-cortex,
kei-notify-telegram) into a personal-assistant Telegram bot called
KeiBuddy.
On first contact the bot walks the user through an 11-state onboarding flow: name, tone, interests, hobbies, per-topic decomposition (specifics → now-or-later → research preference → source selection), and digest schedule. After onboarding the bot enters ongoing conversation mode, drawing on the stored persona and memory.
This crate provides the state-machine enum and skeleton driver. The
onboarding FSM is ported from
keisei-marketplace/src/lib/keibuddy/chat-onboard.ts.
Status
Scaffold only. The OnboardState enum and TransitionInput struct are
defined. All transition logic is stubbed (next() returns self.clone()).
The binary entry point prints a placeholder message and exits 0.
Running
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_BOT_TOKEN |
yes (serve) | — | Bot token from @BotFather |
TELEGRAM_WEBHOOK_SECRET |
yes (serve) | — | Secret token for webhook verification |
KEI_BUDDY_PORT |
no | 8080 |
HTTP port to bind |
KEI_BUDDY_DB_PATH |
no | ./kei-buddy.db |
SQLite database path |
OPENAI_API_KEY |
no | — | Enables OpenAiExtractor when set (requires extractor-openai feature) |
Subcommands
# Apply schema (idempotent; run once before first serve)
kei-buddy migrate
# Register the webhook URL with Telegram
kei-buddy webhook-set https://your-domain.com/webhook
# Start the HTTP server
kei-buddy serve
# Remove the registered webhook (revert to polling)
kei-buddy webhook-delete
Example systemd unit
[Unit]
Description=KeiBuddy Telegram bot
After=network.target
[Service]
EnvironmentFile=/etc/kei-buddy/env
ExecStart=/usr/local/bin/kei-buddy serve
Restart=on-failure
User=keisei
[Install]
WantedBy=multi-user.target
Roadmap
- OpenAiExtractor wiring — pass real OPENAI_API_KEY to OpenAiExtractor in serve.rs when feature enabled.
- Persona binding — read persona manifest via
kei-pet; apply tone overlay to outgoing replies. - Digest scheduling — wire
kei-cron-schedulerfor morning/evening digest delivery.