Hasil audit alur AI agent round 3 (fokus correctness & latent crash).
- fix(subagent): engine.rs sebelumnya mengeksekusi tool lalu push
ChatMessage::tool hasil TANPA mendahuluinya dengan pesan assistant yang
mendeklarasikan tool_calls → history malformed ([..., tool, tool,
assistant(text)]). Kontrak OpenAI/Anthropic mensyaratkan pesan assistant
(berisi tool_calls) sebelum hasil tool. Kini push response_msg
(assistant + tool_calls + content) sebelum eksekusi, dan hapus push
assistant content-only di akhir (agar tidak duplikat). Loop utama sudah
benar; subagent kini selaras.
- fix(utils): &content[..1500] / &content[..1000] di build_rich_context
dan &diff[..5000] di auto/engine.rs bisa panic saat indeks byte jatuh di
tengah karakter multi-byte UTF-8 (emoji/CJK/panah). Tambah helper
truncate_chars() yang memotong per karakter (char-safe) dan pakai di
3 titik tersebut.
- test: +4 unit test truncate_chars (ASCII, potong, multibyte no-panic,
emoji).
Catatan audit: subagent/auto (auto-review) & build_rich_context adalah dead
code (spawn_background_review & build_rich_context tidak pernah dipanggil).
Auto-review jangan diaktifkan asal (parser format teks rapuh + tanpa
verifikasi pasca-fix) — dilaporkan, bukan dicolokkan.
Lanjutan audit alur AI agent (round 2), mengisi celah yang tersisa dari
perpbaikan paralel tool di loop utama (74b1ad4) agar lebih mirip Claude Code.
- feat(subagent): eksekusi batch tool read-only paralel di subagent engine
(engine.rs). Tool::run sinkron, jadi pakai scoped OS thread (bounded
window 8); hasil dipertahankan dalam urutan panggilan asli. Batch dengan
tool mutating jatuh balik ke jalur sequential aman.
- feat(agent): auto-load AGENTS.md/CLAUDE.md/.cursorrules ke system prompt
tiap turn (seperti Claude Code load AGENTS.md saat startup). Fungsi
main_agent_prompt_with_project_context menempel blok PROJECT CONTEXT;
dibaca dari workspace root pertama & dibatasi 12k char.
- feat(prompt): arahan VERIFY AFTER EDIT — setelah edit/write, agent wajib
jalankan cargo check/clippy/test (atau lint/test sesuai stack) via bash
sebelum mengakhiri turn; perbaiki error yang terlihat, jangan klaim
'compiles/works' tanpa hasil nyata.
- feat(infra): build_rich_context kini membaca AGENTS.md & CLAUDE.md juga
(untuk explore_codebase/scout).
- test: +3 subagent engine (order paralel, kecepatan konkuren, fallback
mutating), +2 domain prompt (konteks proyek & fallback kosong).
Sebelumnya loop utama mengeksekusi semua tool call satu-per-satu
(sequential for loop). Seperti Claude Code, tool read-only yang
independen dalam satu pesan assistant (read/grep/glob/semantic_search
dsb.) kini dijalankan konkuren dengan bounded parallelism (max 8),
mengurangi latensi per turn secara signifikan untuk beban coding.
- feat(registry): tool_is_parallel_safe() — whitelist tool read-only
yang aman dijalankan paralel; tool mutating/shell tetap sequential
- feat(executor): is_parallel_safe() delegasi ke registry; ToolExecutor
trait Default=false (konservatif)
- fix(application): execute_tool_calls_in_parallel() — join_all +
semaphore bounded 8, hasil dikumpulkan dalam URUTAN panggilan asli
(kontrak OpenAI/Anthropic tool-result ordering)
- loop utama: batch paralel hanya jika SEMUA tool parallel-safe; jika
ada satu tool mutating, jatuh balik ke jalur sequential aman
- test: +2 registry test, +2 application test (konkurensi & urutan,
fallback batch mutating)
Model terbaru di 9router adalah claude-opus-5. Update semua jalur
model default Opus:
- fix(app_config_repo): fallback default_model custom_model.unwrap_or
-> claude-opus-5; model_roles list claude-opus-5
- fix(app_config): router provider default_model -> claude-opus-5
- fix(settings test): assertion claude-opus-5
- fix(data): ~/.local/share/zesdex/settings.json model -> claude-opus-5
TUI turn.rs & daemon handler.rs ambil model langsung dari
settings.model (tersimpan 'deepseek-v4-flash-free' di
~/.local/share/zesdex/settings.json) padahal provider sudah 'claude'.
- feat(domain): resolve_effective_model() — saat provider claude, model
diambil dari app_config provider claude (default_model=claude-opus-4-8
hasil deteksi ~/.claude/settings.json), menang atas settings.model basi.
Provider non-claude tetap hormati settings.model user.
- fix(tui): turn.rs pakai resolve_effective_model (bukan settings.model)
- fix(daemon): handler.rs run_turn + compaction pakai resolve_effective_model
- fix(data): ~/.local/share/zesdex/settings.json model deepseek -> claude-opus-4-8
- test: 3 unit test resolve_effective_model
Perbaiki provider claude agar selalu refresh dari settings.json dan
menjadi default (claude-opus-4-8) setiap startup:
- fix(app_config_repo): ganti or_insert -> insert untuk provider claude —
base_url/key dari ~/.claude/settings.json selalu di-refresh, tidak
tertutup snapshot lama app_config.json.
- fix(app_config_repo): hapus kondisi default_provider == default — saat
settings.json terdeteksi, default_provider='claude' dan
default_model='claude-opus-4-8' SELALU di-set (sebelumnya skip kalau
user pernah ganti provider).
- fix(subagent/provider): resolve_subagent_provider fallback ke
app_config.default_provider/default_model kalau settings.provider/model
kosong — subagent ikut pakai Opus.
- test: 4 unit test (parse settings.json, refresh stale provider, custom
model, env fallback). Verified live: settings.json terbaca (9router URL
+ key).
Ganti explore phase MANDATORY (3 subagent tiap turn, boros) dengan
tool explore_codebase yang DIPUTUSKAN agent sendiri (lazy, token-aware):
- hapus ExploreService trait + with_explore + Phase 0 dari turn loop
- ExploreServiceImpl kini jadi tool 'explore_codebase' (1 context-scout
subagent, read-only, cap output 4k chars)
- system prompt: instruksi TOKEN BUDGET (jawab langsung utk query simple,
panggil explore_codebase sekali utk task kompleks)
Loop utama kini adaptif & self-healing:
- max_tokens adaptif (800/1600/4096 by request length) — bukan selalu 4096
- temperature 0.2 saat tool-calling, 0.7 utk final answer
- ErrorTracker: deteksi tool error berulang → inject recovery note,
stop setelah 8 error total (bukan 50 iterasi sia-sia)
- auto-compact history > 60k chars sebelum LLM call
- tool output di-truncate ke 12k chars sebelum masuk konteks
Tambah 8 unit test (truncation, adaptive tokens, error tracker).
- fix(view): token streaming kini benar-benar tampil — sebelumnya cache
display_lines tidak pernah di-rebuild saat pesan terakhir berubah
(msg_count == cached_count), jadi teks AI streaming tidak pernah muncul
sampai pesan baru/resize
- perf(view): streaming kini hanya re-render pesan TERAKHIR (splice di
batas cached_last_start) → O(konten baru) per token, bukan O(seluruh
history); guard cached_last_len mencegah re-render pada frame spinner
tanpa token baru
- perf(run): skip chrono::Utc::now() + drain toasts saat tidak ada toast
- perf(misc): drain_expired_toasts tidak lagi clone seluruh daftar toast
- perf(view): render_toasts fast-path saat toasts kosong
- Tambah users_lock (Mutex) di ApiState untuk serialisasi read-modify-write
users.json pada endpoint register; lock hanya dipegang selama operasi
file sinkron (tidak pernah lintas .await, menjaga future tetap Send)
- Hash password dihitung sebelum lock sehingga request concurrent tidak
saling blokir selama hashing Argon2
Security fixes hasil audit:
- fix(auth): refresh token kini memakai claim typ=refresh; access token
tidak bisa dipakai sebagai refresh token (sebelumnya bisa — eskalasi
masa berlaku 1 jam -> 7 hari)
- fix(api): layer JWT hanya melindungi route /sessions dan /chat;
/auth/login, /auth/register, /auth/refresh, /health kini publik
(sebelumnya semua route 401-lock, API tidak bisa dipakai sama sekali)
- fix(ws): endpoint /ws kini memverifikasi token ZESDEX_WS_TOKEN via
query param jika env diset (mencegah pemakaian LLM proxy terbuka)
- feat(api): rate limiting login/register/refresh (20 request / 10 menit
per client IP) memakai RateLimiter yang tadinya dead code
- test(jwt): tambah unit test token type access vs refresh + expired
openssl-sys vendors an OpenSSL source that runs ./Configure via perl during
the build phase. The Nix sandbox had no perl on PATH, causing the gatekeeper
build of the zesdex binary to fail ('Command failed ... openssl-build ...
Configure'). Adding perl to nativeBuildInputs makes the vendored build
resolve. This unblocks the GHA-only deploy workflow.
The gateway crate's package name is zesdex-gateway (not zesdex-backend);
the stale -p flag caused to fail in CI with
'package ID specification zesdex-backend did not match any packages'.
This unblocks the GHA-only deploy workflow.
Adds the canonical Nix CI/CD deploy workflow (install Nix, build .#default,
copy to VPS via SSH, update profile, systemctl restart) previously missing
from this repo. Enforces push-to-GitHub + GHA deploy only (no direct deploy).
- Use type alias ExtDispatch for the HashMap type (fixes type_complexity)
- Use .insert() instead of HashMap::from([...]) to avoid fn ptr trivial casts
- Remove all as fn(...) casts to avoid clippy::trivial_casts
- turn.rs: remove needless ref borrowing
- view/mod.rs: use unit struct directly instead of ::default() for
ChatComponent, InputComponent, StatusBarComponent, SidebarComponent
These were uncovered after fixing the infrastructure crate errors.
Fix 18 clippy errors across 7 files:
- lib.rs: change doc comment to regular comment (empty line after doc)
- arch_audit.rs: replace format!() with string literal, use is_none_or
- code_quality.rs: collapsible if, map_or → is_none_or
- commit.rs: collapsible match guard
- explore.rs: needless_range_loop → iterator enumerate
- skills.rs: map_or(false,...) → is_some_and
- semantic_search.rs: map_or → is_none_or, sort_by → sort_by_key,
remove explicit type to avoid type_complexity
CI was failing with 'error: could not compile zesdex-infrastructure
due to 18 previous errors' at clippy step.
- Added `ExploreService` trait and `ExploreServiceImpl` struct to handle the exploration of codebase context before agent turns.
- Implemented three parallel subagents: Code Structure, Symbol Index, and Semantic Context, each with specific directives.
- Integrated the explore phase into the agent turn process, ensuring that each turn starts with a consolidated context message.
- Enhanced `spawn_agent_turn` function to include explore service wiring and context preparation.
- Implemented a code quality scanner that checks for common clean-code violations in Rust source files, including missing documentation, usage of `.unwrap()` in production code, and commented-out code.
- Introduced a commit message validator that follows the Conventional Commits specification, ensuring proper formatting and providing suggestions for invalid messages.
- Created a unified BestPracticeEngine to encapsulate the functionalities of skills, architecture audits, code quality checks, and commit message validation.
- Added tests for both the code quality scanner and commit message validator to ensure reliability and correctness.
- Created solid.md to document the SOLID principles for clean code practices.
- Created tdd.md to outline Test Driven Development principles and practices.
- Added kana-rust-backend-best-practice.md as a reference guide for building a Rust backend using Axum and SeaORM.
- Established push-flow-convention.md to enforce pre-commit and pre-push hooks with versioning rules.
- Introduced AGENTS.md to provide guidance on best practices and available commands for Kilo.
- Configured kilo.json to include new skills and agents for enhanced functionality.
- Added lefthook.yml for managing git hooks to ensure code quality and adherence to conventions.