refactor: adopt cora-review v2 β standalone workflow + hardened action#119
Conversation
- Extract cora-review into its own workflow (.github/workflows/cora-review.yml) with dedicated concurrency group, 10-minute timeout, and scoped permissions - Harden action.yml: pinned action SHAs, checksum verification on cora-cli download, retry logic for version resolution, empty-result handling - Remove cora-review job and elevated permissions from ci.yml (CI pipeline now contains only Rust check/fmt/clippy/test/build)
|
Warning Review limit reached
More reviews will be available in 39 minutes and 9 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. β How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. π¦ How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. βΉοΈ Review infoβοΈ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: π Files selected for processing (3)
β¨ Finishing Touchesπ§ͺ Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
π Cora AI Code Reviewβ Blocked β critical issues found. π΄ Error (2)
Review powered by cora-cli Β· BYOK Β· MIT |
* feat: add uteke-status pi extension Pi extension that shows uteke memory stats in the footer status bar: - π§ uteke: π₯3 hot | π‘0 warm | βοΈ0 cold (65 total) - Auto-refreshes after memory operations (remember, forget, import, cleanup) - Registers /uteke-stats command to manually refresh - Registers /uteke command for quick stats/aging/doctor/tags Install: copy to ~/.pi/agent/extensions/uteke-status/ or use pi install * feat(uteke-status): v2 β cross-namespace stats + system prompt injection - Query SQLite directly for cross-namespace totals (was only showing default namespace before) - Add proper spacing between icons and numbers - Inject system prompt via before_agent_start to remind agent to use uteke actively (remember, recall, search, save summaries) - Simplified: removed /uteke command, kept /uteke-stats - Uses sqlite3 CLI (pre-installed on macOS/Linux) * feat: bulk memory operations (#43) - forget <id> β now prompts for confirmation [y/N] - forget --tag <tag> β delete all memories with a tag - forget --cold β delete all cold (>30d or never accessed) memories - forget --all β delete ALL memories in namespace - All bulk ops require --confirm flag to execute - Added BulkDeleteResult type with deleted count + IDs - Added store methods: bulk_delete_by_tag, bulk_delete_cold, bulk_delete_all, count_by_tag - Added Uteke methods: bulk_forget_by_tag, bulk_forget_cold, bulk_forget_all, store() * ci: add cora AI code review composite action (#86) - Add .github/actions/cora-review composite action (downloads cora-cli from GitHub Releases, fetches LLM secrets via Infisical OIDC, runs review on PR diff, uploads SARIF to Code Scanning, posts PR comment) - Add cora-review job to CI workflow (runs after check/fmt/clippy/test pass, only on pull_request events) - Add required permissions (security-events, pull-requests, id-token) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(ci): comment default, SARIF upload optional (#87) - Post PR comment: always runs (default behavior) - SARIF upload: opt-in via upload-sarif: 'true' input - SARIF upload failure: continue-on-error (never blocks) - Blocking: only error-level findings block merge Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(ci): resolve latest version via API before download (#89) GitHub release download URL doesn't support 'latest' tag. Resolve to actual tag via GitHub API first. Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat: smooth namespace switching and defaults (#82) * feat: add uteke-status pi extension Pi extension that shows uteke memory stats in the footer status bar: - π§ uteke: π₯3 hot | π‘0 warm | βοΈ0 cold (65 total) - Auto-refreshes after memory operations (remember, forget, import, cleanup) - Registers /uteke-stats command to manually refresh - Registers /uteke command for quick stats/aging/doctor/tags Install: copy to ~/.pi/agent/extensions/uteke-status/ or use pi install * feat(uteke-status): v2 β cross-namespace stats + system prompt injection - Query SQLite directly for cross-namespace totals (was only showing default namespace before) - Add proper spacing between icons and numbers - Inject system prompt via before_agent_start to remind agent to use uteke actively (remember, recall, search, save summaries) - Simplified: removed /uteke command, kept /uteke-stats - Uses sqlite3 CLI (pre-installed on macOS/Linux) * feat: bulk memory operations (#43) - forget <id> β now prompts for confirmation [y/N] - forget --tag <tag> β delete all memories with a tag - forget --cold β delete all cold (>30d or never accessed) memories - forget --all β delete ALL memories in namespace - All bulk ops require --confirm flag to execute - Added BulkDeleteResult type with deleted count + IDs - Added store methods: bulk_delete_by_tag, bulk_delete_cold, bulk_delete_all, count_by_tag - Added Uteke methods: bulk_forget_by_tag, bulk_forget_cold, bulk_forget_all, store() * feat: smooth namespace switching and defaults (#45) - Add `uteke namespace list` β list all namespaces with memory counts - Add `uteke namespace stats <name>` β show stats for a namespace - Add `uteke namespace switch <name>` β set default namespace in config - Implement layered namespace resolution: CLI flag > env > config > default - Fix broken `resolve_namespace` that referenced undefined variable - Support UTEKE_NAMESPACE env var for per-session defaults - Config file default_namespace persists across sessions * feat: daemon/server mode for warm recall <50ms (#83) * feat: add uteke-status pi extension Pi extension that shows uteke memory stats in the footer status bar: - π§ uteke: π₯3 hot | π‘0 warm | βοΈ0 cold (65 total) - Auto-refreshes after memory operations (remember, forget, import, cleanup) - Registers /uteke-stats command to manually refresh - Registers /uteke command for quick stats/aging/doctor/tags Install: copy to ~/.pi/agent/extensions/uteke-status/ or use pi install * feat(uteke-status): v2 β cross-namespace stats + system prompt injection - Query SQLite directly for cross-namespace totals (was only showing default namespace before) - Add proper spacing between icons and numbers - Inject system prompt via before_agent_start to remind agent to use uteke actively (remember, recall, search, save summaries) - Simplified: removed /uteke command, kept /uteke-stats - Uses sqlite3 CLI (pre-installed on macOS/Linux) * feat: bulk memory operations (#43) - forget <id> β now prompts for confirmation [y/N] - forget --tag <tag> β delete all memories with a tag - forget --cold β delete all cold (>30d or never accessed) memories - forget --all β delete ALL memories in namespace - All bulk ops require --confirm flag to execute - Added BulkDeleteResult type with deleted count + IDs - Added store methods: bulk_delete_by_tag, bulk_delete_cold, bulk_delete_all, count_by_tag - Added Uteke methods: bulk_forget_by_tag, bulk_forget_cold, bulk_forget_all, store() * feat: smooth namespace switching and defaults (#45) - Add `uteke namespace list` β list all namespaces with memory counts - Add `uteke namespace stats <name>` β show stats for a namespace - Add `uteke namespace switch <name>` β set default namespace in config - Implement layered namespace resolution: CLI flag > env > config > default - Fix broken `resolve_namespace` that referenced undefined variable - Support UTEKE_NAMESPACE env var for per-session defaults - Config file default_namespace persists across sessions * feat: daemon/server mode for warm recall <50ms (#54) - Add uteke-server crate with HTTP API (tiny_http) - Endpoints: /health, /remember, /recall, /search, /list, /forget, /stats, /namespaces - Namespace support on all endpoints via JSON body - CORS headers for cross-origin access - Graceful shutdown on SIGINT (saves index, closes DB) - Config: [server] section in uteke.toml (host, port, enabled) - Benchmark: recall ~41ms (vs 2600ms CLI cold start) - Binary: uteke-serve --host 127.0.0.1 --port 8767 * feat: auto-forget, temporal facts & contradiction detection (#51) (#84) - Add temporal metadata: deprecated, valid_from, valid_until, memory_type - Memory types: fact, procedure, preference, decision, context - Contradiction detection on remember (--detect-contradiction flag) - Auto-deprecates old conflicting memories via vector similarity - Threshold calibrated for embeddinggemma-q4 model - Prune command: uteke prune --ttl 30d --dry-run - Removes deprecated memories older than TTL - Dry-run mode for safe preview - remember --type flag for memory classification - DB migration: auto-adds new columns to existing stores - All 22 tests pass * feat: knowledge graph consolidation & deduplication (#52) (#85) - Add consolidate command: uteke consolidate --threshold 0.90 --dry-run - Detect near-duplicate memories via cosine similarity - Merge duplicates: keeps newer, removes older, updates vector index - Dry-run mode shows duplicate pairs without modifying store - Add SimilarPair and ConsolidationResult types - cosine_similarity helper for O(nΒ²) pairwise comparison - Threshold configurable (default 0.90, recommend 0.60-0.70 for small models) - All 22 tests pass * feat: CLI auto-routes to server when enabled (#90) - CLI detects running uteke-serve via HTTP health check - When server.available, routes remember/recall/search/list/stats/forget via HTTP - Recall latency: 21ms (vs 946ms CLI cold start) β 45x faster - Fallback: if server not running, CLI works as before (cold start) - Config: [server] enabled = true in uteke.toml - All 22 tests pass * chore: prepare v0.0.4 release (#91) * chore: prepare v0.0.4 release - Bump version 0.0.3 β 0.0.4 - CHANGELOG: add v0.0.4 with all new features - README: add server mode, consolidate, prune, namespace switch, fix 256d embedding - CLI reference docs: add forget bulk, consolidate, prune, namespace, server mode - Configuration docs: add server section, namespace resolution - Roadmap: add v0.0.4 completed items, update next/future - Multi-agent docs: add namespace switching section - Release workflow: build both uteke + uteke-serve, updated release notes * chore: fix clippy warnings, add cora review config - Fix all clippy warnings across workspace (uteke-cli, uteke-core, uteke-server) - Fix rustfmt issues across workspace - Remove unused Arc import in uteke-server - Fix cosine_similarity placement after test module in uteke-core - Fix config loop indexing in uteke-cli - Add .cora.yaml with custom provider (glm-5.1) - Install cora pre-commit hook (warn mode) - Fix strip fallback in release workflow - Add config migration docs to website * fix(ci): cora review exit code handling (#92) - Update cora-cli to v0.1.2 (fixes spurious exit code 2) - Add || true to cora review step so SARIF is always generated - Blocking check still works via SARIF level analysis * fix(ci): proper cora review error handling (#93) - Replace || true with explicit exit code handling - Exit code 0 (clean) and 2 (findings found) both proceed - Other exit codes show ::warning with stderr log - Empty SARIF produces warning instead of silent failure - No more 2>/dev/null β errors are visible when unexpected * fix(ci): dynamic release notes from CHANGELOG.md (#94) - Extract changelog section via awk instead of hardcoded body - Filter out bottom comparison links - Printf-based footer to avoid YAML indentation leaking - Warning annotation if CHANGELOG section not found - No more manual workflow edits per release Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat(core): add UTEKE_HOME env var for custom data directory (#106) - Add public uteke_home() in uteke-core β resolves data directory - UTEKE_HOME set: uses that path directly (e.g. /data) - UTEKE_HOME unset: falls back to ~/.uteke (zero breaking change) - engine.rs: model path uses uteke_home() instead of dirs::home_dir() - lib.rs: doctor model check uses uteke_home() - uteke-server: DB path uses uteke_core::uteke_home() - Remove unused dirs dependency from uteke-server Closes #95 Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * chore(docs): update roadmap with v0.0.5-v0.0.7 milestones (#103) - v0.0.5: Docker & Deployment (5 issues) - v0.0.6: Network & Auth (4 issues) - v0.0.7: Cloud MVP (future) - Backlog reorganized (6 items) - Color-coded sections per version - Descriptions for each milestone Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat(server): read uteke.toml config + smart server fallback (#107) * feat(server): read uteke.toml config, default host 0.0.0.0 Server now reads [server] section from uteke.toml: - Layered resolution: uteke_home/uteke.toml β cwd/.uteke/uteke.toml - Default host changed: 127.0.0.1 β 0.0.0.0 (Docker-compatible) - CLI --host/--port override config values - Added toml dependency for config parsing Also fixes smart server fallback (#104): - CLI commands not supported via HTTP auto-fallback to local store - No more error 'This command requires local store' - Log message: 'Command not supported via server, using local store' Closes #96 Closes #104 * fix(server): resolve type mismatch in load_uteke_toml path array * style(server): apply cargo fmt --------- Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat(server): API parity β expanded remember, GET /memory endpoint (#108) Expanded POST /remember to accept optional fields: - type: fact, procedure, preference, decision, context - valid_from, valid_until: temporal facts - detect_contradiction: auto-deprecate conflicting memories Added GET /memory?id=<uuid> endpoint: - Returns full memory by ID - 404 if not found Updated --help to document new endpoint. Closes #105 Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat(docker): add multi-stage Dockerfile and .dockerignore (#109) Dockerfile: - Stage 1: download release binary + embedding model from HuggingFace - Stage 2: runtime only (debian:bookworm-slim + binaries + model) - ENV UTEKE_HOME=/data for volume mount - EXPOSE 8767, ENTRYPOINT uteke-serve - ARG VERSION and TARGET for build flexibility .dockerignore: - Excludes .git, target, node_modules, website, docs Closes #97 Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat(ci): Docker image build & push on release (#110) * feat(docker): add multi-stage Dockerfile and .dockerignore Dockerfile: - Stage 1: download release binary + embedding model from HuggingFace - Stage 2: runtime only (debian:bookworm-slim + binaries + model) - ENV UTEKE_HOME=/data for volume mount - EXPOSE 8767, ENTRYPOINT uteke-serve - ARG VERSION and TARGET for build flexibility .dockerignore: - Excludes .git, target, node_modules, website, docs Closes #97 * feat(ci): add Docker image build & push to release workflow Multi-arch Docker build (linux/amd64 + linux/arm64): - Triggered after release job completes - Builds from Dockerfile with VERSION and TARGET build args - Pushes to ghcr.io/ajianaz/uteke with semver tags + latest - Uses GITHUB_TOKEN for GHCR auth (no new secrets needed) - QEMU + buildx for cross-platform Closes #99 --------- Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * chore: prepare v0.0.5 release (#111) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(docker): remove pinned digest and update default version (#112) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(docker): remove pinned digest from runtime stage too (#113) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(docker): add curl retry and timeout for CI reliability (#114) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(ci): move downloads to host runner β buildx cannot access network (#115) Buildx docker-container driver cannot reach github.com/huggingface.co, causing consistent curl exit code 1. Move all downloads to CI host steps and pass files via Docker context COPY instead. - Dockerfile: COPY binaries/ and models/ from context, select by TARGETARCH - release.yml: download step before build, single multi-platform push Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(ci): use build artifacts + lazy runtime model download (#116) Primary: Docker job now depends on build-release (not release), gets binaries via actions/download-artifact@v4 β no curl to github.com. Fallback: Entrypoint checks if model exists at startup, downloads if missing β works even if CI model bake step fails. Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(ci): find artifacts recursively β merge-multiple adds subdir (#117) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix(ci): remove --strip-components from tar extraction (#118) The tar.gz archives contain uteke + uteke-serve at root level (no directory prefix). --strip-components=1 was stripping the filenames themselves, resulting in empty extraction. Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * refactor: adopt cora-review v2 β standalone workflow + hardened action (#119) - Extract cora-review into its own workflow (.github/workflows/cora-review.yml) with dedicated concurrency group, 10-minute timeout, and scoped permissions - Harden action.yml: pinned action SHAs, checksum verification on cora-cli download, retry logic for version resolution, empty-result handling - Remove cora-review job and elevated permissions from ci.yml (CI pipeline now contains only Rust check/fmt/clippy/test/build) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * fix: v0.0.6 patch & hardening (#146) * fix: v0.0.6 patch & hardening β CI, Docker, API correctness Closes #122, #123 (already done on develop), #124, #125, #126, #145 - ci.yml, release.yml: add FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 (#125) - ci.yml, release.yml: remove unused musl-tools install (#145) - release.yml: remove musl-tools apt step (#145) - Dockerfile: add non-root USER directive with uteke user (#126) - Dockerfile: create /data with correct ownership before USER switch - types.rs: add #[serde(skip_serializing)] on Memory.embedding (#124) - lib.rs: persist vector index after import() completes (#124) - vector.rs: improve expect() panic message with dims and root cause hint (#124) - .github/dependabot.yml: add Dependabot for cargo, github-actions, docker (#122) * fix(test): update test_memory_types_serialization for skip_serializing embedding The embedding field now uses #[serde(skip_serializing)], so the test verifies that embedding is excluded from JSON output and that deserialization produces an empty embedding (expected β embeddings are populated programmatically via ONNX, not from JSON). * fix: add serde(default) to skip_serializing embedding skip_serializing without default causes deserialization error when embedding field is missing from JSON. Adding default allows graceful fallback to empty vec. * release: v0.0.6 β patch & hardening - CHANGELOG: add v0.0.6 entry, reorder all versions chronologically, consolidate link refs - Cargo.toml: bump 0.0.5 β 0.0.6 --------- Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat: v0.0.7 β core stability (#157) * feat: v0.0.7 β core stability (tag refactor, config wiring, tests) #120 Tag storage: refactor all LIKE-based tag queries to json_each() - list(), unique_tags(), tags_with_counts(), count_tag(), rename_tag(), delete_tag(), bulk_delete_by_tag(), count_by_tag - tags_with_counts: N+1 β single GROUP BY query - unique_tags: in-Rust JSON parse β SQL json_each() - 11 new tag-related tests #127 Config wiring: pass tier thresholds from config to core - Add TierConfig struct (hot_days, warm_days, hot_boost) - Uteke::open_with_tier() accepts custom tier config - MemoryTier::from_last_accessed() now takes configurable thresholds - main.rs passes config.tier.* to core - 7 new config tests (merge_from_file_all_sections, expand_tilde, etc.) #129 Test coverage: +44 tests (22 β 66 in store, 8 β 25 in lib, 4 β 15 in config) - Bulk operations: bulk_delete_by_tag, bulk_delete_cold, bulk_delete_all - Store operations: rename_tag, delete_tag, deprecate, tier_counts - Edge cases: search_content, find_aged, find_similar, pagination - Double insert, namespace isolation, empty results #140 Namespace CLI: already implemented (NamespaceCommands::List) Closes #120, #127, #129, #140 * fix: update old tests for new MemoryTier::from_last_accessed() signature - Pass hot_days=7, warm_days=30 to old tier tests - Remove dead count_tag() method (replaced by count_by_tag) * fix: update all callers for tier_counts/bulk_delete_cold new signatures Old tests called tier_counts(None) and bulk_delete_cold(None) with 1 arg, but sub-agent changed signatures to accept hot_days/warm_days. Updated 5 test call sites. * fix: correct test_path_in_memory and test_search_content_edge_cases - test_path_in_memory: rusqlite may return Some for :memory: DB path - test_search_content_edge_cases: SQLite LIKE is case-insensitive by default * docs: fix configuration section in README (#128) - Fix config search paths: .uteke/uteke.toml + ~/.uteke/uteke.toml - Fix config format: proper TOML sections matching actual Config struct - Remove non-existent --config flag from CLI reference - Add all config sections: store, embedding, tier, logging, server --------- Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * release: v0.0.7 β core stability (#158) CHANGELOG: add v0.0.7 entry with all changes Cargo.toml: bump 0.0.6 β 0.0.7 Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * chore(deps): consolidate Dependabot bumps β 10 deps in 1 PR (#159) Cargo deps: - thiserror 1 β 2 (API unchanged for our usage) - dirs 5 β 6 (home_dir() unchanged) - toml 0.8 β 1 (from_str() unchanged) - uuid 1.23.1 β 1.23.2 (patch) GitHub Actions: - docker/login-action v3 β v4 - docker/metadata-action v5 β v6 - actions/upload-artifact v4 β v7 - Infisical/secrets-action v1.0.9 β v1.0.16 - actions/setup-node v4 β v6 - cloudflare/wrangler-action v3 β v4 All changes reviewed β no breaking API impact for our usage. Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> * feat: release branch setup β main as release-only mirror (#168) - Add install.sh at root with SHA256 checksum verification - Add sync-main job to release.yml (develop β main on every v* tag) - Add SHA256 checksums generation to release job - Enable Cora Review on PRs to main branch - Update INSTALL.md to reference main/install.sh - Update release notes template to use main/install.sh Clones cora-cli #154/#155/#156 release branch pattern. Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com> --------- Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com>
Summary
Adopts the hardened cora-review v2 action from
cora-cliβ same changes as cora-cli PR #107.Changes
Standalone workflow (
.github/workflows/cora-review.yml)cora-review-${{ github.ref }}) withcancel-in-progress: truecontents: read,pull-requests: write,id-token: write,security-events: write)develop(opened,synchronize,ready_for_review,reopened)Hardened composite action (
.github/actions/cora-review/action.yml)v0.1.7${{ }}interpolation)CI cleanup (
.github/workflows/ci.yml)cora-reviewjob (previously ran aftercheck/fmt/clippy/testwithneeds)security-events,pull-requests,id-token) β CI only needs defaultcontents: readFiles changed
.github/workflows/cora-review.ymlβ new standalone workflow.github/actions/cora-review/action.ymlβ updated hardened v2 action.github/workflows/ci.ymlβ cleaned up, cora job + elevated perms removed