review_enabled (default TRUE) selama ini no-op: tampil di TUI settings
overlay ("Review: true"), bisa di-toggle via command, TAPI spawn_background_review
tidak pernah dipanggil & Origin::Reviewer tidak pernah dikonstruksi. User
melihat "Review: true" padahal auto-review setelah edit tak pernah jalan.
Sekarang feature yang sudah dibangun penuh (subagent/auto/engine.rs: git diff
-> LLM review -> auto-fix HIGH/MEDIUM) di-wire:
- daemon/handler.rs: trigger setelah run_turn bila review_enabled; capture
flag+creds SEBELUM api_key/provider_cfg di-move ke LlmClient.
- tui/turn.rs: sama, gated by state.settings.flags.review_enabled.
- ws/lib.rs: channel minimal tanpa settings -> review nyala tiap prompt
(konsisten dgn default ON).
Aman: review fire-and-forget (tokio::spawn), get_git_diff skip bila no-change,
no-op bila bukan git repo (auto/engine). Creds dipakai = creds ter-resolve yg
sama dgn komposisi turn.
Verifikasi: check/clippy/fmt/test workspace hijau (0 error/warning/fail).
Sebelumnya SemanticSearch/ListSymbols/RebuildIndex menahan SYMBOL_INDEX
Mutex selama full `rebuild` (walk seluruh workspace, bisa detikan) +
selama search. Di main loop yang menjalankan read-only tools paralel,
semantic_search/list_symbols lain jadi BLOCK selama rebuild.
Refactor:
- Global berubah Mutex<Option<SymbolIndex>> -> OnceLock<Mutex<HashMap<
workspace, SymbolIndex>>> — index per-workspace, jadi pencarian workspace B
tidak mungkin bocor simbol stale dari A (workspace-awareness kini struktural,
bukan hanya via needs_rebuild).
- ensure_symbol_index(workspace, force): rebuild dijalankan DI LUAR lock
(mutex hanya dicek/insert/lookup singkat), lalu hasilnya di-swap-in di bawah
short lock. Search/list/rebuild-report tak lagi memblock thread lain selama
walk I/O. Per-workspace key menghilangkan race lintas-workspace dari skema
swap tunggal.
- Test +1 (test_ensure_symbol_index_per_workspace_isolation): verifikasi dua
workspace punya index independen, rebuild A tidak menimpa B.
Verifikasi: check/clippy -D warnings/fmt clean; test infra 64 (0 gagal).
SymbolIndex global sudah melacak workspace_path tapi SemanticSearch dan
ListSymbols Cuma rebuild saat index kosong (is_empty). Akibat: setelah
mengindeks workspace A, mencari di workspace B diam-diam mengembalikan
simbol STALE dari A — menyesatkan coding agent (referensikan simbol yang
tidak ada di repo aktif).
Fix:
- Tambah SymbolIndex::needs_rebuild(workspace) — true bila index kosong
ATAU workspace diminta beda dari yang ter-cache.
- Pakai di 2 call site (SemanticSearch::run, ListSymbols::run) menggantikan
is_empty(), jadi pindah workspace otomatis trigger rebuild.
- test: +1 (test_needs_rebuild_workspace_aware — verifikasi flip workspace
memicu rebuild bolak-balik A -> B -> A).
Catatan (bukan bug, dilaporkan): mutex SYMBOL_INDEX masih dipegang selama
full rebuild di run() — bottleneck saat semantic_search dipanggil paralel;
perbaikan butuh restrukturisasi double-checked rebuild, tak diubah di sini.
Verifikasi: check/clippy -D warnings/fmt clean; test infra 63 (0 gagal).
synth_consensus selama ini Cuma concatenate output node lalu dilabeli
"Consensus" — tidak ada sintesis. Kini:
- Resolve kredensial LLM (provider/model/base_url/api_key) dari Store,
sumber yang sama dgn execute_cycle.
- Kirim prompt sintesis ke model: minta distilasi node outputs jadi satu
laporan konsensus berisi AGREEMENTS / CONFLICTS / KEY FINDINGS /
RECOMMENDATION.
- Graceful fallback ke summary concatenation bila panggilan LLM gagal /
output kosong, supaya sintesis konsensus tidak pernah merusak siklus
hive-mind (konsisten dgn filosofi isolated-errors utk node).
- Batasi output per-node (MAX_NODE_OUTPUT_CHARS=4000, char-safe via
truncate_chars) agar prompt tetap bounded.
- test: +2 (truncation char-safe pada output besar multi-byte; concat
summary memuat semua node id).
Verifikasi: cargo check/clippy -D warnings/fmt clean; test infra 62 (0
gagal). Disk root sudah di-cargo clean (free 43.7GB, turun 98% -> 63%).
Hasil audit round 4 (workflow/hive_mind + memory + semantic_search).
- fix(memory): recall.search selama ini TIDAK pernah dipakai — tool
mengiklankan keyword search di skema tapi run() cuma list semua nama.
Kini search benar-benar memfilter (cocok di name/description/content,
case-insensitive), + output 'No memories match' bila kosong.
- fix(memory): ToolCtxBuilder tidak punya setter memory_dir dan tak ada
call-site yang mengisinya — remember/recall/forget memakai PathBuf kosong
dan menulis memory ke CWD (bukan lokasi persisten). Tambah setter
memory_dir + worktrees_dir, dan helper resolve_memory_dir() yang fallback
ke Store::new().memory_dir bila ctx.memory_dir kosong; dipakai di ketiga
tool memory.
- refactor(workflow): hapus LlmClient dummy di WorkflowRun (dibuat dengan
API key kosong + model default + base_url default lalu tak pernah dipakai
— execute_workflow menerimanya sebagai _llm_client). Kini execute_workflow
tak ambil parameter tak terpakai; LLM asli tetap lewat execute_primitive
yang resolve kredensial dengan benar.
- test: +2 (recall search memfilter; resolve_memory_dir fallback/eksplisit).
Catatan audit yang dilaporkan (belum difix): synth_consensus hanya
menggabungkan output (label Consensus menyesatkan, bukan sintesis LLM), dan
semantic_search memegang Mutex index global saat full rebuild (bottleneck
saat paralel) + index tidak workspace-aware.
PENTING (infra): disk root 100% saat kerja. Saya bebaskan ~4.6G dari /tmp +
cache aman (sekai*, verify-z, bun/npm cache). target/debug di repo = 38G —
rampah, perlu cargo clean + rebuild (jangan dibiarkan).
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
- 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.
- Add AppStateRest as the central state struct for managing TUI state.
- Implement InputState for handling user input, autocomplete, and history.
- Create MiscState to manage overlays, notifications, and editor state.
- Introduce ScrollState for viewport scrolling functionality.
- Develop TranscriptCache for efficient message rendering in the chat pane.
- Implement SimpleAgent and SimpleWorkflowEngine for agent lifecycle management.
- Add helper functions for managing effort levels and token counting.
- Organize state-related modules for better maintainability and clarity.
- Moved `AccessTier` and `SubagentEvent` enums to `zesdex_domain::subagent`.
- Consolidated workflow-related types into `zesdex_domain::workflow`.
- Updated references across the codebase to use the new domain models.
- Refactored tool execution logic to utilize a new `ToolExecutor` trait.
- Enhanced `AgentTurnService` to handle tool calls and events more effectively.
- Adjusted API handlers and state management to align with new domain structure.
- Implemented a new tool for semantic code search that indexes Rust code symbols (functions, structs, enums, traits, modules) and allows searching by name, concept, or meaning.
- Introduced a symbol index structure with methods for rebuilding the index and searching symbols.
- Added regex patterns for extracting various code symbols from Rust source files.
- Implemented scoring logic for search results based on exact matches, prefix matches, and context relevance.
- Created a web search tool that interacts with a SearXNG instance to fetch documentation and API information based on user queries.
- Added a diff preview overlay for rendering git diff output with color-coded additions and deletions in a TUI interface.
feat(shell): enhance output capturing by using threads for stdout and stderr
feat(tui): update usage widget to display token counts and provider/model information
refactor(tui): simplify status bar rendering by removing unnecessary token calculations
- Added tracing instrumentation and improved logging messages in the Pong, Todofinish, and Todowrite tools for better debugging and monitoring.
- Enhanced documentation comments for clarity on tool functionalities and workflows.
- Implemented tracing in WorkflowRun, NoteFinding, ReadFindings, and HiveMind tools to track execution phases and findings.
- Updated TUI overlays (e.g., Bash, Clear Confirm, Editor, Effort Level, Help, Key Input, Learning, Loading, MCP, Model Selector, Plan, Quit Confirm, Rewind, Settings, Todo, Usage) with debug logging to capture rendering details.
- Improved the status bar and workflow panel rendering with additional debug information.
- Added tracing to various utility functions to facilitate better performance monitoring and error tracking.
feat(bootstrap): create temporary settings and config files to prevent data loss
refactor(edit_log): switch from Vec to VecDeque for efficient memory management
fix(gateway): ensure store directories are created before starting the API server
refactor(bgbash): implement a global singleton for BashControl
feat(auth): enhance session authentication middleware to use SessionRepository
fix(edit_log_repo): update to use VecDeque for in-memory edit log storage
fix(memory_repo): add newline escaping for frontmatter fields
fix(session_lock_repo): improve error handling for lock file operations
fix(bash_tools): prevent path traversal in job_id argument
refactor(delete): enforce empty directory deletion in file system tools
fix(edit): optimize string replacement to only replace the first occurrence
fix(git_cred): improve credential management with piped input to git commands
feat(git_operator): add safety filter to block destructive git operations
fix(shell): register background jobs in Bash control
feat(spawn): add access tier specification for pipeline stages
refactor(hive_mind): run directives concurrently for improved performance
fix(auth): update refresh token verification in the refresh handler
fix(chat): optimize LLM client usage based on model matching
fix(conversations): enhance message deletion to target specific indices
feat(api): add JWT authentication middleware for all API routes
fix(state): implement refresh token verification in JwtTokenService
fix(daemon): improve usage tracking with saturating addition
fix(tui): handle compacted messages in the TUI state management
feat(tui): implement status bar with connection and turn state indicators
feat(tui): create workflow panel for agent status and progress visualization
feat(web): introduce web frontend interface with static file serving
feat(ws): add WebSocket interface for real-time communication and session management
- Removed HTTP adapter module from CMS infrastructure.
- Updated CMS infrastructure module to exclude HTTP.
- Introduced presentation layer in CMS with DTOs and handlers for REST API.
- Added command types for CMS domain operations to encapsulate input data.
- Created typed error handling for CMS presentation layer.
- Implemented handlers for CMS REST API endpoints.
- Removed HTTP DTOs and handlers from IAM infrastructure.
- Introduced command types for IAM domain operations.
- Created presentation layer in IAM with DTOs and handlers for OAuth flow.
- Implemented typed error handling for IAM presentation layer.
- Introduced `SessionId` newtype for validated session identifiers, ensuring safety against path traversal attacks.
- Updated session repository methods to accept `SessionId` instead of raw strings, enhancing type safety.
- Removed redundant error handling in repository methods by leveraging the new `Error` type from `zesdex_utils`.
- Simplified atomic JSON write operations by eliminating unnecessary error conversions.
- Enhanced integer casting with a new `CastOr` trait for safer narrowing conversions.
- Removed deprecated error handling code and consolidated error types across the codebase.
- Updated HTTP handlers to utilize the new session ID validation, improving overall robustness.
- Introduced `RepositoryError` and `ServiceError` enums in both IAM and CMS domains for better error management.
- Updated domain traits and services to return specific error types instead of `anyhow::Result`.
- Enhanced session and OAuth repository implementations to handle errors more explicitly.
- Refactored session service methods to return `Result<T, ServiceError>` for improved error handling.
- Updated HTTP handlers to utilize the new error types.
- Modified password hashing functions to run in a blocking context using `tokio::task::spawn_blocking`.
- Added tests for new error handling mechanisms and async password functions.
Extract duplicated session ID extraction + validation logic from
SessionAuthMiddleware::call() and require_session() into two shared
helper functions: extract_session_id and validate_and_build_identity.
Removes ~60 lines of duplicated code while preserving behavior:
- Both call sites now rely on the same extraction/validation path
- User-Agent default remains empty string (existing behavior unchanged)
- Error response format (401 with header/validation messages) unchanged
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the cast-allow block to zesdex-entities/src/lib.rs and
zesdex-utils/src/lib.rs (which lacked it), then remove from
65 sub-files across all 8 crates. Build and all 223 tests
continue to pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Simplified token type assignment in OAuth service.
- Removed unused session_lock module and re-exported Session from zesdex_entities.
- Cleaned up session entity by removing unnecessary comments and code.
- Consolidated session handling in HTTP handlers for better readability.
- Improved formatting and readability in OAuth repository tests.
- Enhanced session lock repository with clearer match statements.
- Streamlined session repository error handling.
- Refined RNG tests for better clarity.
- Adjusted module visibility and organization in lib.rs.
- Updated IPC client and connection code for better error handling and clarity.
- Improved frame handling in IPC for better readability.
- Organized module imports and added test utilities for IPC.
- Enhanced database connection error handling.
- Simplified JWT token creation error handling.
- Improved password verification error handling.
- Cleaned up state management code for better readability.
- Refactored middleware for session authentication and rate limiting.
- Simplified clipboard utility for better error handling.
- Enhanced logging initialization for better error reporting.
- Improved pagination utility with clearer method annotations.
- Cleaned up sanitization functions for filenames and paths.
- Enhanced slug generation functions for better clarity and usability.
Ganti semua pemanggilan Memory::read/write/remove/list di zesdex-backend
dengan MarkdownMemoryRepository dari zesdex-cms. Hapus re-export
model::memory yang sudah tidak dipakai.
Method mapping: read -> load, write -> save, remove -> delete, list -> list.
Import trait MemoryRepository untuk method resolution.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Semua pemanggilan AppConfig::load() diganti dengan
JsonAppConfigRepository + AppConfigRepository trait.
Re-export model::app_config dihapus dari model/mod.rs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Duplikasi verbatim dari crates/zesdex-backend/src/service/oauth/loopback.rs
ke zesdex-iam untuk sentralisasi primitif OAuth.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>