1. OID-check в parse_x25519_pkcs8_pem
До: брался последний 32-байтный slice любого PKCS#8 DER, OID не
проверялся. RSA/EC/Ed25519 ключ молча давал 32 неправильных байта
→ decrypt падал с generic "wrong key" без объяснения.
После: строгая проверка длины (48 байт) + OID 1.3.101.110 (X25519,
byte slice 9..12 = 0x2b,0x65,0x6e). Внешний openssl ключ другого
алгоритма теперь даёт явную ошибку с указанием реального OID.
Константы X25519_OID + X25519_PKCS8_DER_LEN.
RFC 8410 §3 + §7 ссылка в doc-комментарии.
2. x25519-dalek feature `zeroize`
До: features=["static_secrets"] — StaticSecret хранил priv-ключ
в куче без затирания при Drop. Локальный priv_raw.zeroize() стирал
только стек-копию, оригинал в куче оставался до GC.
После: features=["static_secrets","zeroize"] — StaticSecret сам
реализует ZeroizeOnDrop, ключ затирается при выходе из scope.
3. Два новых теста:
- parse_rejects_wrong_length_der — 32-байтный DER (вместо 48)
отклоняется с сообщением про "48 bytes"
- parse_rejects_wrong_oid — DER с OID Ed25519 (0x2b,0x65,0x70)
отклоняется с сообщением про "X25519"
8/8 тестов модуля проходят, cargo check workspace чисто.
Старая 0.14.5 mcp-server (с source maps содержавшими /Users/
denisparfionovich/...) удалена с keigit.com отдельной операцией
через Forgejo DELETE API.
|
||
|---|---|---|
| .. | ||
| 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.