Replace global failed-attempt counter with per-client HashMap keyed by
client identity (IP address for gateway, chat_id for Telegram). This
prevents a single attacker from locking out all legitimate clients.
Bounded state: entries are evicted after lockout expiry, and the map is
capped at 1024 tracked clients.
Closes#603
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three related agent UX issues found during MiniMax channel testing:
1. DateTimeSection injected only timezone, not the actual date/time.
Models have no reliable way to know the current date from training
data alone, causing wrong or hallucinated dates in responses.
Fix: include full timestamp (YYYY-MM-DD HH:MM:SS TZ) in the prompt.
2. The `date` shell command was absent from the security policy
allowed_commands default list. When a model tried to call
shell("date") to get the current time, it received a policy
rejection and told the user it was "blocked by security policy".
Fix: add "date" to the default allowed_commands list. The command
is read-only, side-effect-free, and carries no security risk.
3. (Context) The datetime prompt fix makes the date command fallback
largely unnecessary, but the allowlist addition ensures the tool
works correctly if models choose to call it anyway.
Non-goals:
- Not changing the autonomy model or risk classification
- Not adding new config keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a `config schema` subcommand that dumps the full configuration
schema as JSON Schema (draft 2020-12) to stdout. This enables
downstream consumers (like PankoAgent) to programmatically validate
configs, generate forms, and stay in sync with zeroclaw's evolving
config surface without hand-maintaining copies of the schema.
- Add schemars 1.2 dependency and derive JsonSchema on all config
structs/enums (schema.rs, policy.rs, email_channel.rs)
- Add `Config` subcommand group with `Schema` sub-command
- Output is valid JSON Schema with $defs for all 56 config types
fix(misc): complete parking_lot::Mutex migration (fixes#505)
- DiscordChannel: store actual channel_id in ChannelMessage.channel
instead of hardcoded "discord" string
- channels/mod.rs: use msg.channel instead of msg.sender for replies
- Migrate all std::sync::Mutex to parking_lot::Mutex:
* src/security/audit.rs
* src/memory/sqlite.rs
* src/memory/response_cache.rs
* src/memory/lucid.rs
* src/channels/email_channel.rs
* src/gateway/mod.rs
* src/observability/traits.rs
* src/providers/reliable.rs
* src/providers/router.rs
* src/agent/agent.rs
- Remove all .lock().unwrap() and .map_err(PoisonError) patterns
since parking_lot::Mutex never poisons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(security): enhance shell redirection blocking in security policy
Block process substitution (<(...) and >(...)) and tee command in
is_command_allowed() to close shell escape vectors that bypass existing
redirect and subshell checks.
Closes#514
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: apply rustfmt to providers/mod.rs
Fix pre-existing formatting issue from main.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Fixes#430 - Prevents duplicate memories after restart by using platform message IDs instead of random UUIDs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use Path::components() to check for actual .. path components instead of
simple string matching (which was too conservative)
- Block URL-encoded traversal attempts (e.g., ..%2f)
- Expand tilde (~) for comparison
- Use path-component-aware matching for forbidden paths
- Update test to allow .. in filenames but block actual path traversal
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- 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