OpenClaw & AI Operasional

Bug P1 Hermes Agent 0.21.0: Maintenance state.db saat Gateway Aktif Bisa Memicu Korupsi

Jawaban singkat: hal utama tentang Bug P1 Hermes Agent 0.21.0: Maintenance state.db saat Gateway Aktif Bisa Memicu Korupsi adalah ini: Audit bug P1 Hermes Agent 0.21.0: maintenance state.db saat gateway aktif bisa memicu korupsi, status PR #103362, dan mitigasi aman.

Bug P1 Hermes Agent 0.21.0: doctor --fix, repair, atau prune saat gateway aktif dapat membuka second writer dan memicu korupsi state.db.

Bug P1 Hermes Agent 0.21.0: Maintenance state.db saat Gateway Aktif Bisa Memicu Korupsi

Hermes Agent 0.21.0 mendapat laporan bug P1 baru pada 5 September 2026. Menjalankan operasi maintenance terhadap state.db ketika gateway masih aktif dapat membuka jalur second writer pada database SQLite WAL. Dalam laporan lapangan issue #103339, pola ini dikaitkan dengan tujuh kejadian korupsi database dalam empat hari pada host multi-profile.

Operasi yang disebut bukan workload aneh. Dua kejadian muncul setelah hermes doctor --fix dijalankan ketika gateway masih hidup. Reporter juga mencatat sessions prune dan beberapa profile gateway yang menulis database root bersama sebagai pemicu lain.

Dampaknya lebih berat daripada chat yang gagal dibuka sesaat. Gateway dapat terus memegang file WAL yang sudah berstatus deleted, sementara proses lain bekerja pada WAL baru. Setelah itu, write berikutnya mulai gagal dengan sqlite3.DatabaseError: file is not a database. History session dan state operasional berada di jalur risiko.

Issue tersebut masih terbuka. Pull request perbaikan #103362 sudah tersedia dengan CI hijau, tetapi belum di-merge, belum direview, dan belum masuk release stable. Release terbaru masih Hermes Agent 0.21.0.

Ini bukan bug WAL yang sama dengan temuan sebelumnya

Rama Digital sebelumnya membahas risiko korupsi SQLite WAL pada Hermes Agent 0.19.0. Artikel tersebut berfokus pada bug WAL-reset di SQLite versi tertentu dan kebutuhan menguji runtime SQLite yang sudah diperbaiki.

Temuan kali ini berbeda. Fokusnya adalah cara beberapa proses Hermes menyentuh file state.db yang sama, terutama saat satu gateway masih menjadi writer dan proses maintenance membuka database tersebut untuk checkpoint atau repair.

Ini juga berbeda dari bug pembacaan WAL transient pada Hermes Agent 0.21.0. Bug itu dapat membuat Desktop gagal membuka chat sekali lalu pulih setelah retry, dengan integrity check tetap sehat. Issue #103339 melaporkan korupsi nyata dan kegagalan write yang menetap.

Jadi ada tiga kelas masalah yang perlu dipisahkan:

  • bug SQLite upstream pada runtime lama;
  • read-only SQLITE_IOERR yang transient ketika WAL sibuk;
  • operasi struktural atau maintenance dari proses kedua saat database live masih ditulis gateway.

Artikel ini hanya membahas kelas ketiga.

Bagaimana second writer merusak database live

Hermes menyimpan session dan state lain di SQLite dengan mode Write-Ahead Logging. Dalam kondisi normal, beberapa proses dapat melakukan row write karena SQLite punya mekanisme locking sendiri. Masalah muncul ketika proses kedua melakukan pekerjaan yang mengubah struktur atau lifecycle WAL ketika writer utama masih aktif.

Laporan #103339 menjelaskan signature yang konsisten. Gateway tetap memegang file descriptor ke state.db-wal (deleted). Proses lain membuka database yang sama dan membuat atau mengganti WAL. Dua proses lalu tidak lagi melihat generasi WAL yang sama. Hasil akhirnya adalah split-brain write yang merusak page terbaru pada database.

Ada tiga jalur yang dilaporkan:

  1. beberapa profile gateway mengakses shared root state.db melalui hosted_rooms;
  2. hermes doctor --fix menjalankan schema atau FTS repair dan wal_checkpoint(PASSIVE) melalui koneksi SQLite terpisah;
  3. hermes sessions prune dijalankan ketika gateway masih hidup.

Pada kasus doctor --fix, risikonya agak menjebak. Command ini terdengar seperti alat pemulihan, tetapi justru dapat memperparah situasi bila repair dilakukan pada database yang masih digunakan writer lain.

Kenapa guard yang ada bisa gagal pada saat terburuk

Hermes sudah memiliki cross-process repair lock dan pemeriksaan live writer. Keduanya belum menutup kelas bug ini.

Menurut verifikasi pada current main yang dicatat di issue, pemeriksaan holder mengembalikan hasil negatif ketika database malformed menghasilkan DatabaseError. Artinya, saat database sehat guard bisa melihat writer, tetapi saat database rusak dan repair paling mungkin dijalankan, probe dapat gagal membaca kondisi lalu bersikap seolah tidak ada holder.

Ini disebut fail-open. Repair tetap berjalan walau status writer tidak dapat dipastikan.

Jalur checkpoint di doctor punya masalah lebih langsung. Implementasinya membuka database dengan sqlite3.connect, lalu menjalankan PRAGMA wal_checkpoint(PASSIVE) tanpa gate yang sama dengan lifecycle SessionDB. Kalau gateway masih memegang database, proses maintenance masuk ke WAL yang sedang live.

Repair lock juga tidak menyelesaikan semuanya. Lock tersebut mencegah dua proses repair saling bertabrakan, tetapi tidak otomatis mencegah repair bertabrakan dengan gateway yang sudah aktif menulis.

Bukti yang ada dan batas klaimnya

Issue #103339 membawa data lapangan yang cukup serius: tujuh kejadian dalam empat hari pada satu deployment Linux/ext4 dengan tiga gateway. Dua kejadian dikaitkan langsung dengan doctor --fix. Reporter menyatakan patch lokal yang melindungi jalur tersebut tidak mengalami kejadian baru selama 48 jam.

Repo memberi label P1, type/bug, comp/cli, comp/gateway, serta sweeper:risk-session-state. Seorang contributor kemudian memeriksa jalur kode terkait di branch main dan membuka PR perbaikan.

Namun, ini belum GitHub Security Advisory dan bukan bukti bahwa setiap instalasi 0.21.0 akan korup. Angka tujuh kejadian berasal dari satu fleet, bukan pengukuran lintas pengguna. Kondisi pemicunya juga lebih dekat dengan deployment multi-profile atau operator yang menjalankan maintenance saat gateway tetap hidup.

Sikap yang waras saat ini: anggap risikonya nyata karena jalur kodenya spesifik, tetapi jangan mengarang angka prevalensi yang belum tersedia.

Perbaikan yang diusulkan PR #103362

Desain PR berubah setelah test menangkap masalah pada pendekatan pertama. Versi awal menolak semua write dari proses kedua. Ternyata itu mematahkan concurrency yang memang dibutuhkan oleh handoff claim, cron tick, dan turn lease.

Versi terbaru mempersempit gate ke operasi struktural:

  • setiap proses writer mengumumkan presence melalui file per-PID;
  • ordinary row writes tetap memakai locking SQLite dan boleh berjalan paralel;
  • repair atau checkpoint mengambil global structural lock;
  • operasi struktural menolak berjalan bila ada live writer;
  • writer baru juga ditolak bila masuk tepat ketika surgery sedang berjalan;
  • read-only operation tetap tidak memakai gate;
  • marker proses mati dibersihkan agar crash tidak meninggalkan lock permanen.

Pada jalur repair_state_db_schema, hasilnya dirancang menjadi penolakan eksplisit dengan pesan REFUSED, bukan melanjutkan repair atau melempar traceback mentah. Pada doctor --fix, WAL checkpoint dilewati bila live writer masih terdeteksi. Help text untuk repair dan prune juga mengingatkan operator agar menghentikan gateway profile terlebih dahulu.

PR menyertakan test untuk concurrent row writes, repair refusal tanpa modifikasi file, doctor checkpoint, proses fork, stale marker, close lifecycle, dan kondisi writer yang muncul di tengah operasi. Komentar terbaru di issue menyebut CI sudah hijau. Status API GitHub saat audit tetap open, mergeable state clean, dan belum ada review.

Ada satu batas penting: shared-root routing pada hosted_rooms belum diselesaikan oleh PR ini. Deskripsi PR menempatkannya di pekerjaan terpisah bersama issue #102176. Jadi walaupun PR nantinya di-merge, operator multi-profile tetap perlu memeriksa arsitektur database yang dipakai profile mereka.

Mitigasi aman untuk Hermes Agent 0.21.0

Sampai patch masuk release bertag, anggap operasi maintenance state.db membutuhkan maintenance window.

Hentikan gateway sebelum menjalankan fix atau repair

Jangan menjalankan hermes doctor --fix atau hermes sessions repair terhadap profile yang gateway-nya masih aktif. Hentikan gateway profile secara terkontrol, pastikan prosesnya benar-benar selesai, baru ambil backup dan jalankan maintenance.

Untuk sessions prune, gunakan aturan yang sama. Meski delete row biasa semestinya ditangani SQLite, field report memasukkan prune sebagai salah satu trigger dan PR baru menambahkan peringatan untuk menghentikan gateway.

Pisahkan diagnosis read-only dari tindakan perbaikan

hermes doctor tanpa --fix dimaksudkan tetap dapat membaca kondisi database. Jangan menaikkan diagnosis menjadi repair hanya karena satu error transient. Cocokkan timestamp, log, status gateway, dan hasil integrity check terlebih dahulu.

Jangan melakukan recovery pada file yang masih berubah

Bila state.db sudah menghasilkan file is not a database, hentikan seluruh writer sebelum menyentuh file utama, -wal, atau -shm. Ambil snapshot forensik dari state yang sudah dibekukan. Menjalankan repair berulang ketika gateway masih hidup dapat menambah kerusakan dan mengurangi peluang recovery.

Audit deployment multi-profile

Periksa apakah profile gateway berbeda mengarah ke root state.db yang sama. Jangan berasumsi nama profile otomatis berarti database terisolasi. Issue melaporkan hosted_rooms masih dapat merutekan beberapa profile ke shared root database.

Jika shared state memang diperlukan, jangan membuat perubahan path atau memindahkan file secara spontan di production. Dokumentasikan writer yang ada, lakukan canary, lalu tunggu keputusan upstream untuk routing dan locking yang kompatibel.

Jangan hot-patch PR langsung ke production

PR #103362 masih berubah pada hari yang sama saat dibuat. CI bahkan menemukan desain awal yang terlalu luas dan memaksa scoping ulang. Itu contoh bagus kenapa patch branch tidak boleh dianggap release.

Jika perlu menguji, gunakan salinan database dan canary terisolasi. Jangan menguji repair concurrency pada satu-satunya database production.

Checklist setelah fix resmi dirilis

Ketika release baru menyatakan perbaikan ini sudah masuk, verifikasi behavior, bukan hanya nomor versi:

  • hidupkan satu gateway dan pastikan ordinary row write tetap berjalan;
  • jalankan doctor --fix terhadap database canary yang sedang dipakai writer;
  • pastikan command menolak atau melewati checkpoint tanpa mengubah file;
  • ulangi untuk sessions repair;
  • pastikan diagnosis read-only dan export tetap bekerja;
  • hentikan gateway, lalu pastikan maintenance dapat berjalan normal;
  • jalankan concurrent handoff, cron, dan turn lease agar structural gate tidak memblokir row write yang sah;
  • cek quick check, integrity check, jumlah session, dan resume history sebelum serta setelah canary;
  • audit profile routing untuk memastikan tidak ada shared-root writer yang tidak disengaja;
  • cocokkan tag release dengan commit yang benar-benar terpasang.

Keputusan operasional

Operator Hermes Agent 0.21.0 sebaiknya tidak menjalankan maintenance write pada state.db sambil membiarkan gateway profile aktif. Ini berlaku terutama untuk doctor --fix, session repair, dan prune pada deployment multi-profile.

Temuan ini bukan alasan untuk meninggalkan SQLite WAL atau menganggap semua row write lintas proses berbahaya. PR terbaru justru mempertahankan ordinary row concurrency. Yang perlu dicegah adalah operasi struktural terhadap database live.

Stable terbaru belum membawa perlindungan tersebut. Sampai ada release bertag dan canary lulus, prosedur paling aman sederhana: hentikan writer, bekukan state, backup, baru lakukan maintenance.

Sumber primer

Lanjut membaca

Artikel yang masih relevan