Commit graph

162 commits

Author SHA1 Message Date
Argenis
e5cd3f1378
Merge pull request #75 from theonlyhennygod/fix/imessage-sql-injection-50
fix(imessage): replace sqlite CLI path with rusqlite parameterized reads
2026-02-14 21:24:41 -05:00
Argenis
cd2517b5b7
Merge pull request #74 from fettpl/fix/gateway-timeout-layer
fix: apply TimeoutLayer to gateway router for request timeouts
2026-02-14 21:23:31 -05:00
Argenis
f70bf3f943
Merge pull request #72 from fettpl/fix/windows-key-permissions-warning
fix: log warning when Windows key file permissions fail to set
2026-02-14 21:21:30 -05:00
Argenis
c327260e28
Merge pull request #73 from fettpl/fix/constant-time-eq-length-leak
fix: constant_time_eq no longer leaks secret length via early return
2026-02-14 21:20:07 -05:00
Argenis
0a94b54b79
Merge pull request #87 from fettpl/fix/stable-hex-check
fix: replace unstable is_multiple_of with modulo and fix flaky temp test
2026-02-14 20:45:20 -05:00
fettpl
e56bcf7a89 Merge remote-tracking branch 'origin/main' into fix/stable-hex-check
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:30:30 +01:00
fettpl
6d68e89ef0 Merge remote-tracking branch 'origin/main' into fix/windows-key-permissions-warning
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:29:59 +01:00
fettpl
82601f17f5 Merge remote-tracking branch 'origin/main' into fix/gateway-timeout-layer
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:29:40 +01:00
fettpl
b5071c13f3 Merge remote-tracking branch 'origin/main' into fix/constant-time-eq-length-leak
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:29:24 +01:00
fettpl
65c22ff027 Merge remote-tracking branch 'origin/main' into fix/bearer-token-hashing
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:29:09 +01:00
fettpl
2741e0f024 Merge remote-tracking branch 'origin/main' into fix/key-generation-csprng
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:28:52 +01:00
fettpl
33f64c7146 fix: consolidate env-var override tests to eliminate parallel races
Tests that set/remove the same environment variables can race when
cargo test runs them in parallel. Merges each racing pair into a
single test function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:27:13 +01:00
fettpl
e62b7c9153 fix: consolidate env-var override tests to eliminate parallel races
Tests that set/remove the same environment variables can race when
cargo test runs them in parallel. Merges each racing pair into a
single test function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:27:08 +01:00
fettpl
f87cbb28f2 fix: consolidate env-var override tests to eliminate parallel races
Tests that set/remove the same environment variables can race when
cargo test runs them in parallel. Merges each racing pair into a
single test function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:27:02 +01:00
fettpl
882e1320dc fix: consolidate all env-var override tests to eliminate parallel races
Extends the temperature test fix to also cover provider, api_key, port,
and host env-var tests that had the same race condition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:26:51 +01:00
fettpl
65a5c3c1e8 fix: consolidate env-var override tests to eliminate parallel races
Tests that set/remove the same environment variables can race when
cargo test runs them in parallel. Merges each racing pair into a
single test function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:26:39 +01:00
fettpl
cfa44250a7 fix: consolidate env-var override tests to eliminate parallel races
Tests that set/remove the same environment variables (PROVIDER,
PORT, HOST, TEMPERATURE, API_KEY) can race when cargo test runs
them in parallel. Merges each racing pair into a single test function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:26:04 +01:00
argenis de la rosa
04a35144e8 feat: integrate open-skills library and cleanup clippy warnings
- Add open-skills auto-clone/pull/sync support in skills loader
  - Clone https://github.com/besoeasy/open-skills to ~/open-skills
  - Weekly sync via .zeroclaw-open-skills-sync marker
  - Env controls: ZEROCLAW_OPEN_SKILLS_ENABLED, ZEROCLAW_OPEN_SKILLS_DIR
  - Load open-skills markdown files before workspace skills
  - Track Skill.location for accurate prompt rendering

- Update system prompt to render skill.location with fallback
  - Use actual file path when available
  - Maintain backward compatibility with workspace SKILL.md path

- Fix clippy warnings across tests and supporting files
  - Readable timestamp literals
  - Remove underscore bindings in tests
  - Use struct update syntax for Config::default() patterns
  - Fix module inception, duplicate attributes, manual strip
  - Clean raw string hashes and empty string construction

Resolves: #77
2026-02-14 20:25:07 -05:00
fettpl
f7ae04e64e Merge remote-tracking branch 'origin/main' into fix/windows-key-permissions-warning
# Conflicts:
#	src/security/secrets.rs
2026-02-15 02:16:00 +01:00
fettpl
d2afc014b2 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:15:38 +01:00
fettpl
0247ac13e8 Merge remote-tracking branch 'origin/main' into fix/gateway-timeout-layer 2026-02-15 02:15:28 +01:00
fettpl
e0341e5996 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:15:24 +01:00
fettpl
b3c995c849 Merge remote-tracking branch 'origin/main' into fix/constant-time-eq-length-leak 2026-02-15 02:15:13 +01:00
fettpl
0603bed843 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:15:08 +01:00
fettpl
74648717f7 Merge remote-tracking branch 'origin/main' into fix/bearer-token-hashing 2026-02-15 02:14:45 +01:00
fettpl
dc0d6b6ca9 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 02:14:25 +01:00
fettpl
8d7e9a7dde Merge remote-tracking branch 'origin/main' into fix/key-generation-csprng 2026-02-15 02:14:06 +01:00
fettpl
6f64099a48 fix: replace unstable is_multiple_of with modulo and fix flaky temp test
The `is_multiple_of` method is unstable before Rust 1.87, breaking Docker
builds that use rust:1.83-slim. Also merges the two temperature env-var
tests into one to eliminate the race condition when tests run in parallel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:29:23 +01:00
fettpl
91f2edab05 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:27:03 +01:00
fettpl
ac7c625368 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:26:44 +01:00
fettpl
671c3b2a55 fix: replace unstable is_multiple_of and update Cargo.lock for sha2
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.
Also regenerates Cargo.lock to include the sha2 dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:26:24 +01:00
argenis de la rosa
a68004184c fix(secrets): harden windows icacls username edge cases 2026-02-14 19:25:30 -05:00
fettpl
41ba251686 fix: replace unstable is_multiple_of with modulo for Rust 1.83 compat
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:24:24 +01:00
argenis de la rosa
db1366f3e5 fix(ci): restore stable hex check and satisfy browser clippy gate 2026-02-14 19:09:35 -05:00
Edvard
1110158b23 fix: propagate warmup errors and skip when no API key configured
Address review feedback from @coderabbitai and @gemini-code-assist:
- Missing API key is now a silent no-op instead of returning an error
- Network/TLS errors are now propagated via `?` instead of silently
  discarded, so they surface as non-fatal warnings in the caller's log
- Added `error_for_status()` to catch HTTP-level failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 18:51:23 -05:00
Edvard
cc13fec16d fix: add provider warmup to prevent cold-start timeout on first channel message
The first API request after daemon startup consistently timed out (120s)
when using channels (Telegram, Discord, etc.), requiring a retry before
succeeding. This happened because the reqwest HTTP client's connection
pool was cold — no TLS handshake, DNS resolution, or HTTP/2 negotiation
had occurred yet.

The fix adds a `warmup()` method to the Provider trait that establishes
the connection pool on startup by hitting a lightweight endpoint
(`/api/v1/auth/key` for OpenRouter). The channel server calls this
immediately after creating the provider, before entering the message
processing loop.

Tested on Raspberry Pi 5 (aarch64) with OpenRouter + DeepSeek v3.2 via
Telegram channel. Before: first message took 2-7 minutes (120s timeout +
retries). After: first message responds in <30s with no retries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 18:43:26 -05:00
Argenis
b931aeb56c
Merge pull request #69 from fettpl/fix/llm-error-leakage
fix: stop leaking LLM error details to clients
2026-02-14 18:34:30 -05:00
fettpl
2f2f56fc0c fix: use branchless operations in constant_time_eq
- Use bitwise & instead of && to avoid short-circuit timing leak
- Use get().unwrap_or(&0) instead of if/else for branchless byte access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:30:23 +01:00
fettpl
6fd4b2d750 fix: handle empty USERNAME and add debug log for icacls success
- Check for empty USERNAME env var before running icacls to avoid a
  doomed invocation with ":F" grant argument
- Log a clear warning when USERNAME is empty
- Add tracing::debug on successful permission set

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:29:22 +01:00
fettpl
23048d10ac refactor: simplify hash_token using format macro
Replace manual hex encoding loop with `format!("{:x}", Sha256::digest(...))`,
which is more idiomatic and concise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:28:04 +01:00
fettpl
a7ed2329d1 fix: assert variant_match in CSPRNG key entropy test
Add missing assertion for variant_match (byte[8] UUID v4 variant bits)
which was computed but never checked.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:25:20 +01:00
argenis de la rosa
7c3f2f565f fix(imessage): replace sqlite CLI path with rusqlite parameterized reads
- use rusqlite with SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_NO_MUTEX
- run sync sqlite reads via spawn_blocking
- bind since_rowid with ?1 parameter to avoid SQL interpolation
- add comprehensive edge-case tests for message fetch and rowid helpers

Fixes #50
2026-02-14 18:10:39 -05:00
fettpl
8a304505df fix: apply TimeoutLayer to gateway router for request timeouts
Add tower-http TimeoutLayer with the existing REQUEST_TIMEOUT_SECS (30s)
constant and 408 Request Timeout status code. Previously, the constant
was defined but no timeout middleware was applied, allowing slow
requests to hold connections indefinitely (slow-loris risk).

Closes #60

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:04:05 +01:00
fettpl
6776373e8e fix: constant_time_eq no longer leaks secret length via early return
Remove the early return on length mismatch that leaked length
information via timing. Now iterates over max(a.len(), b.len()),
padding the shorter input with zeros, and checks both byte-level
differences and length equality at the end.

Closes #57

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:01:23 +01:00
fettpl
2942e5607d fix: log warning when Windows key file permissions fail to set
Replace silently discarded icacls result with proper error handling
that logs a tracing::warn! on failure. Previously, if icacls failed
(binary not found, permission denied), the key file would remain
world-readable on Windows with no indication of the problem.

Closes #56

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:59:36 +01:00
fettpl
b3bfbaff4a fix: store bearer tokens as SHA-256 hashes instead of plaintext
Hash paired bearer tokens with SHA-256 before storing in config and
in-memory. When authenticating, hash the incoming token and compare
against stored hashes. Backward compatible: existing plaintext tokens
(zc_ prefix) are detected and hashed on load; already-hashed tokens
(64-char hex) are stored as-is.

Closes #58

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:58:09 +01:00
Argenis
da9a607788
Merge pull request #70 from theonlyhennygod/theonlyhennygod-patch-1
Update CI workflow to simplify steps and add build
2026-02-14 17:54:50 -05:00
fettpl
25e5f670bb fix: stop leaking LLM error details to HTTP clients and WhatsApp users
Log full error details server-side with tracing::error! and return
generic messages to clients. Previously, the raw anyhow error chain
(which could include provider URLs, HTTP status codes, or partial
request bodies) was forwarded to end users.

Closes #59

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:53:39 +01:00
Argenis
658b9fa4fc
Update CI workflow to simplify steps and add build
Removed unnecessary steps for formatting and clippy checks, and added a build step.
2026-02-14 17:53:39 -05:00
fettpl
1f9247092c fix: replace UUID v4 key generation with direct CSPRNG
Use ChaCha20Poly1305::generate_key(&mut OsRng) to generate encryption
keys directly from the OS CSPRNG, providing full 256-bit entropy without
the fixed version/variant bits that UUID v4 introduces (6 fixed bits
per 128-bit UUID = only 244 effective bits from two UUIDs).

Closes #54

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:51:57 +01:00