Commit graph

759 commits

Author SHA1 Message Date
tercerapersona
455eb3b847 feat: add prompt caching support to Anthropic provider
Implements Anthropic's prompt caching API to enable significant cost
reduction (up to 90%) and latency improvements (up to 85%) for
requests with repeated content.

Key features:
- Auto-caching heuristics: large system prompts (>3KB), tool
  definitions, and long conversations (>4 messages)
- Full backward compatibility: cache_control fields are optional
- Supports both string and block-array system prompt formats
- Cache control on all content types (text, tool_use, tool_result)

Implementation details:
- Added CacheControl, SystemPrompt, and SystemBlock structures
- Updated NativeContentOut and NativeToolSpec with cache_control
- Strategic cache breakpoint placement (last tool, last message)
- Comprehensive test coverage for serialization and heuristics

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
(cherry picked from commit fff04f4edb5e4cb7e581b1b16035da8cc2e55cef)
2026-02-18 14:29:50 +08:00
Maya Walcher
63bc4721e3 feat(onboard): add signup URL, model catalog, and live fetch for Astrai
Add three onboarding improvements for the Astrai provider:

- Signup URL: users now see "Get your API key at: https://as-trai.com"
  during onboarding instead of a blank prompt
- Curated model list: auto (best execution), GPT-4o, Claude Sonnet 4.5,
  DeepSeek V3, Llama 3.3 70B
- Live model fetch: Astrai's OpenAI-compatible /v1/models endpoint is
  now queried when an API key is present, matching other providers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:19:21 +08:00
Chummy
d70324f4f7 fix(robot-kit): format crate and harden cross-platform feature gating 2026-02-18 14:19:17 +08:00
Lumi-node
0dfc707c49 feat: add zeroclaw-robot-kit crate for AI-powered robotics
Standalone robot toolkit providing AI agents with physical world interaction.

Features:
- 6 tools: drive, look, listen, speak, sense, emote
- Multiple backends: ROS2, serial, GPIO, mock
- Independent SafetyMonitor with E-stop, collision avoidance
- Designed for Raspberry Pi 5 + Ollama offline operation
- 55 unit/integration tests
- Complete Pi 5 hardware setup guide
2026-02-18 14:19:17 +08:00
Chummy
431287184b style(tests): apply rustfmt to brittle-test hardening changes 2026-02-18 14:17:58 +08:00
Alex Gorevski
45cdd25b3d fix(tests): harden brittle tests for cross-platform stability and refactoring resilience
## Problem

The test suite contained several categories of latent brittleness
identified in docs/testing-brittle-tests.md that would surface during
refactoring or cross-platform (Windows) CI execution:

1. Hardcoded Unix paths: \Path::new("/tmp")\ and \PathBuf::from("/tmp")\
   used as workspace directories in agent tests, which fail on Windows
   where /tmp does not exist.

2. Exact string match assertions: ~20 \ssert_eq!(response, "exact text")\
   assertions in agent unit and e2e tests that break on any mock wording
   change, even when the underlying orchestration behavior is correct.

3. Fragile error message string matching: \.contains("specific message")\
   assertions coupled to internal error wording rather than testing the
   error category or behavioral outcome.

## What Changed

### Hardcoded paths → platform-agnostic temp dirs (4 files, 7 locations)
- \src/agent/tests.rs\: Replaced all 4 instances of \Path::new("/tmp")\
  and \PathBuf::from("/tmp")\ with \std::env::temp_dir()\ in
  \make_memory()\, \uild_agent_with()\, \uild_agent_with_memory()\,
  and \uild_agent_with_config()\ helpers.
- \	ests/agent_e2e.rs\: Replaced all 3 instances in \make_memory()\,
  \uild_agent()\, and \uild_agent_xml()\ helpers.

### Exact string assertions → behavioral checks (2 files, ~20 locations)
- \src/agent/tests.rs\: Converted 10 \ssert_eq!(response, "...")\ to
  \ssert!(!response.is_empty(), "descriptive message")\ across tests for
  text pass-through, tool execution, tool failure recovery, XML dispatch,
  mixed text+tool responses, multi-tool batch, and run_single delegation.
- \	ests/agent_e2e.rs\: Converted 9 exact-match assertions to behavioral
  checks. Multi-turn test now uses \ssert_ne!(r1, r2)\ to verify
  sequential responses are distinct without coupling to exact wording.
- Provider error propagation test simplified to \ssert!(result.is_err())\
  without asserting on the error message string.

### Fragile error message assertions → structural checks (2 files)
- \src/tools/git_operations.rs\: Replaced fragile OR-branch string match
  (\contains("git repository") || contains("Git command failed")\) with
  structural assertions: checks \!result.success\, error is non-empty,
  and error does NOT mention autonomy/read-only (verifying the failure
  is git-related, not permission-related).
- \src/cron/scheduler.rs\: Replaced \contains("agent job failed:")\ with
  \!success\ and \!output.is_empty()\ checks that verify failure behavior
  without coupling to exact log format.

## What Was NOT Changed (and why)
- \src/agent/loop_.rs\ parser tests: Exact string assertions are the
  contract for XML tool call parsing — the exact output IS the spec.
- \src/providers/reliable.rs\: Error message assertions test the error
  format contract (provider/model attribution in failure messages).
- \src/service/mod.rs\: Already platform-gated with \#[cfg]\; XML escape
  test is a formatting contract where exact match is appropriate.
- \src/config/schema.rs\: TOML test strings use /tmp as data values for
  deserialization tests, not filesystem access; HOME tests already use
  \std::env::temp_dir()\.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 14:17:58 +08:00
Chummy
decea532ed refactor(memory): keep default hybrid weights while adding relevance threshold 2026-02-18 14:14:33 +08:00
Edvard
8a1e7cc7ef fix(agent): use config max_tool_iterations, add memory relevance filtering, rebalance search weights
Three fixes for conversation quality issues:

1. loop_.rs and channels now read max_tool_iterations from AgentConfig
   instead of using a hardcoded constant of 10, making it configurable.

2. Memory recall now filters entries below a configurable
   min_relevance_score threshold (default 0.4), preventing unrelated
   memories from bleeding into conversation context.

3. Default hybrid search weights rebalanced from 70/30 vector/keyword
   to 40/60, reducing cross-topic semantic bleed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:14:33 +08:00
Alex Gorevski
21c5f58363 perf(cron): wrap record_run INSERT+DELETE in explicit transaction
Problem:
In record_run(), an INSERT into cron_runs followed by a pruning DELETE
ran as separate implicit transactions. If the INSERT succeeded but the
DELETE failed (e.g., due to disk pressure or lock contention), the run
table would grow unboundedly since the pruning step was lost while the
new row persisted.

Fix:
Wrap both statements in an explicit transaction using
conn.unchecked_transaction(). If either statement fails, the entire
transaction is rolled back, maintaining the invariant that the run
history stays bounded by max_run_history.

Ref: zeroclaw-labs/zeroclaw#710 (Item 5)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 14:07:31 +08:00
Alex Gorevski
9967eeb954 perf(cron): add composite index on cron_runs(job_id, started_at)
Problem:
The pruning query in record_run uses WHERE job_id = ?1 with
ORDER BY started_at DESC, but only single-column indexes exist
for job_id and started_at separately. SQLite must scan one index
and then sort or scan the other, which is suboptimal for the
combined filter + sort pattern used during pruning.

Fix:
Add a composite index CREATE INDEX IF NOT EXISTS
idx_cron_runs_job_started ON cron_runs(job_id, started_at).
This lets SQLite satisfy the WHERE job_id = ?1 ORDER BY
started_at DESC subquery in a single index scan without a
separate sort step. The existing single-column indexes are
retained for other queries that filter on only one column.

Ref: zeroclaw-labs/zeroclaw#710 (Item 7)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 14:06:59 +08:00
Chummy
151bc6a600 fix(scripts): align installer filename and docs placement 2026-02-18 13:56:35 +08:00
reidliu41
fdef03e455 feat(scripts): add one-line install script
- Add `scripts/install.sh` — a single `curl | bash` installer that handles system deps, Rust, clone, build, and install
  automatically.
- Update README Linux/macOS section with a "One-Line Installer (Recommended)" block above the existing manual steps.

1. Detects OS (Linux apt/dnf, macOS Xcode CLT)
2. Installs build deps + git via system package manager (sudo only here)
3. Installs Rust via rustup (skipped if already present)
4. Shallow-clones the repo to `/tmp/zeroclaw-install`
5. `cargo build --release --locked` + `cargo install --path . --force --locked`
6. Cleans up temp dir and prints next steps (`source ~/.cargo/env`, `zeroclaw onboard`)
2026-02-18 13:56:35 +08:00
ikunali
61eb72f6eb docs(readme): dark mode support for Star History chart 2026-02-18 13:50:42 +08:00
Chummy
d42cb1e906 fix(auth): rebase PR #200 onto main and restore auth CLI flow 2026-02-18 12:57:44 +08:00
Codex
96109d46d1 Fix pending OAuth verifier storage and account id fallback 2026-02-18 12:57:44 +08:00
Codex
e8aa63822a fix PR #200 review issues 2026-02-18 12:57:44 +08:00
Codex
39087a446d Fix OpenAI Codex contract, SSE parsing, and default xhigh reasoning 2026-02-18 12:57:44 +08:00
Codex
007368d586 feat(auth): add subscription auth profiles and codex/claude flows 2026-02-18 12:57:44 +08:00
Edvard
6d8725c9e6 fix(agent): log warning when native tool call arguments fail JSON parsing
The NativeToolDispatcher silently defaults to an empty object when tool
call arguments from the LLM fail to parse as JSON. The XML dispatcher
already logs a warning for the same case (line 68). Add a matching
tracing::warn with tool name and parse error for observability parity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:56:56 +08:00
fettpl
7de052c7d2 fix(cron): add timeout and bounded execution for due jobs 2026-02-18 12:55:21 +08:00
Alex Gorevski
5f5cb27690
fix(cron): handle ALTER TABLE race condition in schema migration
Problem: add_column_if_missing() checks PRAGMA table_info for column existence, then issues ALTER TABLE ADD COLUMN if not found. When two concurrent processes both pass the check before either executes the ALTER, the second process fails with a 'duplicate column name' error.

Fix: Catch the 'duplicate column name' SQLite error after the ALTER TABLE and treat it as a benign no-op. Also explicitly drop statement/rows handles before ALTER to release locks.

Ref: #710 (Item 8)
2026-02-17 23:50:08 -05:00
Edvard
63602a262f fix(agent): use config-driven limits in run_tool_call_loop and trim_history
run_tool_call_loop used a hardcoded MAX_TOOL_ITERATIONS (10) and
trim_history/auto_compact_history used a hardcoded MAX_HISTORY_MESSAGES (50),
ignoring the user-configurable agent.max_tool_iterations and
agent.max_history_messages values in config.toml.

Meanwhile, agent.rs correctly reads from config — creating an inconsistency
where CLI single-shot mode respected config but the channel runtime and
interactive CLI loop silently ignored it.

Changes:
- Rename constants to DEFAULT_* to clarify they are fallback defaults
- Add max_tool_iterations parameter to run_tool_call_loop
- Add max_history parameter to trim_history and auto_compact_history
- Thread config.agent.max_tool_iterations through ChannelRuntimeContext
- Both CLI code paths now pass config values to run_tool_call_loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:49:28 +08:00
h1n054ur
1c074d5204 fix(discord): use channel name for reply routing instead of discord channel ID
The Discord channel was setting msg.channel to the numeric Discord
channel ID instead of the literal string 'discord'. This caused
process_channel_message() to fail the channels_by_name lookup since
the map is keyed by channel name (e.g. 'discord', 'telegram', 'slack').

The result: the bot receives messages and generates LLM responses but
never sends them back -- target_channel resolves to None so the send
call is silently skipped.

Every other channel (telegram, slack, whatsapp, matrix, signal, irc,
imessage, lark, dingtalk, qq, email, mattermost) correctly sets this
field to its channel name string. Discord was the only one using the
platform-specific ID.
2026-02-18 12:49:06 +08:00
fettpl
4f9c87ff74 fix(policy): standardize side-effect tool autonomy gates 2026-02-18 12:42:56 +08:00
Edvard
89d0fb9a1e feat(providers): implement chat_with_history for GLM provider
The GLM provider previously relied on the trait default for
chat_with_history, which only forwarded the last user message. This adds
a proper multi-turn implementation that sends the full conversation
history to the GLM API, matching the pattern used by OpenRouter, Ollama,
and other providers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:33:51 +08:00
Ademílson Tonato
73e675d298 feat(memory): optional SQLite connection open timeout
- Add memory.sqlite_open_timeout_secs config (None = wait indefinitely).
- When set, open the DB in a thread with recv_timeout; cap at 300s.
- Default remains None for backward compatibility.
- Document in README; add tests for timeout path and default.
2026-02-18 12:18:05 +08:00
Edvard
b3b1679218 feat(channels): implement typing indicator for Telegram channel
Add start_typing/stop_typing overrides to TelegramChannel following the
same pattern as DiscordChannel: spawn a tokio task that sends
sendChatAction every 4 seconds (Telegram typing expires after 5s),
and abort it on stop_typing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:06:58 +08:00
Chummy
2560399423 feat(observability): focus PR 596 on Prometheus backend 2026-02-18 12:06:05 +08:00
argenis de la rosa
eba544dbd4 feat(observability): implement Prometheus metrics backend with /metrics endpoint
- Adds PrometheusObserver backend with counters, histograms, and gauges
- Tracks agent starts/duration, tool calls, channel messages, heartbeat ticks, errors, request latency, tokens, sessions, queue depth
- Adds GET /metrics endpoint to gateway for Prometheus scraping
- Adds provider/model labels to AgentStart and AgentEnd events for better observability
- Adds as_any() method to Observer trait for backend-specific downcast

Metrics exposed:
- zeroclaw_agent_starts_total (Counter) with provider/model labels
- zeroclaw_agent_duration_seconds (Histogram) with provider/model labels
- zeroclaw_tool_calls_total (Counter) with tool/success labels
- zeroclaw_tool_duration_seconds (Histogram) with tool label
- zeroclaw_channel_messages_total (Counter) with channel/direction labels
- zeroclaw_heartbeat_ticks_total (Counter)
- zeroclaw_errors_total (Counter) with component label
- zeroclaw_request_latency_seconds (Histogram)
- zeroclaw_tokens_used_last (Gauge)
- zeroclaw_active_sessions (Gauge)
- zeroclaw_queue_depth (Gauge)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:06:05 +08:00
Edvard
c04f2855e4 feat(tools): expose custom memory categories in memory_store tool
The MemoryCategory::Custom variant already exists in the memory backend
but the memory_store tool only accepted core/daily/conversation. Now any
string is accepted as a category, passing through to Custom(name) for
non-builtin values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:05:37 +08:00
mikeboensel
b2993d68c4
Merge pull request #727 from zeroclaw-labs/git_attributes_for_cross_platform_dev
feat(repo): add .gitattributes for cross-platform line ending normalization
2026-02-17 22:14:50 -05:00
Alex Gorevski
da326b265d fix(container): address all container anti-patterns (4.1–4.4)
- Replace broad COPY . . with targeted COPY src/ and firmware/ to
  preserve Docker layer cache across non-build file changes (4.1)
- Inline permissions/config prep into builder stage, removing the
  extra busybox stage and its maintenance/security overhead (4.2)
- Strip heavy dev tools (vim, git, iputils-ping, openssl) from dev
  image, keeping only ca-certificates and curl (4.3)
- Replace expensive zeroclaw doctor healthcheck with lightweight
  zeroclaw status; increase interval from 30s to 60s (4.4)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 10:35:09 +08:00
Chummy
9e9a4a53ab style(gemini): apply rustfmt to oauth endpoint patch 2026-02-18 10:25:15 +08:00
KNIGHTABDO
1d8e57d388 fix(gemini): route OAuth tokens to cloudcode-pa.googleapis.com
Gemini CLI OAuth tokens are scoped for Google's internal Code Assist
API at cloudcode-pa.googleapis.com/v1internal, not the public
generativelanguage.googleapis.com/v1beta endpoint.

This commit:
- Routes OAuth requests to the correct internal endpoint
- Wraps the request payload with model metadata (internal API format)
- Keeps API key auth unchanged on the public endpoint

Fixes #578
2026-02-18 10:25:15 +08:00
ZeroClaw Agent
36062fb1c2 feat(telegram): add forum topic support
Implement Telegram Forum (topic) support to allow the bot to respond
in the same topic where it was mentioned/called.

Changes:
- parse_update_message(): Extract message_thread_id and format reply_target as 'chat_id:thread_id'
- send(): Parse recipient to extract chat_id and optional thread_id
- All send methods now pass thread_id parameter and include message_thread_id in API requests
- Added test for forum topic message parsing

This ensures bot replies stay within the same forum topic thread.
2026-02-18 10:22:40 +08:00
Chummy
3467d34596 fix(agent): avoid duplicate text in markdown tool_call fallback 2026-02-18 10:15:46 +08:00
Edvard
cb7df7c87f style(agent): apply rustfmt formatting to loop_.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:15:46 +08:00
Edvard
0c46b56555 fix(agent): satisfy clippy::if_not_else lint in tool history push
Flip conditional to use positive check (is_empty) in the if-branch
to resolve clippy::if_not_else error in CI strict delta lint gate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:15:46 +08:00
Edvard
0e5a785015 fix(agent): use native format for tool result history in run_tool_call_loop
When use_native_tools is true, the agent loop now:
- Formats assistant history as JSON with tool_calls array (matching
  what convert_messages() expects to reconstruct NativeMessage)
- Pushes each tool result as ChatMessage::tool with tool_call_id
  (instead of a single ChatMessage::user with XML tool_result tags)
- Adds fallback parsing for markdown code block tool calls
  (```tool_call ... ``` and hybrid ```tool_call ... </tool_call>)

Without this, the second LLM call (sending tool results back) gets
rejected with 4xx by OpenRouter/Gemini because the message format
doesn't match the OpenAI tool calling API expectations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:15:46 +08:00
Edvard
508fb53ac1 fix(provider): delegate native tool calling through ReliableProvider
ReliableProvider wraps underlying providers with retry/fallback logic
but did not delegate `supports_native_tools()` or `chat_with_tools()`.
This caused the agent loop to fall back to prompt-based tool calling
for all providers, even those with native tool support (OpenRouter,
OpenAI, Anthropic). Models like Gemini 2.0 Flash would then output
tool calls as text instead of structured API responses, breaking the
tool execution loop entirely.

Add `supports_native_tools()` delegation to the primary provider and
`chat_with_tools()` with the same retry/fallback logic as the existing
`chat_with_system()` and `chat_with_history()` methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:15:46 +08:00
Mike-Boensel
4c6f3c3506 feat(repo): add .gitattributes for cross-platform line ending normalization
Ensures consistent LF line endings in the repository across all platforms.
Critical for shell scripts that execute on Linux CI/CD environments.

Key changes:
- Shell scripts (*.sh) enforce eol=lf to prevent bash interpreter errors
- Rust source and config files normalized to LF
- Binary files explicitly marked to prevent conversion
- Default text=auto provides safe handling for unlisted file types

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

Simplified
2026-02-17 21:12:25 -05:00
Chummy
c5602a80bd fix(gateway): honor configured max key bounds 2026-02-18 10:05:44 +08:00
fettpl
c507856710 fix(gateway): harden client identity and bound key stores 2026-02-18 10:05:44 +08:00
Alex Gorevski
b1c04d8f88 feat(tooling): add .editorconfig, rustfmt.toml, and clippy.toml
Add explicit linting and formatting configuration files to document
intent and provide consistent defaults across editors and platforms.

- .editorconfig: UTF-8, LF line endings, 4-space indent for Rust,
  2-space for YAML/TOML, preserve trailing whitespace in Markdown.
- rustfmt.toml: Pin edition to 2021 matching Cargo.toml. Uses
  standard defaults; file documents that this is intentional.
- clippy.toml: Set cognitive-complexity-threshold to 30,
  too-many-arguments-threshold to 10, and too-many-lines-threshold
  to 200. Thresholds tuned to match existing codebase patterns and
  reduce noise from existing allow-attributes.

All values match current implicit defaults or are tuned to avoid
triggering on existing code. No source code changes required.

Validated: cargo fmt --check and cargo clippy -D clippy::correctness
both pass with no regressions.

Resolves #662

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 10:02:09 +08:00
Kieran
d756293871 feat: add /clear command 2026-02-18 10:01:22 +08:00
Maya Walcher
c830a513a5 fix(provider): address Astrai follow-up review from #486
- Add "astrai" to factory_all_providers_create_successfully test
- Add "astrai" => "ASTRAI_API_KEY" in provider_env_var() for onboarding
- Add Astrai to onboarding provider selection list (Gateway tier)
- Add provider_env_var("astrai") assertion in known_providers test

Addresses review comments from @chumyin on #486.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:00:32 +08:00
daniiiiekisde
92eeb8889f feat(onboard): add missing Ollama Cloud models 2026-02-18 09:46:54 +08:00
Alex Gorevski
fbc26be7af fix(policy): treat git branch listing as read-only operation
Remove 'branch' from requires_write_access() to resolve the
contradiction where branch listing was classified as both read-only
and write-requiring. Branch listing only enumerates local refs and
has no side effects, so it should remain available under ReadOnly
autonomy mode.

Add regression tests:
- branch_is_not_write_gated: verifies classification consistency
- allows_branch_listing_in_readonly_mode: verifies end-to-end
  execution under ReadOnly autonomy
- is_read_only_detection: now explicitly asserts branch is read-only

Resolves zeroclaw-labs/zeroclaw#612

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 09:15:28 +08:00
Will Sarg
b5e1c3a8f5
chore(ci): align workflow names with file naming style (#723)
* feat: Add GitHub Actions workflows for security audits, CodeQL analysis, contributor updates, performance benchmarks, integration tests, fuzz testing, and reusable Rust build jobs

- Implemented `sec-audit.yml` for Rust package security audits using `rustsec/audit-check` and `cargo-deny-action`.
- Created `sec-codeql.yml` for CodeQL analysis scheduled twice daily.
- Added `sync-contributors.yml` to update the NOTICE file with new contributors automatically.
- Introduced `test-benchmarks.yml` for performance benchmarks using Criterion.
- Established `test-e2e.yml` for running integration and end-to-end tests.
- Developed `test-fuzz.yml` for fuzz testing with configurable runtime.
- Created `test-rust-build.yml` as a reusable job for executing Rust commands with customizable parameters.
- Documented main branch delivery flows in `main-branch-flow.md` for clarity on CI/CD processes.

* ci(workflows): update workflow scripts and rename for clarity; remove obsolete lint feedback script

* chore(ci): externalize workflow scripts and relocate main flow doc

* chore(ci): align workflow names with file naming style
2026-02-17 19:55:05 -05:00
Will Sarg
69a3b54968
chore(ci): externalize workflow scripts and relocate main flow doc (#722)
* feat: Add GitHub Actions workflows for security audits, CodeQL analysis, contributor updates, performance benchmarks, integration tests, fuzz testing, and reusable Rust build jobs

- Implemented `sec-audit.yml` for Rust package security audits using `rustsec/audit-check` and `cargo-deny-action`.
- Created `sec-codeql.yml` for CodeQL analysis scheduled twice daily.
- Added `sync-contributors.yml` to update the NOTICE file with new contributors automatically.
- Introduced `test-benchmarks.yml` for performance benchmarks using Criterion.
- Established `test-e2e.yml` for running integration and end-to-end tests.
- Developed `test-fuzz.yml` for fuzz testing with configurable runtime.
- Created `test-rust-build.yml` as a reusable job for executing Rust commands with customizable parameters.
- Documented main branch delivery flows in `main-branch-flow.md` for clarity on CI/CD processes.

* ci(workflows): update workflow scripts and rename for clarity; remove obsolete lint feedback script

* chore(ci): externalize workflow scripts and relocate main flow doc
2026-02-17 19:48:37 -05:00